diff --git a/README.md b/README.md
index 670195c3c92..b0a86b728ae 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
a code editor with what developers need for their core edit-build-debug cycle. Code
provides comprehensive editing and debugging support, an extensibility model, and lightweight integration with existing tools.
-VS Code is updated monthly with new features and bug fixes. You can download it for Windows, macOS, and Linux on [VS Code's website](https://code.visualstudio.com/Download). To get the latest releases everyday, you can install the [Insiders version of VS Code](https://code.visualstudio.com/insiders). This builds from the master branch and is updated at least daily.
+VS Code is updated monthly with new features and bug fixes. You can download it for Windows, macOS, and Linux on [VS Code's website](https://code.visualstudio.com/Download). To get the latest releases every day, you can install the [Insiders version of VS Code](https://code.visualstudio.com/insiders). This builds from the master branch and is updated at least daily.
diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js
index 8915457164b..f1807d26252 100644
--- a/build/gulpfile.vscode.js
+++ b/build/gulpfile.vscode.js
@@ -43,7 +43,7 @@ const nodeModules = ['electron', 'original-fs']
// Build
const builtInExtensions = [
- { name: 'ms-vscode.node-debug', version: '1.17.3' },
+ { name: 'ms-vscode.node-debug', version: '1.17.5' },
{ name: 'ms-vscode.node-debug2', version: '1.17.1' }
];
diff --git a/build/tfs/win32/smoketest.ps1 b/build/tfs/win32/smoketest.ps1
index 072707d0432..65f6896806d 100644
--- a/build/tfs/win32/smoketest.ps1
+++ b/build/tfs/win32/smoketest.ps1
@@ -38,7 +38,7 @@ step "Build minified" {
}
step "Run smoke test" {
- $Screenshots = "$env:AGENT_BUILDDIRECTORY\smoketests-screenshots"
+ $Screenshots = "$env:AGENT_BUILDDIRECTORY\smoketest-screenshots"
Remove-Item -Recurse -Force -ErrorAction Ignore $Screenshots
exec { & Push-Location test\smoke }
diff --git a/extensions/coffeescript/test/colorize-results/test-regex_coffee.json b/extensions/coffeescript/test/colorize-results/test-regex_coffee.json
index b6a7a06b854..445fab1f1c2 100644
--- a/extensions/coffeescript/test/colorize-results/test-regex_coffee.json
+++ b/extensions/coffeescript/test/colorize-results/test-regex_coffee.json
@@ -69,8 +69,8 @@
"c": "(",
"t": "source.coffee string.regexp.coffee meta.group.regexp punctuation.definition.group.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "punctuation.definition.group.regexp: #CE9178",
+ "light_plus": "punctuation.definition.group.regexp: #D16969",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
"hc_black": "string.regexp: #D16969"
@@ -80,19 +80,19 @@
"c": "\\d",
"t": "source.coffee string.regexp.coffee meta.group.regexp constant.character.character-class.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "constant.character.character-class.regexp: #D16969",
+ "light_plus": "constant.character.character-class.regexp: #811F3F",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
- "hc_black": "string.regexp: #D16969"
+ "hc_black": "constant.character: #569CD6"
}
},
{
"c": "+",
"t": "source.coffee string.regexp.coffee meta.group.regexp keyword.operator.quantifier.regexp",
"r": {
- "dark_plus": "keyword.operator: #D4D4D4",
- "light_plus": "keyword.operator: #000000",
+ "dark_plus": "keyword.operator.quantifier.regexp: #D7BA7D",
+ "light_plus": "keyword.operator.quantifier.regexp: #000000",
"dark_vs": "keyword.operator: #D4D4D4",
"light_vs": "keyword.operator: #000000",
"hc_black": "keyword.operator: #D4D4D4"
@@ -102,8 +102,8 @@
"c": ")",
"t": "source.coffee string.regexp.coffee meta.group.regexp punctuation.definition.group.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "punctuation.definition.group.regexp: #CE9178",
+ "light_plus": "punctuation.definition.group.regexp: #D16969",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
"hc_black": "string.regexp: #D16969"
@@ -454,11 +454,11 @@
"c": "#{",
"t": "source.coffee string.regexp.coffee source.coffee.embedded.source punctuation.section.embedded.coffee",
"r": {
- "dark_plus": "punctuation.section.embedded.coffee: #569CD6",
- "light_plus": "punctuation.section.embedded.coffee: #0000FF",
- "dark_vs": "punctuation.section.embedded.coffee: #569CD6",
- "light_vs": "punctuation.section.embedded.coffee: #0000FF",
- "hc_black": "punctuation.section.embedded.coffee: #569CD6"
+ "dark_plus": "punctuation.section.embedded: #569CD6",
+ "light_plus": "punctuation.section.embedded: #0000FF",
+ "dark_vs": "punctuation.section.embedded: #569CD6",
+ "light_vs": "punctuation.section.embedded: #0000FF",
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
@@ -476,11 +476,11 @@
"c": "}",
"t": "source.coffee string.regexp.coffee source.coffee.embedded.source punctuation.section.embedded.coffee",
"r": {
- "dark_plus": "punctuation.section.embedded.coffee: #569CD6",
- "light_plus": "punctuation.section.embedded.coffee: #0000FF",
- "dark_vs": "punctuation.section.embedded.coffee: #569CD6",
- "light_vs": "punctuation.section.embedded.coffee: #0000FF",
- "hc_black": "punctuation.section.embedded.coffee: #569CD6"
+ "dark_plus": "punctuation.section.embedded: #569CD6",
+ "light_plus": "punctuation.section.embedded: #0000FF",
+ "dark_vs": "punctuation.section.embedded: #569CD6",
+ "light_vs": "punctuation.section.embedded: #0000FF",
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
diff --git a/extensions/coffeescript/test/colorize-results/test_coffee.json b/extensions/coffeescript/test/colorize-results/test_coffee.json
index 55a97e8b7ef..a36d10633bf 100644
--- a/extensions/coffeescript/test/colorize-results/test_coffee.json
+++ b/extensions/coffeescript/test/colorize-results/test_coffee.json
@@ -311,11 +311,11 @@
"c": "#{",
"t": "source.coffee meta.function-call.coffee meta.arguments.coffee string.quoted.double.coffee source.coffee.embedded.source punctuation.section.embedded.coffee",
"r": {
- "dark_plus": "punctuation.section.embedded.coffee: #569CD6",
- "light_plus": "punctuation.section.embedded.coffee: #0000FF",
- "dark_vs": "punctuation.section.embedded.coffee: #569CD6",
- "light_vs": "punctuation.section.embedded.coffee: #0000FF",
- "hc_black": "punctuation.section.embedded.coffee: #569CD6"
+ "dark_plus": "punctuation.section.embedded: #569CD6",
+ "light_plus": "punctuation.section.embedded: #0000FF",
+ "dark_vs": "punctuation.section.embedded: #569CD6",
+ "light_vs": "punctuation.section.embedded: #0000FF",
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
@@ -333,11 +333,11 @@
"c": "}",
"t": "source.coffee meta.function-call.coffee meta.arguments.coffee string.quoted.double.coffee source.coffee.embedded.source punctuation.section.embedded.coffee",
"r": {
- "dark_plus": "punctuation.section.embedded.coffee: #569CD6",
- "light_plus": "punctuation.section.embedded.coffee: #0000FF",
- "dark_vs": "punctuation.section.embedded.coffee: #569CD6",
- "light_vs": "punctuation.section.embedded.coffee: #0000FF",
- "hc_black": "punctuation.section.embedded.coffee: #569CD6"
+ "dark_plus": "punctuation.section.embedded: #569CD6",
+ "light_plus": "punctuation.section.embedded: #0000FF",
+ "dark_vs": "punctuation.section.embedded: #569CD6",
+ "light_vs": "punctuation.section.embedded: #0000FF",
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
@@ -575,11 +575,11 @@
"c": "#{",
"t": "source.coffee meta.function-call.coffee meta.arguments.coffee string.quoted.double.coffee source.coffee.embedded.source punctuation.section.embedded.coffee",
"r": {
- "dark_plus": "punctuation.section.embedded.coffee: #569CD6",
- "light_plus": "punctuation.section.embedded.coffee: #0000FF",
- "dark_vs": "punctuation.section.embedded.coffee: #569CD6",
- "light_vs": "punctuation.section.embedded.coffee: #0000FF",
- "hc_black": "punctuation.section.embedded.coffee: #569CD6"
+ "dark_plus": "punctuation.section.embedded: #569CD6",
+ "light_plus": "punctuation.section.embedded: #0000FF",
+ "dark_vs": "punctuation.section.embedded: #569CD6",
+ "light_vs": "punctuation.section.embedded: #0000FF",
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
@@ -597,11 +597,11 @@
"c": "}",
"t": "source.coffee meta.function-call.coffee meta.arguments.coffee string.quoted.double.coffee source.coffee.embedded.source punctuation.section.embedded.coffee",
"r": {
- "dark_plus": "punctuation.section.embedded.coffee: #569CD6",
- "light_plus": "punctuation.section.embedded.coffee: #0000FF",
- "dark_vs": "punctuation.section.embedded.coffee: #569CD6",
- "light_vs": "punctuation.section.embedded.coffee: #0000FF",
- "hc_black": "punctuation.section.embedded.coffee: #569CD6"
+ "dark_plus": "punctuation.section.embedded: #569CD6",
+ "light_plus": "punctuation.section.embedded: #0000FF",
+ "dark_vs": "punctuation.section.embedded: #569CD6",
+ "light_vs": "punctuation.section.embedded: #0000FF",
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
@@ -1378,8 +1378,8 @@
"c": "(",
"t": "source.coffee string.regexp.coffee meta.group.regexp punctuation.definition.group.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "punctuation.definition.group.regexp: #CE9178",
+ "light_plus": "punctuation.definition.group.regexp: #D16969",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
"hc_black": "string.regexp: #D16969"
@@ -1389,19 +1389,19 @@
"c": "\\d",
"t": "source.coffee string.regexp.coffee meta.group.regexp constant.character.character-class.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "constant.character.character-class.regexp: #D16969",
+ "light_plus": "constant.character.character-class.regexp: #811F3F",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
- "hc_black": "string.regexp: #D16969"
+ "hc_black": "constant.character: #569CD6"
}
},
{
"c": "+",
"t": "source.coffee string.regexp.coffee meta.group.regexp keyword.operator.quantifier.regexp",
"r": {
- "dark_plus": "keyword.operator: #D4D4D4",
- "light_plus": "keyword.operator: #000000",
+ "dark_plus": "keyword.operator.quantifier.regexp: #D7BA7D",
+ "light_plus": "keyword.operator.quantifier.regexp: #000000",
"dark_vs": "keyword.operator: #D4D4D4",
"light_vs": "keyword.operator: #000000",
"hc_black": "keyword.operator: #D4D4D4"
@@ -1411,8 +1411,8 @@
"c": ")",
"t": "source.coffee string.regexp.coffee meta.group.regexp punctuation.definition.group.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "punctuation.definition.group.regexp: #CE9178",
+ "light_plus": "punctuation.definition.group.regexp: #D16969",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
"hc_black": "string.regexp: #D16969"
@@ -1466,8 +1466,8 @@
"c": "(",
"t": "source.coffee string.regexp.coffee meta.group.regexp punctuation.definition.group.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "punctuation.definition.group.regexp: #CE9178",
+ "light_plus": "punctuation.definition.group.regexp: #D16969",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
"hc_black": "string.regexp: #D16969"
@@ -1477,19 +1477,19 @@
"c": "\\w",
"t": "source.coffee string.regexp.coffee meta.group.regexp constant.character.character-class.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "constant.character.character-class.regexp: #D16969",
+ "light_plus": "constant.character.character-class.regexp: #811F3F",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
- "hc_black": "string.regexp: #D16969"
+ "hc_black": "constant.character: #569CD6"
}
},
{
"c": "*",
"t": "source.coffee string.regexp.coffee meta.group.regexp keyword.operator.quantifier.regexp",
"r": {
- "dark_plus": "keyword.operator: #D4D4D4",
- "light_plus": "keyword.operator: #000000",
+ "dark_plus": "keyword.operator.quantifier.regexp: #D7BA7D",
+ "light_plus": "keyword.operator.quantifier.regexp: #000000",
"dark_vs": "keyword.operator: #D4D4D4",
"light_vs": "keyword.operator: #000000",
"hc_black": "keyword.operator: #D4D4D4"
@@ -1499,8 +1499,8 @@
"c": ")",
"t": "source.coffee string.regexp.coffee meta.group.regexp punctuation.definition.group.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "punctuation.definition.group.regexp: #CE9178",
+ "light_plus": "punctuation.definition.group.regexp: #D16969",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
"hc_black": "string.regexp: #D16969"
@@ -1554,8 +1554,8 @@
"c": "$",
"t": "source.coffee string.regexp.coffee keyword.control.anchor.regexp",
"r": {
- "dark_plus": "keyword.control: #C586C0",
- "light_plus": "keyword.control: #AF00DB",
+ "dark_plus": "keyword.control.anchor.regexp: #DCDCAA",
+ "light_plus": "keyword.control.anchor.regexp: #FF0000",
"dark_vs": "keyword.control: #569CD6",
"light_vs": "keyword.control: #0000FF",
"hc_black": "keyword.control: #C586C0"
diff --git a/extensions/css/package.json b/extensions/css/package.json
index 6ace6ad649a..1f7e0681b1e 100644
--- a/extensions/css/package.json
+++ b/extensions/css/package.json
@@ -50,694 +50,677 @@
"path": "./snippets/css.json"
}
],
- "configuration": {
- "order": 20,
- "allOf": [
- {
- "id": "css",
- "title": "CSS",
- "allOf": [
- {
- "title": "%css.validate.title%",
- "properties": {
- "css.validate": {
- "type": "boolean",
- "scope": "resource",
- "default": true,
- "description": "%css.validate.desc%"
- },
- "css.colorDecorators.enable": {
- "type": "boolean",
- "scope": "window",
- "default": true,
- "description": "%css.colorDecorators.enable.desc%",
- "deprecationMessage": "%css.colorDecorators.enable.deprecationMessage%"
- },
- "css.lint.compatibleVendorPrefixes": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%css.lint.compatibleVendorPrefixes.desc%"
- },
- "css.lint.vendorPrefix": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "warning",
- "description": "%css.lint.vendorPrefix.desc%"
- },
- "css.lint.duplicateProperties": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%css.lint.duplicateProperties.desc%"
- },
- "css.lint.emptyRules": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "warning",
- "description": "%css.lint.emptyRules.desc%"
- },
- "css.lint.importStatement": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%css.lint.importStatement.desc%"
- },
- "css.lint.boxModel": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%css.lint.boxModel.desc%"
- },
- "css.lint.universalSelector": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%css.lint.universalSelector.desc%"
- },
- "css.lint.zeroUnits": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%css.lint.zeroUnits.desc%"
- },
- "css.lint.fontFaceProperties": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "warning",
- "description": "%css.lint.fontFaceProperties.desc%"
- },
- "css.lint.hexColorLength": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "error",
- "description": "%css.lint.hexColorLength.desc%"
- },
- "css.lint.argumentsInColorFunction": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "error",
- "description": "%css.lint.argumentsInColorFunction.desc%"
- },
- "css.lint.unknownProperties": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "warning",
- "description": "%css.lint.unknownProperties.desc%"
- },
- "css.lint.ieHack": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%css.lint.ieHack.desc%"
- },
- "css.lint.unknownVendorSpecificProperties": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%css.lint.unknownVendorSpecificProperties.desc%"
- },
- "css.lint.propertyIgnoredDueToDisplay": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "warning",
- "description": "%css.lint.propertyIgnoredDueToDisplay.desc%"
- },
- "css.lint.important": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%css.lint.important.desc%"
- },
- "css.lint.float": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%css.lint.float.desc%"
- },
- "css.lint.idSelector": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%css.lint.idSelector.desc%"
- },
- "css.trace.server": {
- "type": "string",
- "scope": "window",
- "enum": [
- "off",
- "messages",
- "verbose"
- ],
- "default": "off",
- "description": "%css.trace.server.desc%"
- }
- }
- }
- ]
- },
- {
- "id": "scss",
- "order": 24,
- "title": "SCSS (Sass)",
- "allOf": [
- {
- "title": "%scss.validate.title%",
- "properties": {
- "scss.validate": {
- "type": "boolean",
- "scope": "resource",
- "default": true,
- "description": "%scss.validate.desc%"
- },
- "scss.colorDecorators.enable": {
- "type": "boolean",
- "scope": "window",
- "default": true,
- "description": "%scss.colorDecorators.enable.desc%",
- "deprecationMessage": "%scss.colorDecorators.enable.deprecationMessage%"
- },
- "scss.lint.compatibleVendorPrefixes": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%scss.lint.compatibleVendorPrefixes.desc%"
- },
- "scss.lint.vendorPrefix": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "warning",
- "description": "%scss.lint.vendorPrefix.desc%"
- },
- "scss.lint.duplicateProperties": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%scss.lint.duplicateProperties.desc%"
- },
- "scss.lint.emptyRules": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "warning",
- "description": "%scss.lint.emptyRules.desc%"
- },
- "scss.lint.importStatement": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%scss.lint.importStatement.desc%"
- },
- "scss.lint.boxModel": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%scss.lint.boxModel.desc%"
- },
- "scss.lint.universalSelector": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%scss.lint.universalSelector.desc%"
- },
- "scss.lint.zeroUnits": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%scss.lint.zeroUnits.desc%"
- },
- "scss.lint.fontFaceProperties": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "warning",
- "description": "%scss.lint.fontFaceProperties.desc%"
- },
- "scss.lint.hexColorLength": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "error",
- "description": "%scss.lint.hexColorLength.desc%"
- },
- "scss.lint.argumentsInColorFunction": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "error",
- "description": "%scss.lint.argumentsInColorFunction.desc%"
- },
- "scss.lint.unknownProperties": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "warning",
- "description": "%scss.lint.unknownProperties.desc%"
- },
- "scss.lint.ieHack": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%scss.lint.ieHack.desc%"
- },
- "scss.lint.unknownVendorSpecificProperties": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%scss.lint.unknownVendorSpecificProperties.desc%"
- },
- "scss.lint.propertyIgnoredDueToDisplay": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "warning",
- "description": "%scss.lint.propertyIgnoredDueToDisplay.desc%"
- },
- "scss.lint.important": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%scss.lint.important.desc%"
- },
- "scss.lint.float": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%scss.lint.float.desc%"
- },
- "scss.lint.idSelector": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%scss.lint.idSelector.desc%"
- }
- }
- }
- ]
- },
- {
- "id": "less",
- "order": 22,
- "type": "object",
- "title": "LESS",
- "allOf": [
- {
- "title": "%less.validate.title%",
- "properties": {
- "less.validate": {
- "type": "boolean",
- "scope": "resource",
- "default": true,
- "description": "%less.validate.desc%"
- },
- "less.colorDecorators.enable": {
- "type": "boolean",
- "scope": "window",
- "default": true,
- "description": "%less.colorDecorators.enable.desc%",
- "deprecationMessage": "%less.colorDecorators.enable.deprecationMessage%"
- },
- "less.lint.compatibleVendorPrefixes": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%less.lint.compatibleVendorPrefixes.desc%"
- },
- "less.lint.vendorPrefix": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "warning",
- "description": "%less.lint.vendorPrefix.desc%"
- },
- "less.lint.duplicateProperties": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%less.lint.duplicateProperties.desc%"
- },
- "less.lint.emptyRules": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "warning",
- "description": "%less.lint.emptyRules.desc%"
- },
- "less.lint.importStatement": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%less.lint.importStatement.desc%"
- },
- "less.lint.boxModel": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%less.lint.boxModel.desc%"
- },
- "less.lint.universalSelector": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%less.lint.universalSelector.desc%"
- },
- "less.lint.zeroUnits": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%less.lint.zeroUnits.desc%"
- },
- "less.lint.fontFaceProperties": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "warning",
- "description": "%less.lint.fontFaceProperties.desc%"
- },
- "less.lint.hexColorLength": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "error",
- "description": "%less.lint.hexColorLength.desc%"
- },
- "less.lint.argumentsInColorFunction": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "error",
- "description": "%less.lint.argumentsInColorFunction.desc%"
- },
- "less.lint.unknownProperties": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "warning",
- "description": "%less.lint.unknownProperties.desc%"
- },
- "less.lint.ieHack": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%less.lint.ieHack.desc%"
- },
- "less.lint.unknownVendorSpecificProperties": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%less.lint.unknownVendorSpecificProperties.desc%"
- },
- "less.lint.propertyIgnoredDueToDisplay": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "warning",
- "description": "%less.lint.propertyIgnoredDueToDisplay.desc%"
- },
- "less.lint.important": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%less.lint.important.desc%"
- },
- "less.lint.float": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%less.lint.float.desc%"
- },
- "less.lint.idSelector": {
- "type": "string",
- "scope": "resource",
- "enum": [
- "ignore",
- "warning",
- "error"
- ],
- "default": "ignore",
- "description": "%less.lint.idSelector.desc%"
- }
- }
- }
- ]
+ "configuration": [
+ {
+ "order": 22,
+ "id": "css",
+ "title": "%css.title%",
+ "properties": {
+ "css.validate": {
+ "type": "boolean",
+ "scope": "resource",
+ "default": true,
+ "description": "%css.validate.desc%"
+ },
+ "css.colorDecorators.enable": {
+ "type": "boolean",
+ "scope": "window",
+ "default": true,
+ "description": "%css.colorDecorators.enable.desc%",
+ "deprecationMessage": "%css.colorDecorators.enable.deprecationMessage%"
+ },
+ "css.lint.compatibleVendorPrefixes": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%css.lint.compatibleVendorPrefixes.desc%"
+ },
+ "css.lint.vendorPrefix": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "warning",
+ "description": "%css.lint.vendorPrefix.desc%"
+ },
+ "css.lint.duplicateProperties": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%css.lint.duplicateProperties.desc%"
+ },
+ "css.lint.emptyRules": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "warning",
+ "description": "%css.lint.emptyRules.desc%"
+ },
+ "css.lint.importStatement": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%css.lint.importStatement.desc%"
+ },
+ "css.lint.boxModel": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%css.lint.boxModel.desc%"
+ },
+ "css.lint.universalSelector": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%css.lint.universalSelector.desc%"
+ },
+ "css.lint.zeroUnits": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%css.lint.zeroUnits.desc%"
+ },
+ "css.lint.fontFaceProperties": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "warning",
+ "description": "%css.lint.fontFaceProperties.desc%"
+ },
+ "css.lint.hexColorLength": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "error",
+ "description": "%css.lint.hexColorLength.desc%"
+ },
+ "css.lint.argumentsInColorFunction": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "error",
+ "description": "%css.lint.argumentsInColorFunction.desc%"
+ },
+ "css.lint.unknownProperties": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "warning",
+ "description": "%css.lint.unknownProperties.desc%"
+ },
+ "css.lint.ieHack": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%css.lint.ieHack.desc%"
+ },
+ "css.lint.unknownVendorSpecificProperties": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%css.lint.unknownVendorSpecificProperties.desc%"
+ },
+ "css.lint.propertyIgnoredDueToDisplay": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "warning",
+ "description": "%css.lint.propertyIgnoredDueToDisplay.desc%"
+ },
+ "css.lint.important": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%css.lint.important.desc%"
+ },
+ "css.lint.float": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%css.lint.float.desc%"
+ },
+ "css.lint.idSelector": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%css.lint.idSelector.desc%"
+ },
+ "css.trace.server": {
+ "type": "string",
+ "scope": "window",
+ "enum": [
+ "off",
+ "messages",
+ "verbose"
+ ],
+ "default": "off",
+ "description": "%css.trace.server.desc%"
+ }
}
- ]
- }
+ },
+ {
+ "id": "scss",
+ "order": 24,
+ "title": "%scss.title%",
+ "properties": {
+ "scss.validate": {
+ "type": "boolean",
+ "scope": "resource",
+ "default": true,
+ "description": "%scss.validate.desc%"
+ },
+ "scss.colorDecorators.enable": {
+ "type": "boolean",
+ "scope": "window",
+ "default": true,
+ "description": "%scss.colorDecorators.enable.desc%",
+ "deprecationMessage": "%scss.colorDecorators.enable.deprecationMessage%"
+ },
+ "scss.lint.compatibleVendorPrefixes": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%scss.lint.compatibleVendorPrefixes.desc%"
+ },
+ "scss.lint.vendorPrefix": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "warning",
+ "description": "%scss.lint.vendorPrefix.desc%"
+ },
+ "scss.lint.duplicateProperties": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%scss.lint.duplicateProperties.desc%"
+ },
+ "scss.lint.emptyRules": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "warning",
+ "description": "%scss.lint.emptyRules.desc%"
+ },
+ "scss.lint.importStatement": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%scss.lint.importStatement.desc%"
+ },
+ "scss.lint.boxModel": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%scss.lint.boxModel.desc%"
+ },
+ "scss.lint.universalSelector": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%scss.lint.universalSelector.desc%"
+ },
+ "scss.lint.zeroUnits": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%scss.lint.zeroUnits.desc%"
+ },
+ "scss.lint.fontFaceProperties": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "warning",
+ "description": "%scss.lint.fontFaceProperties.desc%"
+ },
+ "scss.lint.hexColorLength": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "error",
+ "description": "%scss.lint.hexColorLength.desc%"
+ },
+ "scss.lint.argumentsInColorFunction": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "error",
+ "description": "%scss.lint.argumentsInColorFunction.desc%"
+ },
+ "scss.lint.unknownProperties": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "warning",
+ "description": "%scss.lint.unknownProperties.desc%"
+ },
+ "scss.lint.ieHack": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%scss.lint.ieHack.desc%"
+ },
+ "scss.lint.unknownVendorSpecificProperties": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%scss.lint.unknownVendorSpecificProperties.desc%"
+ },
+ "scss.lint.propertyIgnoredDueToDisplay": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "warning",
+ "description": "%scss.lint.propertyIgnoredDueToDisplay.desc%"
+ },
+ "scss.lint.important": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%scss.lint.important.desc%"
+ },
+ "scss.lint.float": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%scss.lint.float.desc%"
+ },
+ "scss.lint.idSelector": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%scss.lint.idSelector.desc%"
+ }
+ }
+ },
+ {
+ "id": "less",
+ "order": 23,
+ "type": "object",
+ "title": "%less.title%",
+ "properties": {
+ "less.validate": {
+ "type": "boolean",
+ "scope": "resource",
+ "default": true,
+ "description": "%less.validate.desc%"
+ },
+ "less.colorDecorators.enable": {
+ "type": "boolean",
+ "scope": "window",
+ "default": true,
+ "description": "%less.colorDecorators.enable.desc%",
+ "deprecationMessage": "%less.colorDecorators.enable.deprecationMessage%"
+ },
+ "less.lint.compatibleVendorPrefixes": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%less.lint.compatibleVendorPrefixes.desc%"
+ },
+ "less.lint.vendorPrefix": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "warning",
+ "description": "%less.lint.vendorPrefix.desc%"
+ },
+ "less.lint.duplicateProperties": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%less.lint.duplicateProperties.desc%"
+ },
+ "less.lint.emptyRules": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "warning",
+ "description": "%less.lint.emptyRules.desc%"
+ },
+ "less.lint.importStatement": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%less.lint.importStatement.desc%"
+ },
+ "less.lint.boxModel": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%less.lint.boxModel.desc%"
+ },
+ "less.lint.universalSelector": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%less.lint.universalSelector.desc%"
+ },
+ "less.lint.zeroUnits": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%less.lint.zeroUnits.desc%"
+ },
+ "less.lint.fontFaceProperties": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "warning",
+ "description": "%less.lint.fontFaceProperties.desc%"
+ },
+ "less.lint.hexColorLength": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "error",
+ "description": "%less.lint.hexColorLength.desc%"
+ },
+ "less.lint.argumentsInColorFunction": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "error",
+ "description": "%less.lint.argumentsInColorFunction.desc%"
+ },
+ "less.lint.unknownProperties": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "warning",
+ "description": "%less.lint.unknownProperties.desc%"
+ },
+ "less.lint.ieHack": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%less.lint.ieHack.desc%"
+ },
+ "less.lint.unknownVendorSpecificProperties": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%less.lint.unknownVendorSpecificProperties.desc%"
+ },
+ "less.lint.propertyIgnoredDueToDisplay": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "warning",
+ "description": "%less.lint.propertyIgnoredDueToDisplay.desc%"
+ },
+ "less.lint.important": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%less.lint.important.desc%"
+ },
+ "less.lint.float": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%less.lint.float.desc%"
+ },
+ "less.lint.idSelector": {
+ "type": "string",
+ "scope": "resource",
+ "enum": [
+ "ignore",
+ "warning",
+ "error"
+ ],
+ "default": "ignore",
+ "description": "%less.lint.idSelector.desc%"
+ }
+ }
+ }
+ ]
},
"dependencies": {
- "color-convert": "^0.5.3",
+ "color-convert": "^0.5.3",
"vscode-languageclient": "3.4.0-next.17",
"vscode-languageserver-protocol": "^3.1.1",
"vscode-nls": "^2.0.2"
@@ -745,4 +728,4 @@
"devDependencies": {
"@types/node": "^6.0.51"
}
-}
+}
\ No newline at end of file
diff --git a/extensions/css/package.nls.json b/extensions/css/package.nls.json
index b2a7126c30d..33fbf6d5c28 100644
--- a/extensions/css/package.nls.json
+++ b/extensions/css/package.nls.json
@@ -1,4 +1,5 @@
{
+ "css.title": "CSS",
"css.lint.argumentsInColorFunction.desc": "Invalid number of parameters",
"css.lint.boxModel.desc": "Do not use width or height when using padding or border",
"css.lint.compatibleVendorPrefixes.desc": "When using a vendor-specific prefix make sure to also include all other vendor-specific properties",
@@ -20,6 +21,7 @@
"css.trace.server.desc": "Traces the communication between VS Code and the CSS language server.",
"css.validate.title": "Controls CSS validation and problem severities.",
"css.validate.desc": "Enables or disables all validations",
+ "less.title": "LESS",
"less.lint.argumentsInColorFunction.desc": "Invalid number of parameters",
"less.lint.boxModel.desc": "Do not use width or height when using padding or border",
"less.lint.compatibleVendorPrefixes.desc": "When using a vendor-specific prefix make sure to also include all other vendor-specific properties",
@@ -40,6 +42,7 @@
"less.lint.zeroUnits.desc": "No unit for zero needed",
"less.validate.title": "Controls LESS validation and problem severities.",
"less.validate.desc": "Enables or disables all validations",
+ "scss.title": "SCSS (Sass)",
"scss.lint.argumentsInColorFunction.desc": "Invalid number of parameters",
"scss.lint.boxModel.desc": "Do not use width or height when using padding or border",
"scss.lint.compatibleVendorPrefixes.desc": "When using a vendor-specific prefix make sure to also include all other vendor-specific properties",
diff --git a/extensions/css/server/npm-shrinkwrap.json b/extensions/css/server/npm-shrinkwrap.json
index eeafae21433..2c2d280b1a2 100644
--- a/extensions/css/server/npm-shrinkwrap.json
+++ b/extensions/css/server/npm-shrinkwrap.json
@@ -3,9 +3,9 @@
"version": "1.0.0",
"dependencies": {
"vscode-css-languageservice": {
- "version": "2.1.4",
+ "version": "2.1.6",
"from": "vscode-css-languageservice@next",
- "resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-2.1.4.tgz"
+ "resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-2.1.6.tgz"
},
"vscode-jsonrpc": {
"version": "3.3.1",
diff --git a/extensions/css/server/package.json b/extensions/css/server/package.json
index ad6c972e571..b62b50928bf 100644
--- a/extensions/css/server/package.json
+++ b/extensions/css/server/package.json
@@ -8,7 +8,7 @@
"node": "*"
},
"dependencies": {
- "vscode-css-languageservice": "^2.1.4",
+ "vscode-css-languageservice": "^2.1.6",
"vscode-languageserver": "3.4.0-next.6",
"vscode-languageserver-protocol": "^3.1.1"
},
diff --git a/extensions/emmet/npm-shrinkwrap.json b/extensions/emmet/npm-shrinkwrap.json
index 28091803b29..e91e4e9c33b 100644
--- a/extensions/emmet/npm-shrinkwrap.json
+++ b/extensions/emmet/npm-shrinkwrap.json
@@ -38,9 +38,9 @@
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz"
},
"vscode-emmet-helper": {
- "version": "1.1.7",
- "from": "vscode-emmet-helper@>=1.0.17 <2.0.0",
- "resolved": "https://registry.npmjs.org/vscode-emmet-helper/-/vscode-emmet-helper-1.1.7.tgz"
+ "version": "1.1.8",
+ "from": "vscode-emmet-helper@>=1.0.8 <2.0.0",
+ "resolved": "https://registry.npmjs.org/vscode-emmet-helper/-/vscode-emmet-helper-1.1.8.tgz"
},
"vscode-languageserver-types": {
"version": "3.3.0",
diff --git a/extensions/emmet/package.json b/extensions/emmet/package.json
index 31de43eb8bf..7e6d7155d31 100644
--- a/extensions/emmet/package.json
+++ b/extensions/emmet/package.json
@@ -265,7 +265,7 @@
"@emmetio/html-matcher": "^0.3.1",
"@emmetio/css-parser": "ramya-rao-a/css-parser#vscode",
"@emmetio/math-expression": "^0.1.1",
- "vscode-emmet-helper": "^1.1.7",
+ "vscode-emmet-helper": "^1.1.8",
"vscode-languageserver-types": "^3.0.3",
"image-size": "^0.5.2",
"vscode-nls": "2.0.2"
diff --git a/extensions/emmet/src/defaultCompletionProvider.ts b/extensions/emmet/src/defaultCompletionProvider.ts
index 5c78aea06a0..f01fb6db568 100644
--- a/extensions/emmet/src/defaultCompletionProvider.ts
+++ b/extensions/emmet/src/defaultCompletionProvider.ts
@@ -55,7 +55,7 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi
return;
}
- let result: vscode.CompletionList = doComplete(document, position, syntax, getEmmetConfiguration(syntax));
+ let result = doComplete(document, position, syntax, getEmmetConfiguration(syntax));
let newItems: vscode.CompletionItem[] = [];
if (result && result.items) {
result.items.forEach(item => {
diff --git a/extensions/fsharp/test/colorize-results/test_fs.json b/extensions/fsharp/test/colorize-results/test_fs.json
index 2f161a6fccc..ee0ae2ca9c1 100644
--- a/extensions/fsharp/test/colorize-results/test_fs.json
+++ b/extensions/fsharp/test/colorize-results/test_fs.json
@@ -1026,11 +1026,11 @@
"c": "\\n",
"t": "source.fsharp string.quoted.double.fsharp constant.character.string.escape.fsharp",
"r": {
- "dark_plus": "string: #CE9178",
- "light_plus": "string: #A31515",
+ "dark_plus": "constant.character: #569CD6",
+ "light_plus": "constant.character: #0000FF",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
- "hc_black": "string: #CE9178"
+ "hc_black": "constant.character: #569CD6"
}
},
{
diff --git a/extensions/git/package.json b/extensions/git/package.json
index bd646d7f8a6..995ac785f74 100644
--- a/extensions/git/package.json
+++ b/extensions/git/package.json
@@ -529,6 +529,11 @@
"group": "3_commit",
"when": "config.git.enabled && scmProvider == git"
},
+ {
+ "command": "git.stageAll",
+ "group": "4_stage",
+ "when": "config.git.enabled && scmProvider == git"
+ },
{
"command": "git.unstageAll",
"group": "4_stage",
diff --git a/extensions/git/src/askpass.ts b/extensions/git/src/askpass.ts
index 597cc043d4e..e241ced459a 100644
--- a/extensions/git/src/askpass.ts
+++ b/extensions/git/src/askpass.ts
@@ -27,10 +27,6 @@ function getIPCHandlePath(nonce: string): string {
return `\\\\.\\pipe\\vscode-git-askpass-${nonce}-sock`;
}
- if (process.env['XDG_RUNTIME_DIR']) {
- return path.join(process.env['XDG_RUNTIME_DIR'], `vscode-git-askpass-${nonce}.sock`);
- }
-
return path.join(os.tmpdir(), `vscode-git-askpass-${nonce}.sock`);
}
diff --git a/extensions/groovy/test/colorize-results/test_groovy.json b/extensions/groovy/test/colorize-results/test_groovy.json
index ee78a65becc..8d1191aa367 100644
--- a/extensions/groovy/test/colorize-results/test_groovy.json
+++ b/extensions/groovy/test/colorize-results/test_groovy.json
@@ -9232,33 +9232,33 @@
"c": "${",
"t": "source.groovy meta.definition.method.groovy meta.method.body.java string.quoted.double.groovy source.groovy.embedded.source punctuation.section.embedded.groovy",
"r": {
- "dark_plus": "string: #CE9178",
- "light_plus": "string: #A31515",
- "dark_vs": "string: #CE9178",
- "light_vs": "string: #A31515",
- "hc_black": "string: #CE9178"
+ "dark_plus": "punctuation.section.embedded: #569CD6",
+ "light_plus": "punctuation.section.embedded: #0000FF",
+ "dark_vs": "punctuation.section.embedded: #569CD6",
+ "light_vs": "punctuation.section.embedded: #0000FF",
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
"c": "System.currentTimeMillis() - start",
"t": "source.groovy meta.definition.method.groovy meta.method.body.java string.quoted.double.groovy source.groovy.embedded.source",
"r": {
- "dark_plus": "string: #CE9178",
- "light_plus": "string: #A31515",
- "dark_vs": "string: #CE9178",
- "light_vs": "string: #A31515",
- "hc_black": "string: #CE9178"
+ "dark_plus": "source.groovy.embedded: #D4D4D4",
+ "light_plus": "source.groovy.embedded: #000000",
+ "dark_vs": "source.groovy.embedded: #D4D4D4",
+ "light_vs": "source.groovy.embedded: #000000",
+ "hc_black": "source.groovy.embedded: #FFFFFF"
}
},
{
"c": "}",
"t": "source.groovy meta.definition.method.groovy meta.method.body.java string.quoted.double.groovy source.groovy.embedded.source punctuation.section.embedded.groovy",
"r": {
- "dark_plus": "string: #CE9178",
- "light_plus": "string: #A31515",
- "dark_vs": "string: #CE9178",
- "light_vs": "string: #A31515",
- "hc_black": "string: #CE9178"
+ "dark_plus": "punctuation.section.embedded: #569CD6",
+ "light_plus": "punctuation.section.embedded: #0000FF",
+ "dark_vs": "punctuation.section.embedded: #569CD6",
+ "light_vs": "punctuation.section.embedded: #0000FF",
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
diff --git a/extensions/grunt/package.json b/extensions/grunt/package.json
index 0758d440b08..4c028b73312 100644
--- a/extensions/grunt/package.json
+++ b/extensions/grunt/package.json
@@ -31,6 +31,7 @@
"title": "Grunt",
"properties": {
"grunt.autoDetect": {
+ "scope": "resource",
"type": "string",
"enum": [
"off",
diff --git a/extensions/grunt/src/main.ts b/extensions/grunt/src/main.ts
index 554bb4963e6..a5e74585e8e 100644
--- a/extensions/grunt/src/main.ts
+++ b/extensions/grunt/src/main.ts
@@ -13,49 +13,6 @@ import * as nls from 'vscode-nls';
const localize = nls.config(process.env.VSCODE_NLS_CONFIG)();
type AutoDetect = 'on' | 'off';
-let taskProvider: vscode.Disposable | undefined;
-
-export function activate(_context: vscode.ExtensionContext): void {
- let workspaceRoot = vscode.workspace.rootPath;
- if (!workspaceRoot) {
- return;
- }
- let pattern = path.join(workspaceRoot, '[Gg]runtfile.js');
- let detectorPromise: Thenable | undefined = undefined;
- let fileWatcher = vscode.workspace.createFileSystemWatcher(pattern);
- fileWatcher.onDidChange(() => detectorPromise = undefined);
- fileWatcher.onDidCreate(() => detectorPromise = undefined);
- fileWatcher.onDidDelete(() => detectorPromise = undefined);
-
- function onConfigurationChanged() {
- let autoDetect = vscode.workspace.getConfiguration('grunt').get('autoDetect');
- if (taskProvider && autoDetect === 'off') {
- detectorPromise = undefined;
- taskProvider.dispose();
- taskProvider = undefined;
- } else if (!taskProvider && autoDetect === 'on') {
- taskProvider = vscode.workspace.registerTaskProvider('grunt', {
- provideTasks: () => {
- if (!detectorPromise) {
- detectorPromise = getGruntTasks();
- }
- return detectorPromise;
- },
- resolveTask(_task: vscode.Task): vscode.Task | undefined {
- return undefined;
- }
- });
- }
- }
- vscode.workspace.onDidChangeConfiguration(onConfigurationChanged);
- onConfigurationChanged();
-}
-
-export function deactivate(): void {
- if (taskProvider) {
- taskProvider.dispose();
- }
-}
function exists(file: string): Promise {
return new Promise((resolve, _reject) => {
@@ -76,19 +33,6 @@ function exec(command: string, options: cp.ExecOptions): Promise<{ stdout: strin
});
}
-let _channel: vscode.OutputChannel;
-function getOutputChannel(): vscode.OutputChannel {
- if (!_channel) {
- _channel = vscode.window.createOutputChannel('Grunt Auto Detection');
- }
- return _channel;
-}
-
-interface GruntTaskDefinition extends vscode.TaskDefinition {
- task: string;
- file?: string;
-}
-
const buildNames: string[] = ['build', 'compile', 'watch'];
function isBuildTask(name: string): boolean {
for (let buildName of buildNames) {
@@ -109,97 +53,287 @@ function isTestTask(name: string): boolean {
return false;
}
-async function getGruntTasks(): Promise {
- let workspaceRoot = vscode.workspace.rootPath;
- let emptyTasks: vscode.Task[] = [];
- if (!workspaceRoot) {
- return emptyTasks;
+let _channel: vscode.OutputChannel;
+function getOutputChannel(): vscode.OutputChannel {
+ if (!_channel) {
+ _channel = vscode.window.createOutputChannel('Gulp Auto Detection');
}
- if (!await exists(path.join(workspaceRoot, 'gruntfile.js')) && !await exists(path.join(workspaceRoot, 'Gruntfile.js'))) {
- return emptyTasks;
+ return _channel;
+}
+
+interface GruntTaskDefinition extends vscode.TaskDefinition {
+ task: string;
+ file?: string;
+}
+
+class FolderDetector {
+
+ private fileWatcher: vscode.FileSystemWatcher;
+ private promise: Thenable | undefined;
+
+ constructor(private _workspaceFolder: vscode.WorkspaceFolder) {
}
- let command: string;
- let platform = process.platform;
- if (platform === 'win32' && await exists(path.join(workspaceRoot!, 'node_modules', '.bin', 'grunt.cmd'))) {
- command = path.join('.', 'node_modules', '.bin', 'grunt.cmd');
- } else if ((platform === 'linux' || platform === 'darwin') && await exists(path.join(workspaceRoot!, 'node_modules', '.bin', 'grunt'))) {
- command = path.join('.', 'node_modules', '.bin', 'grunt');
- } else {
- command = 'grunt';
+ public get workspaceFolder(): vscode.WorkspaceFolder {
+ return this._workspaceFolder;
}
- let commandLine = `${command} --help --no-color`;
- try {
- let { stdout, stderr } = await exec(commandLine, { cwd: workspaceRoot });
- if (stderr) {
- getOutputChannel().appendLine(stderr);
- getOutputChannel().show(true);
+ public isEnabled(): boolean {
+ return vscode.workspace.getConfiguration('grunt', this._workspaceFolder.uri).get('autoDetect') === 'on';
+ }
+
+ public start(): void {
+ let pattern = path.join(this._workspaceFolder.uri.fsPath, '[Gg]runtfile.js');
+ this.fileWatcher = vscode.workspace.createFileSystemWatcher(pattern);
+ this.fileWatcher.onDidChange(() => this.promise = undefined);
+ this.fileWatcher.onDidCreate(() => this.promise = undefined);
+ this.fileWatcher.onDidDelete(() => this.promise = undefined);
+ }
+
+ public async getTasks(): Promise {
+ if (!this.promise) {
+ this.promise = this.computeTasks();
}
- let result: vscode.Task[] = [];
- if (stdout) {
- // grunt lists tasks as follows (description is wrapped into a new line if too long):
- // ...
- // Available tasks
- // uglify Minify files with UglifyJS. *
- // jshint Validate files with JSHint. *
- // test Alias for "jshint", "qunit" tasks.
- // default Alias for "jshint", "qunit", "concat", "uglify" tasks.
- // long Alias for "eslint", "qunit", "browserify", "sass",
- // "autoprefixer", "uglify", tasks.
- //
- // Tasks run in the order specified
+ return this.promise;
+ }
- let lines = stdout.split(/\r{0,1}\n/);
- let tasksStart = false;
- let tasksEnd = false;
- for (let line of lines) {
- if (line.length === 0) {
- continue;
- }
- if (!tasksStart && !tasksEnd) {
- if (line.indexOf('Available tasks') === 0) {
- tasksStart = true;
+ private async computeTasks(): Promise {
+ let rootPath = this._workspaceFolder.uri.scheme === 'file' ? this._workspaceFolder.uri.fsPath : undefined;
+ let emptyTasks: vscode.Task[] = [];
+ if (!rootPath) {
+ return emptyTasks;
+ }
+ if (!await exists(path.join(rootPath, 'gruntfile.js')) && !await exists(path.join(rootPath, 'Gruntfile.js'))) {
+ return emptyTasks;
+ }
+
+ let command: string;
+ let platform = process.platform;
+ if (platform === 'win32' && await exists(path.join(rootPath!, 'node_modules', '.bin', 'grunt.cmd'))) {
+ command = path.join('.', 'node_modules', '.bin', 'grunt.cmd');
+ } else if ((platform === 'linux' || platform === 'darwin') && await exists(path.join(rootPath!, 'node_modules', '.bin', 'grunt'))) {
+ command = path.join('.', 'node_modules', '.bin', 'grunt');
+ } else {
+ command = 'grunt';
+ }
+
+ let commandLine = `${command} --help --no-color`;
+ try {
+ let { stdout, stderr } = await exec(commandLine, { cwd: rootPath });
+ if (stderr) {
+ getOutputChannel().appendLine(stderr);
+ getOutputChannel().show(true);
+ }
+ let result: vscode.Task[] = [];
+ if (stdout) {
+ // grunt lists tasks as follows (description is wrapped into a new line if too long):
+ // ...
+ // Available tasks
+ // uglify Minify files with UglifyJS. *
+ // jshint Validate files with JSHint. *
+ // test Alias for "jshint", "qunit" tasks.
+ // default Alias for "jshint", "qunit", "concat", "uglify" tasks.
+ // long Alias for "eslint", "qunit", "browserify", "sass",
+ // "autoprefixer", "uglify", tasks.
+ //
+ // Tasks run in the order specified
+
+ let lines = stdout.split(/\r{0,1}\n/);
+ let tasksStart = false;
+ let tasksEnd = false;
+ for (let line of lines) {
+ if (line.length === 0) {
+ continue;
}
- } else if (tasksStart && !tasksEnd) {
- if (line.indexOf('Tasks run in the order specified') === 0) {
- tasksEnd = true;
- } else {
- let regExp = /^\s*(\S.*\S) \S/g;
- let matches = regExp.exec(line);
- if (matches && matches.length === 2) {
- let name = matches[1];
- let kind: GruntTaskDefinition = {
- type: 'grunt',
- task: name
- };
- let source = 'grunt';
- let task = name.indexOf(' ') === -1
- ? new vscode.Task(kind, name, source, new vscode.ShellExecution(`${command} ${name}`))
- : new vscode.Task(kind, name, source, new vscode.ShellExecution(`${command} "${name}"`));
- result.push(task);
- let lowerCaseTaskName = name.toLowerCase();
- if (isBuildTask(lowerCaseTaskName)) {
- task.group = vscode.TaskGroup.Build;
- } else if (isTestTask(lowerCaseTaskName)) {
- task.group = vscode.TaskGroup.Test;
+ if (!tasksStart && !tasksEnd) {
+ if (line.indexOf('Available tasks') === 0) {
+ tasksStart = true;
+ }
+ } else if (tasksStart && !tasksEnd) {
+ if (line.indexOf('Tasks run in the order specified') === 0) {
+ tasksEnd = true;
+ } else {
+ let regExp = /^\s*(\S.*\S) \S/g;
+ let matches = regExp.exec(line);
+ if (matches && matches.length === 2) {
+ let name = matches[1];
+ let kind: GruntTaskDefinition = {
+ type: 'grunt',
+ task: name
+ };
+ let source = 'grunt';
+ let options: vscode.ShellExecutionOptions = { cwd: this.workspaceFolder.uri.fsPath };
+ let task = name.indexOf(' ') === -1
+ ? new vscode.Task(kind, this.workspaceFolder, name, source, new vscode.ShellExecution(`${command} ${name}`, options))
+ : new vscode.Task(kind, this.workspaceFolder, name, source, new vscode.ShellExecution(`${command} "${name}"`, options));
+ result.push(task);
+ let lowerCaseTaskName = name.toLowerCase();
+ if (isBuildTask(lowerCaseTaskName)) {
+ task.group = vscode.TaskGroup.Build;
+ } else if (isTestTask(lowerCaseTaskName)) {
+ task.group = vscode.TaskGroup.Test;
+ }
}
}
}
}
}
+ return result;
+ } catch (err) {
+ let channel = getOutputChannel();
+ if (err.stderr) {
+ channel.appendLine(err.stderr);
+ }
+ if (err.stdout) {
+ channel.appendLine(err.stdout);
+ }
+ channel.appendLine(localize('execFailed', 'Auto detecting Grunt failed with error: {0}', err.error ? err.error.toString() : 'unknown'));
+ channel.show(true);
+ return emptyTasks;
}
- return result;
- } catch (err) {
- let channel = getOutputChannel();
- if (err.stderr) {
- channel.appendLine(err.stderr);
- }
- if (err.stdout) {
- channel.appendLine(err.stdout);
- }
- channel.appendLine(localize('execFailed', 'Auto detecting Grunt failed with error: {0}', err.error ? err.error.toString() : 'unknown'));
- channel.show(true);
- return emptyTasks;
}
+
+ public dispose() {
+ this.promise = undefined;
+ if (this.fileWatcher) {
+ this.fileWatcher.dispose();
+ }
+ }
+}
+
+class TaskDetector {
+
+ private taskProvider: vscode.Disposable | undefined;
+ private detectors: Map = new Map();
+ private promise: Promise | undefined;
+
+ constructor() {
+ }
+
+ public start(): void {
+ let folders = vscode.workspace.workspaceFolders;
+ if (folders) {
+ this.updateWorkspaceFolders(folders, []);
+ }
+ vscode.workspace.onDidChangeWorkspaceFolders((event) => this.updateWorkspaceFolders(event.added, event.removed));
+ vscode.workspace.onDidChangeConfiguration(this.updateConfiguration, this);
+ }
+
+ public dispose(): void {
+ if (this.taskProvider) {
+ this.taskProvider.dispose();
+ this.taskProvider = undefined;
+ }
+ this.detectors.clear();
+ this.promise = undefined;
+ }
+
+ private updateWorkspaceFolders(added: vscode.WorkspaceFolder[], removed: vscode.WorkspaceFolder[]): void {
+ let changed = false;
+ for (let remove of removed) {
+ let detector = this.detectors.get(remove.uri.toString());
+ if (detector) {
+ changed = true;
+ detector.dispose();
+ this.detectors.delete(remove.uri.toString());
+ }
+ }
+ for (let add of added) {
+ let detector = new FolderDetector(add);
+ if (detector.isEnabled()) {
+ changed = true;
+ this.detectors.set(add.uri.toString(), detector);
+ detector.start();
+ }
+ }
+ if (changed) {
+ this.promise = undefined;
+ }
+ this.updateProvider();
+ }
+
+ private updateConfiguration(): void {
+ let changed = false;
+ for (let detector of this.detectors.values()) {
+ if (!detector.isEnabled()) {
+ changed = true;
+ detector.dispose();
+ this.detectors.delete(detector.workspaceFolder.uri.toString());
+ }
+ }
+ let folders = vscode.workspace.workspaceFolders;
+ if (folders) {
+ for (let folder of folders) {
+ if (!this.detectors.has(folder.uri.toString())) {
+ let detector = new FolderDetector(folder);
+ if (detector.isEnabled()) {
+ changed = true;
+ this.detectors.set(folder.uri.toString(), detector);
+ detector.start();
+ }
+ }
+ }
+ }
+ if (changed) {
+ this.promise = undefined;
+ }
+ this.updateProvider();
+ }
+
+ private updateProvider(): void {
+ if (!this.taskProvider && this.detectors.size > 0) {
+ this.taskProvider = vscode.workspace.registerTaskProvider('gulp', {
+ provideTasks: () => {
+ return this.getTasks();
+ },
+ resolveTask(_task: vscode.Task): vscode.Task | undefined {
+ return undefined;
+ }
+ });
+ }
+ else if (this.taskProvider && this.detectors.size === 0) {
+ this.taskProvider.dispose();
+ this.taskProvider = undefined;
+ this.promise = undefined;
+ }
+ }
+
+ public getTasks(): Promise {
+ if (!this.promise) {
+ this.promise = this.computeTasks();
+ }
+ return this.promise;
+ }
+
+ private computeTasks(): Promise {
+ if (this.detectors.size === 0) {
+ return Promise.resolve([]);
+ } else if (this.detectors.size === 1) {
+ return this.detectors.values().next().value.getTasks();
+ } else {
+ let promises: Promise[] = [];
+ for (let detector of this.detectors.values()) {
+ promises.push(detector.getTasks().then((value) => value, () => []));
+ }
+ return Promise.all(promises).then((values) => {
+ let result: vscode.Task[] = [];
+ for (let tasks of values) {
+ if (tasks && tasks.length > 0) {
+ result.push(...tasks);
+ }
+ }
+ return result;
+ });
+ }
+ }
+}
+
+let detector: TaskDetector;
+export function activate(_context: vscode.ExtensionContext): void {
+ detector = new TaskDetector();
+ detector.start();
+}
+
+export function deactivate(): void {
+ detector.dispose();
}
\ No newline at end of file
diff --git a/extensions/gulp/package.json b/extensions/gulp/package.json
index 235f3e2d138..498384f3fa7 100644
--- a/extensions/gulp/package.json
+++ b/extensions/gulp/package.json
@@ -31,6 +31,7 @@
"title": "Gulp",
"properties": {
"gulp.autoDetect": {
+ "scope": "resource",
"type": "string",
"enum": [
"off",
diff --git a/extensions/gulp/src/main.ts b/extensions/gulp/src/main.ts
index 24d7370cf13..127e07afd64 100644
--- a/extensions/gulp/src/main.ts
+++ b/extensions/gulp/src/main.ts
@@ -13,49 +13,6 @@ import * as nls from 'vscode-nls';
const localize = nls.config(process.env.VSCODE_NLS_CONFIG)();
type AutoDetect = 'on' | 'off';
-let taskProvider: vscode.Disposable | undefined;
-
-export function activate(_context: vscode.ExtensionContext): void {
- let workspaceRoot = vscode.workspace.rootPath;
- if (!workspaceRoot) {
- return;
- }
- let pattern = path.join(workspaceRoot, 'gulpfile{.babel.js,.js}');
- let gulpPromise: Thenable | undefined = undefined;
- let fileWatcher = vscode.workspace.createFileSystemWatcher(pattern);
- fileWatcher.onDidChange(() => gulpPromise = undefined);
- fileWatcher.onDidCreate(() => gulpPromise = undefined);
- fileWatcher.onDidDelete(() => gulpPromise = undefined);
-
- function onConfigurationChanged() {
- let autoDetect = vscode.workspace.getConfiguration('gulp').get('autoDetect');
- if (taskProvider && autoDetect === 'off') {
- gulpPromise = undefined;
- taskProvider.dispose();
- taskProvider = undefined;
- } else if (!taskProvider && autoDetect === 'on') {
- taskProvider = vscode.workspace.registerTaskProvider('gulp', {
- provideTasks: () => {
- if (!gulpPromise) {
- gulpPromise = getGulpTasks();
- }
- return gulpPromise;
- },
- resolveTask(_task: vscode.Task): vscode.Task | undefined {
- return undefined;
- }
- });
- }
- }
- vscode.workspace.onDidChangeConfiguration(onConfigurationChanged);
- onConfigurationChanged();
-}
-
-export function deactivate(): void {
- if (taskProvider) {
- taskProvider.dispose();
- }
-}
function exists(file: string): Promise {
return new Promise((resolve, _reject) => {
@@ -76,19 +33,6 @@ function exec(command: string, options: cp.ExecOptions): Promise<{ stdout: strin
});
}
-let _channel: vscode.OutputChannel;
-function getOutputChannel(): vscode.OutputChannel {
- if (!_channel) {
- _channel = vscode.window.createOutputChannel('Gulp Auto Detection');
- }
- return _channel;
-}
-
-interface GulpTaskDefinition extends vscode.TaskDefinition {
- task: string;
- file?: string;
-}
-
const buildNames: string[] = ['build', 'compile', 'watch'];
function isBuildTask(name: string): boolean {
for (let buildName of buildNames) {
@@ -109,69 +53,259 @@ function isTestTask(name: string): boolean {
return false;
}
-async function getGulpTasks(): Promise {
- let workspaceRoot = vscode.workspace.rootPath;
- let emptyTasks: vscode.Task[] = [];
- if (!workspaceRoot) {
- return emptyTasks;
+let _channel: vscode.OutputChannel;
+function getOutputChannel(): vscode.OutputChannel {
+ if (!_channel) {
+ _channel = vscode.window.createOutputChannel('Gulp Auto Detection');
}
- let gulpfile = path.join(workspaceRoot, 'gulpfile.js');
- if (!await exists(gulpfile)) {
- gulpfile = path.join(workspaceRoot, 'gulpfile.babel.js');
- if (! await exists(gulpfile)) {
+ return _channel;
+}
+
+interface GulpTaskDefinition extends vscode.TaskDefinition {
+ task: string;
+ file?: string;
+}
+
+class FolderDetector {
+
+ private fileWatcher: vscode.FileSystemWatcher;
+ private promise: Thenable | undefined;
+
+ constructor(private _workspaceFolder: vscode.WorkspaceFolder) {
+ }
+
+ public get workspaceFolder(): vscode.WorkspaceFolder {
+ return this._workspaceFolder;
+ }
+
+ public isEnabled(): boolean {
+ return vscode.workspace.getConfiguration('gulp', this._workspaceFolder.uri).get('autoDetect') === 'on';
+ }
+
+ public start(): void {
+ let pattern = path.join(this._workspaceFolder.uri.fsPath, 'gulpfile{.babel.js,.js}');
+ this.fileWatcher = vscode.workspace.createFileSystemWatcher(pattern);
+ this.fileWatcher.onDidChange(() => this.promise = undefined);
+ this.fileWatcher.onDidCreate(() => this.promise = undefined);
+ this.fileWatcher.onDidDelete(() => this.promise = undefined);
+ }
+
+ public async getTasks(): Promise {
+ if (!this.promise) {
+ this.promise = this.computeTasks();
+ }
+ return this.promise;
+ }
+
+ private async computeTasks(): Promise {
+ let rootPath = this._workspaceFolder.uri.scheme === 'file' ? this._workspaceFolder.uri.fsPath : undefined;
+ let emptyTasks: vscode.Task[] = [];
+ if (!rootPath) {
+ return emptyTasks;
+ }
+ let gulpfile = path.join(rootPath, 'gulpfile.js');
+ if (!await exists(gulpfile)) {
+ gulpfile = path.join(rootPath, 'gulpfile.babel.js');
+ if (! await exists(gulpfile)) {
+ return emptyTasks;
+ }
+ }
+
+ let gulpCommand: string;
+ let platform = process.platform;
+ if (platform === 'win32' && await exists(path.join(rootPath!, 'node_modules', '.bin', 'gulp.cmd'))) {
+ gulpCommand = path.join('.', 'node_modules', '.bin', 'gulp.cmd');
+ } else if ((platform === 'linux' || platform === 'darwin') && await exists(path.join(rootPath!, 'node_modules', '.bin', 'gulp'))) {
+ gulpCommand = path.join('.', 'node_modules', '.bin', 'gulp');
+ } else {
+ gulpCommand = 'gulp';
+ }
+
+ let commandLine = `${gulpCommand} --tasks-simple --no-color`;
+ try {
+ let { stdout, stderr } = await exec(commandLine, { cwd: rootPath });
+ if (stderr && stderr.length > 0) {
+ getOutputChannel().appendLine(stderr);
+ getOutputChannel().show(true);
+ }
+ let result: vscode.Task[] = [];
+ if (stdout) {
+ let lines = stdout.split(/\r{0,1}\n/);
+ for (let line of lines) {
+ if (line.length === 0) {
+ continue;
+ }
+ let kind: GulpTaskDefinition = {
+ type: 'gulp',
+ task: line
+ };
+ let options: vscode.ShellExecutionOptions = { cwd: this.workspaceFolder.uri.fsPath };
+ let task = new vscode.Task(kind, this.workspaceFolder, line, 'gulp', new vscode.ShellExecution(`${gulpCommand} ${line}`, options));
+ result.push(task);
+ let lowerCaseLine = line.toLowerCase();
+ if (isBuildTask(lowerCaseLine)) {
+ task.group = vscode.TaskGroup.Build;
+ } else if (isTestTask(lowerCaseLine)) {
+ task.group = vscode.TaskGroup.Test;
+ }
+ }
+ }
+ return result;
+ } catch (err) {
+ let channel = getOutputChannel();
+ if (err.stderr) {
+ channel.appendLine(err.stderr);
+ }
+ if (err.stdout) {
+ channel.appendLine(err.stdout);
+ }
+ channel.appendLine(localize('execFailed', 'Auto detecting gulp failed with error: {0}', err.error ? err.error.toString() : 'unknown'));
+ channel.show(true);
return emptyTasks;
}
}
- let gulpCommand: string;
- let platform = process.platform;
- if (platform === 'win32' && await exists(path.join(workspaceRoot!, 'node_modules', '.bin', 'gulp.cmd'))) {
- gulpCommand = path.join('.', 'node_modules', '.bin', 'gulp.cmd');
- } else if ((platform === 'linux' || platform === 'darwin') && await exists(path.join(workspaceRoot!, 'node_modules', '.bin', 'gulp'))) {
- gulpCommand = path.join('.', 'node_modules', '.bin', 'gulp');
- } else {
- gulpCommand = 'gulp';
+ public dispose() {
+ this.promise = undefined;
+ if (this.fileWatcher) {
+ this.fileWatcher.dispose();
+ }
+ }
+}
+
+class TaskDetector {
+
+ private taskProvider: vscode.Disposable | undefined;
+ private detectors: Map = new Map();
+ private promise: Promise | undefined;
+
+ constructor() {
}
- let commandLine = `${gulpCommand} --tasks-simple --no-color`;
- try {
- let { stdout, stderr } = await exec(commandLine, { cwd: workspaceRoot });
- if (stderr && stderr.length > 0) {
- getOutputChannel().appendLine(stderr);
- getOutputChannel().show(true);
+ public start(): void {
+ let folders = vscode.workspace.workspaceFolders;
+ if (folders) {
+ this.updateWorkspaceFolders(folders, []);
}
- let result: vscode.Task[] = [];
- if (stdout) {
- let lines = stdout.split(/\r{0,1}\n/);
- for (let line of lines) {
- if (line.length === 0) {
- continue;
- }
- let kind: GulpTaskDefinition = {
- type: 'gulp',
- task: line
- };
- let task = new vscode.Task(kind, line, 'gulp', new vscode.ShellExecution(`${gulpCommand} ${line}`));
- result.push(task);
- let lowerCaseLine = line.toLowerCase();
- if (isBuildTask(lowerCaseLine)) {
- task.group = vscode.TaskGroup.Build;
- } else if (isTestTask(lowerCaseLine)) {
- task.group = vscode.TaskGroup.Test;
+ vscode.workspace.onDidChangeWorkspaceFolders((event) => this.updateWorkspaceFolders(event.added, event.removed));
+ vscode.workspace.onDidChangeConfiguration(this.updateConfiguration, this);
+ }
+
+ public dispose(): void {
+ if (this.taskProvider) {
+ this.taskProvider.dispose();
+ this.taskProvider = undefined;
+ }
+ this.detectors.clear();
+ this.promise = undefined;
+ }
+
+ private updateWorkspaceFolders(added: vscode.WorkspaceFolder[], removed: vscode.WorkspaceFolder[]): void {
+ let changed = false;
+ for (let remove of removed) {
+ let detector = this.detectors.get(remove.uri.toString());
+ if (detector) {
+ changed = true;
+ detector.dispose();
+ this.detectors.delete(remove.uri.toString());
+ }
+ }
+ for (let add of added) {
+ let detector = new FolderDetector(add);
+ if (detector.isEnabled()) {
+ changed = true;
+ this.detectors.set(add.uri.toString(), detector);
+ detector.start();
+ }
+ }
+ if (changed) {
+ this.promise = undefined;
+ }
+ this.updateProvider();
+ }
+
+ private updateConfiguration(): void {
+ let changed = false;
+ for (let detector of this.detectors.values()) {
+ if (!detector.isEnabled()) {
+ changed = true;
+ detector.dispose();
+ this.detectors.delete(detector.workspaceFolder.uri.toString());
+ }
+ }
+ let folders = vscode.workspace.workspaceFolders;
+ if (folders) {
+ for (let folder of folders) {
+ if (!this.detectors.has(folder.uri.toString())) {
+ let detector = new FolderDetector(folder);
+ if (detector.isEnabled()) {
+ changed = true;
+ this.detectors.set(folder.uri.toString(), detector);
+ detector.start();
+ }
}
}
}
- return result;
- } catch (err) {
- let channel = getOutputChannel();
- if (err.stderr) {
- channel.appendLine(err.stderr);
+ if (changed) {
+ this.promise = undefined;
}
- if (err.stdout) {
- channel.appendLine(err.stdout);
- }
- channel.appendLine(localize('execFailed', 'Auto detecting gulp failed with error: {0}', err.error ? err.error.toString() : 'unknown'));
- channel.show(true);
- return emptyTasks;
+ this.updateProvider();
}
+
+ private updateProvider(): void {
+ if (!this.taskProvider && this.detectors.size > 0) {
+ this.taskProvider = vscode.workspace.registerTaskProvider('gulp', {
+ provideTasks: () => {
+ return this.getTasks();
+ },
+ resolveTask(_task: vscode.Task): vscode.Task | undefined {
+ return undefined;
+ }
+ });
+ }
+ else if (this.taskProvider && this.detectors.size === 0) {
+ this.taskProvider.dispose();
+ this.taskProvider = undefined;
+ this.promise = undefined;
+ }
+ }
+
+ public getTasks(): Promise {
+ if (!this.promise) {
+ this.promise = this.computeTasks();
+ }
+ return this.promise;
+ }
+
+ private computeTasks(): Promise {
+ if (this.detectors.size === 0) {
+ return Promise.resolve([]);
+ } else if (this.detectors.size === 1) {
+ return this.detectors.values().next().value.getTasks();
+ } else {
+ let promises: Promise[] = [];
+ for (let detector of this.detectors.values()) {
+ promises.push(detector.getTasks().then((value) => value, () => []));
+ }
+ return Promise.all(promises).then((values) => {
+ let result: vscode.Task[] = [];
+ for (let tasks of values) {
+ if (tasks && tasks.length > 0) {
+ result.push(...tasks);
+ }
+ }
+ return result;
+ });
+ }
+ }
+}
+
+let detector: TaskDetector;
+export function activate(_context: vscode.ExtensionContext): void {
+ detector = new TaskDetector();
+ detector.start();
+}
+
+export function deactivate(): void {
+ detector.dispose();
}
\ No newline at end of file
diff --git a/extensions/html/package.json b/extensions/html/package.json
index a5ebee09dd3..240cb7d8d9f 100644
--- a/extensions/html/package.json
+++ b/extensions/html/package.json
@@ -92,7 +92,7 @@
"null"
],
"scope": "resource",
- "default": "a, abbr, acronym, b, bdo, big, br, button, cite, code, dfn, em, i, img, input, kbd, label, map, object, q, samp, select, small, span, strong, sub, sup, textarea, tt, var",
+ "default": "",
"description": "%html.format.unformatted.desc%"
},
"html.format.contentUnformatted": {
@@ -101,7 +101,7 @@
"null"
],
"scope": "resource",
- "default": "pre",
+ "default": "pre,code,textarea",
"description": "%html.format.contentUnformatted.desc%"
},
"html.format.indentInnerHtml": {
diff --git a/extensions/html/server/npm-shrinkwrap.json b/extensions/html/server/npm-shrinkwrap.json
index 62a5bf9b691..52f9b38450f 100644
--- a/extensions/html/server/npm-shrinkwrap.json
+++ b/extensions/html/server/npm-shrinkwrap.json
@@ -3,14 +3,14 @@
"version": "1.0.0",
"dependencies": {
"vscode-css-languageservice": {
- "version": "2.1.4",
+ "version": "2.1.6",
"from": "vscode-css-languageservice@next",
- "resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-2.1.4.tgz"
+ "resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-2.1.6.tgz"
},
"vscode-html-languageservice": {
- "version": "2.0.7",
+ "version": "2.0.8",
"from": "vscode-html-languageservice@next",
- "resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-2.0.7.tgz"
+ "resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-2.0.8.tgz"
},
"vscode-jsonrpc": {
"version": "3.3.1",
diff --git a/extensions/html/server/package.json b/extensions/html/server/package.json
index 3cac05b7da9..8bcae7d7d90 100644
--- a/extensions/html/server/package.json
+++ b/extensions/html/server/package.json
@@ -8,8 +8,8 @@
"node": "*"
},
"dependencies": {
- "vscode-css-languageservice": "^2.1.4",
- "vscode-html-languageservice": "^2.0.7",
+ "vscode-css-languageservice": "^2.1.6",
+ "vscode-html-languageservice": "^2.0.8",
"vscode-languageserver": "3.4.0-next.6",
"vscode-languageserver-protocol": "^3.1.1",
"vscode-languageserver-types": "^3.3.0",
diff --git a/extensions/html/server/src/htmlServerMain.ts b/extensions/html/server/src/htmlServerMain.ts
index 9b53da722a2..14ea13ba25c 100644
--- a/extensions/html/server/src/htmlServerMain.ts
+++ b/extensions/html/server/src/htmlServerMain.ts
@@ -54,7 +54,6 @@ documents.onDidClose(e => {
});
function getDocumentSettings(textDocument: TextDocument, needsDocumentSettings: () => boolean): Thenable {
- console.log('scopedSettingsSupport ' + scopedSettingsSupport + 'needsSettings ' + needsDocumentSettings());
if (scopedSettingsSupport && needsDocumentSettings()) {
let promise = documentSettings[textDocument.uri];
if (!promise) {
diff --git a/extensions/html/test/colorize-results/12750_html.json b/extensions/html/test/colorize-results/12750_html.json
index 571e60f4ee5..a89b03aa84f 100644
--- a/extensions/html/test/colorize-results/12750_html.json
+++ b/extensions/html/test/colorize-results/12750_html.json
@@ -29,7 +29,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -51,7 +51,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -106,7 +106,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -128,7 +128,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -150,7 +150,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -194,7 +194,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -205,7 +205,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -293,7 +293,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -315,7 +315,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -337,7 +337,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -381,7 +381,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -392,7 +392,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
diff --git a/extensions/html/test/colorize-results/25920_html.json b/extensions/html/test/colorize-results/25920_html.json
index 88dc0cc895c..16b71acbe88 100644
--- a/extensions/html/test/colorize-results/25920_html.json
+++ b/extensions/html/test/colorize-results/25920_html.json
@@ -62,7 +62,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -84,7 +84,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -139,7 +139,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -172,7 +172,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -194,7 +194,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -359,7 +359,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -381,7 +381,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -436,7 +436,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -458,7 +458,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -480,7 +480,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -502,7 +502,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -524,7 +524,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -601,7 +601,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -623,7 +623,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -678,7 +678,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -711,7 +711,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -733,7 +733,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
diff --git a/extensions/html/test/colorize-results/test_html.json b/extensions/html/test/colorize-results/test_html.json
index 1609f7270c1..a1da5d2c393 100644
--- a/extensions/html/test/colorize-results/test_html.json
+++ b/extensions/html/test/colorize-results/test_html.json
@@ -480,7 +480,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -502,7 +502,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -557,7 +557,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -579,7 +579,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -590,7 +590,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -601,7 +601,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -623,7 +623,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -634,7 +634,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -656,7 +656,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -667,7 +667,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -689,7 +689,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -700,7 +700,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -733,7 +733,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -744,7 +744,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -755,7 +755,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -766,7 +766,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1129,7 +1129,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1151,7 +1151,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1283,7 +1283,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1305,7 +1305,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1448,7 +1448,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1470,7 +1470,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1492,7 +1492,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1536,7 +1536,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1547,7 +1547,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1558,7 +1558,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1580,7 +1580,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1602,7 +1602,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1613,7 +1613,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1624,7 +1624,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1657,7 +1657,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1701,7 +1701,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1712,7 +1712,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1745,7 +1745,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1756,7 +1756,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1767,7 +1767,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1800,7 +1800,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1844,7 +1844,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1855,7 +1855,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1866,7 +1866,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1877,7 +1877,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1888,7 +1888,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1899,7 +1899,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1910,7 +1910,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1932,7 +1932,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1943,7 +1943,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1954,7 +1954,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1976,7 +1976,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1987,7 +1987,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1998,7 +1998,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2009,7 +2009,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2020,7 +2020,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2042,7 +2042,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2053,7 +2053,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2064,7 +2064,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2075,7 +2075,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2086,7 +2086,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2097,7 +2097,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2119,7 +2119,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2141,7 +2141,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2152,7 +2152,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2163,7 +2163,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2174,7 +2174,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2185,7 +2185,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2196,7 +2196,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2207,7 +2207,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
diff --git a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json
index 6a9a32ac03c..de12bfe729c 100644
--- a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json
+++ b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json
@@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
- "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/648a036db2bad78ee93463269ec49ed91ee5aa91",
+ "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/30d95ebb561fc57e784b43d08f0a6f46ad0c3e5d",
"name": "JavaScript (with React support)",
"scopeName": "source.js",
"fileTypes": [
@@ -94,6 +94,29 @@
{
"include": "#comment"
},
+ {
+ "begin": "(,)\\s*(?!\\S)",
+ "beginCaptures": {
+ "1": {
+ "name": "punctuation.separator.comma.js"
+ }
+ },
+ "end": "(?)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n )) |\n (:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n ))\n)",
+ "begin": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\n (=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n )) |\n (:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n ))\n)",
"beginCaptures": {
"1": {
"name": "meta.definition.variable.js entity.name.function.js"
@@ -727,7 +750,7 @@
},
"import-declaration": {
"name": "meta.import.js",
- "begin": "(?)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n )) |\n (:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n ))\n)"
+ "match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=(\\?\\s*)?\\s*\n (=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n )) |\n (:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n ))\n)"
},
{
"name": "meta.definition.property.js variable.object.property.js",
@@ -1572,7 +1595,7 @@
}
},
{
- "match": "(?x)(?:\\s*\\b(public|private|protected|readonly)\\s+)?(\\.\\.\\.)?\\s*(?)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n )) |\n (:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n ))\n)",
+ "match": "(?x)(?:\\s*\\b(public|private|protected|readonly)\\s+)?(\\.\\.\\.)?\\s*(?)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n )) |\n (:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n ))\n)",
"captures": {
"1": {
"name": "storage.modifier.js"
@@ -2410,7 +2433,7 @@
}
},
{
- "match": "(?x) (\\.) \\s* (?:\n (ATTRIBUTE_NODE|CDATA_SECTION_NODE|COMMENT_NODE|DOCUMENT_FRAGMENT_NODE|DOCUMENT_NODE|DOCUMENT_TYPE_NODE\n |DOMSTRING_SIZE_ERR|ELEMENT_NODE|ENTITY_NODE|ENTITY_REFERENCE_NODE|HIERARCHY_REQUEST_ERR|INDEX_SIZE_ERR\n |INUSE_ATTRIBUTE_ERR|INVALID_CHARACTER_ERR|NO_DATA_ALLOWED_ERR|NO_MODIFICATION_ALLOWED_ERR|NOT_FOUND_ERR\n |NOT_SUPPORTED_ERR|NOTATION_NODE|PROCESSING_INSTRUCTION_NODE|TEXT_NODE|WRONG_DOCUMENT_ERR)\n |\n (_content|[xyz]|abbr|above|accept|acceptCharset|accessKey|action|align|[av]Link(?:color)?|all|alt|anchors|appCodeName\n |appCore|applets|appMinorVersion|appName|appVersion|archive|areas|arguments|attributes|availHeight|availLeft|availTop\n |availWidth|axis|background|backgroundColor|backgroundImage|below|bgColor|body|border|borderBottomWidth|borderColor\n |borderLeftWidth|borderRightWidth|borderStyle|borderTopWidth|borderWidth|bottom|bufferDepth|callee|caller|caption\n |cellPadding|cells|cellSpacing|ch|characterSet|charset|checked|childNodes|chOff|cite|classes|className|clear\n |clientInformation|clip|clipBoardData|closed|code|codeBase|codeType|color|colorDepth|cols|colSpan|compact|complete\n |components|content|controllers|cookie|cookieEnabled|cords|cpuClass|crypto|current|data|dateTime|declare|defaultCharset\n |defaultChecked|defaultSelected|defaultStatus|defaultValue|defaultView|defer|description|dialogArguments|dialogHeight\n |dialogLeft|dialogTop|dialogWidth|dir|directories|disabled|display|docmain|doctype|documentElement|elements|embeds\n |enabledPlugin|encoding|enctype|entities|event|expando|external|face|fgColor|filename|firstChild|fontFamily|fontSize\n |fontWeight|form|formName|forms|frame|frameBorder|frameElement|frames|hasFocus|hash|headers|height|history|host\n |hostname|href|hreflang|hspace|htmlFor|httpEquiv|id|ids|ignoreCase|images|implementation|index|innerHeight|innerWidth\n |input|isMap|label|lang|language|lastChild|lastIndex|lastMatch|lastModified|lastParen|layer[sXY]|left|leftContext\n |lineHeight|link|linkColor|links|listStyleType|localName|location|locationbar|longDesc|lowsrc|lowSrc|marginBottom\n |marginHeight|marginLeft|marginRight|marginTop|marginWidth|maxLength|media|menubar|method|mimeTypes|multiline|multiple\n |name|nameProp|namespaces|namespaceURI|next|nextSibling|nodeName|nodeType|nodeValue|noHref|noResize|noShade|notationName\n |notations|noWrap|object|offscreenBuffering|onLine|onreadystatechange|opener|opsProfile|options|oscpu|outerHeight\n |outerWidth|ownerDocument|paddingBottom|paddingLeft|paddingRight|paddingTop|page[XY]|page[XY]Offset|parent|parentLayer\n |parentNode|parentWindow|pathname|personalbar|pixelDepth|pkcs11|platform|plugins|port|prefix|previous|previousDibling\n |product|productSub|profile|profileend|prompt|prompter|protocol|publicId|readOnly|readyState|referrer|rel|responseText\n |responseXML|rev|right|rightContext|rowIndex|rows|rowSpan|rules|scheme|scope|screen[XY]|screenLeft|screenTop|scripts\n |scrollbars|scrolling|sectionRowIndex|security|securityPolicy|selected|selectedIndex|selection|self|shape|siblingAbove\n |siblingBelow|size|source|specified|standby|start|status|statusbar|statusText|style|styleSheets|suffixes|summary\n |systemId|systemLanguage|tagName|tags|target|tBodies|text|textAlign|textDecoration|textIndent|textTransform|tFoot|tHead\n |title|toolbar|top|type|undefined|uniqueID|updateInterval|URL|URLUnencoded|useMap|userAgent|userLanguage|userProfile\n |vAlign|value|valueType|vendor|vendorSub|version|visibility|vspace|whiteSpace|width|X[MS]LDocument|zIndex))\\b(?!\\$|\\s*(<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
+ "match": "(?x) (\\.) \\s* (?:\n (ATTRIBUTE_NODE|CDATA_SECTION_NODE|COMMENT_NODE|DOCUMENT_FRAGMENT_NODE|DOCUMENT_NODE|DOCUMENT_TYPE_NODE\n |DOMSTRING_SIZE_ERR|ELEMENT_NODE|ENTITY_NODE|ENTITY_REFERENCE_NODE|HIERARCHY_REQUEST_ERR|INDEX_SIZE_ERR\n |INUSE_ATTRIBUTE_ERR|INVALID_CHARACTER_ERR|NO_DATA_ALLOWED_ERR|NO_MODIFICATION_ALLOWED_ERR|NOT_FOUND_ERR\n |NOT_SUPPORTED_ERR|NOTATION_NODE|PROCESSING_INSTRUCTION_NODE|TEXT_NODE|WRONG_DOCUMENT_ERR)\n |\n (_content|[xyz]|abbr|above|accept|acceptCharset|accessKey|action|align|[av]Link(?:color)?|all|alt|anchors|appCodeName\n |appCore|applets|appMinorVersion|appName|appVersion|archive|areas|arguments|attributes|availHeight|availLeft|availTop\n |availWidth|axis|background|backgroundColor|backgroundImage|below|bgColor|body|border|borderBottomWidth|borderColor\n |borderLeftWidth|borderRightWidth|borderStyle|borderTopWidth|borderWidth|bottom|bufferDepth|callee|caller|caption\n |cellPadding|cells|cellSpacing|ch|characterSet|charset|checked|childNodes|chOff|cite|classes|className|clear\n |clientInformation|clip|clipBoardData|closed|code|codeBase|codeType|color|colorDepth|cols|colSpan|compact|complete\n |components|content|controllers|cookie|cookieEnabled|cords|cpuClass|crypto|current|data|dateTime|declare|defaultCharset\n |defaultChecked|defaultSelected|defaultStatus|defaultValue|defaultView|defer|description|dialogArguments|dialogHeight\n |dialogLeft|dialogTop|dialogWidth|dir|directories|disabled|display|docmain|doctype|documentElement|elements|embeds\n |enabledPlugin|encoding|enctype|entities|event|expando|external|face|fgColor|filename|firstChild|fontFamily|fontSize\n |fontWeight|form|formName|forms|frame|frameBorder|frameElement|frames|hasFocus|hash|headers|height|history|host\n |hostname|href|hreflang|hspace|htmlFor|httpEquiv|id|ids|ignoreCase|images|implementation|index|innerHeight|innerWidth\n |input|isMap|label|lang|language|lastChild|lastIndex|lastMatch|lastModified|lastParen|layer[sXY]|left|leftContext\n |lineHeight|link|linkColor|links|listStyleType|localName|location|locationbar|longDesc|lowsrc|lowSrc|marginBottom\n |marginHeight|marginLeft|marginRight|marginTop|marginWidth|maxLength|media|menubar|method|mimeTypes|multiline|multiple\n |name|nameProp|namespaces|namespaceURI|next|nextSibling|nodeName|nodeType|nodeValue|noHref|noResize|noShade|notationName\n |notations|noWrap|object|offscreenBuffering|onLine|onreadystatechange|opener|opsProfile|options|oscpu|outerHeight\n |outerWidth|ownerDocument|paddingBottom|paddingLeft|paddingRight|paddingTop|page[XY]|page[XY]Offset|parent|parentLayer\n |parentNode|parentWindow|pathname|personalbar|pixelDepth|pkcs11|platform|plugins|port|prefix|previous|previousDibling\n |product|productSub|profile|profileend|prompt|prompter|protocol|publicId|readOnly|readyState|referrer|rel|responseText\n |responseXML|rev|right|rightContext|rowIndex|rows|rowSpan|rules|scheme|scope|screen[XY]|screenLeft|screenTop|scripts\n |scrollbars|scrolling|sectionRowIndex|security|securityPolicy|selected|selectedIndex|selection|self|shape|siblingAbove\n |siblingBelow|size|source|specified|standby|start|status|statusbar|statusText|style|styleSheets|suffixes|summary\n |systemId|systemLanguage|tagName|tags|target|tBodies|text|textAlign|textDecoration|textIndent|textTransform|tFoot|tHead\n |title|toolbar|top|type|undefined|uniqueID|updateInterval|URL|URLUnencoded|useMap|userAgent|userLanguage|userProfile\n |vAlign|value|valueType|vendor|vendorSub|version|visibility|vspace|whiteSpace|width|X[MS]LDocument|zIndex))\\b(?!\\$|\\s*(<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
"captures": {
"1": {
"name": "punctuation.accessor.js"
@@ -2485,13 +2508,13 @@
]
},
"function-call": {
- "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\.\\s*)*|(\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
- "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\.\\s*)*|(\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
+ "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\.\\s*)*|(\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
+ "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\.\\s*)*|(\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
"patterns": [
{
"name": "meta.function-call.js",
"begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\.\\s*)*|(\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*))",
- "end": "(?=\\s*(<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
+ "end": "(?=\\s*(<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
"patterns": [
{
"include": "#literal"
@@ -2552,7 +2575,7 @@
"include": "#object-identifiers"
},
{
- "match": "(?x)(?:(\\.)\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n))",
+ "match": "(?x)(?:(\\.)\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n))",
"captures": {
"1": {
"name": "punctuation.accessor.js"
@@ -2697,7 +2720,7 @@
},
{
"name": "meta.object.member.js",
- "match": "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=:\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n)))",
+ "match": "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=:\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n)))",
"captures": {
"0": {
"name": "meta.object-literal.key.js"
@@ -2714,8 +2737,7 @@
"0": {
"name": "meta.object-literal.key.js"
}
- },
- "end": "(?=,|\\})"
+ }
},
{
"name": "meta.object.member.js",
@@ -2741,6 +2763,16 @@
}
}
},
+ {
+ "name": "meta.object.member.js",
+ "begin": "(?=[_$[:alpha:]][_$[:alnum:]]*\\s*=)",
+ "end": "(?=,|\\}|$)",
+ "patterns": [
+ {
+ "include": "#expression"
+ }
+ ]
+ },
{
"include": "#object-member-body"
},
@@ -2815,7 +2847,7 @@
"name": "keyword.control.as.js"
}
},
- "end": "(?=$|^|[;,:})\\]])",
+ "end": "(?=$|^|[;,:})\\]]|((? is on new line\n (\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n ) |\n (\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends \n ) |\n # arrow function possible to detect only with => on same line\n (\n (<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)? # typeparameters\n \\(([^()]|\\([^()]*\\))*\\) # parameteres\n (\\s*:\\s*(.)*)? # return type\n \\s*=> # arrow operator\n )\n )\n)",
+ "begin": "(?x) (?:\n (? is on new line\n (\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n ) |\n (\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends \n ) |\n # arrow function possible to detect only with => on same line\n (\n (<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)? # typeparameters\n \\(([^()]|\\([^()]*\\))*\\) # parameteres\n (\\s*:\\s*(.)*)? # return type\n \\s*=> # arrow operator\n )\n )\n)",
"beginCaptures": {
"1": {
"name": "storage.modifier.async.js"
@@ -3053,7 +3085,7 @@
"patterns": [
{
"name": "string.regexp.js",
- "begin": "(?<=[=(:,\\[?+!]|return|case|=>|&&|\\|\\||\\*\\/)\\s*(\\/)(?![\\/*])(?=(?:[^\\/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+\\/(?![\\/*])[gimy]*(?!\\s*[a-zA-Z0-9_$]))",
+ "begin": "(?<=[=(:,\\[?+!]|return|case|=>|&&|\\|\\||\\*\\/)\\s*(\\/)(?![\\/*])(?=(?:[^\\/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+\\/(?![\\/*])[gimuy]*(?!\\s*[a-zA-Z0-9_$]))",
"beginCaptures": {
"1": {
"name": "punctuation.definition.string.begin.js"
@@ -3076,7 +3108,7 @@
},
{
"name": "string.regexp.js",
- "begin": "(? {
+ for (let setting of schemaSettings) {
+ let url = getSchemaId(setting, rootPath);
+ if (!url) {
+ continue;
+ }
+ let schemaSetting = schemaSettingsById[url];
+ if (!schemaSetting) {
+ schemaSetting = schemaSettingsById[url] = { url, fileMatch: [] };
+ settings.json.schemas.push(schemaSetting);
+ }
+ let fileMatches = setting.fileMatch;
+ if (Array.isArray(fileMatches)) {
+ if (fileMatchPrefix) {
+ fileMatches = fileMatches.map(m => fileMatchPrefix + m);
+ }
+ schemaSetting.fileMatch.push(...fileMatches);
+ }
+ if (setting.schema) {
+ schemaSetting.schema = setting.schema;
+ }
}
};
- let settingsSchemas = jsonSettings.get('schemas');
- if (Array.isArray(settingsSchemas)) {
- schemas.push(...settingsSchemas);
- }
+ // merge global and folder settings. Qualify all file matches with the folder path.
+ let globalSettings = jsonSettings.get('schemas');
+ if (Array.isArray(globalSettings)) {
+ collectSchemaSettings(globalSettings, workspace.rootPath);
+ }
let folders = workspace.workspaceFolders;
if (folders) {
- folders.forEach(folder => {
- let jsonConfig = workspace.getConfiguration('json', folder.uri);
- let schemaConfigInfo = jsonConfig.inspect('schemas');
+ for (let folder of folders) {
+ let folderUri = folder.uri;
+ let schemaConfigInfo = workspace.getConfiguration('json', folderUri).inspect('schemas');
let folderSchemas = schemaConfigInfo.workspaceFolderValue;
if (Array.isArray(folderSchemas)) {
- folderSchemas.forEach(schema => {
- let url = schema.url;
- if (!url && schema.schema) {
- url = schema.schema.id;
- }
- if (url && url[0] === '.') {
- url = Uri.file(path.normalize(path.join(folder.uri.fsPath, url))).toString();
- }
- let fileMatch = schema.fileMatch;
- if (fileMatch) {
- fileMatch = fileMatch.map(m => folder.uri.toString() + '*' + m);
- }
- schemas.push({ url, fileMatch, schema: schema.schema });
- });
+ let folderPath = folderUri.toString();
+ if (folderPath[folderPath.length - 1] !== '/') {
+ folderPath = folderPath + '/';
+ }
+ collectSchemaSettings(folderSchemas, folderUri.fsPath, folderPath + '*');
};
- });
+ };
}
return settings;
}
+function getSchemaId(schema: JSONSchemaSettings, rootPath?: string) {
+ let url = schema.url;
+ if (!url) {
+ if (schema.schema) {
+ url = schema.schema.id || `vscode://schemas/custom/${encodeURIComponent(hash(schema.schema).toString(16))}`;
+ }
+ } else if (rootPath && (url[0] === '.' || url[0] === '/')) {
+ url = Uri.file(path.normalize(path.join(rootPath, url))).toString();
+ }
+ return url;
+}
+
function getPackageInfo(context: ExtensionContext): IPackageInfo {
let extensionPackage = require(context.asAbsolutePath('./package.json'));
if (extensionPackage) {
diff --git a/extensions/json/client/src/utils/hash.ts b/extensions/json/client/src/utils/hash.ts
new file mode 100644
index 00000000000..e7149e43cd7
--- /dev/null
+++ b/extensions/json/client/src/utils/hash.ts
@@ -0,0 +1,59 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+'use strict';
+
+/**
+ * Return a hash value for an object.
+ */
+export function hash(obj: any, hashVal = 0): number {
+ switch (typeof obj) {
+ case 'object':
+ if (obj === null) {
+ return numberHash(349, hashVal);
+ } else if (Array.isArray(obj)) {
+ return arrayHash(obj, hashVal);
+ }
+ return objectHash(obj, hashVal);
+ case 'string':
+ return stringHash(obj, hashVal);
+ case 'boolean':
+ return booleanHash(obj, hashVal);
+ case 'number':
+ return numberHash(obj, hashVal);
+ case 'undefined':
+ return numberHash(obj, 937);
+ default:
+ return numberHash(obj, 617);
+ }
+}
+
+function numberHash(val: number, initialHashVal: number): number {
+ return (((initialHashVal << 5) - initialHashVal) + val) | 0; // hashVal * 31 + ch, keep as int32
+}
+
+function booleanHash(b: boolean, initialHashVal: number): number {
+ return numberHash(b ? 433 : 863, initialHashVal);
+}
+
+function stringHash(s: string, hashVal: number) {
+ hashVal = numberHash(149417, hashVal);
+ for (let i = 0, length = s.length; i < length; i++) {
+ hashVal = numberHash(s.charCodeAt(i), hashVal);
+ }
+ return hashVal;
+}
+
+function arrayHash(arr: any[], initialHashVal: number): number {
+ initialHashVal = numberHash(104579, initialHashVal);
+ return arr.reduce((hashVal, item) => hash(item, hashVal), initialHashVal);
+}
+
+function objectHash(obj: any, initialHashVal: number): number {
+ initialHashVal = numberHash(181387, initialHashVal);
+ return Object.keys(obj).sort().reduce((hashVal, key) => {
+ hashVal = stringHash(key, hashVal);
+ return hash(obj[key], hashVal);
+ }, initialHashVal);
+}
diff --git a/extensions/json/server/npm-shrinkwrap.json b/extensions/json/server/npm-shrinkwrap.json
index 517efec26a3..3bcdb83008a 100644
--- a/extensions/json/server/npm-shrinkwrap.json
+++ b/extensions/json/server/npm-shrinkwrap.json
@@ -43,9 +43,9 @@
"resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.1.tgz"
},
"vscode-json-languageservice": {
- "version": "2.0.16",
+ "version": "2.0.18",
"from": "vscode-json-languageservice@next",
- "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-2.0.16.tgz"
+ "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-2.0.18.tgz"
},
"vscode-jsonrpc": {
"version": "3.3.1",
diff --git a/extensions/json/server/package.json b/extensions/json/server/package.json
index 3b6e892cc42..684e9c35d28 100644
--- a/extensions/json/server/package.json
+++ b/extensions/json/server/package.json
@@ -10,10 +10,11 @@
"dependencies": {
"jsonc-parser": "^1.0.0",
"request-light": "^0.2.1",
- "vscode-json-languageservice": "^2.0.16",
+ "vscode-json-languageservice": "^2.0.18",
"vscode-languageserver": "3.4.0-next.6",
"vscode-languageserver-protocol": "^3.1.1",
- "vscode-nls": "^2.0.2"
+ "vscode-nls": "^2.0.2",
+ "vscode-uri": "^1.0.1"
},
"devDependencies": {
"@types/node": "^6.0.51"
diff --git a/extensions/json/server/src/jsonServerMain.ts b/extensions/json/server/src/jsonServerMain.ts
index 2fe428f717f..4d1c416c41c 100644
--- a/extensions/json/server/src/jsonServerMain.ts
+++ b/extensions/json/server/src/jsonServerMain.ts
@@ -13,9 +13,8 @@ import {
import { DocumentColorRequest, ServerCapabilities as CPServerCapabilities } from 'vscode-languageserver-protocol/lib/protocol.colorProvider.proposed';
import { xhr, XHRResponse, configure as configureHttpRequests, getErrorStatusDescription } from 'request-light';
-import path = require('path');
import fs = require('fs');
-import URI from './utils/uri';
+import URI from 'vscode-uri';
import * as URL from 'url';
import Strings = require('./utils/strings');
import { JSONDocument, JSONSchema, LanguageSettings, getLanguageService } from 'vscode-json-languageservice';
@@ -54,9 +53,7 @@ let clientDynamicRegisterSupport = false;
// After the server has started the client sends an initilize request. The server receives
// in the passed params the rootPath of the workspace plus the client capabilities.
-let workspaceRoot: URI;
connection.onInitialize((params: InitializeParams): InitializeResult => {
- workspaceRoot = URI.parse(params.rootPath);
function hasClientCapability(...keys: string[]) {
let c = params.capabilities;
@@ -192,19 +189,12 @@ function updateConfiguration() {
}
}
if (jsonConfigurationSettings) {
- jsonConfigurationSettings.forEach(schema => {
+ jsonConfigurationSettings.forEach((schema, index) => {
let uri = schema.url;
if (!uri && schema.schema) {
- uri = schema.schema.id;
- }
- if (!uri && schema.fileMatch) {
- uri = 'vscode://schemas/custom/' + encodeURIComponent(schema.fileMatch.join('&'));
+ uri = schema.schema.id || `vscode://schemas/custom/${index}`;
}
if (uri) {
- if (uri[0] === '.' && workspaceRoot) {
- // workspace relative path
- uri = URI.file(path.normalize(path.join(workspaceRoot.fsPath, uri))).toString();
- }
languageSettings.schemas.push({ uri, fileMatch: schema.fileMatch, schema: schema.schema });
}
});
diff --git a/extensions/json/server/src/utils/uri.ts b/extensions/json/server/src/utils/uri.ts
deleted file mode 100644
index 5cce7590977..00000000000
--- a/extensions/json/server/src/utils/uri.ts
+++ /dev/null
@@ -1,351 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-'use strict';
-
-function _encode(ch: string): string {
- return '%' + ch.charCodeAt(0).toString(16).toUpperCase();
-}
-
-// see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
-function encodeURIComponent2(str: string): string {
- return encodeURIComponent(str).replace(/[!'()*]/g, _encode);
-}
-
-function encodeNoop(str: string): string {
- return str;
-}
-
-
-/**
- * Uniform Resource Identifier (URI) http://tools.ietf.org/html/rfc3986.
- * This class is a simple parser which creates the basic component paths
- * (http://tools.ietf.org/html/rfc3986#section-3) with minimal validation
- * and encoding.
- *
- * foo://example.com:8042/over/there?name=ferret#nose
- * \_/ \______________/\_________/ \_________/ \__/
- * | | | | |
- * scheme authority path query fragment
- * | _____________________|__
- * / \ / \
- * urn:example:animal:ferret:nose
- *
- *
- */
-export default class URI {
-
- private static _empty = '';
- private static _slash = '/';
- private static _regexp = /^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
- private static _driveLetterPath = /^\/[a-zA-z]:/;
- private static _upperCaseDrive = /^(\/)?([A-Z]:)/;
-
- private _scheme: string;
- private _authority: string;
- private _path: string;
- private _query: string;
- private _fragment: string;
- private _formatted: string;
- private _fsPath: string;
-
- constructor() {
- this._scheme = URI._empty;
- this._authority = URI._empty;
- this._path = URI._empty;
- this._query = URI._empty;
- this._fragment = URI._empty;
-
- this._formatted = null;
- this._fsPath = null;
- }
-
- /**
- * scheme is the 'http' part of 'http://www.msft.com/some/path?query#fragment'.
- * The part before the first colon.
- */
- get scheme() {
- return this._scheme;
- }
-
- /**
- * authority is the 'www.msft.com' part of 'http://www.msft.com/some/path?query#fragment'.
- * The part between the first double slashes and the next slash.
- */
- get authority() {
- return this._authority;
- }
-
- /**
- * path is the '/some/path' part of 'http://www.msft.com/some/path?query#fragment'.
- */
- get path() {
- return this._path;
- }
-
- /**
- * query is the 'query' part of 'http://www.msft.com/some/path?query#fragment'.
- */
- get query() {
- return this._query;
- }
-
- /**
- * fragment is the 'fragment' part of 'http://www.msft.com/some/path?query#fragment'.
- */
- get fragment() {
- return this._fragment;
- }
-
- // ---- filesystem path -----------------------
-
- /**
- * Returns a string representing the corresponding file system path of this URI.
- * Will handle UNC paths and normalize windows drive letters to lower-case. Also
- * uses the platform specific path separator. Will *not* validate the path for
- * invalid characters and semantics. Will *not* look at the scheme of this URI.
- */
- get fsPath() {
- if (!this._fsPath) {
- var value: string;
- if (this._authority && this.scheme === 'file') {
- // unc path: file://shares/c$/far/boo
- value = `//${this._authority}${this._path}`;
- } else if (URI._driveLetterPath.test(this._path)) {
- // windows drive letter: file:///c:/far/boo
- value = this._path[1].toLowerCase() + this._path.substr(2);
- } else {
- // other path
- value = this._path;
- }
- if (process.platform === 'win32') {
- value = value.replace(/\//g, '\\');
- }
- this._fsPath = value;
- }
- return this._fsPath;
- }
-
- // ---- modify to new -------------------------
-
- public with(scheme: string, authority: string, path: string, query: string, fragment: string): URI {
- var ret = new URI();
- ret._scheme = scheme || this.scheme;
- ret._authority = authority || this.authority;
- ret._path = path || this.path;
- ret._query = query || this.query;
- ret._fragment = fragment || this.fragment;
- URI._validate(ret);
- return ret;
- }
-
- public withScheme(value: string): URI {
- return this.with(value, undefined, undefined, undefined, undefined);
- }
-
- public withAuthority(value: string): URI {
- return this.with(undefined, value, undefined, undefined, undefined);
- }
-
- public withPath(value: string): URI {
- return this.with(undefined, undefined, value, undefined, undefined);
- }
-
- public withQuery(value: string): URI {
- return this.with(undefined, undefined, undefined, value, undefined);
- }
-
- public withFragment(value: string): URI {
- return this.with(undefined, undefined, undefined, undefined, value);
- }
-
- // ---- parse & validate ------------------------
-
- public static parse(value: string): URI {
- const ret = new URI();
- const data = URI._parseComponents(value);
- ret._scheme = data.scheme;
- ret._authority = decodeURIComponent(data.authority);
- ret._path = decodeURIComponent(data.path);
- ret._query = decodeURIComponent(data.query);
- ret._fragment = decodeURIComponent(data.fragment);
- URI._validate(ret);
- return ret;
- }
-
- public static file(path: string): URI {
-
- const ret = new URI();
- ret._scheme = 'file';
-
- // normalize to fwd-slashes
- path = path.replace(/\\/g, URI._slash);
-
- // check for authority as used in UNC shares
- // or use the path as given
- if (path[0] === URI._slash && path[0] === path[1]) {
- let idx = path.indexOf(URI._slash, 2);
- if (idx === -1) {
- ret._authority = path.substring(2);
- } else {
- ret._authority = path.substring(2, idx);
- ret._path = path.substring(idx);
- }
- } else {
- ret._path = path;
- }
-
- // Ensure that path starts with a slash
- // or that it is at least a slash
- if (ret._path[0] !== URI._slash) {
- ret._path = URI._slash + ret._path;
- }
-
- URI._validate(ret);
-
- return ret;
- }
-
- private static _parseComponents(value: string): UriComponents {
-
- const ret: UriComponents = {
- scheme: URI._empty,
- authority: URI._empty,
- path: URI._empty,
- query: URI._empty,
- fragment: URI._empty,
- };
-
- const match = URI._regexp.exec(value);
- if (match) {
- ret.scheme = match[2] || ret.scheme;
- ret.authority = match[4] || ret.authority;
- ret.path = match[5] || ret.path;
- ret.query = match[7] || ret.query;
- ret.fragment = match[9] || ret.fragment;
- }
- return ret;
- }
-
- public static create(scheme?: string, authority?: string, path?: string, query?: string, fragment?: string): URI {
- return new URI().with(scheme, authority, path, query, fragment);
- }
-
- private static _validate(ret: URI): void {
-
- // validation
- // path, http://tools.ietf.org/html/rfc3986#section-3.3
- // If a URI contains an authority component, then the path component
- // must either be empty or begin with a slash ("/") character. If a URI
- // does not contain an authority component, then the path cannot begin
- // with two slash characters ("//").
- if (ret.authority && ret.path && ret.path[0] !== '/') {
- throw new Error('[UriError]: If a URI contains an authority component, then the path component must either be empty or begin with a slash ("/") character');
- }
- if (!ret.authority && ret.path.indexOf('//') === 0) {
- throw new Error('[UriError]: If a URI does not contain an authority component, then the path cannot begin with two slash characters ("//")');
- }
- }
-
- // ---- printing/externalize ---------------------------
-
- /**
- *
- * @param skipEncoding Do not encode the result, default is `false`
- */
- public toString(skipEncoding: boolean = false): string {
- if (!skipEncoding) {
- if (!this._formatted) {
- this._formatted = URI._asFormatted(this, false);
- }
- return this._formatted;
- } else {
- // we don't cache that
- return URI._asFormatted(this, true);
- }
- }
-
- private static _asFormatted(uri: URI, skipEncoding: boolean): string {
-
- const encoder = !skipEncoding
- ? encodeURIComponent2
- : encodeNoop;
-
- const parts: string[] = [];
-
- let { scheme, authority, path, query, fragment } = uri;
- if (scheme) {
- parts.push(scheme, ':');
- }
- if (authority || scheme === 'file') {
- parts.push('//');
- }
- if (authority) {
- authority = authority.toLowerCase();
- let idx = authority.indexOf(':');
- if (idx === -1) {
- parts.push(encoder(authority));
- } else {
- parts.push(encoder(authority.substr(0, idx)), authority.substr(idx));
- }
- }
- if (path) {
- // lower-case windown drive letters in /C:/fff
- const m = URI._upperCaseDrive.exec(path);
- if (m) {
- path = m[1] + m[2].toLowerCase() + path.substr(m[1].length + m[2].length);
- }
-
- // encode every segement but not slashes
- // make sure that # and ? are always encoded
- // when occurring in paths - otherwise the result
- // cannot be parsed back again
- let lastIdx = 0;
- while (true) {
- let idx = path.indexOf(URI._slash, lastIdx);
- if (idx === -1) {
- parts.push(encoder(path.substring(lastIdx)).replace(/[#?]/, _encode));
- break;
- }
- parts.push(encoder(path.substring(lastIdx, idx)).replace(/[#?]/, _encode), URI._slash);
- lastIdx = idx + 1;
- };
- }
- if (query) {
- parts.push('?', encoder(query));
- }
- if (fragment) {
- parts.push('#', encoder(fragment));
- }
-
- return parts.join(URI._empty);
- }
-
- public toJSON(): any {
- return {
- scheme: this.scheme,
- authority: this.authority,
- path: this.path,
- fsPath: this.fsPath,
- query: this.query,
- fragment: this.fragment,
- external: this.toString(),
- $mid: 1
- };
- }
-}
-
-interface UriComponents {
- scheme: string;
- authority: string;
- path: string;
- query: string;
- fragment: string;
-}
-
-interface UriState extends UriComponents {
- $mid: number;
- fsPath: string;
- external: string;
-}
diff --git a/extensions/json/test/colorize-results/test_json.json b/extensions/json/test/colorize-results/test_json.json
index 5f9b48b1ea0..f5295bcf70a 100644
--- a/extensions/json/test/colorize-results/test_json.json
+++ b/extensions/json/test/colorize-results/test_json.json
@@ -388,11 +388,11 @@
"c": "\\u0056",
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json constant.character.escape.json",
"r": {
- "dark_plus": "string: #CE9178",
- "light_plus": "string: #A31515",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
- "hc_black": "string: #CE9178"
+ "hc_black": "constant.character: #569CD6"
}
},
{
diff --git a/extensions/make/test/colorize-results/makefile.json b/extensions/make/test/colorize-results/makefile.json
index b91562aaa2f..94d9b456703 100644
--- a/extensions/make/test/colorize-results/makefile.json
+++ b/extensions/make/test/colorize-results/makefile.json
@@ -135,11 +135,11 @@
"c": "\\",
"t": "source.makefile meta.scope.target.makefile meta.scope.prerequisites.makefile constant.character.escape.continuation.makefile",
"r": {
- "dark_plus": "default: #D4D4D4",
- "light_plus": "default: #000000",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -278,11 +278,11 @@
"c": "\\",
"t": "source.makefile meta.scope.target.makefile meta.scope.prerequisites.makefile constant.character.escape.continuation.makefile",
"r": {
- "dark_plus": "default: #D4D4D4",
- "light_plus": "default: #000000",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -322,11 +322,11 @@
"c": "\\",
"t": "source.makefile meta.scope.target.makefile meta.scope.prerequisites.makefile comment.line.number-sign.makefile constant.character.escape.continuation.makefile",
"r": {
- "dark_plus": "comment: #608B4E",
- "light_plus": "comment: #008000",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
- "hc_black": "comment: #7CA668"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -377,11 +377,11 @@
"c": "\\",
"t": "source.makefile comment.line.number-sign.makefile constant.character.escape.continuation.makefile",
"r": {
- "dark_plus": "comment: #608B4E",
- "light_plus": "comment: #008000",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
- "hc_black": "comment: #7CA668"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -553,11 +553,11 @@
"c": "\\",
"t": "source.makefile meta.scope.target.makefile meta.scope.prerequisites.makefile constant.character.escape.continuation.makefile",
"r": {
- "dark_plus": "default: #D4D4D4",
- "light_plus": "default: #000000",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "constant.character: #569CD6"
}
},
{
diff --git a/extensions/markdown/test/colorize-results/test_md.json b/extensions/markdown/test/colorize-results/test_md.json
index 4779949f7ae..c07d8316525 100644
--- a/extensions/markdown/test/colorize-results/test_md.json
+++ b/extensions/markdown/test/colorize-results/test_md.json
@@ -656,7 +656,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -678,7 +678,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -733,7 +733,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -744,7 +744,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1030,7 +1030,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1052,7 +1052,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1063,7 +1063,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1074,7 +1074,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1096,7 +1096,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1107,7 +1107,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1151,7 +1151,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1162,7 +1162,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1173,7 +1173,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
diff --git a/extensions/perl/test/colorize-results/test2_pl.json b/extensions/perl/test/colorize-results/test2_pl.json
index ef4bcabf439..bf690458af4 100644
--- a/extensions/perl/test/colorize-results/test2_pl.json
+++ b/extensions/perl/test/colorize-results/test2_pl.json
@@ -1301,11 +1301,11 @@
"c": "\\d\\d\\d",
"t": "source.perl string.regexp.find.perl constant.character.escape.perl",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
- "hc_black": "string.regexp: #D16969"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -1323,11 +1323,11 @@
"c": "\\d\\d",
"t": "source.perl string.regexp.find.perl constant.character.escape.perl",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
- "hc_black": "string.regexp: #D16969"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -1345,11 +1345,11 @@
"c": "\\d\\d",
"t": "source.perl string.regexp.find.perl constant.character.escape.perl",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
- "hc_black": "string.regexp: #D16969"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -1774,11 +1774,11 @@
"c": "\\d",
"t": "source.perl string.regexp.find.perl constant.character.escape.perl",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
- "hc_black": "string.regexp: #D16969"
+ "hc_black": "constant.character: #569CD6"
}
},
{
diff --git a/extensions/perl/test/colorize-results/test_pl.json b/extensions/perl/test/colorize-results/test_pl.json
index dd6dc702ac1..e6551c2c639 100644
--- a/extensions/perl/test/colorize-results/test_pl.json
+++ b/extensions/perl/test/colorize-results/test_pl.json
@@ -388,11 +388,11 @@
"c": "\\s",
"t": "source.perl string.regexp.find.perl constant.character.escape.perl",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
- "hc_black": "string.regexp: #D16969"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -410,11 +410,11 @@
"c": "\\s",
"t": "source.perl string.regexp.find.perl constant.character.escape.perl",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
- "hc_black": "string.regexp: #D16969"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -432,11 +432,11 @@
"c": "\\(",
"t": "source.perl string.regexp.find.perl constant.character.escape.perl",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
- "hc_black": "string.regexp: #D16969"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -454,11 +454,11 @@
"c": "\\)",
"t": "source.perl string.regexp.find.perl constant.character.escape.perl",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
- "hc_black": "string.regexp: #D16969"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -476,11 +476,11 @@
"c": "\\)",
"t": "source.perl string.regexp.find.perl constant.character.escape.perl",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
- "hc_black": "string.regexp: #D16969"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -674,11 +674,11 @@
"c": "\\n",
"t": "source.perl string.quoted.double.perl constant.character.escape.perl",
"r": {
- "dark_plus": "string: #CE9178",
- "light_plus": "string: #A31515",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
- "hc_black": "string: #CE9178"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -949,11 +949,11 @@
"c": "\\n",
"t": "source.perl string.quoted.double.perl constant.character.escape.perl",
"r": {
- "dark_plus": "string: #CE9178",
- "light_plus": "string: #A31515",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
- "hc_black": "string: #CE9178"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -1444,11 +1444,11 @@
"c": "\\n",
"t": "source.perl string.quoted.double.perl constant.character.escape.perl",
"r": {
- "dark_plus": "string: #CE9178",
- "light_plus": "string: #A31515",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
- "hc_black": "string: #CE9178"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -2280,11 +2280,11 @@
"c": "\\n",
"t": "source.perl string.quoted.double.perl constant.character.escape.perl",
"r": {
- "dark_plus": "string: #CE9178",
- "light_plus": "string: #A31515",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
- "hc_black": "string: #CE9178"
+ "hc_black": "constant.character: #569CD6"
}
},
{
diff --git a/extensions/php/package.json b/extensions/php/package.json
index e3b313bb321..3f50c17669b 100644
--- a/extensions/php/package.json
+++ b/extensions/php/package.json
@@ -27,7 +27,7 @@
"PHP",
"php"
],
- "firstLine": "^#!/.*\\bphp\\b",
+ "firstLine": "^#!/.*\\bphp\\b",
"mimetypes": [
"application/x-php"
],
diff --git a/extensions/php/syntaxes/php.tmLanguage.json b/extensions/php/syntaxes/php.tmLanguage.json
index 0a36eb0b2f5..3f4d3f537f6 100644
--- a/extensions/php/syntaxes/php.tmLanguage.json
+++ b/extensions/php/syntaxes/php.tmLanguage.json
@@ -1,10 +1,10 @@
{
"information_for_contributors": [
- "This file has been converted from https://github.com/atom/language-php/blob/master/grammars/php.cson",
+ "This file has been converted from https://github.com/roblourens/language-php/blob/revertBraceMatching/grammars/php.cson",
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
- "version": "https://github.com/atom/language-php/commit/efab9c83b91c02f04b8cfd0236e0239e14c4af52",
+ "version": "https://github.com/roblourens/language-php/commit/91d50ab5f871ea2d11b4c511dc0b9a972e4ac5ce",
"scopeName": "text.html.php",
"name": "PHP",
"fileTypes": [
@@ -1428,6 +1428,14 @@
{
"include": "#comments"
},
+ {
+ "match": "{",
+ "name": "punctuation.section.scope.begin.php"
+ },
+ {
+ "match": "}",
+ "name": "punctuation.section.scope.end.php"
+ },
{
"begin": "(?i)^\\s*(interface)\\s+([a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*)\\s*(extends)?\\s*",
"beginCaptures": {
@@ -2086,25 +2094,6 @@
{
"include": "#string-backtick"
},
- {
- "begin": "{",
- "beginCaptures": {
- "0": {
- "name": "punctuation.definition.begin.bracket.curly.php"
- }
- },
- "end": "}",
- "endCaptures": {
- "0": {
- "name": "punctuation.definition.end.bracket.curly.php"
- }
- },
- "patterns": [
- {
- "include": "#language"
- }
- ]
- },
{
"begin": "\\[",
"beginCaptures": {
diff --git a/extensions/php/test/colorize-results/issue-28354_php.json b/extensions/php/test/colorize-results/issue-28354_php.json
index 669388a960e..10314265464 100644
--- a/extensions/php/test/colorize-results/issue-28354_php.json
+++ b/extensions/php/test/colorize-results/issue-28354_php.json
@@ -40,7 +40,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -62,7 +62,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -73,7 +73,7 @@
"light_plus": "punctuation.section.embedded.begin.php: #800000",
"dark_vs": "punctuation.section.embedded.begin.php: #569CD6",
"light_vs": "punctuation.section.embedded.begin.php: #800000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
@@ -84,7 +84,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -106,7 +106,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -139,7 +139,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -161,7 +161,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -194,7 +194,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -205,18 +205,18 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
"c": "{",
- "t": "text.html.php meta.embedded.block.html source.js meta.embedded.block.php source.php punctuation.definition.begin.bracket.curly.php",
+ "t": "text.html.php meta.embedded.block.html source.js meta.embedded.block.php source.php punctuation.section.scope.begin.php",
"r": {
"dark_plus": "meta.embedded: #D4D4D4",
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -227,7 +227,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -249,7 +249,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -278,11 +278,11 @@
"c": "\\'",
"t": "text.html.php meta.embedded.block.html source.js meta.embedded.block.php source.php string.quoted.single.php constant.character.escape.php",
"r": {
- "dark_plus": "string: #CE9178",
- "light_plus": "string: #A31515",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
- "hc_black": "string: #CE9178"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -377,11 +377,11 @@
"c": "\\'",
"t": "text.html.php meta.embedded.block.html source.js meta.embedded.block.php source.php string.quoted.single.php constant.character.escape.php",
"r": {
- "dark_plus": "string: #CE9178",
- "light_plus": "string: #A31515",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
- "hc_black": "string: #CE9178"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -414,7 +414,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -425,18 +425,18 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
"c": "}",
- "t": "text.html.php meta.embedded.block.html source.js meta.embedded.block.php source.php punctuation.definition.end.bracket.curly.php",
+ "t": "text.html.php meta.embedded.block.html source.js meta.embedded.block.php source.php punctuation.section.scope.end.php",
"r": {
"dark_plus": "meta.embedded: #D4D4D4",
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -447,7 +447,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -458,7 +458,7 @@
"light_plus": "punctuation.section.embedded.end.php: #800000",
"dark_vs": "punctuation.section.embedded.end.php: #569CD6",
"light_vs": "punctuation.section.embedded.end.php: #800000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
@@ -469,7 +469,7 @@
"light_plus": "punctuation.section.embedded.end.php: #800000",
"dark_vs": "punctuation.section.embedded.end.php: #569CD6",
"light_vs": "punctuation.section.embedded.end.php: #800000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
@@ -480,7 +480,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
diff --git a/extensions/php/test/colorize-results/test_php.json b/extensions/php/test/colorize-results/test_php.json
index 5e1b41ed8e1..5f8cff26aa6 100644
--- a/extensions/php/test/colorize-results/test_php.json
+++ b/extensions/php/test/colorize-results/test_php.json
@@ -227,7 +227,7 @@
"light_plus": "punctuation.section.embedded.begin.php: #800000",
"dark_vs": "punctuation.section.embedded.begin.php: #569CD6",
"light_vs": "punctuation.section.embedded.begin.php: #800000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
@@ -238,7 +238,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -260,7 +260,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -282,7 +282,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -293,18 +293,18 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
"c": "{",
- "t": "text.html.php meta.embedded.block.php source.php punctuation.definition.begin.bracket.curly.php",
+ "t": "text.html.php meta.embedded.block.php source.php punctuation.section.scope.begin.php",
"r": {
"dark_plus": "meta.embedded: #D4D4D4",
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -315,7 +315,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -348,18 +348,18 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
"c": "}",
- "t": "text.html.php meta.embedded.block.php source.php punctuation.definition.end.bracket.curly.php",
+ "t": "text.html.php meta.embedded.block.php source.php punctuation.section.scope.end.php",
"r": {
"dark_plus": "meta.embedded: #D4D4D4",
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -370,7 +370,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -436,7 +436,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -469,7 +469,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -491,7 +491,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -513,7 +513,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -557,7 +557,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -568,7 +568,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -612,7 +612,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -623,7 +623,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -667,7 +667,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -678,7 +678,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -722,7 +722,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -733,7 +733,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -777,7 +777,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -788,7 +788,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -832,7 +832,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -843,7 +843,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -887,7 +887,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -898,7 +898,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -942,7 +942,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -953,7 +953,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -964,7 +964,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -986,7 +986,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1008,7 +1008,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1019,7 +1019,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1030,7 +1030,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1041,7 +1041,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1052,7 +1052,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1074,7 +1074,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1107,7 +1107,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1129,7 +1129,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1151,7 +1151,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1162,7 +1162,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1195,7 +1195,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1217,7 +1217,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1239,7 +1239,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1250,7 +1250,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1294,7 +1294,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1305,18 +1305,18 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
"c": "{",
- "t": "text.html.php meta.embedded.block.php source.php punctuation.definition.begin.bracket.curly.php",
+ "t": "text.html.php meta.embedded.block.php source.php punctuation.section.scope.begin.php",
"r": {
"dark_plus": "meta.embedded: #D4D4D4",
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1327,7 +1327,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1360,7 +1360,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1382,7 +1382,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1404,7 +1404,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1437,7 +1437,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1448,7 +1448,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1459,7 +1459,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1492,7 +1492,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1514,7 +1514,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1525,7 +1525,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1547,7 +1547,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1558,7 +1558,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1602,7 +1602,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1613,7 +1613,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1624,7 +1624,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1646,7 +1646,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1679,7 +1679,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1712,7 +1712,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1723,7 +1723,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1745,7 +1745,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1778,7 +1778,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1789,18 +1789,18 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
"c": "{",
- "t": "text.html.php meta.embedded.block.php source.php punctuation.definition.begin.bracket.curly.php",
+ "t": "text.html.php meta.embedded.block.php source.php punctuation.section.scope.begin.php",
"r": {
"dark_plus": "meta.embedded: #D4D4D4",
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1811,7 +1811,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1855,7 +1855,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1866,18 +1866,18 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
"c": "}",
- "t": "text.html.php meta.embedded.block.php source.php punctuation.definition.end.bracket.curly.php",
+ "t": "text.html.php meta.embedded.block.php source.php punctuation.section.scope.end.php",
"r": {
"dark_plus": "meta.embedded: #D4D4D4",
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1888,7 +1888,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1910,18 +1910,18 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
"c": "{",
- "t": "text.html.php meta.embedded.block.php source.php punctuation.definition.begin.bracket.curly.php",
+ "t": "text.html.php meta.embedded.block.php source.php punctuation.section.scope.begin.php",
"r": {
"dark_plus": "meta.embedded: #D4D4D4",
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1932,7 +1932,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1965,7 +1965,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1976,7 +1976,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -1987,7 +1987,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2009,7 +2009,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2042,7 +2042,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2075,7 +2075,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2086,7 +2086,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2097,7 +2097,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2130,7 +2130,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2163,7 +2163,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2174,7 +2174,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2196,7 +2196,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2229,7 +2229,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2240,18 +2240,18 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
"c": "}",
- "t": "text.html.php meta.embedded.block.php source.php punctuation.definition.end.bracket.curly.php",
+ "t": "text.html.php meta.embedded.block.php source.php punctuation.section.scope.end.php",
"r": {
"dark_plus": "meta.embedded: #D4D4D4",
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2262,18 +2262,18 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
"c": "}",
- "t": "text.html.php meta.embedded.block.php source.php punctuation.definition.end.bracket.curly.php",
+ "t": "text.html.php meta.embedded.block.php source.php punctuation.section.scope.end.php",
"r": {
"dark_plus": "meta.embedded: #D4D4D4",
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2284,7 +2284,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2306,7 +2306,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2328,7 +2328,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2339,7 +2339,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2350,7 +2350,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2361,7 +2361,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2372,7 +2372,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2405,7 +2405,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2427,7 +2427,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2438,7 +2438,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2460,7 +2460,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2471,7 +2471,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2504,7 +2504,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2515,7 +2515,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2526,7 +2526,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2548,7 +2548,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2625,7 +2625,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2636,7 +2636,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2647,7 +2647,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2680,7 +2680,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2702,7 +2702,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2713,7 +2713,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2746,7 +2746,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2768,7 +2768,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2790,7 +2790,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2801,7 +2801,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2834,7 +2834,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2856,7 +2856,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2878,7 +2878,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2889,7 +2889,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2933,7 +2933,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2944,18 +2944,18 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
"c": "{",
- "t": "text.html.php meta.embedded.block.php source.php punctuation.definition.begin.bracket.curly.php",
+ "t": "text.html.php meta.embedded.block.php source.php punctuation.section.scope.begin.php",
"r": {
"dark_plus": "meta.embedded: #D4D4D4",
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2966,7 +2966,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2988,7 +2988,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -2999,7 +2999,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3032,7 +3032,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3054,7 +3054,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3076,7 +3076,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3087,18 +3087,18 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
"c": "{",
- "t": "text.html.php meta.embedded.block.php source.php punctuation.definition.begin.bracket.curly.php",
+ "t": "text.html.php meta.embedded.block.php source.php punctuation.section.scope.begin.php",
"r": {
"dark_plus": "meta.embedded: #D4D4D4",
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3109,7 +3109,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3142,7 +3142,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3164,7 +3164,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3186,7 +3186,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3197,18 +3197,18 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
"c": "}",
- "t": "text.html.php meta.embedded.block.php source.php punctuation.definition.end.bracket.curly.php",
+ "t": "text.html.php meta.embedded.block.php source.php punctuation.section.scope.end.php",
"r": {
"dark_plus": "meta.embedded: #D4D4D4",
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3219,7 +3219,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3241,7 +3241,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3362,7 +3362,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3373,7 +3373,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3384,7 +3384,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3428,7 +3428,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3439,18 +3439,18 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
"c": "}",
- "t": "text.html.php meta.embedded.block.php source.php punctuation.definition.end.bracket.curly.php",
+ "t": "text.html.php meta.embedded.block.php source.php punctuation.section.scope.end.php",
"r": {
"dark_plus": "meta.embedded: #D4D4D4",
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3461,7 +3461,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3483,7 +3483,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3505,7 +3505,7 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3516,29 +3516,29 @@
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
"c": "{",
- "t": "text.html.php meta.embedded.block.php source.php punctuation.definition.begin.bracket.curly.php",
+ "t": "text.html.php meta.embedded.block.php source.php punctuation.section.scope.begin.php",
"r": {
"dark_plus": "meta.embedded: #D4D4D4",
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
"c": "}",
- "t": "text.html.php meta.embedded.block.php source.php punctuation.definition.end.bracket.curly.php",
+ "t": "text.html.php meta.embedded.block.php source.php punctuation.section.scope.end.php",
"r": {
"dark_plus": "meta.embedded: #D4D4D4",
"light_plus": "meta.embedded: #000000",
"dark_vs": "meta.embedded: #D4D4D4",
"light_vs": "meta.embedded: #000000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "meta.embedded: #FFFFFF"
}
},
{
@@ -3549,7 +3549,7 @@
"light_plus": "punctuation.section.embedded.end.php: #800000",
"dark_vs": "punctuation.section.embedded.end.php: #569CD6",
"light_vs": "punctuation.section.embedded.end.php: #800000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
@@ -3560,7 +3560,7 @@
"light_plus": "punctuation.section.embedded.end.php: #800000",
"dark_vs": "punctuation.section.embedded.end.php: #569CD6",
"light_vs": "punctuation.section.embedded.end.php: #800000",
- "hc_black": "default: #FFFFFF"
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
diff --git a/extensions/python/test/colorize-results/test_py.json b/extensions/python/test/colorize-results/test_py.json
index b456114b1ed..235958f078f 100644
--- a/extensions/python/test/colorize-results/test_py.json
+++ b/extensions/python/test/colorize-results/test_py.json
@@ -5294,8 +5294,8 @@
"c": "(",
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.parenthesis.regexp punctuation.parenthesis.begin.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "support.other.parenthesis.regexp: #CE9178",
+ "light_plus": "support.other.parenthesis.regexp: #D16969",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
"hc_black": "string.regexp: #D16969"
@@ -5305,8 +5305,8 @@
"c": "[",
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python meta.character.set.regexp punctuation.character.set.begin.regexp constant.other.set.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "punctuation.character.set.begin.regexp: #CE9178",
+ "light_plus": "punctuation.character.set.begin.regexp: #D16969",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
"hc_black": "string.regexp: #D16969"
@@ -5316,19 +5316,19 @@
"c": "0-9-",
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python meta.character.set.regexp constant.character.set.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "constant.character.set.regexp: #D16969",
+ "light_plus": "constant.character.set.regexp: #811F3F",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
- "hc_black": "string.regexp: #D16969"
+ "hc_black": "constant.character: #569CD6"
}
},
{
"c": "]",
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python meta.character.set.regexp punctuation.character.set.end.regexp constant.other.set.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "punctuation.character.set.end.regexp: #CE9178",
+ "light_plus": "punctuation.character.set.end.regexp: #D16969",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
"hc_black": "string.regexp: #D16969"
@@ -5338,8 +5338,8 @@
"c": "*",
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python keyword.operator.quantifier.regexp",
"r": {
- "dark_plus": "keyword.operator: #D4D4D4",
- "light_plus": "keyword.operator: #000000",
+ "dark_plus": "keyword.operator.quantifier.regexp: #D7BA7D",
+ "light_plus": "keyword.operator.quantifier.regexp: #000000",
"dark_vs": "keyword.operator: #D4D4D4",
"light_vs": "keyword.operator: #000000",
"hc_black": "keyword.operator: #D4D4D4"
@@ -5349,8 +5349,8 @@
"c": ")",
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.parenthesis.regexp punctuation.parenthesis.end.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "support.other.parenthesis.regexp: #CE9178",
+ "light_plus": "support.other.parenthesis.regexp: #D16969",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
"hc_black": "string.regexp: #D16969"
@@ -5371,8 +5371,8 @@
"c": "*",
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python keyword.operator.quantifier.regexp",
"r": {
- "dark_plus": "keyword.operator: #D4D4D4",
- "light_plus": "keyword.operator: #000000",
+ "dark_plus": "keyword.operator.quantifier.regexp: #D7BA7D",
+ "light_plus": "keyword.operator.quantifier.regexp: #000000",
"dark_vs": "keyword.operator: #D4D4D4",
"light_vs": "keyword.operator: #000000",
"hc_black": "keyword.operator: #D4D4D4"
@@ -5382,8 +5382,8 @@
"c": "(",
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.parenthesis.regexp punctuation.parenthesis.begin.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "support.other.parenthesis.regexp: #CE9178",
+ "light_plus": "support.other.parenthesis.regexp: #D16969",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
"hc_black": "string.regexp: #D16969"
@@ -5393,8 +5393,8 @@
"c": "[",
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python meta.character.set.regexp punctuation.character.set.begin.regexp constant.other.set.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "punctuation.character.set.begin.regexp: #CE9178",
+ "light_plus": "punctuation.character.set.begin.regexp: #D16969",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
"hc_black": "string.regexp: #D16969"
@@ -5404,19 +5404,19 @@
"c": "A-Za-z",
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python meta.character.set.regexp constant.character.set.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "constant.character.set.regexp: #D16969",
+ "light_plus": "constant.character.set.regexp: #811F3F",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
- "hc_black": "string.regexp: #D16969"
+ "hc_black": "constant.character: #569CD6"
}
},
{
"c": "]",
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python meta.character.set.regexp punctuation.character.set.end.regexp constant.other.set.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "punctuation.character.set.end.regexp: #CE9178",
+ "light_plus": "punctuation.character.set.end.regexp: #D16969",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
"hc_black": "string.regexp: #D16969"
@@ -5426,8 +5426,8 @@
"c": "+",
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python keyword.operator.quantifier.regexp",
"r": {
- "dark_plus": "keyword.operator: #D4D4D4",
- "light_plus": "keyword.operator: #000000",
+ "dark_plus": "keyword.operator.quantifier.regexp: #D7BA7D",
+ "light_plus": "keyword.operator.quantifier.regexp: #000000",
"dark_vs": "keyword.operator: #D4D4D4",
"light_vs": "keyword.operator: #000000",
"hc_black": "keyword.operator: #D4D4D4"
@@ -5437,8 +5437,8 @@
"c": ")",
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.parenthesis.regexp punctuation.parenthesis.end.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "support.other.parenthesis.regexp: #CE9178",
+ "light_plus": "support.other.parenthesis.regexp: #D16969",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
"hc_black": "string.regexp: #D16969"
@@ -5470,8 +5470,8 @@
"c": "+",
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python keyword.operator.quantifier.regexp",
"r": {
- "dark_plus": "keyword.operator: #D4D4D4",
- "light_plus": "keyword.operator: #000000",
+ "dark_plus": "keyword.operator.quantifier.regexp: #D7BA7D",
+ "light_plus": "keyword.operator.quantifier.regexp: #000000",
"dark_vs": "keyword.operator: #D4D4D4",
"light_vs": "keyword.operator: #000000",
"hc_black": "keyword.operator: #D4D4D4"
@@ -5481,8 +5481,8 @@
"c": "(",
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.parenthesis.regexp punctuation.parenthesis.begin.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "support.other.parenthesis.regexp: #CE9178",
+ "light_plus": "support.other.parenthesis.regexp: #D16969",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
"hc_black": "string.regexp: #D16969"
@@ -5503,8 +5503,8 @@
"c": "*",
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python keyword.operator.quantifier.regexp",
"r": {
- "dark_plus": "keyword.operator: #D4D4D4",
- "light_plus": "keyword.operator: #000000",
+ "dark_plus": "keyword.operator.quantifier.regexp: #D7BA7D",
+ "light_plus": "keyword.operator.quantifier.regexp: #000000",
"dark_vs": "keyword.operator: #D4D4D4",
"light_vs": "keyword.operator: #000000",
"hc_black": "keyword.operator: #D4D4D4"
@@ -5514,8 +5514,8 @@
"c": ")",
"t": "source.python meta.function-call.python meta.function-call.arguments.python string.regexp.quoted.single.python support.other.parenthesis.regexp punctuation.parenthesis.end.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "support.other.parenthesis.regexp: #CE9178",
+ "light_plus": "support.other.parenthesis.regexp: #D16969",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
"hc_black": "string.regexp: #D16969"
@@ -6504,8 +6504,8 @@
"c": "[",
"t": "source.python string.regexp.quoted.multi.python meta.character.set.regexp punctuation.character.set.begin.regexp constant.other.set.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "punctuation.character.set.begin.regexp: #CE9178",
+ "light_plus": "punctuation.character.set.begin.regexp: #D16969",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
"hc_black": "string.regexp: #D16969"
@@ -6515,11 +6515,11 @@
"c": "1,2)`` leads to",
"t": "source.python string.regexp.quoted.multi.python meta.character.set.regexp constant.character.set.regexp",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "constant.character.set.regexp: #D16969",
+ "light_plus": "constant.character.set.regexp: #811F3F",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
- "hc_black": "string.regexp: #D16969"
+ "hc_black": "constant.character: #569CD6"
}
},
{
diff --git a/extensions/razor/test/colorize-results/test_cshtml.json b/extensions/razor/test/colorize-results/test_cshtml.json
index 2e3dbe31e97..e7eead2eeeb 100644
--- a/extensions/razor/test/colorize-results/test_cshtml.json
+++ b/extensions/razor/test/colorize-results/test_cshtml.json
@@ -14,11 +14,11 @@
"c": "{",
"t": "text.html.cshtml section.embedded.source.cshtml punctuation.section.embedded.begin.cshtml",
"r": {
- "dark_plus": "default: #D4D4D4",
- "light_plus": "default: #000000",
- "dark_vs": "default: #D4D4D4",
- "light_vs": "default: #000000",
- "hc_black": "default: #FFFFFF"
+ "dark_plus": "punctuation.section.embedded: #569CD6",
+ "light_plus": "punctuation.section.embedded: #0000FF",
+ "dark_vs": "punctuation.section.embedded: #569CD6",
+ "light_vs": "punctuation.section.embedded: #0000FF",
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
@@ -333,11 +333,11 @@
"c": "{",
"t": "text.html.cshtml section.embedded.source.cshtml section.embedded.source.cshtml punctuation.section.embedded.begin.cshtml",
"r": {
- "dark_plus": "default: #D4D4D4",
- "light_plus": "default: #000000",
- "dark_vs": "default: #D4D4D4",
- "light_vs": "default: #000000",
- "hc_black": "default: #FFFFFF"
+ "dark_plus": "punctuation.section.embedded: #569CD6",
+ "light_plus": "punctuation.section.embedded: #0000FF",
+ "dark_vs": "punctuation.section.embedded: #569CD6",
+ "light_vs": "punctuation.section.embedded: #0000FF",
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
@@ -1125,22 +1125,22 @@
"c": "}",
"t": "text.html.cshtml section.embedded.source.cshtml section.embedded.source.cshtml punctuation.section.embedded.begin.cshtml",
"r": {
- "dark_plus": "default: #D4D4D4",
- "light_plus": "default: #000000",
- "dark_vs": "default: #D4D4D4",
- "light_vs": "default: #000000",
- "hc_black": "default: #FFFFFF"
+ "dark_plus": "punctuation.section.embedded: #569CD6",
+ "light_plus": "punctuation.section.embedded: #0000FF",
+ "dark_vs": "punctuation.section.embedded: #569CD6",
+ "light_vs": "punctuation.section.embedded: #0000FF",
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
"c": "}",
"t": "text.html.cshtml section.embedded.source.cshtml punctuation.section.embedded.begin.cshtml",
"r": {
- "dark_plus": "default: #D4D4D4",
- "light_plus": "default: #000000",
- "dark_vs": "default: #D4D4D4",
- "light_vs": "default: #000000",
- "hc_black": "default: #FFFFFF"
+ "dark_plus": "punctuation.section.embedded: #569CD6",
+ "light_plus": "punctuation.section.embedded: #0000FF",
+ "dark_vs": "punctuation.section.embedded: #569CD6",
+ "light_vs": "punctuation.section.embedded: #0000FF",
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
@@ -3226,11 +3226,11 @@
"c": "@(",
"t": "text.html.cshtml punctuation.section.embedded.begin.cshtml",
"r": {
- "dark_plus": "default: #D4D4D4",
- "light_plus": "default: #000000",
- "dark_vs": "default: #D4D4D4",
- "light_vs": "default: #000000",
- "hc_black": "default: #FFFFFF"
+ "dark_plus": "punctuation.section.embedded: #569CD6",
+ "light_plus": "punctuation.section.embedded: #0000FF",
+ "dark_vs": "punctuation.section.embedded: #569CD6",
+ "light_vs": "punctuation.section.embedded: #0000FF",
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
@@ -3270,11 +3270,11 @@
"c": ")",
"t": "text.html.cshtml punctuation.section.embedded.begin.cshtml",
"r": {
- "dark_plus": "default: #D4D4D4",
- "light_plus": "default: #000000",
- "dark_vs": "default: #D4D4D4",
- "light_vs": "default: #000000",
- "hc_black": "default: #FFFFFF"
+ "dark_plus": "punctuation.section.embedded: #569CD6",
+ "light_plus": "punctuation.section.embedded: #0000FF",
+ "dark_vs": "punctuation.section.embedded: #569CD6",
+ "light_vs": "punctuation.section.embedded: #0000FF",
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
diff --git a/extensions/ruby/test/colorize-results/test_rb.json b/extensions/ruby/test/colorize-results/test_rb.json
index a3c5163218e..996dbbf0192 100644
--- a/extensions/ruby/test/colorize-results/test_rb.json
+++ b/extensions/ruby/test/colorize-results/test_rb.json
@@ -2258,11 +2258,11 @@
"c": "#{",
"t": "source.ruby string.interpolated.ruby meta.embedded.line.ruby punctuation.section.embedded.begin.ruby",
"r": {
- "dark_plus": "meta.embedded: #D4D4D4",
- "light_plus": "meta.embedded: #000000",
- "dark_vs": "meta.embedded: #D4D4D4",
- "light_vs": "meta.embedded: #000000",
- "hc_black": "string: #CE9178"
+ "dark_plus": "punctuation.section.embedded: #569CD6",
+ "light_plus": "punctuation.section.embedded: #0000FF",
+ "dark_vs": "punctuation.section.embedded: #569CD6",
+ "light_vs": "punctuation.section.embedded: #0000FF",
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
@@ -2280,11 +2280,11 @@
"c": "}",
"t": "source.ruby string.interpolated.ruby meta.embedded.line.ruby punctuation.section.embedded.end.ruby source.ruby",
"r": {
- "dark_plus": "meta.embedded: #D4D4D4",
- "light_plus": "meta.embedded: #000000",
- "dark_vs": "meta.embedded: #D4D4D4",
- "light_vs": "meta.embedded: #000000",
- "hc_black": "string: #CE9178"
+ "dark_plus": "punctuation.section.embedded: #569CD6",
+ "light_plus": "punctuation.section.embedded: #0000FF",
+ "dark_vs": "punctuation.section.embedded: #569CD6",
+ "light_vs": "punctuation.section.embedded: #0000FF",
+ "hc_black": "punctuation.section.embedded: #569CD6"
}
},
{
@@ -2500,11 +2500,11 @@
"c": "\\d",
"t": "source.ruby string.regexp.classic.ruby meta.group.regexp.ruby constant.character.escape.ruby",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
- "hc_black": "string.regexp: #D16969"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -2522,11 +2522,11 @@
"c": "\\.\\d",
"t": "source.ruby string.regexp.classic.ruby meta.group.regexp.ruby constant.character.escape.ruby",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
- "hc_black": "string.regexp: #D16969"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -2544,11 +2544,11 @@
"c": "\\.\\d",
"t": "source.ruby string.regexp.classic.ruby meta.group.regexp.ruby constant.character.escape.ruby",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
- "hc_black": "string.regexp: #D16969"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -2577,11 +2577,11 @@
"c": "\\.\\d",
"t": "source.ruby string.regexp.classic.ruby meta.group.regexp.ruby meta.group.regexp.ruby constant.character.escape.ruby",
"r": {
- "dark_plus": "string.regexp: #D16969",
- "light_plus": "string.regexp: #811F3F",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string.regexp: #D16969",
"light_vs": "string.regexp: #811F3F",
- "hc_black": "string.regexp: #D16969"
+ "hc_black": "constant.character: #569CD6"
}
},
{
diff --git a/extensions/scss/test/colorize-results/test_scss.json b/extensions/scss/test/colorize-results/test_scss.json
index 961c9da0912..cc598d4c7a2 100644
--- a/extensions/scss/test/colorize-results/test_scss.json
+++ b/extensions/scss/test/colorize-results/test_scss.json
@@ -20716,11 +20716,11 @@
"c": "\\\\",
"t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss meta.property-list.scss meta.property-value.scss string.quoted.single.scss constant.character.escape.scss",
"r": {
- "dark_plus": "string: #CE9178",
- "light_plus": "string: #A31515",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
- "hc_black": "string: #CE9178"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -20837,11 +20837,11 @@
"c": "\\'",
"t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss meta.property-value.scss string.quoted.single.scss constant.character.escape.scss",
"r": {
- "dark_plus": "string: #CE9178",
- "light_plus": "string: #A31515",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
- "hc_black": "string: #CE9178"
+ "hc_black": "constant.character: #569CD6"
}
},
{
@@ -20914,11 +20914,11 @@
"c": "\\\"",
"t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss meta.property-value.scss string.quoted.double.scss constant.character.escape.scss",
"r": {
- "dark_plus": "string: #CE9178",
- "light_plus": "string: #A31515",
+ "dark_plus": "constant.character.escape: #D7BA7D",
+ "light_plus": "constant.character.escape: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
- "hc_black": "string: #CE9178"
+ "hc_black": "constant.character: #569CD6"
}
},
{
diff --git a/extensions/theme-abyss/themes/abyss-color-theme.json b/extensions/theme-abyss/themes/abyss-color-theme.json
index 6b1a0f1c474..bae5fd48804 100644
--- a/extensions/theme-abyss/themes/abyss-color-theme.json
+++ b/extensions/theme-abyss/themes/abyss-color-theme.json
@@ -8,7 +8,7 @@
}
},
{
- "scope": "meta.embedded",
+ "scope": ["meta.embedded", "source.groovy.embedded"],
"settings": {
"background": "#000c18",
"foreground": "#6688cc"
diff --git a/extensions/theme-defaults/themes/dark_plus.json b/extensions/theme-defaults/themes/dark_plus.json
index 972481b7e22..6fdfb2263ce 100644
--- a/extensions/theme-defaults/themes/dark_plus.json
+++ b/extensions/theme-defaults/themes/dark_plus.json
@@ -101,6 +101,59 @@
"settings": {
"foreground": "#CE9178"
}
+ },
+ {
+ "name": "Regular expression groups",
+ "scope": [
+ "punctuation.definition.group.regexp",
+ "punctuation.definition.group.assertion.regexp",
+ "punctuation.definition.character-class.regexp",
+ "punctuation.character.set.begin.regexp",
+ "punctuation.character.set.end.regexp",
+ "keyword.operator.negation.regexp",
+ "support.other.parenthesis.regexp"
+ ],
+ "settings": {
+ "foreground": "#CE9178"
+ }
+ },
+ {
+ "scope": [
+ "constant.character.character-class.regexp",
+ "constant.other.character-class.set.regexp",
+ "constant.other.character-class.regexp",
+ "constant.character.set.regexp"
+ ],
+ "settings": {
+ "foreground": "#d16969"
+ }
+ },
+ {
+ "scope": [
+ "keyword.operator.or.regexp",
+ "keyword.control.anchor.regexp"
+ ],
+ "settings": {
+ "foreground": "#DCDCAA"
+ }
+ },
+ {
+ "scope": "keyword.operator.quantifier.regexp",
+ "settings": {
+ "foreground": "#d7ba7d"
+ }
+ },
+ {
+ "scope": "constant.character",
+ "settings": {
+ "foreground": "#569cd6"
+ }
+ },
+ {
+ "scope": "constant.character.escape",
+ "settings": {
+ "foreground": "#d7ba7d"
+ }
}
]
}
\ No newline at end of file
diff --git a/extensions/theme-defaults/themes/dark_vs.json b/extensions/theme-defaults/themes/dark_vs.json
index 57dd332be52..084720561d0 100644
--- a/extensions/theme-defaults/themes/dark_vs.json
+++ b/extensions/theme-defaults/themes/dark_vs.json
@@ -10,7 +10,10 @@
}
},
{
- "scope": "meta.embedded",
+ "scope": [
+ "meta.embedded",
+ "source.groovy.embedded"
+ ],
"settings": {
"foreground": "#D4D4D4",
"background": "#1E1E1E"
@@ -248,11 +251,11 @@
}
},
{
- "name": "JavaScript string interpolation ${}",
+ "name": "String interpolation",
"scope": [
"punctuation.definition.template-expression.begin",
"punctuation.definition.template-expression.end",
- "punctuation.section.embedded.coffee"
+ "punctuation.section.embedded"
],
"settings": {
"foreground": "#569cd6"
diff --git a/extensions/theme-defaults/themes/hc_black_defaults.json b/extensions/theme-defaults/themes/hc_black_defaults.json
index 986fa7cf615..8833ff32c1f 100644
--- a/extensions/theme-defaults/themes/hc_black_defaults.json
+++ b/extensions/theme-defaults/themes/hc_black_defaults.json
@@ -14,6 +14,16 @@
"background": "#000000"
}
},
+ {
+ "scope": [
+ "meta.embedded",
+ "source.groovy.embedded"
+ ],
+ "settings": {
+ "foreground": "#FFFFFF",
+ "background": "#000000"
+ }
+ },
{
"scope": "emphasis",
"settings": {
@@ -61,6 +71,12 @@
"foreground": "#b46695"
}
},
+ {
+ "scope": "constant.character",
+ "settings": {
+ "foreground": "#569cd6"
+ }
+ },
{
"scope": "entity.name.tag",
"settings": {
@@ -227,11 +243,11 @@
}
},
{
- "name": "JavaScript string interpolation ${}",
+ "name": "String interpolation",
"scope": [
"punctuation.definition.template-expression.begin",
"punctuation.definition.template-expression.end",
- "punctuation.section.embedded.coffee"
+ "punctuation.section.embedded"
],
"settings": {
"foreground": "#569cd6"
diff --git a/extensions/theme-defaults/themes/light_plus.json b/extensions/theme-defaults/themes/light_plus.json
index c087a8f6ca1..3d5775ecec5 100644
--- a/extensions/theme-defaults/themes/light_plus.json
+++ b/extensions/theme-defaults/themes/light_plus.json
@@ -101,6 +101,60 @@
"settings": {
"foreground": "#0451a5"
}
+ },
+ {
+ "name": "Regular expression groups",
+ "scope": [
+ "punctuation.definition.group.regexp",
+ "punctuation.definition.group.assertion.regexp",
+ "punctuation.definition.character-class.regexp",
+ "punctuation.character.set.begin.regexp",
+ "punctuation.character.set.end.regexp",
+ "keyword.operator.negation.regexp",
+ "support.other.parenthesis.regexp"
+ ],
+ "settings": {
+ "foreground": "#d16969"
+ }
+ },
+ {
+ "scope": [
+ "constant.character.character-class.regexp",
+ "constant.other.character-class.set.regexp",
+ "constant.other.character-class.regexp",
+ "constant.character.set.regexp"
+ ],
+ "settings": {
+ "foreground": "#811f3f"
+ }
+ },
+ {
+ "scope": "keyword.operator.quantifier.regexp",
+ "settings": {
+ "foreground": "#000000"
+ }
+ },
+ {
+ "scope": [
+ "keyword.operator.or.regexp",
+ "keyword.control.anchor.regexp"
+ ],
+ "settings": {
+ "foreground": "#ff0000"
+ }
+ },
+ {
+ "scope": "constant.character",
+ "settings": {
+ "foreground": "#0000ff"
+ }
+ },
+ {
+ "scope": "constant.character.escape",
+ "settings": {
+ "foreground": "#a31515"
+ }
}
+
]
}
\ No newline at end of file
diff --git a/extensions/theme-defaults/themes/light_vs.json b/extensions/theme-defaults/themes/light_vs.json
index 91f311a80a8..883d88347dc 100644
--- a/extensions/theme-defaults/themes/light_vs.json
+++ b/extensions/theme-defaults/themes/light_vs.json
@@ -4,7 +4,7 @@
"include": "./light_defaults.json",
"tokenColors": [
{
- "scope": "meta.embedded",
+ "scope": ["meta.embedded", "source.groovy.embedded"],
"settings": {
"foreground": "#000000ff",
"background":"#ffffffff"
@@ -244,11 +244,11 @@
}
},
{
- "name": "JavaScript string interpolation ${}",
+ "name": "String interpolation",
"scope": [
"punctuation.definition.template-expression.begin",
"punctuation.definition.template-expression.end",
- "punctuation.section.embedded.coffee"
+ "punctuation.section.embedded"
],
"settings": {
"foreground": "#0000ff"
diff --git a/extensions/theme-kimbie-dark/themes/kimbie-dark-color-theme.json b/extensions/theme-kimbie-dark/themes/kimbie-dark-color-theme.json
index 3a14293383f..bad21aface9 100644
--- a/extensions/theme-kimbie-dark/themes/kimbie-dark-color-theme.json
+++ b/extensions/theme-kimbie-dark/themes/kimbie-dark-color-theme.json
@@ -55,7 +55,7 @@
}
},
{
- "scope": "meta.embedded",
+ "scope": ["meta.embedded", "source.groovy.embedded"],
"settings": {
"background": "#221a0f",
"foreground": "#d3af86"
diff --git a/extensions/theme-monokai-dimmed/themes/dimmed-monokai-color-theme.json b/extensions/theme-monokai-dimmed/themes/dimmed-monokai-color-theme.json
index 31cd63a47bc..398853e9988 100644
--- a/extensions/theme-monokai-dimmed/themes/dimmed-monokai-color-theme.json
+++ b/extensions/theme-monokai-dimmed/themes/dimmed-monokai-color-theme.json
@@ -52,7 +52,7 @@
}
},
{
- "scope": "meta.embedded",
+ "scope": ["meta.embedded", "source.groovy.embedded"],
"settings": {
"background": "#1e1e1e",
"foreground": "#C5C8C6"
@@ -453,7 +453,9 @@
},
{
"name": "Ruby Embedded Source",
- "scope": "source.ruby.embedded.source",
+ "scope": [
+ "punctuation.section.embedded.begin.ruby",
+ "punctuation.section.embedded.end.ruby"],
"settings": {
"foreground": "#D08442"
}
diff --git a/extensions/theme-monokai/themes/monokai-color-theme.json b/extensions/theme-monokai/themes/monokai-color-theme.json
index a3152125248..f7e45a6daf0 100644
--- a/extensions/theme-monokai/themes/monokai-color-theme.json
+++ b/extensions/theme-monokai/themes/monokai-color-theme.json
@@ -97,7 +97,7 @@
}
},
{
- "scope": "meta.embedded",
+ "scope": ["meta.embedded", "source.groovy.embedded"],
"settings": {
"background": "#272822",
"foreground": "#F8F8F2"
@@ -121,7 +121,7 @@
"name": "Template Definition",
"scope": [
"punctuation.definition.template-expression",
- "punctuation.section.embedded.coffee"
+ "punctuation.section.embedded"
],
"settings": {
"foreground": "#F92672"
diff --git a/extensions/theme-quietlight/themes/quietlight-color-theme.json b/extensions/theme-quietlight/themes/quietlight-color-theme.json
index 59c6834293f..9fd5ad62cee 100644
--- a/extensions/theme-quietlight/themes/quietlight-color-theme.json
+++ b/extensions/theme-quietlight/themes/quietlight-color-theme.json
@@ -8,7 +8,7 @@
}
},
{
- "scope": "meta.embedded",
+ "scope": ["meta.embedded", "source.groovy.embedded"],
"settings": {
"background": "#F5F5F5",
"foreground": "#333333"
diff --git a/extensions/theme-red/themes/Red-color-theme.json b/extensions/theme-red/themes/Red-color-theme.json
index 414ad2fb5e8..df3b63b3792 100644
--- a/extensions/theme-red/themes/Red-color-theme.json
+++ b/extensions/theme-red/themes/Red-color-theme.json
@@ -69,7 +69,7 @@
}
},
{
- "scope": "meta.embedded",
+ "scope": ["meta.embedded", "source.groovy.embedded"],
"settings": {
"background": "#390000",
"foreground": "#F8F8F8"
@@ -170,16 +170,16 @@
}
},
{
- "name": "String embedded-source",
- "scope": "string.quoted source",
+ "scope": "constant.character",
"settings": {
- "fontStyle": "",
- "foreground": "#9df39fff"
+ "foreground": "#ec0d1e"
}
},
{
- "name": "String constant",
- "scope": "string constant",
+ "scope": [
+ "string constant",
+ "constant.character.escape"
+ ],
"settings": {
"fontStyle": "",
"foreground": "#ffe862ff"
@@ -393,6 +393,18 @@
"fontStyle": "",
"foreground": "#fec758ff"
}
+ },
+ {
+ "name": "String interpolation",
+ "scope": [
+ "punctuation.definition.template-expression.begin",
+ "punctuation.definition.template-expression.end",
+ "punctuation.section.embedded",
+ ".format.placeholder"
+ ],
+ "settings": {
+ "foreground": "#ec0d1e"
+ }
}
]
}
\ No newline at end of file
diff --git a/extensions/theme-solarized-dark/themes/solarized-dark-color-theme.json b/extensions/theme-solarized-dark/themes/solarized-dark-color-theme.json
index 88e94050dee..c7bf6f68cb1 100644
--- a/extensions/theme-solarized-dark/themes/solarized-dark-color-theme.json
+++ b/extensions/theme-solarized-dark/themes/solarized-dark-color-theme.json
@@ -8,7 +8,7 @@
}
},
{
- "scope": "meta.embedded",
+ "scope": ["meta.embedded", "source.groovy.embedded"],
"settings": {
"background": "#002B36",
"foreground": "#93A1A1"
diff --git a/extensions/theme-solarized-light/themes/solarized-light-color-theme.json b/extensions/theme-solarized-light/themes/solarized-light-color-theme.json
index a7a4be6acb7..6d2b7146583 100644
--- a/extensions/theme-solarized-light/themes/solarized-light-color-theme.json
+++ b/extensions/theme-solarized-light/themes/solarized-light-color-theme.json
@@ -8,7 +8,7 @@
}
},
{
- "scope": "meta.embedded",
+ "scope": ["meta.embedded", "source.groovy.embedded"],
"settings": {
"background": "#FDF6E3",
"foreground": "#657B83"
diff --git a/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-theme.json b/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-theme.json
index 23bf67fb9a6..7163c4d671a 100644
--- a/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-theme.json
+++ b/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-theme.json
@@ -61,7 +61,7 @@
}
},
{
- "scope": "meta.embedded",
+ "scope": ["meta.embedded", "source.groovy.embedded"],
"settings": {
"background": "#002451",
"foreground": "#FFFFFF"
diff --git a/extensions/typescript/syntaxes/TypeScript.tmLanguage.json b/extensions/typescript/syntaxes/TypeScript.tmLanguage.json
index 96f7d0e6fed..185a638d78d 100644
--- a/extensions/typescript/syntaxes/TypeScript.tmLanguage.json
+++ b/extensions/typescript/syntaxes/TypeScript.tmLanguage.json
@@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
- "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/648a036db2bad78ee93463269ec49ed91ee5aa91",
+ "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/30d95ebb561fc57e784b43d08f0a6f46ad0c3e5d",
"name": "TypeScript",
"scopeName": "source.ts",
"fileTypes": [
@@ -91,6 +91,29 @@
{
"include": "#comment"
},
+ {
+ "begin": "(,)\\s*(?!\\S)",
+ "beginCaptures": {
+ "1": {
+ "name": "punctuation.separator.comma.ts"
+ }
+ },
+ "end": "(?)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n )) |\n (:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n ))\n)",
+ "begin": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\n (=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n )) |\n (:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n ))\n)",
"beginCaptures": {
"1": {
"name": "meta.definition.variable.ts entity.name.function.ts"
@@ -721,7 +744,7 @@
},
"import-declaration": {
"name": "meta.import.ts",
- "begin": "(?)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n )) |\n (:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n ))\n)"
+ "match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=(\\?\\s*)?\\s*\n (=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n )) |\n (:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n ))\n)"
},
{
"name": "meta.definition.property.ts variable.object.property.ts",
@@ -1566,7 +1589,7 @@
}
},
{
- "match": "(?x)(?:\\s*\\b(public|private|protected|readonly)\\s+)?(\\.\\.\\.)?\\s*(?)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n )) |\n (:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n ))\n)",
+ "match": "(?x)(?:\\s*\\b(public|private|protected|readonly)\\s+)?(\\.\\.\\.)?\\s*(?)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n )) |\n (:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n ))\n)",
"captures": {
"1": {
"name": "storage.modifier.ts"
@@ -2404,7 +2427,7 @@
}
},
{
- "match": "(?x) (\\.) \\s* (?:\n (ATTRIBUTE_NODE|CDATA_SECTION_NODE|COMMENT_NODE|DOCUMENT_FRAGMENT_NODE|DOCUMENT_NODE|DOCUMENT_TYPE_NODE\n |DOMSTRING_SIZE_ERR|ELEMENT_NODE|ENTITY_NODE|ENTITY_REFERENCE_NODE|HIERARCHY_REQUEST_ERR|INDEX_SIZE_ERR\n |INUSE_ATTRIBUTE_ERR|INVALID_CHARACTER_ERR|NO_DATA_ALLOWED_ERR|NO_MODIFICATION_ALLOWED_ERR|NOT_FOUND_ERR\n |NOT_SUPPORTED_ERR|NOTATION_NODE|PROCESSING_INSTRUCTION_NODE|TEXT_NODE|WRONG_DOCUMENT_ERR)\n |\n (_content|[xyz]|abbr|above|accept|acceptCharset|accessKey|action|align|[av]Link(?:color)?|all|alt|anchors|appCodeName\n |appCore|applets|appMinorVersion|appName|appVersion|archive|areas|arguments|attributes|availHeight|availLeft|availTop\n |availWidth|axis|background|backgroundColor|backgroundImage|below|bgColor|body|border|borderBottomWidth|borderColor\n |borderLeftWidth|borderRightWidth|borderStyle|borderTopWidth|borderWidth|bottom|bufferDepth|callee|caller|caption\n |cellPadding|cells|cellSpacing|ch|characterSet|charset|checked|childNodes|chOff|cite|classes|className|clear\n |clientInformation|clip|clipBoardData|closed|code|codeBase|codeType|color|colorDepth|cols|colSpan|compact|complete\n |components|content|controllers|cookie|cookieEnabled|cords|cpuClass|crypto|current|data|dateTime|declare|defaultCharset\n |defaultChecked|defaultSelected|defaultStatus|defaultValue|defaultView|defer|description|dialogArguments|dialogHeight\n |dialogLeft|dialogTop|dialogWidth|dir|directories|disabled|display|docmain|doctype|documentElement|elements|embeds\n |enabledPlugin|encoding|enctype|entities|event|expando|external|face|fgColor|filename|firstChild|fontFamily|fontSize\n |fontWeight|form|formName|forms|frame|frameBorder|frameElement|frames|hasFocus|hash|headers|height|history|host\n |hostname|href|hreflang|hspace|htmlFor|httpEquiv|id|ids|ignoreCase|images|implementation|index|innerHeight|innerWidth\n |input|isMap|label|lang|language|lastChild|lastIndex|lastMatch|lastModified|lastParen|layer[sXY]|left|leftContext\n |lineHeight|link|linkColor|links|listStyleType|localName|location|locationbar|longDesc|lowsrc|lowSrc|marginBottom\n |marginHeight|marginLeft|marginRight|marginTop|marginWidth|maxLength|media|menubar|method|mimeTypes|multiline|multiple\n |name|nameProp|namespaces|namespaceURI|next|nextSibling|nodeName|nodeType|nodeValue|noHref|noResize|noShade|notationName\n |notations|noWrap|object|offscreenBuffering|onLine|onreadystatechange|opener|opsProfile|options|oscpu|outerHeight\n |outerWidth|ownerDocument|paddingBottom|paddingLeft|paddingRight|paddingTop|page[XY]|page[XY]Offset|parent|parentLayer\n |parentNode|parentWindow|pathname|personalbar|pixelDepth|pkcs11|platform|plugins|port|prefix|previous|previousDibling\n |product|productSub|profile|profileend|prompt|prompter|protocol|publicId|readOnly|readyState|referrer|rel|responseText\n |responseXML|rev|right|rightContext|rowIndex|rows|rowSpan|rules|scheme|scope|screen[XY]|screenLeft|screenTop|scripts\n |scrollbars|scrolling|sectionRowIndex|security|securityPolicy|selected|selectedIndex|selection|self|shape|siblingAbove\n |siblingBelow|size|source|specified|standby|start|status|statusbar|statusText|style|styleSheets|suffixes|summary\n |systemId|systemLanguage|tagName|tags|target|tBodies|text|textAlign|textDecoration|textIndent|textTransform|tFoot|tHead\n |title|toolbar|top|type|undefined|uniqueID|updateInterval|URL|URLUnencoded|useMap|userAgent|userLanguage|userProfile\n |vAlign|value|valueType|vendor|vendorSub|version|visibility|vspace|whiteSpace|width|X[MS]LDocument|zIndex))\\b(?!\\$|\\s*(<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
+ "match": "(?x) (\\.) \\s* (?:\n (ATTRIBUTE_NODE|CDATA_SECTION_NODE|COMMENT_NODE|DOCUMENT_FRAGMENT_NODE|DOCUMENT_NODE|DOCUMENT_TYPE_NODE\n |DOMSTRING_SIZE_ERR|ELEMENT_NODE|ENTITY_NODE|ENTITY_REFERENCE_NODE|HIERARCHY_REQUEST_ERR|INDEX_SIZE_ERR\n |INUSE_ATTRIBUTE_ERR|INVALID_CHARACTER_ERR|NO_DATA_ALLOWED_ERR|NO_MODIFICATION_ALLOWED_ERR|NOT_FOUND_ERR\n |NOT_SUPPORTED_ERR|NOTATION_NODE|PROCESSING_INSTRUCTION_NODE|TEXT_NODE|WRONG_DOCUMENT_ERR)\n |\n (_content|[xyz]|abbr|above|accept|acceptCharset|accessKey|action|align|[av]Link(?:color)?|all|alt|anchors|appCodeName\n |appCore|applets|appMinorVersion|appName|appVersion|archive|areas|arguments|attributes|availHeight|availLeft|availTop\n |availWidth|axis|background|backgroundColor|backgroundImage|below|bgColor|body|border|borderBottomWidth|borderColor\n |borderLeftWidth|borderRightWidth|borderStyle|borderTopWidth|borderWidth|bottom|bufferDepth|callee|caller|caption\n |cellPadding|cells|cellSpacing|ch|characterSet|charset|checked|childNodes|chOff|cite|classes|className|clear\n |clientInformation|clip|clipBoardData|closed|code|codeBase|codeType|color|colorDepth|cols|colSpan|compact|complete\n |components|content|controllers|cookie|cookieEnabled|cords|cpuClass|crypto|current|data|dateTime|declare|defaultCharset\n |defaultChecked|defaultSelected|defaultStatus|defaultValue|defaultView|defer|description|dialogArguments|dialogHeight\n |dialogLeft|dialogTop|dialogWidth|dir|directories|disabled|display|docmain|doctype|documentElement|elements|embeds\n |enabledPlugin|encoding|enctype|entities|event|expando|external|face|fgColor|filename|firstChild|fontFamily|fontSize\n |fontWeight|form|formName|forms|frame|frameBorder|frameElement|frames|hasFocus|hash|headers|height|history|host\n |hostname|href|hreflang|hspace|htmlFor|httpEquiv|id|ids|ignoreCase|images|implementation|index|innerHeight|innerWidth\n |input|isMap|label|lang|language|lastChild|lastIndex|lastMatch|lastModified|lastParen|layer[sXY]|left|leftContext\n |lineHeight|link|linkColor|links|listStyleType|localName|location|locationbar|longDesc|lowsrc|lowSrc|marginBottom\n |marginHeight|marginLeft|marginRight|marginTop|marginWidth|maxLength|media|menubar|method|mimeTypes|multiline|multiple\n |name|nameProp|namespaces|namespaceURI|next|nextSibling|nodeName|nodeType|nodeValue|noHref|noResize|noShade|notationName\n |notations|noWrap|object|offscreenBuffering|onLine|onreadystatechange|opener|opsProfile|options|oscpu|outerHeight\n |outerWidth|ownerDocument|paddingBottom|paddingLeft|paddingRight|paddingTop|page[XY]|page[XY]Offset|parent|parentLayer\n |parentNode|parentWindow|pathname|personalbar|pixelDepth|pkcs11|platform|plugins|port|prefix|previous|previousDibling\n |product|productSub|profile|profileend|prompt|prompter|protocol|publicId|readOnly|readyState|referrer|rel|responseText\n |responseXML|rev|right|rightContext|rowIndex|rows|rowSpan|rules|scheme|scope|screen[XY]|screenLeft|screenTop|scripts\n |scrollbars|scrolling|sectionRowIndex|security|securityPolicy|selected|selectedIndex|selection|self|shape|siblingAbove\n |siblingBelow|size|source|specified|standby|start|status|statusbar|statusText|style|styleSheets|suffixes|summary\n |systemId|systemLanguage|tagName|tags|target|tBodies|text|textAlign|textDecoration|textIndent|textTransform|tFoot|tHead\n |title|toolbar|top|type|undefined|uniqueID|updateInterval|URL|URLUnencoded|useMap|userAgent|userLanguage|userProfile\n |vAlign|value|valueType|vendor|vendorSub|version|visibility|vspace|whiteSpace|width|X[MS]LDocument|zIndex))\\b(?!\\$|\\s*(<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
"captures": {
"1": {
"name": "punctuation.accessor.ts"
@@ -2479,13 +2502,13 @@
]
},
"function-call": {
- "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\.\\s*)*|(\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
- "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\.\\s*)*|(\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
+ "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\.\\s*)*|(\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
+ "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\.\\s*)*|(\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
"patterns": [
{
"name": "meta.function-call.ts",
"begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\.\\s*)*|(\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*))",
- "end": "(?=\\s*(<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
+ "end": "(?=\\s*(<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
"patterns": [
{
"include": "#literal"
@@ -2546,7 +2569,7 @@
"include": "#object-identifiers"
},
{
- "match": "(?x)(?:(\\.)\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n))",
+ "match": "(?x)(?:(\\.)\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n))",
"captures": {
"1": {
"name": "punctuation.accessor.ts"
@@ -2625,7 +2648,7 @@
"patterns": [
{
"name": "cast.expr.ts",
- "begin": "(?:(?<=return|throw|yield|await|default|[=(,:>*?]))\\s*(<)(?!\\=)",
+ "begin": "(?:(?<=return|throw|yield|await|default|[=(,:>+*?]))\\s*(<)(?!\\=)",
"beginCaptures": {
"1": {
"name": "meta.brace.angle.ts"
@@ -2728,7 +2751,7 @@
},
{
"name": "meta.object.member.ts",
- "match": "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=:\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n)))",
+ "match": "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=:\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n)))",
"captures": {
"0": {
"name": "meta.object-literal.key.ts"
@@ -2745,8 +2768,7 @@
"0": {
"name": "meta.object-literal.key.ts"
}
- },
- "end": "(?=,|\\})"
+ }
},
{
"name": "meta.object.member.ts",
@@ -2772,6 +2794,16 @@
}
}
},
+ {
+ "name": "meta.object.member.ts",
+ "begin": "(?=[_$[:alpha:]][_$[:alnum:]]*\\s*=)",
+ "end": "(?=,|\\}|$)",
+ "patterns": [
+ {
+ "include": "#expression"
+ }
+ ]
+ },
{
"include": "#object-member-body"
},
@@ -2846,7 +2878,7 @@
"name": "keyword.control.as.ts"
}
},
- "end": "(?=$|^|[;,:})\\]])",
+ "end": "(?=$|^|[;,:})\\]]|((? is on new line\n (\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n ) |\n (\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends \n ) |\n # arrow function possible to detect only with => on same line\n (\n (<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)? # typeparameters\n \\(([^()]|\\([^()]*\\))*\\) # parameteres\n (\\s*:\\s*(.)*)? # return type\n \\s*=> # arrow operator\n )\n )\n)",
+ "begin": "(?x) (?:\n (? is on new line\n (\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n ) |\n (\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends \n ) |\n # arrow function possible to detect only with => on same line\n (\n (<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)? # typeparameters\n \\(([^()]|\\([^()]*\\))*\\) # parameteres\n (\\s*:\\s*(.)*)? # return type\n \\s*=> # arrow operator\n )\n )\n)",
"beginCaptures": {
"1": {
"name": "storage.modifier.async.ts"
@@ -3084,7 +3116,7 @@
"patterns": [
{
"name": "string.regexp.ts",
- "begin": "(?<=[=(:,\\[?+!]|return|case|=>|&&|\\|\\||\\*\\/)\\s*(\\/)(?![\\/*])(?=(?:[^\\/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+\\/(?![\\/*])[gimy]*(?!\\s*[a-zA-Z0-9_$]))",
+ "begin": "(?<=[=(:,\\[?+!]|return|case|=>|&&|\\|\\||\\*\\/)\\s*(\\/)(?![\\/*])(?=(?:[^\\/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+\\/(?![\\/*])[gimuy]*(?!\\s*[a-zA-Z0-9_$]))",
"beginCaptures": {
"1": {
"name": "punctuation.definition.string.begin.ts"
@@ -3107,7 +3139,7 @@
},
{
"name": "string.regexp.ts",
- "begin": "(?)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n )) |\n (:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n ))\n)",
+ "begin": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*\n (=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n )) |\n (:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n ))\n)",
"beginCaptures": {
"1": {
"name": "meta.definition.variable.tsx entity.name.function.tsx"
@@ -724,7 +747,7 @@
},
"import-declaration": {
"name": "meta.import.tsx",
- "begin": "(?)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n )) |\n (:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n ))\n)"
+ "match": "(?x)([_$[:alpha:]][_$[:alnum:]]*)(?=(\\?\\s*)?\\s*\n (=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n )) |\n (:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n ))\n)"
},
{
"name": "meta.definition.property.tsx variable.object.property.tsx",
@@ -1569,7 +1592,7 @@
}
},
{
- "match": "(?x)(?:\\s*\\b(public|private|protected|readonly)\\s+)?(\\.\\.\\.)?\\s*(?)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n )) |\n (:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n ))\n)",
+ "match": "(?x)(?:\\s*\\b(public|private|protected|readonly)\\s+)?(\\.\\.\\.)?\\s*(?)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n )) |\n (:\\s*(\n (<) |\n ([(]\\s*(\n ([)]) |\n (\\.\\.\\.) |\n ([_$[:alnum:]]+\\s*(\n ([:,?=])|\n ([)]\\s*=>)\n ))\n ))\n ))\n)",
"captures": {
"1": {
"name": "storage.modifier.tsx"
@@ -2407,7 +2430,7 @@
}
},
{
- "match": "(?x) (\\.) \\s* (?:\n (ATTRIBUTE_NODE|CDATA_SECTION_NODE|COMMENT_NODE|DOCUMENT_FRAGMENT_NODE|DOCUMENT_NODE|DOCUMENT_TYPE_NODE\n |DOMSTRING_SIZE_ERR|ELEMENT_NODE|ENTITY_NODE|ENTITY_REFERENCE_NODE|HIERARCHY_REQUEST_ERR|INDEX_SIZE_ERR\n |INUSE_ATTRIBUTE_ERR|INVALID_CHARACTER_ERR|NO_DATA_ALLOWED_ERR|NO_MODIFICATION_ALLOWED_ERR|NOT_FOUND_ERR\n |NOT_SUPPORTED_ERR|NOTATION_NODE|PROCESSING_INSTRUCTION_NODE|TEXT_NODE|WRONG_DOCUMENT_ERR)\n |\n (_content|[xyz]|abbr|above|accept|acceptCharset|accessKey|action|align|[av]Link(?:color)?|all|alt|anchors|appCodeName\n |appCore|applets|appMinorVersion|appName|appVersion|archive|areas|arguments|attributes|availHeight|availLeft|availTop\n |availWidth|axis|background|backgroundColor|backgroundImage|below|bgColor|body|border|borderBottomWidth|borderColor\n |borderLeftWidth|borderRightWidth|borderStyle|borderTopWidth|borderWidth|bottom|bufferDepth|callee|caller|caption\n |cellPadding|cells|cellSpacing|ch|characterSet|charset|checked|childNodes|chOff|cite|classes|className|clear\n |clientInformation|clip|clipBoardData|closed|code|codeBase|codeType|color|colorDepth|cols|colSpan|compact|complete\n |components|content|controllers|cookie|cookieEnabled|cords|cpuClass|crypto|current|data|dateTime|declare|defaultCharset\n |defaultChecked|defaultSelected|defaultStatus|defaultValue|defaultView|defer|description|dialogArguments|dialogHeight\n |dialogLeft|dialogTop|dialogWidth|dir|directories|disabled|display|docmain|doctype|documentElement|elements|embeds\n |enabledPlugin|encoding|enctype|entities|event|expando|external|face|fgColor|filename|firstChild|fontFamily|fontSize\n |fontWeight|form|formName|forms|frame|frameBorder|frameElement|frames|hasFocus|hash|headers|height|history|host\n |hostname|href|hreflang|hspace|htmlFor|httpEquiv|id|ids|ignoreCase|images|implementation|index|innerHeight|innerWidth\n |input|isMap|label|lang|language|lastChild|lastIndex|lastMatch|lastModified|lastParen|layer[sXY]|left|leftContext\n |lineHeight|link|linkColor|links|listStyleType|localName|location|locationbar|longDesc|lowsrc|lowSrc|marginBottom\n |marginHeight|marginLeft|marginRight|marginTop|marginWidth|maxLength|media|menubar|method|mimeTypes|multiline|multiple\n |name|nameProp|namespaces|namespaceURI|next|nextSibling|nodeName|nodeType|nodeValue|noHref|noResize|noShade|notationName\n |notations|noWrap|object|offscreenBuffering|onLine|onreadystatechange|opener|opsProfile|options|oscpu|outerHeight\n |outerWidth|ownerDocument|paddingBottom|paddingLeft|paddingRight|paddingTop|page[XY]|page[XY]Offset|parent|parentLayer\n |parentNode|parentWindow|pathname|personalbar|pixelDepth|pkcs11|platform|plugins|port|prefix|previous|previousDibling\n |product|productSub|profile|profileend|prompt|prompter|protocol|publicId|readOnly|readyState|referrer|rel|responseText\n |responseXML|rev|right|rightContext|rowIndex|rows|rowSpan|rules|scheme|scope|screen[XY]|screenLeft|screenTop|scripts\n |scrollbars|scrolling|sectionRowIndex|security|securityPolicy|selected|selectedIndex|selection|self|shape|siblingAbove\n |siblingBelow|size|source|specified|standby|start|status|statusbar|statusText|style|styleSheets|suffixes|summary\n |systemId|systemLanguage|tagName|tags|target|tBodies|text|textAlign|textDecoration|textIndent|textTransform|tFoot|tHead\n |title|toolbar|top|type|undefined|uniqueID|updateInterval|URL|URLUnencoded|useMap|userAgent|userLanguage|userProfile\n |vAlign|value|valueType|vendor|vendorSub|version|visibility|vspace|whiteSpace|width|X[MS]LDocument|zIndex))\\b(?!\\$|\\s*(<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
+ "match": "(?x) (\\.) \\s* (?:\n (ATTRIBUTE_NODE|CDATA_SECTION_NODE|COMMENT_NODE|DOCUMENT_FRAGMENT_NODE|DOCUMENT_NODE|DOCUMENT_TYPE_NODE\n |DOMSTRING_SIZE_ERR|ELEMENT_NODE|ENTITY_NODE|ENTITY_REFERENCE_NODE|HIERARCHY_REQUEST_ERR|INDEX_SIZE_ERR\n |INUSE_ATTRIBUTE_ERR|INVALID_CHARACTER_ERR|NO_DATA_ALLOWED_ERR|NO_MODIFICATION_ALLOWED_ERR|NOT_FOUND_ERR\n |NOT_SUPPORTED_ERR|NOTATION_NODE|PROCESSING_INSTRUCTION_NODE|TEXT_NODE|WRONG_DOCUMENT_ERR)\n |\n (_content|[xyz]|abbr|above|accept|acceptCharset|accessKey|action|align|[av]Link(?:color)?|all|alt|anchors|appCodeName\n |appCore|applets|appMinorVersion|appName|appVersion|archive|areas|arguments|attributes|availHeight|availLeft|availTop\n |availWidth|axis|background|backgroundColor|backgroundImage|below|bgColor|body|border|borderBottomWidth|borderColor\n |borderLeftWidth|borderRightWidth|borderStyle|borderTopWidth|borderWidth|bottom|bufferDepth|callee|caller|caption\n |cellPadding|cells|cellSpacing|ch|characterSet|charset|checked|childNodes|chOff|cite|classes|className|clear\n |clientInformation|clip|clipBoardData|closed|code|codeBase|codeType|color|colorDepth|cols|colSpan|compact|complete\n |components|content|controllers|cookie|cookieEnabled|cords|cpuClass|crypto|current|data|dateTime|declare|defaultCharset\n |defaultChecked|defaultSelected|defaultStatus|defaultValue|defaultView|defer|description|dialogArguments|dialogHeight\n |dialogLeft|dialogTop|dialogWidth|dir|directories|disabled|display|docmain|doctype|documentElement|elements|embeds\n |enabledPlugin|encoding|enctype|entities|event|expando|external|face|fgColor|filename|firstChild|fontFamily|fontSize\n |fontWeight|form|formName|forms|frame|frameBorder|frameElement|frames|hasFocus|hash|headers|height|history|host\n |hostname|href|hreflang|hspace|htmlFor|httpEquiv|id|ids|ignoreCase|images|implementation|index|innerHeight|innerWidth\n |input|isMap|label|lang|language|lastChild|lastIndex|lastMatch|lastModified|lastParen|layer[sXY]|left|leftContext\n |lineHeight|link|linkColor|links|listStyleType|localName|location|locationbar|longDesc|lowsrc|lowSrc|marginBottom\n |marginHeight|marginLeft|marginRight|marginTop|marginWidth|maxLength|media|menubar|method|mimeTypes|multiline|multiple\n |name|nameProp|namespaces|namespaceURI|next|nextSibling|nodeName|nodeType|nodeValue|noHref|noResize|noShade|notationName\n |notations|noWrap|object|offscreenBuffering|onLine|onreadystatechange|opener|opsProfile|options|oscpu|outerHeight\n |outerWidth|ownerDocument|paddingBottom|paddingLeft|paddingRight|paddingTop|page[XY]|page[XY]Offset|parent|parentLayer\n |parentNode|parentWindow|pathname|personalbar|pixelDepth|pkcs11|platform|plugins|port|prefix|previous|previousDibling\n |product|productSub|profile|profileend|prompt|prompter|protocol|publicId|readOnly|readyState|referrer|rel|responseText\n |responseXML|rev|right|rightContext|rowIndex|rows|rowSpan|rules|scheme|scope|screen[XY]|screenLeft|screenTop|scripts\n |scrollbars|scrolling|sectionRowIndex|security|securityPolicy|selected|selectedIndex|selection|self|shape|siblingAbove\n |siblingBelow|size|source|specified|standby|start|status|statusbar|statusText|style|styleSheets|suffixes|summary\n |systemId|systemLanguage|tagName|tags|target|tBodies|text|textAlign|textDecoration|textIndent|textTransform|tFoot|tHead\n |title|toolbar|top|type|undefined|uniqueID|updateInterval|URL|URLUnencoded|useMap|userAgent|userLanguage|userProfile\n |vAlign|value|valueType|vendor|vendorSub|version|visibility|vspace|whiteSpace|width|X[MS]LDocument|zIndex))\\b(?!\\$|\\s*(<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
"captures": {
"1": {
"name": "punctuation.accessor.tsx"
@@ -2482,13 +2505,13 @@
]
},
"function-call": {
- "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\.\\s*)*|(\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
- "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\.\\s*)*|(\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
+ "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\.\\s*)*|(\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
+ "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\.\\s*)*|(\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
"patterns": [
{
"name": "meta.function-call.tsx",
"begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\.\\s*)*|(\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*))",
- "end": "(?=\\s*(<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
+ "end": "(?=\\s*(<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\()",
"patterns": [
{
"include": "#literal"
@@ -2549,7 +2572,7 @@
"include": "#object-identifiers"
},
{
- "match": "(?x)(?:(\\.)\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n))",
+ "match": "(?x)(?:(\\.)\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n))",
"captures": {
"1": {
"name": "punctuation.accessor.tsx"
@@ -2694,7 +2717,7 @@
},
{
"name": "meta.object.member.tsx",
- "match": "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=:\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n)))",
+ "match": "(?x)(?:([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=:\\s*(\n ((async\\s+)?(\n (function\\s*[(<*]) |\n (function\\s+) |\n ([_$[:alpha:]][_$[:alnum:]]*\\s*=>)\n )) |\n ((async\\s*)?(\n ([(]\\s*(([)]\\s*:)|([_$[:alpha:]][_$[:alnum:]]*\\s*:)|(\\.\\.\\.) )) |\n ([<]\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s*[^=>])|(\\s*[,]))) |\n ((<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)\n ))\n)))",
"captures": {
"0": {
"name": "meta.object-literal.key.tsx"
@@ -2711,8 +2734,7 @@
"0": {
"name": "meta.object-literal.key.tsx"
}
- },
- "end": "(?=,|\\})"
+ }
},
{
"name": "meta.object.member.tsx",
@@ -2738,6 +2760,16 @@
}
}
},
+ {
+ "name": "meta.object.member.tsx",
+ "begin": "(?=[_$[:alpha:]][_$[:alnum:]]*\\s*=)",
+ "end": "(?=,|\\}|$)",
+ "patterns": [
+ {
+ "include": "#expression"
+ }
+ ]
+ },
{
"include": "#object-member-body"
},
@@ -2812,7 +2844,7 @@
"name": "keyword.control.as.tsx"
}
},
- "end": "(?=$|^|[;,:})\\]])",
+ "end": "(?=$|^|[;,:})\\]]|((? is on new line\n (\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n ) |\n (\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends \n ) |\n # arrow function possible to detect only with => on same line\n (\n (<([^<>=]|=[^<]|\\<([^=<>]|=[^<])+\\>)+>\\s*)? # typeparameters\n \\(([^()]|\\([^()]*\\))*\\) # parameteres\n (\\s*:\\s*(.)*)? # return type\n \\s*=> # arrow operator\n )\n )\n)",
+ "begin": "(?x) (?:\n (? is on new line\n (\n [(]\\s*\n (\n ([)]\\s*:) | # ():\n ((\\.\\.\\.\\s*)?[_$[:alpha:]][_$[:alnum:]]*\\s*:) # [(]param: | [(]...param:\n )\n ) |\n (\n [<]\\s*[_$[:alpha:]][_$[:alnum:]]*\\s+extends\\s*[^=>] # < typeparam extends \n ) |\n # arrow function possible to detect only with => on same line\n (\n (<\\s*[_$[:alpha:]\\{\\(]([^<>=]|=[^<]|\\<\\s*[_$[:alpha:]\\{\\(]([^=<>]|=[^<])+\\>)+>\\s*)? # typeparameters\n \\(([^()]|\\([^()]*\\))*\\) # parameteres\n (\\s*:\\s*(.)*)? # return type\n \\s*=> # arrow operator\n )\n )\n)",
"beginCaptures": {
"1": {
"name": "storage.modifier.async.tsx"
@@ -3050,7 +3082,7 @@
"patterns": [
{
"name": "string.regexp.tsx",
- "begin": "(?<=[=(:,\\[?+!]|return|case|=>|&&|\\|\\||\\*\\/)\\s*(\\/)(?![\\/*])(?=(?:[^\\/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+\\/(?![\\/*])[gimy]*(?!\\s*[a-zA-Z0-9_$]))",
+ "begin": "(?<=[=(:,\\[?+!]|return|case|=>|&&|\\|\\||\\*\\/)\\s*(\\/)(?![\\/*])(?=(?:[^\\/\\\\\\[]|\\\\.|\\[([^\\]\\\\]|\\\\.)+\\])+\\/(?![\\/*])[gimuy]*(?!\\s*[a-zA-Z0-9_$]))",
"beginCaptures": {
"1": {
"name": "punctuation.definition.string.begin.tsx"
@@ -3073,7 +3105,7 @@
},
{
"name": "string.regexp.tsx",
- "begin": "(? implements IDisposable {
if (isSelectionRangeChangeEvent(e) && reference !== undefined) {
const min = Math.min(reference, focus);
const max = Math.max(reference, focus);
- const rangeSelection = range(max + 1, min);
+ const rangeSelection = range(min, max + 1);
const selection = this.list.getSelection();
const contiguousRange = getContiguousRangeContaining(disjunction(selection, [reference]), reference);
diff --git a/src/vs/base/browser/ui/sash/sash.ts b/src/vs/base/browser/ui/sash/sash.ts
index 338d07b4681..4fdafd509a4 100644
--- a/src/vs/base/browser/ui/sash/sash.ts
+++ b/src/vs/base/browser/ui/sash/sash.ts
@@ -268,6 +268,10 @@ export class Sash extends EventEmitter {
this.isDisabled = true;
}
+ get enabled(): boolean {
+ return !this.isDisabled;
+ }
+
public dispose(): void {
if (this.$e) {
this.$e.destroy();
diff --git a/src/vs/base/browser/ui/splitview/panelview.ts b/src/vs/base/browser/ui/splitview/panelview.ts
new file mode 100644
index 00000000000..94ed8a2e53e
--- /dev/null
+++ b/src/vs/base/browser/ui/splitview/panelview.ts
@@ -0,0 +1,361 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+'use strict';
+
+import 'vs/css!./splitview';
+import { IDisposable, dispose, combinedDisposable } from 'vs/base/common/lifecycle';
+import Event, { Emitter, chain } from 'vs/base/common/event';
+import { domEvent } from 'vs/base/browser/event';
+import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
+import { KeyCode } from 'vs/base/common/keyCodes';
+import { $, append, addClass, removeClass, toggleClass } from 'vs/base/browser/dom';
+import { firstIndex } from 'vs/base/common/arrays';
+import { Color, RGBA } from 'vs/base/common/color';
+import { SplitView, IView } from './splitview2';
+
+export interface IPanelOptions {
+ ariaHeaderLabel?: string;
+ minimumBodySize?: number;
+ maximumBodySize?: number;
+ expanded?: boolean;
+}
+
+export interface IPanelStyles {
+ dropBackground?: Color;
+}
+
+export abstract class Panel implements IView {
+
+ private static HEADER_SIZE = 22;
+
+ private _expanded: boolean;
+ private _headerVisible: boolean;
+ private _onDidChange = new Emitter();
+ private _minimumBodySize: number;
+ private _maximumBodySize: number;
+ private ariaHeaderLabel: string;
+
+ readonly header: HTMLElement;
+ protected disposables: IDisposable[] = [];
+
+ get minimumBodySize(): number {
+ return this._minimumBodySize;
+ }
+
+ set minimumBodySize(size: number) {
+ this._minimumBodySize = size;
+ this._onDidChange.fire();
+ }
+
+ get maximumBodySize(): number {
+ return this._maximumBodySize;
+ }
+
+ set maximumBodySize(size: number) {
+ this._maximumBodySize = size;
+ this._onDidChange.fire();
+ }
+
+ get minimumSize(): number {
+ const headerSize = this.headerVisible ? Panel.HEADER_SIZE : 0;
+ const expanded = !this.headerVisible || this.expanded;
+ const minimumBodySize = expanded ? this._minimumBodySize : 0;
+
+ return headerSize + minimumBodySize;
+ }
+
+ get maximumSize(): number {
+ const headerSize = this.headerVisible ? Panel.HEADER_SIZE : 0;
+ const expanded = !this.headerVisible || this.expanded;
+ const maximumBodySize = expanded ? this._maximumBodySize : 0;
+
+ return headerSize + maximumBodySize;
+ }
+
+ readonly onDidChange: Event = this._onDidChange.event;
+
+ constructor(options: IPanelOptions = {}) {
+ this._expanded = typeof options.expanded === 'undefined' ? true : !!options.expanded;
+ this.ariaHeaderLabel = options.ariaHeaderLabel || '';
+ this._minimumBodySize = typeof options.minimumBodySize === 'number' ? options.minimumBodySize : 44;
+ this._maximumBodySize = typeof options.maximumBodySize === 'number' ? options.maximumBodySize : Number.POSITIVE_INFINITY;
+ }
+
+ get expanded(): boolean {
+ return this._expanded;
+ }
+
+ set expanded(expanded: boolean) {
+ if (this._expanded === !!expanded) {
+ return;
+ }
+
+ this._expanded = !!expanded;
+ this.renderHeader();
+ this._onDidChange.fire();
+ }
+
+ get headerVisible(): boolean {
+ return this._headerVisible;
+ }
+
+ set headerVisible(visible: boolean) {
+ if (this._headerVisible === !!visible) {
+ return;
+ }
+
+ this._headerVisible = !!visible;
+ this.renderHeader();
+ this._onDidChange.fire();
+ }
+
+ render(container: HTMLElement): void {
+ const panel = append(container, $('.panel'));
+ const header = append(panel, $('.panel-header'));
+
+ header.setAttribute('tabindex', '0');
+ header.setAttribute('role', 'toolbar');
+ header.setAttribute('aria-label', this.ariaHeaderLabel);
+ this.renderHeader();
+
+ const onHeaderKeyDown = chain(domEvent(header, 'keydown'))
+ .map(e => new StandardKeyboardEvent(e));
+
+ onHeaderKeyDown.filter(e => e.keyCode === KeyCode.Enter || e.keyCode === KeyCode.Space)
+ .event(() => this.expanded = !this.expanded, null, this.disposables);
+
+ onHeaderKeyDown.filter(e => e.keyCode === KeyCode.LeftArrow)
+ .event(() => this.expanded = false, null, this.disposables);
+
+ onHeaderKeyDown.filter(e => e.keyCode === KeyCode.RightArrow)
+ .event(() => this.expanded = true, null, this.disposables);
+
+ domEvent(header, 'click')
+ (() => this.expanded = !this.expanded, null, this.disposables);
+
+ // TODO@Joao move this down to panelview
+ // onHeaderKeyDown.filter(e => e.keyCode === KeyCode.UpArrow)
+ // .event(focusPrevious, this, this.disposables);
+
+ // onHeaderKeyDown.filter(e => e.keyCode === KeyCode.DownArrow)
+ // .event(focusNext, this, this.disposables);
+
+ const body = append(panel, $('.panel-body'));
+ this.renderBody(body);
+ }
+
+ layout(size: number): void {
+ const headerSize = this.headerVisible ? Panel.HEADER_SIZE : 0;
+ this.layoutBody(size - headerSize);
+ }
+
+ focus(): void {
+ // TODO@joao what to do
+ }
+
+ private renderHeader(): void {
+ const expanded = !this.headerVisible || this.expanded;
+
+ toggleClass(this.header, 'hidden', !this.headerVisible);
+ toggleClass(this.header, 'expanded', expanded);
+ this.header.setAttribute('aria-expanded', String(expanded));
+ }
+
+ protected abstract renderBody(container: HTMLElement): void;
+ protected abstract layoutBody(size: number): void;
+
+ dispose(): void {
+ this.disposables = dispose(this.disposables);
+ }
+}
+
+interface IDndContext {
+ dropBackground: Color | undefined;
+ draggable: PanelDraggable | null;
+}
+
+class PanelDraggable implements IDisposable {
+
+ private static DefaultDragOverBackgroundColor = new Color(new RGBA(128, 128, 128, 0.5));
+
+ // see https://github.com/Microsoft/vscode/issues/14470
+ private dragOverCounter = 0;
+ private disposables: IDisposable[] = [];
+
+ private _onDidDrop = new Emitter<{ from: Panel, to: Panel }>();
+ readonly onDidDrop = this._onDidDrop.event;
+
+ constructor(private panel: Panel, private context: IDndContext) {
+ domEvent(panel.header, 'dragstart')(this.onDragStart, this, this.disposables);
+ domEvent(panel.header, 'dragenter')(this.onDragEnter, this, this.disposables);
+ domEvent(panel.header, 'dragleave')(this.onDragLeave, this, this.disposables);
+ domEvent(panel.header, 'dragend')(this.onDragEnd, this, this.disposables);
+ domEvent(panel.header, 'drop')(this.onDrop, this, this.disposables);
+ }
+
+ private onDragStart(e: DragEvent): void {
+ e.dataTransfer.effectAllowed = 'move';
+
+ const dragImage = append(document.body, $('.monaco-panel-drag-image', {}, this.panel.header.textContent));
+ e.dataTransfer.setDragImage(dragImage, -10, -10);
+ setTimeout(() => document.body.removeChild(dragImage), 0);
+
+ this.context.draggable = this;
+ }
+
+ private onDragEnter(e: DragEvent): void {
+ if (!this.context.draggable || this.context.draggable === this) {
+ return;
+ }
+
+ this.dragOverCounter++;
+ this.renderHeader();
+ }
+
+ private onDragLeave(e: DragEvent): void {
+ if (!this.context.draggable || this.context.draggable === this) {
+ return;
+ }
+
+ this.dragOverCounter--;
+
+ if (this.dragOverCounter === 0) {
+ this.renderHeader();
+ }
+ }
+
+ private onDragEnd(e: DragEvent): void {
+ if (!this.context.draggable) {
+ return;
+ }
+
+ this.dragOverCounter = 0;
+ this.renderHeader();
+ this.context.draggable = null;
+ }
+
+ private onDrop(e: DragEvent): void {
+ if (!this.context.draggable) {
+ return;
+ }
+
+ this.dragOverCounter = 0;
+ this.renderHeader();
+
+ if (this.context.draggable !== this) {
+ this._onDidDrop.fire({ from: this.context.draggable.panel, to: this.panel });
+ }
+
+ this.context.draggable = null;
+ }
+
+ private renderHeader(): void {
+ let backgroundColor: string = null;
+
+ if (this.dragOverCounter > 0) {
+ backgroundColor = (this.context.dropBackground || PanelDraggable.DefaultDragOverBackgroundColor).toString();
+ }
+
+ this.panel.header.style.backgroundColor = backgroundColor;
+ }
+
+ dispose(): void {
+ this.disposables = dispose(this.disposables);
+ }
+}
+
+export class IPanelViewOptions {
+ dnd?: boolean;
+}
+
+interface IPanelItem {
+ panel: Panel;
+ disposable: IDisposable;
+}
+
+export class PanelView implements IDisposable {
+
+ private dnd: boolean;
+ private dndContext: IDndContext = { dropBackground: undefined, draggable: null };
+ private el: HTMLElement;
+ private panelItems: IPanelItem[] = [];
+ private splitview: SplitView;
+ private animationTimer: number | null = null;
+
+ private _onDidDrop = new Emitter<{ from: Panel, to: Panel }>();
+ readonly onDidDrop: Event<{ from: Panel, to: Panel }> = this._onDidDrop.event;
+
+ constructor(private container: HTMLElement, options?: IPanelViewOptions) {
+ this.dnd = !!options.dnd;
+ this.el = append(container, $('.monaco-panel-view'));
+ this.splitview = new SplitView(container);
+ }
+
+ addPanel(panel: Panel, size: number, index = this.splitview.length): void {
+ const disposables: IDisposable[] = [];
+ panel.onDidChange(this.setupAnimation, this, disposables);
+
+ if (this.dnd) {
+ const draggable = new PanelDraggable(panel, this.dndContext);
+ disposables.push(draggable);
+ draggable.onDidDrop(this._onDidDrop.fire, this._onDidDrop, disposables);
+ }
+
+ const panelItem = { panel, disposable: combinedDisposable(disposables) };
+
+ this.panelItems.splice(index, 0, panelItem);
+ this.splitview.addView(panel, size, index);
+ }
+
+ removePanel(panel: Panel): void {
+ const index = firstIndex(this.panelItems, item => item.panel === panel);
+
+ if (index === -1) {
+ return;
+ }
+
+ this.splitview.removeView(index);
+ const panelItem = this.panelItems.splice(index, 1)[0];
+ panelItem.disposable.dispose();
+ }
+
+ movePanel(from: Panel, to: Panel): void {
+ const fromIndex = firstIndex(this.panelItems, item => item.panel === from);
+ const toIndex = firstIndex(this.panelItems, item => item.panel === to);
+
+ if (fromIndex === -1 || toIndex === -1) {
+ return;
+ }
+
+ this.splitview.moveView(fromIndex, toIndex);
+ }
+
+ layout(size: number): void {
+ this.splitview.layout(size);
+ }
+
+ style(styles: IPanelStyles): void {
+ this.dndContext.dropBackground = styles.dropBackground;
+ }
+
+ private setupAnimation(): void {
+ if (typeof this.animationTimer === 'number') {
+ window.clearTimeout(this.animationTimer);
+ }
+
+ addClass(this.el, 'animated');
+
+ this.animationTimer = window.setTimeout(() => {
+ this.animationTimer = null;
+ removeClass(this.el, 'animated');
+ }, 200);
+ }
+
+ dispose(): void {
+ this.panelItems.forEach(i => i.disposable.dispose());
+ this.splitview.dispose();
+ }
+}
diff --git a/src/vs/base/browser/ui/splitview/splitview2.ts b/src/vs/base/browser/ui/splitview/splitview2.ts
new file mode 100644
index 00000000000..dceae97209f
--- /dev/null
+++ b/src/vs/base/browser/ui/splitview/splitview2.ts
@@ -0,0 +1,293 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+'use strict';
+
+import 'vs/css!./splitview';
+import { IDisposable, combinedDisposable, toDisposable } from 'vs/base/common/lifecycle';
+import Event, { fromEventEmitter, mapEvent } from 'vs/base/common/event';
+import types = require('vs/base/common/types');
+import dom = require('vs/base/browser/dom');
+import { clamp } from 'vs/base/common/numbers';
+import { range, firstIndex } from 'vs/base/common/arrays';
+import { Sash, Orientation, ISashEvent as IBaseSashEvent } from 'vs/base/browser/ui/sash/sash';
+export { Orientation } from 'vs/base/browser/ui/sash/sash';
+
+export interface ISplitViewOptions {
+ orientation?: Orientation; // default Orientation.VERTICAL
+}
+
+export interface IView {
+ readonly minimumSize: number;
+ readonly maximumSize: number;
+ readonly onDidChange: Event;
+ render(container: HTMLElement, orientation: Orientation): void;
+ layout(size: number, orientation: Orientation): void;
+ focus(): void;
+}
+
+interface ISashEvent {
+ sash: Sash;
+ start: number;
+ current: number;
+}
+
+interface IViewItem {
+ view: IView;
+ size: number;
+ explicitSize: number;
+ container: HTMLElement;
+ disposable: IDisposable;
+}
+
+interface ISashItem {
+ sash: Sash;
+ disposable: IDisposable;
+}
+
+interface ISashDragState {
+ index: number;
+ start: number;
+ sizes: number[];
+}
+
+function layoutViewItem(item: IViewItem, orientation: Orientation): void {
+ if (orientation === Orientation.VERTICAL) {
+ item.container.style.height = `${item.size}px`;
+ } else {
+ item.container.style.width = `${item.size}px`;
+ }
+
+ item.view.layout(item.size, orientation);
+}
+
+export class SplitView implements IDisposable {
+
+ private orientation: Orientation;
+ private el: HTMLElement;
+ private size = 0;
+ private viewItems: IViewItem[] = [];
+ private sashItems: ISashItem[] = [];
+ private sashDragState: ISashDragState;
+
+ get length(): number {
+ return this.viewItems.length;
+ }
+
+ constructor(private container: HTMLElement, options: ISplitViewOptions = {}) {
+ this.orientation = types.isUndefined(options.orientation) ? Orientation.VERTICAL : options.orientation;
+
+ this.el = document.createElement('div');
+ dom.addClass(this.el, 'monaco-split-view');
+ dom.addClass(this.el, this.orientation === Orientation.VERTICAL ? 'vertical' : 'horizontal');
+ container.appendChild(this.el);
+ }
+
+ addView(view: IView, size: number, index = this.viewItems.length): void {
+ // Add view
+ const container = dom.$('.split-view-view');
+
+ if (this.viewItems.length === 1) {
+ this.el.appendChild(container);
+ } else {
+ this.el.insertBefore(container, this.el.children.item(index));
+ }
+
+ const onChangeDisposable = mapEvent(view.onDidChange, () => item)(this.onViewChange, this);
+ const containerDisposable = toDisposable(() => this.el.removeChild(container));
+ const disposable = combinedDisposable([onChangeDisposable, containerDisposable]);
+
+ const explicitSize = size;
+ const item: IViewItem = { view, container, explicitSize, size, disposable };
+ this.viewItems.splice(index, 0, item);
+
+ // Add sash
+ if (this.viewItems.length > 1) {
+ const orientation = this.orientation === Orientation.VERTICAL ? Orientation.HORIZONTAL : Orientation.VERTICAL;
+ const layoutProvider = this.orientation === Orientation.VERTICAL ? { getHorizontalSashTop: sash => this.getSashPosition(sash) } : { getVerticalSashLeft: sash => this.getSashPosition(sash) };
+ const sash = new Sash(this.el, layoutProvider, { orientation });
+ const sashEventMapper = this.orientation === Orientation.VERTICAL
+ ? (e: IBaseSashEvent) => ({ sash, start: e.startY, current: e.currentY })
+ : (e: IBaseSashEvent) => ({ sash, start: e.startX, current: e.currentX });
+
+ const onStart = mapEvent(fromEventEmitter(sash, 'start'), sashEventMapper);
+ const onStartDisposable = onStart(this.onSashStart, this);
+ const onChange = mapEvent(fromEventEmitter(sash, 'change'), sashEventMapper);
+ const onSashChangeDisposable = onChange(this.onSashChange, this);
+ const disposable = combinedDisposable([onStartDisposable, onSashChangeDisposable, sash]);
+ const sashItem: ISashItem = { sash, disposable };
+
+ this.sashItems.splice(index - 1, 0, sashItem);
+ }
+
+ view.render(container, this.orientation);
+ this.relayoutPreferredSizes();
+ }
+
+ removeView(index: number): void {
+ if (index < 0 || index >= this.viewItems.length) {
+ return;
+ }
+
+ // Remove view
+ const viewItem = this.viewItems.splice(index, 1)[0];
+ viewItem.disposable.dispose();
+
+ // Remove sash
+ if (this.viewItems.length >= 1) {
+ const sashIndex = Math.max(index - 1, 0);
+ const sashItem = this.sashItems.splice(sashIndex, 1)[0];
+ sashItem.disposable.dispose();
+ }
+
+ this.relayoutPreferredSizes();
+ }
+
+ moveView(from: number, to: number): void {
+ if (from < 0 || from >= this.viewItems.length) {
+ return;
+ }
+
+ if (to < 0 || to >= this.viewItems.length) {
+ return;
+ }
+
+ if (from === to) {
+ return;
+ }
+
+ const viewItem = this.viewItems.splice(from, 1)[0];
+ this.viewItems.splice(to, 0, viewItem);
+ this.layoutViews();
+ }
+
+ private relayoutPreferredSizes(): void {
+ this.viewItems.forEach(i => i.size = clamp(i.explicitSize, i.view.minimumSize, i.view.maximumSize));
+ this.relayout();
+ }
+
+ private relayout(): void {
+ const previousSize = this.size;
+ this.size = this.viewItems.reduce((r, i) => r + i.size, 0);
+ this.layout(previousSize);
+ }
+
+ layout(size: number): void {
+ this.resize(this.viewItems.length - 1, size - this.size);
+ this.size = Math.max(size, this.viewItems.reduce((r, i) => r + i.size, 0));
+ }
+
+ private onSashStart({ sash, start }: ISashEvent): void {
+ const index = firstIndex(this.sashItems, item => item.sash === sash);
+ const sizes = this.viewItems.map(i => i.size);
+
+ this.sashDragState = { start, index, sizes };
+ }
+
+ private onSashChange({ sash, current }: ISashEvent): void {
+ const { index, start, sizes } = this.sashDragState;
+
+ this.resize(index, current - start, sizes);
+ this.viewItems.forEach(viewItem => viewItem.explicitSize = viewItem.size);
+ }
+
+ private onViewChange(item: IViewItem): void {
+ item.size = clamp(item.size, item.view.minimumSize, item.view.maximumSize);
+ this.relayout();
+ }
+
+ resizeView(index: number, size: number): void {
+ if (index < 0 || index >= this.viewItems.length - 1) {
+ throw new Error('Cant resize view');
+ }
+
+ this.resize(index, size - this.viewItems[index].size);
+ }
+
+ private resize(index: number, delta: number, sizes = this.viewItems.map(i => i.size)): void {
+ if (index < 0 || index >= this.viewItems.length) {
+ return;
+ }
+
+ if (delta !== 0) {
+ const upIndexes = range(index, -1);
+ const up = upIndexes.map(i => this.viewItems[i]);
+ const upSizes = upIndexes.map(i => sizes[i]);
+
+ const downIndexes = range(index + 1, this.viewItems.length);
+ const down = downIndexes.map(i => this.viewItems[i]);
+ const downSizes = downIndexes.map(i => sizes[i]);
+
+ for (let i = 0, deltaUp = delta; deltaUp !== 0 && i < up.length; i++) {
+ const item = up[i];
+ const size = clamp(upSizes[i] + deltaUp, item.view.minimumSize, item.view.maximumSize);
+ const viewDelta = size - upSizes[i];
+
+ deltaUp -= viewDelta;
+ item.size = size;
+ }
+
+ for (let i = 0, deltaDown = delta; deltaDown !== 0 && i < down.length; i++) {
+ const item = down[i];
+ const size = clamp(downSizes[i] - deltaDown, item.view.minimumSize, item.view.maximumSize);
+ const viewDelta = size - downSizes[i];
+
+ deltaDown += viewDelta;
+ item.size = size;
+ }
+ }
+
+ this.layoutViews();
+ }
+
+ private layoutViews(): void {
+ this.viewItems.forEach(item => layoutViewItem(item, this.orientation));
+ this.sashItems.forEach(item => item.sash.layout());
+
+ // Update sashes enablement
+ let previous = false;
+ const collapsesDown = this.viewItems.map(i => previous = (i.size - i.view.minimumSize > 0) || previous);
+
+ previous = false;
+ const expandsDown = this.viewItems.map(i => previous = (i.view.maximumSize - i.size > 0) || previous);
+
+ const reverseViews = [...this.viewItems].reverse();
+ previous = false;
+ const collapsesUp = reverseViews.map(i => previous = (i.size - i.view.minimumSize > 0) || previous).reverse();
+
+ previous = false;
+ const expandsUp = reverseViews.map(i => previous = (i.view.maximumSize - i.size > 0) || previous).reverse();
+
+ this.sashItems.forEach((s, i) => {
+ if ((collapsesDown[i] && expandsUp[i + 1]) || (expandsDown[i] && collapsesUp[i + 1])) {
+ s.sash.enable();
+ } else {
+ s.sash.disable();
+ }
+ });
+ }
+
+ private getSashPosition(sash: Sash): number {
+ let position = 0;
+
+ for (let i = 0; i < this.sashItems.length; i++) {
+ position += this.viewItems[i].size;
+
+ if (this.sashItems[i].sash === sash) {
+ return position;
+ }
+ }
+
+ throw new Error('Sash not found');
+ }
+
+ dispose(): void {
+ this.viewItems.forEach(i => i.disposable.dispose());
+ this.viewItems = [];
+
+ this.sashItems.forEach(i => i.disposable.dispose());
+ this.sashItems = [];
+ }
+}
diff --git a/src/vs/base/common/arrays.ts b/src/vs/base/common/arrays.ts
index 4be8d60f396..a64b84276eb 100644
--- a/src/vs/base/common/arrays.ts
+++ b/src/vs/base/common/arrays.ts
@@ -325,11 +325,43 @@ export function flatten(arr: T[][]): T[] {
return arr.reduce((r, v) => r.concat(v), []);
}
-export function range(to: number, from = 0): number[] {
+export function range(to: number): number[];
+export function range(from: number, to: number): number[];
+export function range(arg: number, to?: number): number[] {
+ let from = typeof to === 'number' ? arg : 0;
+
+ if (typeof to === 'number') {
+ from = arg;
+ } else {
+ from = 0;
+ to = arg;
+ }
+
const result: number[] = [];
- for (let i = from; i < to; i++) {
- result.push(i);
+ if (from <= to) {
+ for (let i = from; i < to; i++) {
+ result.push(i);
+ }
+ } else {
+ for (let i = from; i > to; i--) {
+ result.push(i);
+ }
+ }
+
+ return result;
+}
+
+export function weave(a: T[], b: T[]): T[] {
+ const result: T[] = [];
+ let ai = 0, bi = 0;
+
+ for (let i = 0, length = a.length + b.length; i < length; i++) {
+ if ((i % 2 === 0 && ai < a.length) || bi >= b.length) {
+ result.push(a[ai++]);
+ } else {
+ result.push(b[bi++]);
+ }
}
return result;
diff --git a/src/vs/base/common/jsonSchema.ts b/src/vs/base/common/jsonSchema.ts
index 1405eee19a5..44496dbcfb1 100644
--- a/src/vs/base/common/jsonSchema.ts
+++ b/src/vs/base/common/jsonSchema.ts
@@ -45,6 +45,7 @@ export interface IJSONSchema {
patternErrorMessage?: string; // VSCode extension
deprecationMessage?: string; // VSCode extension
enumDescriptions?: string[]; // VSCode extension
+ doNotSuggest?: boolean; // VSCode extension
}
export interface IJSONSchemaMap {
diff --git a/src/vs/base/common/labels.ts b/src/vs/base/common/labels.ts
index d86e3f668e2..6192b7dcd01 100644
--- a/src/vs/base/common/labels.ts
+++ b/src/vs/base/common/labels.ts
@@ -17,10 +17,10 @@ export interface ILabelProvider {
getLabel(element: any): string;
}
-export interface IRootProvider {
- getRoot(resource: URI): URI;
+export interface IWorkspaceFolderProvider {
+ getWorkspaceFolder(resource: URI): URI;
getWorkspace(): {
- roots: URI[];
+ folders: URI[];
};
}
@@ -28,7 +28,7 @@ export interface IUserHomeProvider {
userHome: string;
}
-export function getPathLabel(resource: URI | string, rootProvider?: IRootProvider, userHomeProvider?: IUserHomeProvider): string {
+export function getPathLabel(resource: URI | string, rootProvider?: IWorkspaceFolderProvider, userHomeProvider?: IUserHomeProvider): string {
if (!resource) {
return null;
}
@@ -38,9 +38,9 @@ export function getPathLabel(resource: URI | string, rootProvider?: IRootProvide
}
// return early if we can resolve a relative path label from the root
- const baseResource = rootProvider ? rootProvider.getRoot(resource) : null;
+ const baseResource = rootProvider ? rootProvider.getWorkspaceFolder(resource) : null;
if (baseResource) {
- const hasMultipleRoots = rootProvider.getWorkspace().roots.length > 1;
+ const hasMultipleRoots = rootProvider.getWorkspace().folders.length > 1;
let pathLabel: string;
if (isEqual(baseResource.fsPath, resource.fsPath, !platform.isLinux /* ignorecase */)) {
diff --git a/src/vs/base/common/numbers.ts b/src/vs/base/common/numbers.ts
index 65bcbbd7922..9f804fe6dd9 100644
--- a/src/vs/base/common/numbers.ts
+++ b/src/vs/base/common/numbers.ts
@@ -46,3 +46,8 @@ export function countToArray(fromOrTo: number, to?: number): number[] {
return result;
}
+
+
+export function clamp(value: number, min: number, max: number): number {
+ return Math.min(Math.max(value, min), max);
+}
\ No newline at end of file
diff --git a/src/vs/base/common/strings.ts b/src/vs/base/common/strings.ts
index 7af18aadcb6..2200f4e5721 100644
--- a/src/vs/base/common/strings.ts
+++ b/src/vs/base/common/strings.ts
@@ -238,9 +238,19 @@ export function regExpLeadsToEndlessLoop(regexp: RegExp): boolean {
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize}
*/
export const canNormalize = typeof (('').normalize) === 'function';
-const nonAsciiCharactersPattern = /[^\u0000-\u0080]/;
-const normalizedCache = new BoundedMap(10000); // bounded to 10000 elements
+
+const nfcCache = new BoundedMap(10000); // bounded to 10000 elements
export function normalizeNFC(str: string): string {
+ return normalize(str, 'NFC', nfcCache);
+}
+
+const nfdCache = new BoundedMap(10000); // bounded to 10000 elements
+export function normalizeNFD(str: string): string {
+ return normalize(str, 'NFD', nfdCache);
+}
+
+const nonAsciiCharactersPattern = /[^\u0000-\u0080]/;
+function normalize(str: string, form: string, normalizedCache: BoundedMap): string {
if (!canNormalize || !str) {
return str;
}
@@ -252,7 +262,7 @@ export function normalizeNFC(str: string): string {
let res: string;
if (nonAsciiCharactersPattern.test(str)) {
- res = (str).normalize('NFC');
+ res = (str).normalize(form);
} else {
res = str;
}
diff --git a/src/vs/base/common/uri.ts b/src/vs/base/common/uri.ts
index 043e9be8be9..39ad9e80805 100644
--- a/src/vs/base/common/uri.ts
+++ b/src/vs/base/common/uri.ts
@@ -301,8 +301,20 @@ export default class URI {
parts.push('//');
}
if (authority) {
+ let idx = authority.indexOf('@');
+ if (idx !== -1) {
+ const userinfo = authority.substr(0, idx);
+ authority = authority.substr(idx + 1);
+ idx = userinfo.indexOf(':');
+ if (idx === -1) {
+ parts.push(encoder(userinfo));
+ } else {
+ parts.push(encoder(userinfo.substr(0, idx)), ':', encoder(userinfo.substr(idx + 1)));
+ }
+ parts.push('@');
+ }
authority = authority.toLowerCase();
- let idx = authority.indexOf(':');
+ idx = authority.indexOf(':');
if (idx === -1) {
parts.push(encoder(authority));
} else {
diff --git a/src/vs/base/node/config.ts b/src/vs/base/node/config.ts
index 6d30e650d6e..4ec9fede36f 100644
--- a/src/vs/base/node/config.ts
+++ b/src/vs/base/node/config.ts
@@ -6,7 +6,7 @@
'use strict';
import * as fs from 'fs';
-import * as path from 'path';
+import { dirname, basename } from 'path';
import * as objects from 'vs/base/common/objects';
import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
import Event, { Emitter } from 'vs/base/common/event';
@@ -49,9 +49,11 @@ export class ConfigWatcher implements IConfigWatcher, IDisposable {
private timeoutHandle: NodeJS.Timer;
private disposables: IDisposable[];
private _onDidUpdateConfiguration: Emitter>;
+ private configName: string;
constructor(private _path: string, private options: IConfigOptions = { changeBufferDelay: 0, defaultConfig: Object.create(null), onError: error => console.error(error) }) {
this.disposables = [];
+ this.configName = basename(this._path);
this._onDidUpdateConfiguration = new Emitter>();
this.disposables.push(this._onDidUpdateConfiguration);
@@ -121,8 +123,8 @@ export class ConfigWatcher implements IConfigWatcher, IDisposable {
private registerWatcher(): void {
// Watch the parent of the path so that we detect ADD and DELETES
- const parentFolder = path.dirname(this._path);
- this.watch(parentFolder);
+ const parentFolder = dirname(this._path);
+ this.watch(parentFolder, true);
// Check if the path is a symlink and watch its target if so
fs.lstat(this._path, (err, stat) => {
@@ -137,20 +139,20 @@ export class ConfigWatcher implements IConfigWatcher, IDisposable {
return; // path is not a valid symlink
}
- this.watch(realPath);
+ this.watch(realPath, false);
});
}
});
}
- private watch(path: string): void {
+ private watch(path: string, isParentFolder: boolean): void {
if (this.disposed) {
return; // avoid watchers that will never get disposed by checking for being disposed
}
try {
const watcher = fs.watch(path);
- watcher.on('change', () => this.onConfigFileChange());
+ watcher.on('change', (type, file) => this.onConfigFileChange(type, file.toString(), isParentFolder));
watcher.on('error', (code, signal) => this.options.onError(`Error watching ${path} for configuration changes (${code}, ${signal})`));
this.disposables.push(toDisposable(() => {
@@ -166,7 +168,11 @@ export class ConfigWatcher implements IConfigWatcher, IDisposable {
}
}
- private onConfigFileChange(): void {
+ private onConfigFileChange(eventType: string, filename: string, isParentFolder: boolean): void {
+ if (isParentFolder && filename !== this.configName) {
+ return; // a change to a sibling file that is not our config file
+ }
+
if (this.timeoutHandle) {
global.clearTimeout(this.timeoutHandle);
this.timeoutHandle = null;
diff --git a/src/vs/base/node/pfs.ts b/src/vs/base/node/pfs.ts
index 16f8d7509be..ce1f52d799c 100644
--- a/src/vs/base/node/pfs.ts
+++ b/src/vs/base/node/pfs.ts
@@ -189,3 +189,18 @@ const tmpDir = os.tmpdir();
export function del(path: string, tmp = tmpDir): TPromise {
return nfcall(extfs.del, path, tmp);
}
+
+export function whenDeleted(path: string): TPromise {
+
+ // Complete when wait marker file is deleted
+ return new TPromise(c => {
+ const interval = setInterval(() => {
+ fs.exists(path, exists => {
+ if (!exists) {
+ clearInterval(interval);
+ c(null);
+ }
+ });
+ }, 1000);
+ });
+}
\ No newline at end of file
diff --git a/src/vs/base/test/browser/ui/splitview/splitview.test.ts b/src/vs/base/test/browser/ui/splitview/splitview.test.ts
new file mode 100644
index 00000000000..be73ee96d46
--- /dev/null
+++ b/src/vs/base/test/browser/ui/splitview/splitview.test.ts
@@ -0,0 +1,338 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import * as assert from 'assert';
+import { Emitter } from 'vs/base/common/event';
+import { SplitView, IView, Orientation } from 'vs/base/browser/ui/splitview/splitview2';
+import { Sash } from 'vs/base/browser/ui/sash/sash';
+
+class TestView implements IView {
+
+ private _onDidChange = new Emitter();
+ readonly onDidChange = this._onDidChange.event;
+
+ get minimumSize(): number { return this._minimumSize; }
+ set minimumSize(size: number) { this._minimumSize = size; this._onDidChange.fire(); }
+
+ get maximumSize(): number { return this._maximumSize; }
+ set maximumSize(size: number) { this._maximumSize = size; this._onDidChange.fire(); }
+
+ private _onDidRender = new Emitter<{ container: HTMLElement; orientation: Orientation }>();
+ readonly onDidRender = this._onDidRender.event;
+
+ private _size = 0;
+ get size(): number { return this._size; }
+ private _onDidLayout = new Emitter<{ size: number; orientation: Orientation }>();
+ readonly onDidLayout = this._onDidLayout.event;
+
+ private _onDidFocus = new Emitter();
+ readonly onDidFocus = this._onDidFocus.event;
+
+ constructor(
+ private _minimumSize: number,
+ private _maximumSize: number
+ ) {
+ assert(_minimumSize <= _maximumSize, 'splitview view minimum size must be <= maximum size');
+ }
+
+ render(container: HTMLElement, orientation: Orientation): void {
+ this._onDidRender.fire({ container, orientation });
+ }
+
+ layout(size: number, orientation: Orientation): void {
+ this._size = size;
+ this._onDidLayout.fire({ size, orientation });
+ }
+
+ focus(): void {
+ this._onDidFocus.fire();
+ }
+
+ dispose(): void {
+ this._onDidChange.dispose();
+ this._onDidRender.dispose();
+ this._onDidLayout.dispose();
+ this._onDidFocus.dispose();
+ }
+}
+
+function getSashes(splitview: SplitView): Sash[] {
+ return (splitview as any).sashItems.map(i => i.sash) as Sash[];
+}
+
+suite('Splitview', () => {
+ let container: HTMLElement;
+
+ setup(() => {
+ container = document.createElement('div');
+ container.style.position = 'absolute';
+ container.style.width = `${200}px`;
+ container.style.height = `${200}px`;
+ });
+
+ teardown(() => {
+ container = null;
+ });
+
+ test('empty splitview has empty DOM', () => {
+ const splitview = new SplitView(container);
+ assert.equal(container.firstElementChild.childElementCount, 0, 'split view should be empty');
+ splitview.dispose();
+ });
+
+ test('has views as sashes as children', () => {
+ const view1 = new TestView(20, 20);
+ const view2 = new TestView(20, 20);
+ const view3 = new TestView(20, 20);
+ const splitview = new SplitView(container);
+
+ splitview.addView(view1, 20);
+ splitview.addView(view2, 20);
+ splitview.addView(view3, 20);
+
+ let viewQuery = container.querySelectorAll('.monaco-split-view > .split-view-view');
+ assert.equal(viewQuery.length, 3, 'split view should have 3 views');
+
+ let sashQuery = container.querySelectorAll('.monaco-split-view > .monaco-sash');
+ assert.equal(sashQuery.length, 2, 'split view should have 2 sashes');
+
+ splitview.removeView(2);
+
+ viewQuery = container.querySelectorAll('.monaco-split-view > .split-view-view');
+ assert.equal(viewQuery.length, 2, 'split view should have 2 views');
+
+ sashQuery = container.querySelectorAll('.monaco-split-view > .monaco-sash');
+ assert.equal(sashQuery.length, 1, 'split view should have 1 sash');
+
+ splitview.removeView(0);
+
+ viewQuery = container.querySelectorAll('.monaco-split-view > .split-view-view');
+ assert.equal(viewQuery.length, 1, 'split view should have 1 view');
+
+ sashQuery = container.querySelectorAll('.monaco-split-view > .monaco-sash');
+ assert.equal(sashQuery.length, 0, 'split view should have no sashes');
+
+ splitview.removeView(0);
+
+ viewQuery = container.querySelectorAll('.monaco-split-view > .split-view-view');
+ assert.equal(viewQuery.length, 0, 'split view should have no views');
+
+ sashQuery = container.querySelectorAll('.monaco-split-view > .monaco-sash');
+ assert.equal(sashQuery.length, 0, 'split view should have no sashes');
+
+ splitview.dispose();
+ view1.dispose();
+ view2.dispose();
+ view3.dispose();
+ });
+
+ test('calls view methods on addView and removeView', () => {
+ const view = new TestView(20, 20);
+ const splitview = new SplitView(container);
+
+ let didLayout = false;
+ const layoutDisposable = view.onDidLayout(() => didLayout = true);
+
+ let didRender = false;
+ const renderDisposable = view.onDidRender(() => didRender = true);
+
+ splitview.addView(view, 20);
+
+ assert.equal(view.size, 20, 'view has right size');
+ assert(didLayout, 'layout is called');
+ assert(didLayout, 'render is called');
+
+ splitview.dispose();
+ layoutDisposable.dispose();
+ renderDisposable.dispose();
+ view.dispose();
+ });
+
+ test('stretches view to viewport', () => {
+ const view = new TestView(20, Number.POSITIVE_INFINITY);
+ const splitview = new SplitView(container);
+ splitview.layout(200);
+
+ splitview.addView(view, 20);
+ assert.equal(view.size, 200, 'view is stretched');
+
+ splitview.layout(200);
+ assert.equal(view.size, 200, 'view stayed the same');
+
+ splitview.layout(100);
+ assert.equal(view.size, 100, 'view is collapsed');
+
+ splitview.layout(20);
+ assert.equal(view.size, 20, 'view is collapsed');
+
+ splitview.layout(10);
+ assert.equal(view.size, 20, 'view is clamped');
+
+ splitview.layout(200);
+ assert.equal(view.size, 200, 'view is stretched');
+
+ splitview.dispose();
+ view.dispose();
+ });
+
+ test('respects preferred sizes with structural changes', () => {
+ const view1 = new TestView(20, Number.POSITIVE_INFINITY);
+ const view2 = new TestView(20, Number.POSITIVE_INFINITY);
+ const view3 = new TestView(20, Number.POSITIVE_INFINITY);
+ const splitview = new SplitView(container);
+ splitview.layout(200);
+
+ splitview.addView(view1, 20);
+ assert.equal(view1.size, 200, 'view1 is stretched');
+
+ splitview.addView(view2, 20);
+ assert.equal(view1.size, 20, 'view1 size is restored');
+ assert.equal(view2.size, 200 - 20, 'view2 is stretched');
+
+ splitview.addView(view3, 20);
+ assert.equal(view1.size, 20, 'view1 size is restored');
+ assert.equal(view2.size, 20, 'view2 size is restored');
+ assert.equal(view3.size, 160, 'view3 is stretched');
+
+ splitview.dispose();
+ view3.dispose();
+ view2.dispose();
+ view1.dispose();
+ });
+
+ test('can resize views', () => {
+ const view1 = new TestView(20, Number.POSITIVE_INFINITY);
+ const view2 = new TestView(20, Number.POSITIVE_INFINITY);
+ const view3 = new TestView(20, Number.POSITIVE_INFINITY);
+ const splitview = new SplitView(container);
+ splitview.layout(200);
+
+ splitview.addView(view1, 20);
+ splitview.addView(view2, 20);
+ splitview.addView(view3, 20);
+
+ assert.equal(view1.size, 20, 'view1 size is the default');
+ assert.equal(view2.size, 20, 'view2 size the the default');
+ assert.equal(view3.size, 160, 'view3 is stretched');
+
+ splitview.resizeView(1, 40);
+
+ assert.equal(view1.size, 20, 'view1 is untouched');
+ assert.equal(view2.size, 40, 'view2 is stretched');
+ assert.equal(view3.size, 140, 'view3 is collapsed');
+
+ splitview.resizeView(0, 70);
+
+ assert.equal(view1.size, 70, 'view1 is stretched');
+ assert.equal(view2.size, 20, 'view2 is collapsed');
+ assert.equal(view3.size, 110, 'view3 is collapsed');
+
+ assert.throws(() => splitview.resizeView(2, 20));
+
+ assert.equal(view1.size, 70, 'view1 stays the same');
+ assert.equal(view2.size, 20, 'view2 stays the same');
+ assert.equal(view3.size, 110, 'view3 stays the same');
+
+ splitview.dispose();
+ view3.dispose();
+ view2.dispose();
+ view1.dispose();
+ });
+
+ test('reacts to view changes', () => {
+ const view1 = new TestView(20, Number.POSITIVE_INFINITY);
+ const view2 = new TestView(20, Number.POSITIVE_INFINITY);
+ const view3 = new TestView(20, Number.POSITIVE_INFINITY);
+ const splitview = new SplitView(container);
+ splitview.layout(200);
+
+ splitview.addView(view1, 20);
+ splitview.addView(view2, 20);
+ splitview.addView(view3, 20);
+
+ assert.equal(view1.size, 20, 'view1 size is restored');
+ assert.equal(view2.size, 20, 'view2 size is restored');
+ assert.equal(view3.size, 160, 'view3 is stretched');
+
+ view3.maximumSize = 20;
+
+ assert.equal(view1.size, 20, 'view1 stays the same');
+ assert.equal(view2.size, 160, 'view2 is stretched');
+ assert.equal(view3.size, 20, 'view3 is collapsed');
+
+ view2.maximumSize = 40;
+
+ assert.equal(view1.size, 140, 'view1 is stretched');
+ assert.equal(view2.size, 40, 'view2 is collapsed');
+ assert.equal(view3.size, 20, 'view3 is collapsed');
+
+ view3.maximumSize = 200;
+
+ assert.equal(view1.size, 140, 'view1 stays the same');
+ assert.equal(view2.size, 40, 'view2 stays the same');
+ assert.equal(view3.size, 20, 'view3 stays the same');
+
+ view3.minimumSize = 100;
+
+ assert.equal(view1.size, 80, 'view1 is collapsed');
+ assert.equal(view2.size, 20, 'view2 stays the same');
+ assert.equal(view3.size, 100, 'view3 is stretched');
+
+ splitview.dispose();
+ view3.dispose();
+ view2.dispose();
+ view1.dispose();
+ });
+
+ test('sashes are properly enabled/disabled', () => {
+ const view1 = new TestView(20, Number.POSITIVE_INFINITY);
+ const view2 = new TestView(20, Number.POSITIVE_INFINITY);
+ const view3 = new TestView(20, Number.POSITIVE_INFINITY);
+ const splitview = new SplitView(container);
+ splitview.layout(200);
+
+ splitview.addView(view1, 20);
+ splitview.addView(view2, 20);
+ splitview.addView(view3, 20);
+
+ let sashes = getSashes(splitview);
+ assert.equal(sashes.length, 2, 'there are two sashes');
+ assert.equal(sashes[0].enabled, true, 'first sash is enabled');
+ assert.equal(sashes[1].enabled, true, 'second sash is enabled');
+
+ splitview.layout(60);
+ assert.equal(sashes[0].enabled, false, 'first sash is disabled');
+ assert.equal(sashes[1].enabled, false, 'second sash is disabled');
+
+ splitview.layout(20);
+ assert.equal(sashes[0].enabled, false, 'first sash is disabled');
+ assert.equal(sashes[1].enabled, false, 'second sash is disabled');
+
+ splitview.layout(200);
+ assert.equal(sashes[0].enabled, true, 'first sash is enabled');
+ assert.equal(sashes[1].enabled, true, 'second sash is enabled');
+
+ view1.maximumSize = 20;
+ assert.equal(sashes[0].enabled, false, 'first sash is disabled');
+ assert.equal(sashes[1].enabled, true, 'second sash is enabled');
+
+ view2.maximumSize = 20;
+ assert.equal(sashes[0].enabled, false, 'first sash is disabled');
+ assert.equal(sashes[1].enabled, false, 'second sash is disabled');
+
+ view1.maximumSize = 300;
+ assert.equal(sashes[0].enabled, true, 'first sash is enabled');
+ assert.equal(sashes[1].enabled, true, 'second sash is enabled');
+
+ view2.maximumSize = 200;
+ assert.equal(sashes[0].enabled, true, 'first sash is enabled');
+ assert.equal(sashes[1].enabled, true, 'second sash is enabled');
+
+ splitview.dispose();
+ view3.dispose();
+ view2.dispose();
+ view1.dispose();
+ });
+});
\ No newline at end of file
diff --git a/src/vs/base/test/common/uri.test.ts b/src/vs/base/test/common/uri.test.ts
index 1e8340f98c7..3341b0bcb6a 100644
--- a/src/vs/base/test/common/uri.test.ts
+++ b/src/vs/base/test/common/uri.test.ts
@@ -368,6 +368,23 @@ suite('URI', () => {
assert.equal(value.toString(), 'http://l%C3%B6calhost:8080/far');
});
+ test('URI#toString, user information in authority', () => {
+ var value = URI.parse('http://foo:bar@localhost/far');
+ assert.equal(value.toString(), 'http://foo:bar@localhost/far');
+
+ value = URI.parse('http://foo@localhost/far');
+ assert.equal(value.toString(), 'http://foo@localhost/far');
+
+ value = URI.parse('http://foo:bAr@localhost:8080/far');
+ assert.equal(value.toString(), 'http://foo:bAr@localhost:8080/far');
+
+ value = URI.parse('http://foo@localhost:8080/far');
+ assert.equal(value.toString(), 'http://foo@localhost:8080/far');
+
+ value = URI.from({ scheme: 'http', authority: 'fƶƶ:bƶr@lƶcalhost:8080', path: '/far', query: undefined, fragment: undefined });
+ assert.equal(value.toString(), 'http://f%C3%B6%C3%B6:b%C3%B6r@l%C3%B6calhost:8080/far');
+ });
+
test('correctFileUriToFilePath2', () => {
var test = (input: string, expected: string) => {
diff --git a/src/vs/code/electron-main/keyboard.ts b/src/vs/code/electron-main/keyboard.ts
index 73c3289adf6..3b19f2fea15 100644
--- a/src/vs/code/electron-main/keyboard.ts
+++ b/src/vs/code/electron-main/keyboard.ts
@@ -174,4 +174,9 @@ export class KeybindingsResolver {
return this.keybindings[commandId];
}
+
+ public dispose(): void {
+ this._onKeybindingsChanged.dispose();
+ this.keybindingsWatcher.dispose();
+ }
}
\ No newline at end of file
diff --git a/src/vs/code/electron-main/launch.ts b/src/vs/code/electron-main/launch.ts
index 1df7365dc64..189224ef9c6 100644
--- a/src/vs/code/electron-main/launch.ts
+++ b/src/vs/code/electron-main/launch.ts
@@ -14,6 +14,7 @@ import { ParsedArgs } from 'vs/platform/environment/common/environment';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { OpenContext } from 'vs/platform/windows/common/windows';
import { IWindowsMainService, ICodeWindow } from 'vs/platform/windows/electron-main/windows';
+import { whenDeleted } from 'vs/base/node/pfs';
export const ID = 'launchService';
export const ILaunchService = createDecorator(ID);
@@ -113,9 +114,13 @@ export class LaunchService implements ILaunchService {
}
// If the other instance is waiting to be killed, we hook up a window listener if one window
- // is being used and only then resolve the startup promise which will kill this second instance
+ // is being used and only then resolve the startup promise which will kill this second instance.
+ // In addition, we poll for the wait marker file to be deleted to return.
if (args.wait && usedWindows.length === 1 && usedWindows[0]) {
- return this.windowsService.waitForWindowCloseOrLoad(usedWindows[0].id);
+ return TPromise.any([
+ this.windowsService.waitForWindowCloseOrLoad(usedWindows[0].id),
+ whenDeleted(args.waitMarkerFilePath)
+ ]).then(() => void 0, () => void 0);
}
return TPromise.as(null);
diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts
index e04278782bf..5c6464d7db1 100644
--- a/src/vs/code/electron-main/windows.ts
+++ b/src/vs/code/electron-main/windows.ts
@@ -5,7 +5,7 @@
'use strict';
-import * as path from 'path';
+import { basename, normalize, join, dirname } from 'path';
import * as fs from 'original-fs';
import { localize } from 'vs/nls';
import * as arrays from 'vs/base/common/arrays';
@@ -114,6 +114,7 @@ export class WindowsManager implements IWindowsMainService {
private lastClosedWindowState: IWindowState;
private fileDialog: FileDialog;
+ private workspacesManager: WorkspacesManager;
private _onWindowReady = new Emitter();
onWindowReady: CommonEvent = this._onWindowReady.event;
@@ -146,7 +147,9 @@ export class WindowsManager implements IWindowsMainService {
@IInstantiationService private instantiationService: IInstantiationService
) {
this.windowsState = this.storageService.getItem(WindowsManager.windowsStateStorageKey) || { openedWindows: [] };
+
this.fileDialog = new FileDialog(environmentService, telemetryService, storageService, this);
+ this.workspacesManager = new WorkspacesManager(workspacesService, lifecycleService, backupService, environmentService, this);
this.migrateLegacyWindowState();
}
@@ -403,7 +406,7 @@ export class WindowsManager implements IWindowsMainService {
workspacesToRestore.push(...this.workspacesService.getUntitledWorkspacesSync()); // collect from previous window session
emptyToRestore = this.backupService.getEmptyWindowBackupPaths();
- emptyToRestore.push(...pathsToOpen.filter(w => !w.workspace && !w.folderPath && w.backupPath).map(w => path.basename(w.backupPath))); // add empty windows with backupPath
+ emptyToRestore.push(...pathsToOpen.filter(w => !w.workspace && !w.folderPath && w.backupPath).map(w => basename(w.backupPath))); // add empty windows with backupPath
emptyToRestore = arrays.distinct(emptyToRestore); // prevent duplicates
}
@@ -932,7 +935,7 @@ export class WindowsManager implements IWindowsMainService {
anyPath = parsedPath.path;
}
- const candidate = path.normalize(anyPath);
+ const candidate = normalize(anyPath);
try {
const candidateStat = fs.statSync(candidate);
if (candidateStat) {
@@ -1051,7 +1054,7 @@ export class WindowsManager implements IWindowsMainService {
// For all other cases we first call into registerEmptyWindowBackupSync() to set it before
// loading the window.
if (options.emptyWindowBackupFolder) {
- configuration.backupPath = path.join(this.environmentService.backupHome, options.emptyWindowBackupFolder);
+ configuration.backupPath = join(this.environmentService.backupHome, options.emptyWindowBackupFolder);
}
let window: CodeWindow;
@@ -1291,93 +1294,19 @@ export class WindowsManager implements IWindowsMainService {
});
}
- public saveAndOpenWorkspace(window: CodeWindow, path: string): TPromise {
- if (!window || !window.win || window.readyState !== ReadyState.READY || !window.openedWorkspace || !path) {
- return TPromise.as(null); // return early if the window is not ready or disposed or does not have a workspace
- }
-
- return this.doSaveAndOpenWorkspace(window, window.openedWorkspace, path);
+ public saveAndOpenWorkspace(win: CodeWindow, path: string): TPromise {
+ return this.workspacesManager.saveAndOpenWorkspace(win, path);
}
- public createAndOpenWorkspace(window: CodeWindow, folders?: string[], path?: string): TPromise {
- if (!window || !window.win || window.readyState !== ReadyState.READY) {
- return TPromise.as(null); // return early if the window is not ready or disposed
- }
-
- return this.workspacesService.createWorkspace(folders).then(workspace => {
- return this.doSaveAndOpenWorkspace(window, workspace, path);
- });
+ public createAndOpenWorkspace(win: CodeWindow, folders?: string[], path?: string): TPromise {
+ return this.workspacesManager.createAndOpenWorkspace(win, folders, path);
}
- private doSaveAndOpenWorkspace(window: CodeWindow, workspace: IWorkspaceIdentifier, path?: string): TPromise {
- let savePromise: TPromise;
- if (path) {
- savePromise = this.workspacesService.saveWorkspace(workspace, path);
- } else {
- savePromise = TPromise.as(workspace);
- }
-
- return savePromise.then(workspace => {
- window.focus();
-
- // Only open workspace when the window has not vetoed this
- return this.lifecycleService.unload(window, UnloadReason.RELOAD, workspace).done(veto => {
- if (!veto) {
-
- // Register window for backups and migrate current backups over
- let backupPath: string;
- if (window.config && !window.config.extensionDevelopmentPath) {
- backupPath = this.backupService.registerWorkspaceBackupSync(workspace, window.config.backupPath);
- }
-
- // Craft a new window configuration to use for the transition
- const configuration: IWindowConfiguration = mixin({}, window.config);
- configuration.folderPath = void 0;
- configuration.workspace = workspace;
- configuration.backupPath = backupPath;
-
- // Reload
- window.reload(configuration);
- }
- });
- });
+ public openWorkspace(win?: CodeWindow): void {
+ this.workspacesManager.openWorkspace(win);
}
- public openWorkspace(window: CodeWindow = this.getLastActiveWindow()): void {
- let defaultPath: string;
- if (window && window.openedWorkspace && !this.workspacesService.isUntitledWorkspace(window.openedWorkspace)) {
- defaultPath = path.dirname(window.openedWorkspace.configPath);
- } else {
- defaultPath = this.getWorkspaceDialogDefaultPath(window ? (window.openedWorkspace || window.openedFolderPath) : void 0);
- }
- this.pickFileAndOpen({
- windowId: window ? window.id : void 0,
- dialogOptions: {
- buttonLabel: mnemonicButtonLabel(localize({ key: 'openWorkspace', comment: ['&& denotes a mnemonic'] }, "&&Open")),
- title: localize('openWorkspaceTitle', "Open Workspace"),
- filters: WORKSPACE_FILTER,
- properties: ['openFile'],
- defaultPath
- }
- });
- }
-
- private getWorkspaceDialogDefaultPath(workspace?: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier): string {
- let defaultPath: string;
- if (workspace) {
- if (isSingleFolderWorkspaceIdentifier(workspace)) {
- defaultPath = path.dirname(workspace);
- } else {
- const resolvedWorkspace = this.workspacesService.resolveWorkspaceSync(workspace.configPath);
- if (resolvedWorkspace && resolvedWorkspace.folders.length > 0) {
- defaultPath = path.dirname(resolvedWorkspace.folders[0].path);
- }
- }
- }
-
- return defaultPath;
- }
private onBeforeWindowUnload(e: IWindowUnloadEvent): void {
const windowClosing = (e.reason === UnloadReason.CLOSE);
@@ -1399,74 +1328,8 @@ export class WindowsManager implements IWindowsMainService {
return; // Windows/Linux: quits when last window is closed, so do not ask then
}
- this.promptToSaveUntitledWorkspace(e, workspace);
- }
-
- private promptToSaveUntitledWorkspace(e: IWindowUnloadEvent, workspace: IWorkspaceIdentifier): void {
- enum ConfirmResult {
- SAVE,
- DONT_SAVE,
- CANCEL
- }
-
- const save = { label: mnemonicButtonLabel(localize({ key: 'save', comment: ['&& denotes a mnemonic'] }, "&&Save")), result: ConfirmResult.SAVE };
- const dontSave = { label: mnemonicButtonLabel(localize({ key: 'doNotSave', comment: ['&& denotes a mnemonic'] }, "Do&&n't Save")), result: ConfirmResult.DONT_SAVE };
- const cancel = { label: localize('cancel', "Cancel"), result: ConfirmResult.CANCEL };
-
- const buttons: { label: string; result: ConfirmResult; }[] = [];
- if (isWindows) {
- buttons.push(save, dontSave, cancel);
- } else if (isLinux) {
- buttons.push(dontSave, cancel, save);
- } else {
- buttons.push(save, cancel, dontSave);
- }
-
- const options: Electron.MessageBoxOptions = {
- title: this.environmentService.appNameLong,
- message: localize('saveWorkspaceMessage', "Do you want to save your workspace configuration as a file?"),
- detail: localize('saveWorkspaceDetail', "Save your workspace if you plan to open it again."),
- noLink: true,
- type: 'warning',
- buttons: buttons.map(button => button.label),
- cancelId: buttons.indexOf(cancel)
- };
-
- if (isLinux) {
- options.defaultId = 2;
- }
-
- const res = dialog.showMessageBox(e.window.win, options);
-
- switch (buttons[res].result) {
-
- // Cancel: veto unload
- case ConfirmResult.CANCEL:
- e.veto(true);
- break;
-
- // Don't Save: delete workspace
- case ConfirmResult.DONT_SAVE:
- this.workspacesService.deleteUntitledWorkspaceSync(workspace);
- e.veto(false);
- break;
-
- // Save: save workspace, but do not veto unload
- case ConfirmResult.SAVE: {
- const target = dialog.showSaveDialog(e.window.win, {
- buttonLabel: mnemonicButtonLabel(localize({ key: 'save', comment: ['&& denotes a mnemonic'] }, "&&Save")),
- title: localize('saveWorkspace', "Save Workspace"),
- filters: WORKSPACE_FILTER,
- defaultPath: this.getWorkspaceDialogDefaultPath(workspace)
- });
-
- if (target) {
- e.veto(this.workspacesService.saveWorkspace(workspace, target).then(() => false, () => false));
- } else {
- e.veto(true); // keep veto if no target was provided
- }
- }
- }
+ // Handle untitled workspaces with prompt as needed
+ this.workspacesManager.promptToSaveUntitledWorkspace(e, workspace);
}
public focusLastActive(cli: ParsedArgs, context: OpenContext): CodeWindow {
@@ -1754,7 +1617,7 @@ class FileDialog {
if (paths && paths.length > 0) {
// Remember path in storage for next time
- this.storageService.setItem(FileDialog.workingDirPickerStorageKey, path.dirname(paths[0]));
+ this.storageService.setItem(FileDialog.workingDirPickerStorageKey, dirname(paths[0]));
// Return
return clb(paths);
@@ -1763,4 +1626,204 @@ class FileDialog {
return clb(void (0));
});
}
+}
+
+class WorkspacesManager {
+
+ constructor(
+ private workspacesService: IWorkspacesMainService,
+ private lifecycleService: ILifecycleService,
+ private backupService: IBackupMainService,
+ private environmentService: IEnvironmentService,
+ private windowsMainService: IWindowsMainService
+ ) {
+ }
+
+ public saveAndOpenWorkspace(window: CodeWindow, path: string): TPromise {
+ if (!window || !window.win || window.readyState !== ReadyState.READY || !window.openedWorkspace || !path || !this.isValidTargetWorkspacePath(window, path)) {
+ return TPromise.as(null); // return early if the window is not ready or disposed or does not have a workspace
+ }
+
+ return this.doSaveAndOpenWorkspace(window, window.openedWorkspace, path);
+ }
+
+ public createAndOpenWorkspace(window: CodeWindow, folders?: string[], path?: string): TPromise {
+ if (!window || !window.win || window.readyState !== ReadyState.READY || !this.isValidTargetWorkspacePath(window, path)) {
+ return TPromise.as(null); // return early if the window is not ready or disposed
+ }
+
+ return this.workspacesService.createWorkspace(folders).then(workspace => {
+ return this.doSaveAndOpenWorkspace(window, workspace, path);
+ });
+ }
+
+ private isValidTargetWorkspacePath(window: CodeWindow, path?: string): boolean {
+ if (!path) {
+ return true;
+ }
+
+ if (window.openedWorkspace && window.openedWorkspace.configPath === path) {
+ return false; // window is already opened on a workspace with that path
+ }
+
+ // Prevent overwriting a workspace that is currently opened in another window
+ if (findWindowOnWorkspace(this.windowsMainService.getWindows(), { id: this.workspacesService.getWorkspaceId(path), configPath: path })) {
+ const options: Electron.MessageBoxOptions = {
+ title: product.nameLong,
+ type: 'info',
+ buttons: [localize('ok', "OK")],
+ message: localize('workspaceOpenedMessage', "Unable to save workspace '{0}'", basename(path)),
+ detail: localize('workspaceOpenedDetail', "The workspace is already opened in another window. Please close that window first and then try again."),
+ noLink: true
+ };
+
+ const activeWindow = BrowserWindow.getFocusedWindow();
+ if (activeWindow) {
+ dialog.showMessageBox(activeWindow, options);
+ } else {
+ dialog.showMessageBox(options);
+ }
+
+ return false;
+ }
+
+ return true; // OK
+ }
+
+ private doSaveAndOpenWorkspace(window: CodeWindow, workspace: IWorkspaceIdentifier, path?: string): TPromise {
+ let savePromise: TPromise;
+ if (path) {
+ savePromise = this.workspacesService.saveWorkspace(workspace, path);
+ } else {
+ savePromise = TPromise.as(workspace);
+ }
+
+ return savePromise.then(workspace => {
+ window.focus();
+
+ // Only open workspace when the window has not vetoed this
+ return this.lifecycleService.unload(window, UnloadReason.RELOAD, workspace).done(veto => {
+ if (!veto) {
+
+ // Register window for backups and migrate current backups over
+ let backupPath: string;
+ if (window.config && !window.config.extensionDevelopmentPath) {
+ backupPath = this.backupService.registerWorkspaceBackupSync(workspace, window.config.backupPath);
+ }
+
+ // Craft a new window configuration to use for the transition
+ const configuration: IWindowConfiguration = mixin({}, window.config);
+ configuration.folderPath = void 0;
+ configuration.workspace = workspace;
+ configuration.backupPath = backupPath;
+
+ // Reload
+ window.reload(configuration);
+ }
+ });
+ });
+ }
+
+ public openWorkspace(window = this.windowsMainService.getLastActiveWindow()): void {
+ let defaultPath: string;
+ if (window && window.openedWorkspace && !this.workspacesService.isUntitledWorkspace(window.openedWorkspace)) {
+ defaultPath = dirname(window.openedWorkspace.configPath);
+ } else {
+ defaultPath = this.getWorkspaceDialogDefaultPath(window ? (window.openedWorkspace || window.openedFolderPath) : void 0);
+ }
+
+ this.windowsMainService.pickFileAndOpen({
+ windowId: window ? window.id : void 0,
+ dialogOptions: {
+ buttonLabel: mnemonicButtonLabel(localize({ key: 'openWorkspace', comment: ['&& denotes a mnemonic'] }, "&&Open")),
+ title: localize('openWorkspaceTitle', "Open Workspace"),
+ filters: WORKSPACE_FILTER,
+ properties: ['openFile'],
+ defaultPath
+ }
+ });
+ }
+
+ public promptToSaveUntitledWorkspace(e: IWindowUnloadEvent, workspace: IWorkspaceIdentifier): void {
+ enum ConfirmResult {
+ SAVE,
+ DONT_SAVE,
+ CANCEL
+ }
+
+ const save = { label: mnemonicButtonLabel(localize({ key: 'save', comment: ['&& denotes a mnemonic'] }, "&&Save")), result: ConfirmResult.SAVE };
+ const dontSave = { label: mnemonicButtonLabel(localize({ key: 'doNotSave', comment: ['&& denotes a mnemonic'] }, "Do&&n't Save")), result: ConfirmResult.DONT_SAVE };
+ const cancel = { label: localize('cancel', "Cancel"), result: ConfirmResult.CANCEL };
+
+ const buttons: { label: string; result: ConfirmResult; }[] = [];
+ if (isWindows) {
+ buttons.push(save, dontSave, cancel);
+ } else if (isLinux) {
+ buttons.push(dontSave, cancel, save);
+ } else {
+ buttons.push(save, cancel, dontSave);
+ }
+
+ const options: Electron.MessageBoxOptions = {
+ title: this.environmentService.appNameLong,
+ message: localize('saveWorkspaceMessage', "Do you want to save your workspace configuration as a file?"),
+ detail: localize('saveWorkspaceDetail', "Save your workspace if you plan to open it again."),
+ noLink: true,
+ type: 'warning',
+ buttons: buttons.map(button => button.label),
+ cancelId: buttons.indexOf(cancel)
+ };
+
+ if (isLinux) {
+ options.defaultId = 2;
+ }
+
+ const res = dialog.showMessageBox(e.window.win, options);
+
+ switch (buttons[res].result) {
+
+ // Cancel: veto unload
+ case ConfirmResult.CANCEL:
+ e.veto(true);
+ break;
+
+ // Don't Save: delete workspace
+ case ConfirmResult.DONT_SAVE:
+ this.workspacesService.deleteUntitledWorkspaceSync(workspace);
+ e.veto(false);
+ break;
+
+ // Save: save workspace, but do not veto unload
+ case ConfirmResult.SAVE: {
+ const target = dialog.showSaveDialog(e.window.win, {
+ buttonLabel: mnemonicButtonLabel(localize({ key: 'save', comment: ['&& denotes a mnemonic'] }, "&&Save")),
+ title: localize('saveWorkspace', "Save Workspace"),
+ filters: WORKSPACE_FILTER,
+ defaultPath: this.getWorkspaceDialogDefaultPath(workspace)
+ });
+
+ if (target) {
+ e.veto(this.workspacesService.saveWorkspace(workspace, target).then(() => false, () => false));
+ } else {
+ e.veto(true); // keep veto if no target was provided
+ }
+ }
+ }
+ }
+
+ private getWorkspaceDialogDefaultPath(workspace?: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier): string {
+ let defaultPath: string;
+ if (workspace) {
+ if (isSingleFolderWorkspaceIdentifier(workspace)) {
+ defaultPath = dirname(workspace);
+ } else {
+ const resolvedWorkspace = this.workspacesService.resolveWorkspaceSync(workspace.configPath);
+ if (resolvedWorkspace && resolvedWorkspace.folders.length > 0) {
+ defaultPath = dirname(resolvedWorkspace.folders[0].path);
+ }
+ }
+ }
+
+ return defaultPath;
+ }
}
\ No newline at end of file
diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts
index d0f0416e6ff..7476115fcee 100644
--- a/src/vs/code/node/cli.ts
+++ b/src/vs/code/node/cli.ts
@@ -14,6 +14,7 @@ import pkg from 'vs/platform/node/package';
import * as fs from 'fs';
import * as paths from 'path';
import * as os from 'os';
+import { whenDeleted } from 'vs/base/node/pfs';
function shouldSpawnCliProcess(argv: ParsedArgs): boolean {
return argv['list-extensions'] || !!argv['install-extension'] || !!argv['uninstall-extension'];
@@ -105,14 +106,7 @@ export function main(argv: string[]): TPromise {
child.once('exit', () => c(null));
// Complete when wait marker file is deleted
- const interval = setInterval(() => {
- fs.exists(waitMarkerFilePath, exists => {
- if (!exists) {
- clearInterval(interval);
- c(null);
- }
- });
- }, 1000);
+ whenDeleted(waitMarkerFilePath).done(c, c);
});
}
}
diff --git a/src/vs/editor/browser/view/viewImpl.ts b/src/vs/editor/browser/view/viewImpl.ts
index b8c5900a2d2..79cf5f2c105 100644
--- a/src/vs/editor/browser/view/viewImpl.ts
+++ b/src/vs/editor/browser/view/viewImpl.ts
@@ -308,7 +308,8 @@ export class View extends ViewEventHandler {
}
private getEditorClassName() {
- return this._context.configuration.editor.editorClassName + ' ' + getThemeTypeSelector(this._context.theme.type);
+ let focused = this._textAreaHandler.isFocused() ? ' focused' : '';
+ return this._context.configuration.editor.editorClassName + ' ' + getThemeTypeSelector(this._context.theme.type) + focused;
}
// --- begin event handlers
@@ -323,7 +324,7 @@ export class View extends ViewEventHandler {
return false;
}
public onFocusChanged(e: viewEvents.ViewFocusChangedEvent): boolean {
- this.domNode.toggleClassName('focused', e.isFocused);
+ this.domNode.setClassName(this.getEditorClassName());
if (e.isFocused) {
this.outgoingEvents.emitViewFocusGained();
} else {
diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts
index fe646ba39e4..22efae7b65e 100644
--- a/src/vs/editor/browser/widget/codeEditorWidget.ts
+++ b/src/vs/editor/browser/widget/codeEditorWidget.ts
@@ -400,6 +400,7 @@ export abstract class CodeEditorWidget extends CommonCodeEditor implements edito
this._view.render(false, true);
this.hasView = true;
+ this._view.domNode.domNode.setAttribute('data-uri', model.uri.toString());
}
}
diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts
index 14d3ec12623..d00a0e2365b 100644
--- a/src/vs/editor/common/config/commonEditorConfig.ts
+++ b/src/vs/editor/common/config/commonEditorConfig.ts
@@ -598,6 +598,11 @@ const editorConfiguration: IConfigurationNode = {
'default': EDITOR_DEFAULTS.contribInfo.colorDecorators,
'description': nls.localize('colorDecorators', "Controls whether the editor should render the inline color decorators and color picker.")
},
+ 'editor.lightbulb.enabled': {
+ 'type': 'boolean',
+ 'default': EDITOR_DEFAULTS.contribInfo.lightbulbEnabled,
+ 'description': nls.localize('codeActions', "Enables the code action lightbulb")
+ },
'diffEditor.renderSideBySide': {
'type': 'boolean',
'default': true,
diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts
index d3a94dcc623..c619e76e5e9 100644
--- a/src/vs/editor/common/config/editorOptions.ts
+++ b/src/vs/editor/common/config/editorOptions.ts
@@ -114,6 +114,17 @@ export interface IEditorMinimapOptions {
maxColumn?: number;
}
+/**
+ * Configuration options for editor minimap
+ */
+export interface IEditorLightbulbOptions {
+ /**
+ * Enable the lightbulb code action.
+ * Defaults to true.
+ */
+ enabled?: boolean;
+}
+
/**
* Configuration options for the editor.
*/
@@ -462,6 +473,10 @@ export interface IEditorOptions {
* @internal
*/
referenceInfos?: boolean;
+ /**
+ * Control the behavior and rendering of the code action lightbulb.
+ */
+ lightbulb?: IEditorLightbulbOptions;
/**
* Enable code folding
* Defaults to true in vscode and to false in monaco-editor.
@@ -795,6 +810,7 @@ export interface EditorContribOptions {
readonly matchBrackets: boolean;
readonly find: InternalEditorFindOptions;
readonly colorDecorators: boolean;
+ readonly lightbulbEnabled: boolean;
}
/**
@@ -1140,6 +1156,7 @@ export class InternalEditorOptions {
&& a.matchBrackets === b.matchBrackets
&& this._equalFindOptions(a.find, b.find)
&& a.colorDecorators === b.colorDecorators
+ && a.lightbulbEnabled === b.lightbulbEnabled
);
}
@@ -1669,6 +1686,7 @@ export class EditorOptionsValidator {
matchBrackets: _boolean(opts.matchBrackets, defaults.matchBrackets),
find: find,
colorDecorators: _boolean(opts.colorDecorators, defaults.colorDecorators),
+ lightbulbEnabled: _boolean(opts.lightbulb ? opts.lightbulb.enabled : false, defaults.lightbulbEnabled)
};
}
}
@@ -1766,7 +1784,8 @@ export class InternalEditorOptionsFactory {
showFoldingControls: opts.contribInfo.showFoldingControls,
matchBrackets: (accessibilityIsOn ? false : opts.contribInfo.matchBrackets), // DISABLED WHEN SCREEN READER IS ATTACHED
find: opts.contribInfo.find,
- colorDecorators: opts.contribInfo.colorDecorators
+ colorDecorators: opts.contribInfo.colorDecorators,
+ lightbulbEnabled: opts.contribInfo.lightbulbEnabled
}
};
}
@@ -2205,6 +2224,7 @@ export const EDITOR_DEFAULTS: IValidatedEditorOptions = {
seedSearchStringFromSelection: true,
autoFindInSelection: false
},
- colorDecorators: true
+ colorDecorators: true,
+ lightbulbEnabled: true
},
};
diff --git a/src/vs/editor/contrib/parameterHints/browser/parameterHints.css b/src/vs/editor/contrib/parameterHints/browser/parameterHints.css
index db3ff8001ae..812bff41e87 100644
--- a/src/vs/editor/contrib/parameterHints/browser/parameterHints.css
+++ b/src/vs/editor/contrib/parameterHints/browser/parameterHints.css
@@ -45,6 +45,11 @@
.monaco-editor .parameter-hints-widget .docs {
padding: 0 10px 0 5px;
+ white-space: pre-wrap;
+}
+
+.monaco-editor .parameter-hints-widget .docs.markdown-docs {
+ white-space: initial;
}
.monaco-editor .parameter-hints-widget .docs .code {
diff --git a/src/vs/editor/contrib/parameterHints/browser/parameterHintsWidget.ts b/src/vs/editor/contrib/parameterHints/browser/parameterHintsWidget.ts
index bacb7f633f8..547ca4d3757 100644
--- a/src/vs/editor/contrib/parameterHints/browser/parameterHintsWidget.ts
+++ b/src/vs/editor/contrib/parameterHints/browser/parameterHintsWidget.ts
@@ -336,8 +336,10 @@ export class ParameterHintsWidget implements IContentWidget, IDisposable {
if (activeParameter && activeParameter.documentation) {
const documentation = $('span.documentation');
if (typeof activeParameter.documentation === 'string') {
+ dom.removeClass(this.docs, 'markdown-docs');
documentation.textContent = activeParameter.documentation;
} else {
+ dom.addClass(this.docs, 'markdown-docs');
documentation.appendChild(this.markdownRenderer.render(activeParameter.documentation));
}
dom.append(this.docs, $('p', null, documentation));
diff --git a/src/vs/editor/contrib/quickFix/browser/lightBulbWidget.ts b/src/vs/editor/contrib/quickFix/browser/lightBulbWidget.ts
index 8bb2b4c2f02..2b76c9e2540 100644
--- a/src/vs/editor/contrib/quickFix/browser/lightBulbWidget.ts
+++ b/src/vs/editor/contrib/quickFix/browser/lightBulbWidget.ts
@@ -29,12 +29,12 @@ export class LightBulbWidget implements IDisposable, IContentWidget {
private _futureFixes = new CancellationTokenSource();
constructor(editor: ICodeEditor) {
- this._editor = editor;
- this._editor.addContentWidget(this);
-
this._domNode = document.createElement('div');
this._domNode.className = 'lightbulb-glyph';
+ this._editor = editor;
+ this._editor.addContentWidget(this);
+
this._disposables.push(dom.addStandardDisposableListener(this._domNode, 'click', e => {
// a bit of extra work to make sure the menu
// doesn't cover the line-text
@@ -66,6 +66,12 @@ export class LightBulbWidget implements IDisposable, IContentWidget {
dom.removeClass(this._domNode, 'hidden');
});
}));
+ this._disposables.push(this._editor.onDidChangeConfiguration(e => {
+ // hide when told to do so
+ if (e.contribInfo && !this._editor.getConfiguration().contribInfo.lightbulbEnabled) {
+ this.hide();
+ }
+ }));
}
dispose(): void {
@@ -124,11 +130,14 @@ export class LightBulbWidget implements IDisposable, IContentWidget {
}
private _show(): void {
- const { fontInfo } = this._editor.getConfiguration();
+ const config = this._editor.getConfiguration();
+ if (!config.contribInfo.lightbulbEnabled) {
+ return;
+ }
const { lineNumber } = this._model.position;
const model = this._editor.getModel();
const indent = model.getIndentLevel(lineNumber);
- const lineHasSpace = fontInfo.spaceWidth * indent > 22;
+ const lineHasSpace = config.fontInfo.spaceWidth * indent > 22;
let effectiveLineNumber = lineNumber;
if (!lineHasSpace) {
diff --git a/src/vs/editor/contrib/referenceSearch/browser/peekViewWidget.ts b/src/vs/editor/contrib/referenceSearch/browser/peekViewWidget.ts
index 1d912e8d055..a0a78bac128 100644
--- a/src/vs/editor/contrib/referenceSearch/browser/peekViewWidget.ts
+++ b/src/vs/editor/contrib/referenceSearch/browser/peekViewWidget.ts
@@ -174,7 +174,6 @@ export abstract class PeekViewWidget extends ZoneWidget {
if (!this._isShowing && heightInPixel < 0) {
// Looks like the view zone got folded away!
this.dispose();
- this._onDidClose.fire(this);
return;
}
diff --git a/src/vs/editor/contrib/suggest/browser/media/suggest.css b/src/vs/editor/contrib/suggest/browser/media/suggest.css
index 3eee4201f43..2cd4a1b4896 100644
--- a/src/vs/editor/contrib/suggest/browser/media/suggest.css
+++ b/src/vs/editor/contrib/suggest/browser/media/suggest.css
@@ -228,6 +228,11 @@
.monaco-editor .suggest-widget .details > .monaco-scrollable-element > .body > .docs {
margin: 0;
padding: 4px 5px;
+ white-space: pre-wrap;
+}
+
+.monaco-editor .suggest-widget .details > .monaco-scrollable-element > .body > .docs.markdown-docs {
+ white-space: initial;
}
.monaco-editor .suggest-widget .details > .monaco-scrollable-element > .body > .docs .code {
diff --git a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts
index 63a2a0e9e3a..472fce09a86 100644
--- a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts
+++ b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts
@@ -249,8 +249,10 @@ class SuggestionDetails {
}
removeClass(this.el, 'no-docs');
if (typeof item.suggestion.documentation === 'string') {
+ removeClass(this.docs, 'markdown-docs');
this.docs.textContent = item.suggestion.documentation;
} else {
+ addClass(this.docs, 'markdown-docs');
this.docs.innerHTML = this.markdownRenderer.render(item.suggestion.documentation).innerHTML;
}
diff --git a/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts b/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts
index 53c35db2f3b..f2ebd600999 100644
--- a/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts
+++ b/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts
@@ -7,7 +7,6 @@
import 'vs/css!./zoneWidget';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
-import { Widget } from 'vs/base/browser/ui/widget';
import * as objects from 'vs/base/common/objects';
import * as dom from 'vs/base/browser/dom';
import { Sash, Orientation, IHorizontalSashLayoutProvider, ISashEvent } from 'vs/base/browser/ui/sash/sash';
@@ -157,7 +156,7 @@ class Arrow {
}
}
-export abstract class ZoneWidget extends Widget implements IHorizontalSashLayoutProvider {
+export abstract class ZoneWidget implements IHorizontalSashLayoutProvider {
private _arrow: Arrow;
private _overlayWidget: OverlayWidgetDelegate;
@@ -174,7 +173,6 @@ export abstract class ZoneWidget extends Widget implements IHorizontalSashLayout
constructor(editor: ICodeEditor, options: IOptions = {}) {
- super();
this.editor = editor;
this.options = objects.clone(options);
objects.mixin(this.options, defaultOptions, false);
diff --git a/src/vs/editor/standalone/browser/simpleServices.ts b/src/vs/editor/standalone/browser/simpleServices.ts
index 7863e391781..3dadc377cef 100644
--- a/src/vs/editor/standalone/browser/simpleServices.ts
+++ b/src/vs/editor/standalone/browser/simpleServices.ts
@@ -9,6 +9,7 @@ import Severity from 'vs/base/common/severity';
import URI from 'vs/base/common/uri';
import { TPromise } from 'vs/base/common/winjs.base';
import { IConfigurationService, IConfigurationServiceEvent, IConfigurationValue, IConfigurationKeys, IConfigurationValues, Configuration, IConfigurationData, ConfigurationModel, IConfigurationOverrides } from 'vs/platform/configuration/common/configuration';
+import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IEditor, IEditorInput, IEditorOptions, IEditorService, IResourceInput, Position } from 'vs/platform/editor/common/editor';
import { ICommandService, ICommand, ICommandEvent, ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands';
import { AbstractKeybindingService } from 'vs/platform/keybinding/common/abstractKeybindingService';
@@ -17,7 +18,7 @@ import { KeybindingResolver } from 'vs/platform/keybinding/common/keybindingReso
import { IKeybindingEvent, KeybindingSource, IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding';
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IConfirmation, IMessageService } from 'vs/platform/message/common/message';
-import { IWorkspaceContextService, ILegacyWorkspace, IWorkspace } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, IWorkspace, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import * as editorCommon from 'vs/editor/common/editorCommon';
import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser';
import { Selection } from 'vs/editor/common/core/selection';
@@ -525,38 +526,31 @@ export class SimpleWorkspaceContextService implements IWorkspaceContextService {
public readonly onDidChangeWorkspaceName: Event = this._onDidChangeWorkspaceName.event;
private readonly _onDidChangeWorkspaceRoots: Emitter = new Emitter();
- public readonly onDidChangeWorkspaceRoots: Event = this._onDidChangeWorkspaceRoots.event;
+ public readonly onDidChangeWorkspaceFolders: Event = this._onDidChangeWorkspaceRoots.event;
- private readonly legacyWorkspace: ILegacyWorkspace;
private readonly workspace: IWorkspace;
constructor() {
- this.legacyWorkspace = { resource: URI.from({ scheme: SimpleWorkspaceContextService.SCHEME, authority: 'model', path: '/' }) };
- this.workspace = { id: '4064f6ec-cb38-4ad0-af64-ee6467e63c82', roots: [this.legacyWorkspace.resource], name: this.legacyWorkspace.resource.fsPath };
- }
-
- public getLegacyWorkspace(): ILegacyWorkspace {
- return this.legacyWorkspace;
+ const resource = URI.from({ scheme: SimpleWorkspaceContextService.SCHEME, authority: 'model', path: '/' });
+ this.workspace = { id: '4064f6ec-cb38-4ad0-af64-ee6467e63c82', folders: [resource], name: resource.fsPath };
}
public getWorkspace(): IWorkspace {
return this.workspace;
}
- public getRoot(resource: URI): URI {
- return resource && resource.scheme === SimpleWorkspaceContextService.SCHEME ? this.workspace.roots[0] : void 0;
+ public getWorkbenchState(): WorkbenchState {
+ if (this.workspace) {
+ if (this.workspace.configuration) {
+ return WorkbenchState.WORKSPACE;
+ }
+ return WorkbenchState.FOLDER;
+ }
+ return WorkbenchState.EMPTY;
}
- public hasWorkspace(): boolean {
- return true;
- }
-
- public hasFolderWorkspace(): boolean {
- return true;
- }
-
- public hasMultiFolderWorkspace(): boolean {
- return false;
+ public getWorkspaceFolder(resource: URI): URI {
+ return resource && resource.scheme === SimpleWorkspaceContextService.SCHEME ? this.workspace.folders[0] : void 0;
}
public isInsideWorkspace(resource: URI): boolean {
@@ -566,4 +560,8 @@ export class SimpleWorkspaceContextService implements IWorkspaceContextService {
public toResource(workspaceRelativePath: string): URI {
return URI.file(workspaceRelativePath);
}
+
+ public isCurrentWorkspace(workspaceIdentifier: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): boolean {
+ return true;
+ }
}
diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts
index 467ac20a374..194484f2618 100644
--- a/src/vs/monaco.d.ts
+++ b/src/vs/monaco.d.ts
@@ -2683,6 +2683,17 @@ declare module monaco.editor {
maxColumn?: number;
}
+ /**
+ * Configuration options for editor minimap
+ */
+ export interface IEditorLightbulbOptions {
+ /**
+ * Enable the lightbulb code action.
+ * Defaults to true.
+ */
+ enabled?: boolean;
+ }
+
/**
* Configuration options for the editor.
*/
@@ -3018,6 +3029,10 @@ declare module monaco.editor {
* Defaults to true.
*/
codeLens?: boolean;
+ /**
+ * Control the behavior and rendering of the code action lightbulb.
+ */
+ lightbulb?: IEditorLightbulbOptions;
/**
* Enable code folding
* Defaults to true in vscode and to false in monaco-editor.
@@ -3296,6 +3311,7 @@ declare module monaco.editor {
readonly matchBrackets: boolean;
readonly find: InternalEditorFindOptions;
readonly colorDecorators: boolean;
+ readonly lightbulbEnabled: boolean;
}
/**
diff --git a/src/vs/platform/backup/electron-main/backupMainService.ts b/src/vs/platform/backup/electron-main/backupMainService.ts
index 94210b0572f..9ea43c880e6 100644
--- a/src/vs/platform/backup/electron-main/backupMainService.ts
+++ b/src/vs/platform/backup/electron-main/backupMainService.ts
@@ -88,14 +88,19 @@ export class BackupMainService implements IBackupMainService {
}
private moveBackupFolderSync(backupPath: string, moveFromPath: string): void {
- if (!fs.existsSync(moveFromPath)) {
- return;
+
+ // Target exists: make sure to convert existing backups to empty window backups
+ if (fs.existsSync(backupPath)) {
+ this.convertToEmptyWindowBackup(backupPath);
}
- try {
- fs.renameSync(moveFromPath, backupPath);
- } catch (ex) {
- this.logService.error(`Backup: Could not move backup folder to new location: ${ex.toString()}`);
+ // When we have data to migrate from, move it over to the target location
+ if (fs.existsSync(moveFromPath)) {
+ try {
+ fs.renameSync(moveFromPath, backupPath);
+ } catch (ex) {
+ this.logService.error(`Backup: Could not move backup folder to new location: ${ex.toString()}`);
+ }
}
}
@@ -231,16 +236,7 @@ export class BackupMainService implements IBackupMainService {
staleBackupWorkspaces.push({ workspaceIdentifier: workspaceId, backupPath, target: workspaceOrFolder.target });
if (missingWorkspace) {
- const identifier = this.getRandomEmptyWindowId();
- this.pushBackupPathsSync(identifier, this.backups.emptyWorkspaces);
- const newEmptyWindowBackupPath = path.join(this.backupHome, identifier);
- try {
- fs.renameSync(backupPath, newEmptyWindowBackupPath);
- } catch (ex) {
- this.logService.error(`Backup: Could not rename backup folder for missing workspace: ${ex.toString()}`);
-
- this.removeBackupPathSync(identifier, this.backups.emptyWorkspaces);
- }
+ this.convertToEmptyWindowBackup(backupPath);
}
}
});
@@ -267,6 +263,27 @@ export class BackupMainService implements IBackupMainService {
});
}
+ private convertToEmptyWindowBackup(backupPath: string): boolean {
+
+ // New empty window backup
+ const identifier = this.getRandomEmptyWindowId();
+ this.pushBackupPathsSync(identifier, this.backups.emptyWorkspaces);
+
+ // Rename backupPath to new empty window backup path
+ const newEmptyWindowBackupPath = path.join(this.backupHome, identifier);
+ try {
+ fs.renameSync(backupPath, newEmptyWindowBackupPath);
+ } catch (ex) {
+ this.logService.error(`Backup: Could not rename backup folder: ${ex.toString()}`);
+
+ this.removeBackupPathSync(identifier, this.backups.emptyWorkspaces);
+
+ return false;
+ }
+
+ return true;
+ }
+
private hasBackupsSync(backupPath: string): boolean {
try {
const backupSchemas = extfs.readdirSync(backupPath);
diff --git a/src/vs/platform/backup/test/electron-main/backupMainService.test.ts b/src/vs/platform/backup/test/electron-main/backupMainService.test.ts
index 063ebe91c6a..7d5a37d4edb 100644
--- a/src/vs/platform/backup/test/electron-main/backupMainService.test.ts
+++ b/src/vs/platform/backup/test/electron-main/backupMainService.test.ts
@@ -208,6 +208,33 @@ suite('BackupMainService', () => {
assert.ok(fs.existsSync(path.join(workspaceBackupPath, 'backup.txt')));
assert.ok(!fs.existsSync(backupPathToMigrate));
+ const emptyBackups = service.getEmptyWindowBackupPaths();
+ assert.equal(0, emptyBackups.length);
+
+ done();
+ });
+
+ test('service backup migration makes sure to preserve existing backups', done => {
+ const backupPathToMigrate = service.toBackupPath(fooFile.fsPath);
+ fs.mkdirSync(backupPathToMigrate);
+ fs.writeFileSync(path.join(backupPathToMigrate, 'backup.txt'), 'Some Data');
+ service.registerFolderBackupSync(backupPathToMigrate);
+
+ const backupPathToPreserve = service.toBackupPath(barFile.fsPath);
+ fs.mkdirSync(backupPathToPreserve);
+ fs.writeFileSync(path.join(backupPathToPreserve, 'backup.txt'), 'Some Data');
+ service.registerFolderBackupSync(backupPathToPreserve);
+
+ const workspaceBackupPath = service.registerWorkspaceBackupSync(toWorkspace(barFile.fsPath), backupPathToMigrate);
+
+ assert.ok(fs.existsSync(workspaceBackupPath));
+ assert.ok(fs.existsSync(path.join(workspaceBackupPath, 'backup.txt')));
+ assert.ok(!fs.existsSync(backupPathToMigrate));
+
+ const emptyBackups = service.getEmptyWindowBackupPaths();
+ assert.equal(1, emptyBackups.length);
+ assert.equal(1, fs.readdirSync(path.join(backupHome, emptyBackups[0])).length);
+
done();
});
diff --git a/src/vs/platform/configuration/common/configuration.ts b/src/vs/platform/configuration/common/configuration.ts
index 85e3e00ff4c..7b9ecd5e500 100644
--- a/src/vs/platform/configuration/common/configuration.ts
+++ b/src/vs/platform/configuration/common/configuration.ts
@@ -257,7 +257,7 @@ export class Configuration {
lookupLegacy(key: string): IConfigurationValue {
if (!this._legacyWorkspaceConsolidatedConfiguration) {
- this._legacyWorkspaceConsolidatedConfiguration = this._workspace ? new ConfigurationModel().merge(this._workspaceConfiguration).merge(this.folders.get(this._workspace.roots[0])) : null;
+ this._legacyWorkspaceConsolidatedConfiguration = this._workspace ? new ConfigurationModel().merge(this._workspaceConfiguration).merge(this.folders.get(this._workspace.folders[0])) : null;
}
const consolidateConfigurationModel = this.getConsolidateConfigurationModel({});
return {
@@ -325,7 +325,7 @@ export class Configuration {
return this._workspaceConsolidatedConfiguration;
}
- const root = this._workspace.getRoot(resource);
+ const root = this._workspace.getFolder(resource);
if (!root) {
return this._workspaceConsolidatedConfiguration;
}
@@ -338,7 +338,7 @@ export class Configuration {
return null;
}
- const root = this._workspace.getRoot(resource);
+ const root = this._workspace.getFolder(resource);
return root ? this.folders.get(root) : null;
}
diff --git a/src/vs/platform/configuration/node/configurationService.ts b/src/vs/platform/configuration/node/configurationService.ts
index 2eff5bb204f..8f6005c6430 100644
--- a/src/vs/platform/configuration/node/configurationService.ts
+++ b/src/vs/platform/configuration/node/configurationService.ts
@@ -8,7 +8,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { ConfigWatcher } from 'vs/base/node/config';
import { Registry } from 'vs/platform/registry/common/platform';
import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry';
-import { IDisposable, toDisposable, Disposable } from 'vs/base/common/lifecycle';
+import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
import { ConfigurationSource, IConfigurationService, IConfigurationServiceEvent, IConfigurationValue, IConfigurationKeys, ConfigurationModel, IConfigurationOverrides, Configuration, IConfigurationValues, IConfigurationData } from 'vs/platform/configuration/common/configuration';
import { CustomConfigurationModel, DefaultConfigurationModel } from 'vs/platform/configuration/common/model';
import Event, { Emitter } from 'vs/base/common/event';
@@ -37,7 +37,7 @@ export class ConfigurationService extends Disposable implements IConfiguratio
return userConfigModel;
}
});
- this._register(toDisposable(() => this.userConfigModelWatcher.dispose()));
+ this._register(this.userConfigModelWatcher);
// Listeners
this._register(this.userConfigModelWatcher.onDidUpdateConfiguration(() => this.onConfigurationChange(ConfigurationSource.User)));
diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts
index b4ee3dfcca3..540f812d271 100644
--- a/src/vs/platform/environment/common/environment.ts
+++ b/src/vs/platform/environment/common/environment.ts
@@ -40,6 +40,7 @@ export interface ParsedArgs {
'enable-proposed-api'?: string | string[];
'open-url'?: string | string[];
'skip-getting-started'?: boolean;
+ 'sticky-quickopen'?: boolean;
}
export const IEnvironmentService = createDecorator('environmentService');
diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts
index ad6e24e0eb2..6eb3036e94a 100644
--- a/src/vs/platform/environment/node/argv.ts
+++ b/src/vs/platform/environment/node/argv.ts
@@ -46,7 +46,8 @@ const options: minimist.Opts = {
'list-extensions',
'show-versions',
'nolazy',
- 'skip-getting-started'
+ 'skip-getting-started',
+ 'sticky-quickopen'
],
alias: {
add: 'a',
diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts
index 9ba9802831a..01222188e6a 100644
--- a/src/vs/platform/environment/node/environmentService.ts
+++ b/src/vs/platform/environment/node/environmentService.ts
@@ -10,7 +10,7 @@ import * as os from 'os';
import * as path from 'path';
import * as fs from 'fs';
import URI from 'vs/base/common/uri';
-import { generateUuid } from 'vs/base/common/uuid';
+import { generateUuid, isUUID } from 'vs/base/common/uuid';
import { memoize } from 'vs/base/common/decorators';
import pkg from 'vs/platform/node/package';
import product from 'vs/platform/node/product';
@@ -32,9 +32,6 @@ function getUniqueUserId(): string {
}
function getNixIPCHandle(userDataPath: string, type: string): string {
- if (process.env['XDG_RUNTIME_DIR']) {
- return path.join(process.env['XDG_RUNTIME_DIR'], `${pkg.name}-${pkg.version}-${type}.sock`);
- }
return path.join(userDataPath, `${pkg.version}-${type}.sock`);
}
@@ -151,11 +148,15 @@ export class EnvironmentService implements IEnvironmentService {
try {
this.machineUUID = fs.readFileSync(machineIdPath, 'utf8');
+
+ if (!isUUID(this.machineUUID)) {
+ throw new Error('Not a UUID');
+ }
} catch (err) {
this.machineUUID = generateUuid();
try {
- fs.writeFileSync(machineIdPath, this.machineUUID);
+ fs.writeFileSync(machineIdPath, this.machineUUID, 'utf8');
} catch (err) {
console.warn('Could not store machine ID');
}
diff --git a/src/vs/platform/extensionManagement/common/extensionEnablementService.ts b/src/vs/platform/extensionManagement/common/extensionEnablementService.ts
index 75606dd0a96..65348d5095c 100644
--- a/src/vs/platform/extensionManagement/common/extensionEnablementService.ts
+++ b/src/vs/platform/extensionManagement/common/extensionEnablementService.ts
@@ -10,7 +10,7 @@ import Event, { Emitter } from 'vs/base/common/event';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IExtensionManagementService, DidUninstallExtensionEvent, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { adoptToGalleryExtensionId, getIdAndVersionFromLocalExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
@@ -35,7 +35,7 @@ export class ExtensionEnablementService implements IExtensionEnablementService {
}
private get hasWorkspace(): boolean {
- return this.contextService.hasWorkspace();
+ return this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY;
}
public getGloballyDisabledExtensions(): string[] {
diff --git a/src/vs/platform/extensionManagement/test/common/extensionEnablementService.test.ts b/src/vs/platform/extensionManagement/test/common/extensionEnablementService.test.ts
index e44ff52c8c9..e35a98d864c 100644
--- a/src/vs/platform/extensionManagement/test/common/extensionEnablementService.test.ts
+++ b/src/vs/platform/extensionManagement/test/common/extensionEnablementService.test.ts
@@ -12,7 +12,7 @@ import { TestInstantiationService } from 'vs/platform/instantiation/test/common/
import { Emitter } from 'vs/base/common/event';
import { StorageService, InMemoryLocalStorage } from 'vs/platform/storage/common/storageService';
import { IStorageService } from 'vs/platform/storage/common/storage';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
function storageService(instantiationService: TestInstantiationService): IStorageService {
@@ -21,9 +21,7 @@ function storageService(instantiationService: TestInstantiationService): IStorag
let workspaceContextService = instantiationService.get(IWorkspaceContextService);
if (!workspaceContextService) {
workspaceContextService = instantiationService.stub(IWorkspaceContextService, {
- hasWorkspace: () => {
- return true;
- },
+ getWorkbenchState: () => WorkbenchState.FOLDER,
});
}
service = instantiationService.stub(IStorageService, instantiationService.createInstance(StorageService, new InMemoryLocalStorage(), new InMemoryLocalStorage()));
@@ -73,7 +71,7 @@ suite('ExtensionEnablementService Test', () => {
test('test when no extensions are disabled for workspace when there is no workspace', (done) => {
testObject.setEnablement('pub.a', false, true)
.then(() => {
- instantiationService.stub(IWorkspaceContextService, 'hasWorkspace', false);
+ instantiationService.stub(IWorkspaceContextService, 'getWorkbenchState', WorkbenchState.EMPTY);
assert.deepEqual([], testObject.getWorkspaceDisabledExtensions());
})
.then(done, done);
@@ -178,7 +176,7 @@ suite('ExtensionEnablementService Test', () => {
});
test('test disable an extension for workspace when there is no workspace throws error', (done) => {
- instantiationService.stub(IWorkspaceContextService, 'hasWorkspace', false);
+ instantiationService.stub(IWorkspaceContextService, 'getWorkbenchState', WorkbenchState.EMPTY);
testObject.setEnablement('pub.a', false, true)
.then(() => assert.fail('should throw an error'), error => assert.ok(error))
.then(done, done);
diff --git a/src/vs/platform/files/common/files.ts b/src/vs/platform/files/common/files.ts
index 455db1408ec..c89cc6399bf 100644
--- a/src/vs/platform/files/common/files.ts
+++ b/src/vs/platform/files/common/files.ts
@@ -93,7 +93,7 @@ export interface IFileService {
*
* The optional parameter content can be used as value to fill into the new file.
*/
- createFile(resource: URI, content?: string): TPromise;
+ createFile(resource: URI, content?: string, options?: ICreateFileOptions): TPromise;
/**
* Creates a new folder with the given path. The returned promise
@@ -491,6 +491,15 @@ export interface IResolveFileOptions {
resolveSingleChildDescendants?: boolean;
}
+export interface ICreateFileOptions {
+
+ /**
+ * Overwrite the file to create if it already exists on disk. Otherwise
+ * an error will be thrown (FILE_MODIFIED_SINCE).
+ */
+ overwrite?: boolean;
+}
+
export interface IImportResult {
stat: IFileStat;
isNew: boolean;
diff --git a/src/vs/platform/storage/test/common/storageService.test.ts b/src/vs/platform/storage/test/common/storageService.test.ts
index 2bd09689b54..f51d6957118 100644
--- a/src/vs/platform/storage/test/common/storageService.test.ts
+++ b/src/vs/platform/storage/test/common/storageService.test.ts
@@ -8,7 +8,7 @@
import * as assert from 'assert';
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
import { StorageScope } from 'vs/platform/storage/common/storage';
-import { IWorkspaceContextService, IWorkspace } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, IWorkspace, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { StorageService, InMemoryLocalStorage } from 'vs/platform/storage/common/storageService';
import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace';
@@ -19,9 +19,7 @@ suite('Workbench StorageSevice', () => {
setup(() => {
instantiationService = new TestInstantiationService();
contextService = instantiationService.stub(IWorkspaceContextService, {
- hasWorkspace: () => {
- return true;
- },
+ getWorkbenchState: () => WorkbenchState.FOLDER,
getWorkspace: () => {
return TestWorkspace;
}
diff --git a/src/vs/platform/telemetry/common/experiments.ts b/src/vs/platform/telemetry/common/experiments.ts
index 103f1908f50..6911c881760 100644
--- a/src/vs/platform/telemetry/common/experiments.ts
+++ b/src/vs/platform/telemetry/common/experiments.ts
@@ -4,14 +4,12 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
-import * as platform from 'vs/base/common/platform';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
export interface IExperiments {
ripgrepQuickSearch: boolean;
- deployToAzureQuickLink: boolean;
}
export const IExperimentService = createDecorator('experimentService');
@@ -44,10 +42,7 @@ export class ExperimentService implements IExperimentService {
function loadExperiments(storageService: IStorageService, configurationService: IConfigurationService): IExperiments {
const experiments = splitExperimentsRandomness(storageService);
- if (platform.isWindows) {
- // Ripgrep triggers MsMpEng.exe (https://github.com/BurntSushi/ripgrep/issues/600)
- experiments.ripgrepQuickSearch = false;
- }
+ experiments.ripgrepQuickSearch = true;
return applyOverrides(experiments, configurationService);
}
@@ -64,12 +59,11 @@ function applyOverrides(experiments: IExperiments, configurationService: IConfig
function splitExperimentsRandomness(storageService: IStorageService): IExperiments {
const random1 = getExperimentsRandomness(storageService);
const [random2, ripgrepQuickSearch] = splitRandom(random1);
- const [/* random3 */, deployToAzureQuickLink] = splitRandom(random2);
+ const [/* random3 */, /* deployToAzureQuickLink */] = splitRandom(random2);
// const [random4, /* mergeQuickLinks */] = splitRandom(random3);
// const [random5, /* enableWelcomePage */] = splitRandom(random4);
return {
ripgrepQuickSearch,
- deployToAzureQuickLink
};
}
diff --git a/src/vs/platform/theme/common/colorExtensionPoint.ts b/src/vs/platform/theme/common/colorExtensionPoint.ts
index f42ffb926a3..51a47fdb4bb 100644
--- a/src/vs/platform/theme/common/colorExtensionPoint.ts
+++ b/src/vs/platform/theme/common/colorExtensionPoint.ts
@@ -93,7 +93,7 @@ export class ColorExtensionPoint {
extensionValue.forEach(extension => {
if (typeof extension.id !== 'string' || extension.id.length === 0) {
- collector.error(nls.localize('invalid.id', "'configuration.colors.id' must be defined an can not be empty"));
+ collector.error(nls.localize('invalid.id', "'configuration.colors.id' must be defined and can not be empty"));
return;
}
if (!extension.id.match(colorIdPattern)) {
@@ -101,7 +101,7 @@ export class ColorExtensionPoint {
return;
}
if (typeof extension.description !== 'string' || extension.id.length === 0) {
- collector.error(nls.localize('invalid.description', "'configuration.colors.description' must be defined an can not be empty"));
+ collector.error(nls.localize('invalid.description', "'configuration.colors.description' must be defined and can not be empty"));
return;
}
let defaults = extension.defaults;
diff --git a/src/vs/platform/workspace/common/workspace.ts b/src/vs/platform/workspace/common/workspace.ts
index 4eeb0b8fb83..38f755fc658 100644
--- a/src/vs/platform/workspace/common/workspace.ts
+++ b/src/vs/platform/workspace/common/workspace.ts
@@ -6,59 +6,58 @@
import URI from 'vs/base/common/uri';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
-import * as paths from 'vs/base/common/paths';
import { TrieMap } from 'vs/base/common/map';
import Event from 'vs/base/common/event';
import { isLinux } from 'vs/base/common/platform';
import { distinct } from 'vs/base/common/arrays';
+import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
export const IWorkspaceContextService = createDecorator('contextService');
+export enum WorkbenchState {
+ EMPTY = 1,
+ FOLDER,
+ WORKSPACE
+}
+
export interface IWorkspaceContextService {
_serviceBrand: any;
- /**
- * Returns if the application was opened with a workspace or not.
- */
- hasWorkspace(): boolean;
-
- /**
- * Returns if the application was opened with a folder.
- */
- hasFolderWorkspace(): boolean;
-
- /**
- * Returns if the application was opened with a workspace that can have one or more folders.
- */
- hasMultiFolderWorkspace(): boolean;
-
- /**
- * Provides access to the workspace object the platform is running with. This may be null if the workbench was opened
- * without workspace (empty);
- */
- getLegacyWorkspace(): ILegacyWorkspace;
-
/**
* Provides access to the workspace object the platform is running with. This may be null if the workbench was opened
* without workspace (empty);
*/
getWorkspace(): IWorkspace;
+ /**
+ * Return the state of the workbench.
+ *
+ * WorkbenchState.EMPTY - if the workbench was opened with empty window or file
+ * WorkbenchState.FOLDER - if the workbench was opened with a folder
+ * WorkbenchState.WORKSPACE - if the workbench was opened with a workspace
+ */
+ getWorkbenchState(): WorkbenchState;
+
/**
* An event which fires on workspace name changes.
*/
onDidChangeWorkspaceName: Event;
/**
- * An event which fires on workspace roots change.
+ * An event which fires on workspace folders change.
*/
- onDidChangeWorkspaceRoots: Event;
+ onDidChangeWorkspaceFolders: Event;
/**
- * Returns the root for the given resource from the workspace.
+ * Returns the folder for the given resource from the workspace.
* Can be null if there is no workspace or the resource is not inside the workspace.
*/
- getRoot(resource: URI): URI;
+ getWorkspaceFolder(resource: URI): URI;
+
+ /**
+ * Return `true` if the current workspace has the given identifier otherwise `false`.
+ */
+ isCurrentWorkspace(workspaceIdentifier: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): boolean;
/**
* Returns if the provided resource is inside the workspace or not.
@@ -71,20 +70,6 @@ export interface IWorkspaceContextService {
toResource: (workspaceRelativePath: string) => URI;
}
-export interface ILegacyWorkspace {
-
- /**
- * the full uri of the workspace. this is a file:// URL to the location
- * of the workspace on disk.
- */
- resource: URI;
-
- /**
- * creation time of the workspace folder if known
- */
- ctime?: number;
-}
-
export interface IWorkspace {
/**
@@ -98,9 +83,9 @@ export interface IWorkspace {
readonly name: string;
/**
- * Roots in the workspace.
+ * Folders in the workspace.
*/
- readonly roots: URI[];
+ readonly folders: URI[];
/**
* the location of the workspace configuration
@@ -108,59 +93,32 @@ export interface IWorkspace {
readonly configuration?: URI;
}
-export class LegacyWorkspace implements ILegacyWorkspace {
- private _name: string;
-
- constructor(private _resource: URI, private _ctime?: number) {
- this._name = paths.basename(this._resource.fsPath) || this._resource.fsPath;
- }
-
- public get resource(): URI {
- return this._resource;
- }
-
- public get name(): string {
- return this._name;
- }
-
- public get ctime(): number {
- return this._ctime;
- }
-
- public toResource(workspaceRelativePath: string, root?: URI): URI {
- if (typeof workspaceRelativePath === 'string') {
- return URI.file(paths.join(root ? root.fsPath : this._resource.fsPath, workspaceRelativePath));
- }
-
- return null;
- }
-}
-
export class Workspace implements IWorkspace {
- private _rootsMap: TrieMap = new TrieMap();
- private _roots: URI[];
+ private _foldersMap: TrieMap = new TrieMap();
+ private _folders: URI[];
constructor(
public readonly id: string,
private _name: string,
- roots: URI[],
- private _configuration: URI = null
+ folders: URI[],
+ private _configuration: URI = null,
+ public readonly ctime?: number
) {
- this.roots = roots;
+ this.folders = folders;
}
- private ensureUnique(roots: URI[]): URI[] {
- return distinct(roots, root => isLinux ? root.fsPath : root.fsPath.toLowerCase());
+ private ensureUnique(folders: URI[]): URI[] {
+ return distinct(folders, folder => isLinux ? folder.fsPath : folder.fsPath.toLowerCase());
}
- public get roots(): URI[] {
- return this._roots;
+ public get folders(): URI[] {
+ return this._folders;
}
- public set roots(roots: URI[]) {
- this._roots = this.ensureUnique(roots);
- this.updateRootsMap();
+ public set folders(folders: URI[]) {
+ this._folders = this.ensureUnique(folders);
+ this.updateFoldersMap();
}
public get name(): string {
@@ -179,22 +137,22 @@ export class Workspace implements IWorkspace {
this._configuration = configuration;
}
- public getRoot(resource: URI): URI {
+ public getFolder(resource: URI): URI {
if (!resource) {
return null;
}
- return this._rootsMap.findSubstr(resource.fsPath);
+ return this._foldersMap.findSubstr(resource.fsPath);
}
- private updateRootsMap(): void {
- this._rootsMap = new TrieMap();
- for (const root of this.roots) {
- this._rootsMap.insert(root.fsPath, root);
+ private updateFoldersMap(): void {
+ this._foldersMap = new TrieMap();
+ for (const folder of this.folders) {
+ this._foldersMap.insert(folder.fsPath, folder);
}
}
public toJSON(): IWorkspace {
- return { id: this.id, roots: this.roots, name: this.name };
+ return { id: this.id, folders: this.folders, name: this.name };
}
}
diff --git a/src/vs/platform/workspace/test/common/workspace.test.ts b/src/vs/platform/workspace/test/common/workspace.test.ts
index 1f296428317..dcfdff48e38 100644
--- a/src/vs/platform/workspace/test/common/workspace.test.ts
+++ b/src/vs/platform/workspace/test/common/workspace.test.ts
@@ -17,6 +17,6 @@ suite('Workspace', () => {
let roots = [URI.file('/some/path'), URI.file('/some/path')];
let ws = new Workspace('id', 'name', roots, URI.file('/config'));
- assert.equal(ws.roots.length, 1);
+ assert.equal(ws.folders.length, 1);
});
});
\ No newline at end of file
diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts
index 5f4723974a6..c825bfef95b 100644
--- a/src/vs/vscode.d.ts
+++ b/src/vs/vscode.d.ts
@@ -773,7 +773,7 @@ declare module 'vscode' {
export interface ThemableDecorationRenderOptions {
/**
* Background color of the decoration. Use rgba() and define transparent background colors to play well with other decorations.
- * Alternativly a color from the color registry an be [referenced](#ColorIdentifier).
+ * Alternatively a color from the color registry can be [referenced](#ThemeColor).
*/
backgroundColor?: string | ThemeColor;
@@ -3869,6 +3869,21 @@ declare module 'vscode' {
options?: ShellExecutionOptions;
}
+ /**
+ * The scope of a task.
+ */
+ export enum TaskScope {
+ /**
+ * The task is a global task
+ */
+ Global = 1,
+
+ /**
+ * The task is a workspace task
+ */
+ Workspace = 2
+ }
+
/**
* A task to execute
*/
@@ -3877,8 +3892,10 @@ declare module 'vscode' {
/**
* Creates a new task.
*
+ * @deprecated: Use the new constructors that allow specifying a target for the task.
+ *
* @param definition The task definition as defined in the taskDefinitions extension point.
- * @param name The task's name. Is presented in the user interface.
+ * @param scope The task's name. Is presented in the user interface.
* @param source The task's source (e.g. 'gulp', 'npm', ...). Is presented in the user interface.
* @param execution The process or shell execution.
* @param problemMatchers the names of problem matchers to use, like '$tsc'
@@ -3887,11 +3904,31 @@ declare module 'vscode' {
*/
constructor(taskDefinition: TaskDefinition, name: string, source: string, execution?: ProcessExecution | ShellExecution, problemMatchers?: string | string[]);
+ /**
+ * Creates a new task.
+ *
+ * @param definition The task definition as defined in the taskDefinitions extension point.
+ * @param scope Specifies the task's scope. It is either a global or a workspace task or a task for a specific workspace folder.
+ * @param workspaceFolder The workspace folder this task is created for.
+ * @param name The task's name. Is presented in the user interface.
+ * @param source The task's source (e.g. 'gulp', 'npm', ...). Is presented in the user interface.
+ * @param execution The process or shell execution.
+ * @param problemMatchers the names of problem matchers to use, like '$tsc'
+ * or '$eslint'. Problem matchers can be contributed by an extension using
+ * the `problemMatchers` extension point.
+ */
+ constructor(taskDefinition: TaskDefinition, target: TaskScope.Global | TaskScope.Workspace | WorkspaceFolder, name: string, source: string, execution?: ProcessExecution | ShellExecution, problemMatchers?: string | string[]);
+
/**
* The task's definition.
*/
definition: TaskDefinition;
+ /**
+ * The task's scope.
+ */
+ scope?: TaskScope.Global | TaskScope.Workspace | WorkspaceFolder;
+
/**
* The task's name
*/
@@ -4947,7 +4984,7 @@ declare module 'vscode' {
/**
* An event that is emitted when a [text document](#TextDocument) is changed. This usually happens
* when the [contents](#TextDocument.getText) changes but also when other things like the
- * [dirty](TextDocument#isDirty)-state changes.
+ * [dirty](#TextDocument.isDirty)-state changes.
*/
export const onDidChangeTextDocument: Event;
diff --git a/src/vs/workbench/api/electron-browser/mainThreadConfiguration.ts b/src/vs/workbench/api/electron-browser/mainThreadConfiguration.ts
index 36b5e975ef9..71f54113cfd 100644
--- a/src/vs/workbench/api/electron-browser/mainThreadConfiguration.ts
+++ b/src/vs/workbench/api/electron-browser/mainThreadConfiguration.ts
@@ -9,7 +9,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { IDisposable } from 'vs/base/common/lifecycle';
import { Registry } from 'vs/platform/registry/common/platform';
import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
import { IConfigurationEditingService, ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing';
import { MainThreadConfigurationShape, MainContext, ExtHostContext, IExtHostContext } from '../node/extHost.protocol';
@@ -51,7 +51,7 @@ export class MainThreadConfiguration implements MainThreadConfigurationShape {
}
private deriveConfigurationTarget(key: string, resource: URI): ConfigurationTarget {
- if (resource && this._workspaceContextService.hasMultiFolderWorkspace()) {
+ if (resource && this._workspaceContextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
const configurationProperties = Registry.as(ConfigurationExtensions.Configuration).getConfigurationProperties();
if (configurationProperties[key] && configurationProperties[key].scope === ConfigurationScope.RESOURCE) {
return ConfigurationTarget.FOLDER;
diff --git a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts
index ad58576214d..fd9eef3cbef 100644
--- a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts
+++ b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts
@@ -7,7 +7,7 @@
import { isPromiseCanceledError } from 'vs/base/common/errors';
import URI from 'vs/base/common/uri';
import { ISearchService, QueryType, ISearchQuery, ISearchProgressItem, ISearchComplete } from 'vs/platform/search/common/search';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { ICommonCodeEditor, isCommonCodeEditor } from 'vs/editor/common/editorCommon';
@@ -20,6 +20,7 @@ import { IDisposable, dispose, combinedDisposable } from 'vs/base/common/lifecyc
import { RemoteFileService } from 'vs/workbench/services/files/electron-browser/remoteFileService';
import { Emitter } from 'vs/base/common/event';
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
+import { IExperimentService } from 'vs/platform/telemetry/common/experiments';
@extHostNamedCustomer(MainContext.MainThreadWorkspace)
export class MainThreadWorkspace implements MainThreadWorkspaceShape {
@@ -35,10 +36,11 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape {
@ITextFileService private readonly _textFileService: ITextFileService,
@IWorkbenchEditorService private readonly _editorService: IWorkbenchEditorService,
@ITextModelService private readonly _textModelResolverService: ITextModelService,
+ @IExperimentService private experimentService: IExperimentService,
@IFileService private readonly _fileService: IFileService
) {
this._proxy = extHostContext.get(ExtHostContext.ExtHostWorkspace);
- this._contextService.onDidChangeWorkspaceRoots(this._onDidChangeWorkspace, this, this._toDispose);
+ this._contextService.onDidChangeWorkspaceFolders(this._onDidChangeWorkspace, this, this._toDispose);
}
dispose(): void {
@@ -53,23 +55,23 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape {
// --- workspace ---
private _onDidChangeWorkspace(): void {
- this._proxy.$acceptWorkspaceData(this._contextService.getWorkspace());
+ this._proxy.$acceptWorkspaceData(this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? null : this._contextService.getWorkspace());
}
// --- search ---
$startSearch(include: string, exclude: string, maxResults: number, requestId: number): Thenable {
const workspace = this._contextService.getWorkspace();
- if (!workspace) {
+ if (!workspace.folders.length) {
return undefined;
}
-
const query: ISearchQuery = {
- folderQueries: workspace.roots.map(root => ({ folder: root })),
+ folderQueries: workspace.folders.map(root => ({ folder: root })),
type: QueryType.File,
maxResults,
includePattern: { [include]: true },
excludePattern: { [exclude]: true },
+ useRipgrep: this.experimentService.getExperiments().ripgrepQuickSearch
};
this._searchService.extendQuery(query);
diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts
index efe5e932d5c..c678975f35e 100644
--- a/src/vs/workbench/api/node/extHost.api.impl.ts
+++ b/src/vs/workbench/api/node/extHost.api.impl.ts
@@ -97,7 +97,7 @@ export function createApiFactory(
const extHostQuickOpen = threadService.set(ExtHostContext.ExtHostQuickOpen, new ExtHostQuickOpen(threadService));
const extHostTerminalService = threadService.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(threadService));
const extHostSCM = threadService.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(threadService, extHostCommands));
- const extHostTask = threadService.set(ExtHostContext.ExtHostTask, new ExtHostTask(threadService));
+ const extHostTask = threadService.set(ExtHostContext.ExtHostTask, new ExtHostTask(threadService, extHostWorkspace));
const extHostCredentials = threadService.set(ExtHostContext.ExtHostCredentials, new ExtHostCredentials(threadService));
const extHostWindow = threadService.set(ExtHostContext.ExtHostWindow, new ExtHostWindow(threadService));
threadService.set(ExtHostContext.ExtHostExtensionService, extensionService);
@@ -599,6 +599,7 @@ export function createApiFactory(
TaskGroup: extHostTypes.TaskGroup,
ProcessExecution: extHostTypes.ProcessExecution,
ShellExecution: extHostTypes.ShellExecution,
+ TaskScope: extHostTypes.TaskScope,
Task: extHostTypes.Task,
ConfigurationTarget: extHostTypes.ConfigurationTarget
};
diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts
index 7245c7d80bd..04275bdc50a 100644
--- a/src/vs/workbench/api/node/extHost.protocol.ts
+++ b/src/vs/workbench/api/node/extHost.protocol.ts
@@ -64,7 +64,7 @@ export interface IEnvironment {
export interface IWorkspaceData {
id: string;
name: string;
- roots: URI[];
+ folders: URI[];
}
export interface IInitData {
diff --git a/src/vs/workbench/api/node/extHostFileSystemEventService.ts b/src/vs/workbench/api/node/extHostFileSystemEventService.ts
index 822298414c3..6038446ffc4 100644
--- a/src/vs/workbench/api/node/extHostFileSystemEventService.ts
+++ b/src/vs/workbench/api/node/extHostFileSystemEventService.ts
@@ -6,7 +6,7 @@
import Event, { Emitter } from 'vs/base/common/event';
import { Disposable } from './extHostTypes';
-import { match } from 'vs/base/common/glob';
+import { parse } from 'vs/base/common/glob';
import { Uri, FileSystemWatcher as _FileSystemWatcher } from 'vscode';
import { FileSystemEvents, ExtHostFileSystemEventServiceShape } from './extHost.protocol';
@@ -43,24 +43,26 @@ class FileSystemWatcher implements _FileSystemWatcher {
this._config += 0b100;
}
+ const parsedPattern = parse(globPattern);
+
let subscription = dispatcher(events => {
if (!ignoreCreateEvents) {
for (let created of events.created) {
- if (match(globPattern, created.fsPath)) {
+ if (parsedPattern(created.fsPath)) {
this._onDidCreate.fire(created);
}
}
}
if (!ignoreChangeEvents) {
for (let changed of events.changed) {
- if (match(globPattern, changed.fsPath)) {
+ if (parsedPattern(changed.fsPath)) {
this._onDidChange.fire(changed);
}
}
}
if (!ignoreDeleteEvents) {
for (let deleted of events.deleted) {
- if (match(globPattern, deleted.fsPath)) {
+ if (parsedPattern(deleted.fsPath)) {
this._onDidDelete.fire(deleted);
}
}
diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts
index a174c82f1b7..b644dfb2424 100644
--- a/src/vs/workbench/api/node/extHostTask.ts
+++ b/src/vs/workbench/api/node/extHostTask.ts
@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
+import URI from 'vs/base/common/uri';
import * as nls from 'vs/nls';
import { TPromise } from 'vs/base/common/winjs.base';
import * as Objects from 'vs/base/common/objects';
@@ -15,6 +16,7 @@ import * as TaskSystem from 'vs/workbench/parts/tasks/common/tasks';
import { MainContext, MainThreadTaskShape, ExtHostTaskShape, IMainContext } from 'vs/workbench/api/node/extHost.protocol';
import * as types from 'vs/workbench/api/node/extHostTypes';
+import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace';
import * as vscode from 'vscode';
interface StringMap {
@@ -295,13 +297,13 @@ namespace ShellConfiguration {
namespace Tasks {
- export function from(tasks: vscode.Task[], extension: IExtensionDescription): TaskSystem.Task[] {
+ export function from(tasks: vscode.Task[], rootFolder: vscode.WorkspaceFolder, extension: IExtensionDescription): TaskSystem.Task[] {
if (tasks === void 0 || tasks === null) {
return [];
}
let result: TaskSystem.Task[] = [];
for (let task of tasks) {
- let converted = fromSingle(task, extension);
+ let converted = fromSingle(task, rootFolder, extension);
if (converted) {
result.push(converted);
}
@@ -309,7 +311,7 @@ namespace Tasks {
return result;
}
- function fromSingle(task: vscode.Task, extension: IExtensionDescription): TaskSystem.ContributedTask {
+ function fromSingle(task: vscode.Task, rootFolder: vscode.WorkspaceFolder, extension: IExtensionDescription): TaskSystem.ContributedTask {
if (typeof task.name !== 'string') {
return undefined;
}
@@ -326,10 +328,27 @@ namespace Tasks {
return undefined;
}
command.presentation = PresentationOptions.from(task.presentationOptions);
- let source = {
+
+ let taskScope: types.TaskScope.Global | types.TaskScope.Workspace | vscode.WorkspaceFolder | undefined = task.scope;
+ let workspaceFolder: vscode.WorkspaceFolder | undefined;
+ let scope: TaskSystem.TaskScope;
+ // For backwards compatibility
+ if (taskScope === void 0) {
+ scope = TaskSystem.TaskScope.Folder;
+ workspaceFolder = rootFolder;
+ } else if (taskScope === types.TaskScope.Global) {
+ scope = TaskSystem.TaskScope.Global;
+ } else if (taskScope === types.TaskScope.Workspace) {
+ scope = TaskSystem.TaskScope.Workspace;
+ } else {
+ workspaceFolder = taskScope;
+ }
+ let source: TaskSystem.ExtensionTaskSource = {
kind: TaskSystem.TaskSourceKind.Extension,
label: typeof task.source === 'string' ? task.source : extension.name,
- extension: extension.id
+ extension: extension.id,
+ scope: scope,
+ workspaceFolder: workspaceFolder ? { uri: workspaceFolder.uri as URI } : undefined
};
let label = nls.localize('task.label', '{0}: {1}', source.label, task.name);
let key = (task as types.Task).definitionKey;
@@ -398,11 +417,13 @@ interface HandlerData {
export class ExtHostTask implements ExtHostTaskShape {
private _proxy: MainThreadTaskShape;
+ private _extHostWorkspace: ExtHostWorkspace;
private _handleCounter: number;
private _handlers: Map;
- constructor(mainContext: IMainContext) {
+ constructor(mainContext: IMainContext, extHostWorkspace: ExtHostWorkspace) {
this._proxy = mainContext.get(MainContext.MainThreadTask);
+ this._extHostWorkspace = extHostWorkspace;
this._handleCounter = 0;
this._handlers = new Map();
};
@@ -426,8 +447,9 @@ export class ExtHostTask implements ExtHostTaskShape {
return TPromise.wrapError(new Error('no handler found'));
}
return asWinJsPromise(token => handler.provider.provideTasks(token)).then(value => {
+ let workspaceFolders = this._extHostWorkspace.getWorkspaceFolders();
return {
- tasks: Tasks.from(value, handler.extension),
+ tasks: Tasks.from(value, workspaceFolders && workspaceFolders.length > 0 ? workspaceFolders[0] : undefined, handler.extension),
extension: handler.extension
};
});
diff --git a/src/vs/workbench/api/node/extHostTypes.ts b/src/vs/workbench/api/node/extHostTypes.ts
index e1b60f1ba51..a9b213648b8 100644
--- a/src/vs/workbench/api/node/extHostTypes.ts
+++ b/src/vs/workbench/api/node/extHostTypes.ts
@@ -1214,10 +1214,16 @@ export class ShellExecution implements vscode.ShellExecution {
}
}
+export enum TaskScope {
+ Global = 1,
+ Workspace = 2
+}
+
export class Task implements vscode.Task {
private _definition: vscode.TaskDefinition;
private _definitionKey: string;
+ private _scope: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder;
private _name: string;
private _execution: ProcessExecution | ShellExecution;
private _problemMatchers: string[];
@@ -1227,11 +1233,29 @@ export class Task implements vscode.Task {
private _group: TaskGroup;
private _presentationOptions: vscode.TaskPresentationOptions;
- constructor(definition: vscode.TaskDefinition, name: string, source: string, execution?: ProcessExecution | ShellExecution, problemMatchers?: string | string[]) {
+ constructor(definition: vscode.TaskDefinition, name: string, source: string, execution?: ProcessExecution | ShellExecution, problemMatchers?: string | string[]);
+ constructor(definition: vscode.TaskDefinition, scope: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder, name: string, source: string, execution?: ProcessExecution | ShellExecution, problemMatchers?: string | string[]);
+ constructor(definition: vscode.TaskDefinition, arg2: string | (vscode.TaskScope.Global | vscode.TaskScope.Workspace) | vscode.WorkspaceFolder, arg3: any, arg4?: any, arg5?: any, arg6?: any) {
this.definition = definition;
- this.name = name;
- this.source = source;
- this.execution = execution;
+ let problemMatchers: string | string[];
+ if (typeof arg2 === 'string') {
+ this.name = arg2;
+ this.source = arg3;
+ this.execution = arg4;
+ problemMatchers = arg5;
+ } else if (arg2 === TaskScope.Global || arg2 === TaskScope.Workspace) {
+ this.target = arg2;
+ this.name = arg3;
+ this.source = arg4;
+ this.execution = arg5;
+ problemMatchers = arg6;
+ } else {
+ this.target = arg2;
+ this.name = arg3;
+ this.source = arg4;
+ this.execution = arg5;
+ problemMatchers = arg6;
+ }
if (typeof problemMatchers === 'string') {
this._problemMatchers = [problemMatchers];
this._hasDefinedMatchers = true;
@@ -1266,6 +1290,14 @@ export class Task implements vscode.Task {
return this._definitionKey;
}
+ get scope(): vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder {
+ return this._scope;
+ }
+
+ set target(value: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder) {
+ this._scope = value;
+ }
+
get name(): string {
return this._name;
}
diff --git a/src/vs/workbench/api/node/extHostWorkspace.ts b/src/vs/workbench/api/node/extHostWorkspace.ts
index ba50508d0ef..219bfac0312 100644
--- a/src/vs/workbench/api/node/extHostWorkspace.ts
+++ b/src/vs/workbench/api/node/extHostWorkspace.ts
@@ -32,10 +32,10 @@ class Workspace2 extends Workspace {
private readonly _structure = new TrieMap(s => s.split('/'));
private constructor(data: IWorkspaceData) {
- super(data.id, data.name, data.roots);
+ super(data.id, data.name, data.folders);
// setup the workspace folder data structure
- this.roots.forEach((uri, index) => {
+ this.folders.forEach((uri, index) => {
const folder = {
name: basename(uri.fsPath),
uri,
@@ -46,7 +46,7 @@ class Workspace2 extends Workspace {
});
}
- get folders(): vscode.WorkspaceFolder[] {
+ get workspaceFolders(): vscode.WorkspaceFolder[] {
return this._folder.slice(0);
}
@@ -92,7 +92,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
if (!this._workspace) {
return undefined;
} else {
- return this._workspace.folders.slice(0);
+ return this._workspace.workspaceFolders.slice(0);
}
}
@@ -110,11 +110,11 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
if (!this._workspace) {
return undefined;
}
- const { roots } = this._workspace;
- if (roots.length === 0) {
+ const { folders } = this._workspace;
+ if (folders.length === 0) {
return undefined;
}
- return roots[0].fsPath;
+ return folders[0].fsPath;
}
getRelativePath(pathOrUri: string | vscode.Uri, includeWorkspace?: boolean): string {
@@ -140,7 +140,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
}
if (typeof includeWorkspace === 'undefined') {
- includeWorkspace = this.workspace.roots.length > 1;
+ includeWorkspace = this.workspace.folders.length > 1;
}
let result = relative(folder.uri.fsPath, path);
@@ -155,10 +155,10 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape {
// keep old workspace folder, build new workspace, and
// capture new workspace folders. Compute delta between
// them send that as event
- const oldRoots = this._workspace ? this._workspace.folders.sort(ExtHostWorkspace._compareWorkspaceFolder) : [];
+ const oldRoots = this._workspace ? this._workspace.workspaceFolders.sort(ExtHostWorkspace._compareWorkspaceFolder) : [];
this._workspace = Workspace2.fromData(data);
- const newRoots = this._workspace ? this._workspace.folders.sort(ExtHostWorkspace._compareWorkspaceFolder) : [];
+ const newRoots = this._workspace ? this._workspace.workspaceFolders.sort(ExtHostWorkspace._compareWorkspaceFolder) : [];
const { added, removed } = delta(oldRoots, newRoots, ExtHostWorkspace._compareWorkspaceFolder);
this._onDidChangeWorkspace.fire(Object.freeze({
diff --git a/src/vs/workbench/browser/actions/workspaceActions.ts b/src/vs/workbench/browser/actions/workspaceActions.ts
index d67da02d0a5..525931079e0 100644
--- a/src/vs/workbench/browser/actions/workspaceActions.ts
+++ b/src/vs/workbench/browser/actions/workspaceActions.ts
@@ -11,7 +11,7 @@ import nls = require('vs/nls');
import { distinct } from 'vs/base/common/arrays';
import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows';
import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
import URI from 'vs/base/common/uri';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
@@ -74,10 +74,10 @@ export abstract class BaseWorkspacesAction extends Action {
}
protected pickFolders(buttonLabel: string, title: string): string[] {
- const workspace = this.contextService.getWorkspace();
let defaultPath: string;
- if (workspace && workspace.roots.length > 0) {
- defaultPath = dirname(workspace.roots[0].fsPath); // pick the parent of the first root by default
+ const workspace = this.contextService.getWorkspace();
+ if (workspace.folders.length > 0) {
+ defaultPath = dirname(workspace.folders[0].fsPath); // pick the parent of the first root by default
}
return this.windowService.showOpenDialog({
@@ -108,22 +108,16 @@ export class AddRootFolderAction extends BaseWorkspacesAction {
}
public run(): TPromise {
- if (!this.contextService.hasWorkspace()) {
- return this.instantiationService.createInstance(NewWorkspaceAction, NewWorkspaceAction.ID, NewWorkspaceAction.LABEL, []).run();
+ if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
+ const folders = super.pickFolders(mnemonicButtonLabel(nls.localize({ key: 'add', comment: ['&& denotes a mnemonic'] }, "&&Add")), nls.localize('addFolderToWorkspaceTitle', "Add Folder to Workspace"));
+ if (!folders || !folders.length) {
+ return TPromise.as(null);
+ }
+ return this.workspaceEditingService.addFolders(folders.map(folder => URI.file(folder))).then(() => {
+ return this.viewletService.openViewlet(this.viewletService.getDefaultViewletId(), true);
+ });
}
-
- if (this.contextService.hasFolderWorkspace()) {
- return this.instantiationService.createInstance(NewWorkspaceAction, NewWorkspaceAction.ID, NewWorkspaceAction.LABEL, this.contextService.getWorkspace().roots).run();
- }
-
- const folders = super.pickFolders(mnemonicButtonLabel(nls.localize({ key: 'add', comment: ['&& denotes a mnemonic'] }, "&&Add")), nls.localize('addFolderToWorkspaceTitle', "Add Folder to Workspace"));
- if (!folders || !folders.length) {
- return TPromise.as(null);
- }
-
- return this.workspaceEditingService.addRoots(folders.map(folder => URI.file(folder))).then(() => {
- return this.viewletService.openViewlet(this.viewletService.getDefaultViewletId(), true);
- });
+ return this.instantiationService.createInstance(NewWorkspaceAction, NewWorkspaceAction.ID, NewWorkspaceAction.LABEL, this.contextService.getWorkspace().folders).run();
}
}
@@ -176,7 +170,7 @@ export class RemoveRootFolderAction extends Action {
}
public run(): TPromise {
- return this.workspaceEditingService.removeRoots([this.rootUri]);
+ return this.workspaceEditingService.removeFolders([this.rootUri]);
}
}
@@ -199,42 +193,35 @@ export class SaveWorkspaceAsAction extends BaseWorkspacesAction {
}
public run(): TPromise {
- if (!this.contextService.hasWorkspace()) {
+ const workspaceState = this.contextService.getWorkbenchState();
+ if (workspaceState === WorkbenchState.EMPTY) {
this.messageService.show(Severity.Info, nls.localize('saveEmptyWorkspaceNotSupported', "Please open a workspace first to save."));
return TPromise.as(null);
}
const configPath = this.getNewWorkspaceConfigPath();
if (configPath) {
- if (this.contextService.hasFolderWorkspace()) {
- return this.saveFolderWorkspace(configPath);
- }
+ switch (workspaceState) {
- if (this.contextService.hasMultiFolderWorkspace()) {
- return this.saveWorkspace(configPath);
+ case WorkbenchState.FOLDER:
+ const workspaceFolders = this.contextService.getWorkspace().folders.map(root => root.fsPath);
+ return this.windowService.createAndOpenWorkspace(workspaceFolders, configPath);
+
+ case WorkbenchState.WORKSPACE:
+ return this.windowService.saveAndOpenWorkspace(configPath);
}
}
return TPromise.as(null);
}
- private saveWorkspace(configPath: string): TPromise {
- return this.windowService.saveAndOpenWorkspace(configPath);
- }
-
- private saveFolderWorkspace(configPath: string): TPromise {
- const workspaceFolders = this.contextService.getWorkspace().roots.map(root => root.fsPath);
-
- return this.windowService.createAndOpenWorkspace(workspaceFolders, configPath);
- }
-
private getNewWorkspaceConfigPath(): string {
const workspace = this.contextService.getWorkspace();
let defaultPath: string;
- if (this.contextService.hasMultiFolderWorkspace() && !this.isUntitledWorkspace(workspace.configuration.fsPath)) {
+ if (workspace.configuration && !this.isUntitledWorkspace(workspace.configuration.fsPath)) {
defaultPath = workspace.configuration.fsPath;
- } else if (workspace && workspace.roots.length > 0) {
- defaultPath = dirname(workspace.roots[0].fsPath); // pick the parent of the first root by default
+ } else if (workspace.folders.length > 0) {
+ defaultPath = dirname(workspace.folders[0].fsPath); // pick the parent of the first root by default
}
return this.windowService.showSaveDialog({
@@ -281,7 +268,7 @@ export class OpenWorkspaceConfigFileAction extends Action {
) {
super(id, label);
- this.enabled = this.workspaceContextService.hasMultiFolderWorkspace();
+ this.enabled = !!this.workspaceContextService.getWorkspace().configuration;
}
public run(): TPromise {
diff --git a/src/vs/workbench/browser/labels.ts b/src/vs/workbench/browser/labels.ts
index 655bec21217..66922084d46 100644
--- a/src/vs/workbench/browser/labels.ts
+++ b/src/vs/workbench/browser/labels.ts
@@ -12,7 +12,7 @@ import { IExtensionService } from 'vs/platform/extensions/common/extensions';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IEditorInput } from 'vs/platform/editor/common/editor';
import { toResource } from 'vs/workbench/common/editor';
-import { getPathLabel, IRootProvider } from 'vs/base/common/labels';
+import { getPathLabel, IWorkspaceFolderProvider } from 'vs/base/common/labels';
import { PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
@@ -211,9 +211,9 @@ export class FileLabel extends ResourceLabel {
public setFile(resource: uri, options?: IFileLabelOptions): void {
const hidePath = (options && options.hidePath) || (resource.scheme === Schemas.untitled && !this.untitledEditorService.hasAssociatedFilePath(resource));
- const rootProvider: IRootProvider = (options && options.root) ? {
- getRoot(): uri { return options.root; },
- getWorkspace(): { roots: uri[]; } { return { roots: [options.root] }; },
+ const rootProvider: IWorkspaceFolderProvider = (options && options.root) ? {
+ getWorkspaceFolder(): uri { return options.root; },
+ getWorkspace(): { folders: uri[]; } { return { folders: [options.root] }; },
} : this.contextService;
this.setLabel({
diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts
index ab33817c228..10d32871c4b 100644
--- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts
+++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts
@@ -111,6 +111,7 @@ export class QuickOpenController extends Component implements IQuickOpenService
@IInstantiationService private instantiationService: IInstantiationService,
@IPartService private partService: IPartService,
@IListService private listService: IListService,
+ @IEnvironmentService private environmentService: IEnvironmentService,
@IThemeService themeService: IThemeService
) {
super(QuickOpenController.ID, themeService);
@@ -138,7 +139,11 @@ export class QuickOpenController extends Component implements IQuickOpenService
}
private updateConfiguration(settings: IWorkbenchQuickOpenConfiguration): void {
- this.closeOnFocusLost = settings.workbench && settings.workbench.quickOpen && settings.workbench.quickOpen.closeOnFocusLost;
+ if (this.environmentService.args['sticky-quickopen']) {
+ this.closeOnFocusLost = false;
+ } else {
+ this.closeOnFocusLost = settings.workbench && settings.workbench.quickOpen && settings.workbench.quickOpen.closeOnFocusLost;
+ }
}
public get onShow(): Event {
diff --git a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts
index 8131a18ab78..a83c9847408 100644
--- a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts
+++ b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts
@@ -28,7 +28,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
import { Action } from 'vs/base/common/actions';
import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
import { STATUS_BAR_BACKGROUND, STATUS_BAR_FOREGROUND, STATUS_BAR_NO_FOLDER_BACKGROUND, STATUS_BAR_ITEM_HOVER_BACKGROUND, STATUS_BAR_ITEM_ACTIVE_BACKGROUND, STATUS_BAR_PROMINENT_ITEM_BACKGROUND, STATUS_BAR_PROMINENT_ITEM_HOVER_BACKGROUND, STATUS_BAR_BORDER, STATUS_BAR_NO_FOLDER_FOREGROUND, STATUS_BAR_NO_FOLDER_BORDER } from 'vs/workbench/common/theme';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { contrastBorder } from 'vs/platform/theme/common/colorRegistry';
import { isThemeColor } from 'vs/editor/common/editorCommon';
import { Color } from 'vs/base/common/color';
@@ -55,7 +55,7 @@ export class StatusbarPart extends Part implements IStatusbarService {
}
private registerListeners(): void {
- this.toUnbind.push(this.contextService.onDidChangeWorkspaceRoots(() => this.updateStyles()));
+ this.toUnbind.push(this.contextService.onDidChangeWorkspaceFolders(() => this.updateStyles()));
}
public addEntry(entry: IStatusbarEntry, alignment: StatusbarAlignment, priority: number = 0): IDisposable {
@@ -141,10 +141,10 @@ export class StatusbarPart extends Part implements IStatusbarService {
const container = this.getContainer();
- container.style('color', this.getColor(this.contextService.hasWorkspace() ? STATUS_BAR_FOREGROUND : STATUS_BAR_NO_FOLDER_FOREGROUND));
- container.style('background-color', this.getColor(this.contextService.hasWorkspace() ? STATUS_BAR_BACKGROUND : STATUS_BAR_NO_FOLDER_BACKGROUND));
+ container.style('color', this.getColor(this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? STATUS_BAR_FOREGROUND : STATUS_BAR_NO_FOLDER_FOREGROUND));
+ container.style('background-color', this.getColor(this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? STATUS_BAR_BACKGROUND : STATUS_BAR_NO_FOLDER_BACKGROUND));
- const borderColor = this.getColor(this.contextService.hasWorkspace() ? STATUS_BAR_BORDER : STATUS_BAR_NO_FOLDER_BORDER) || this.getColor(contrastBorder);
+ const borderColor = this.getColor(this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? STATUS_BAR_BORDER : STATUS_BAR_NO_FOLDER_BORDER) || this.getColor(contrastBorder);
container.style('border-top-width', borderColor ? '1px' : null);
container.style('border-top-style', borderColor ? 'solid' : null);
container.style('border-top-color', borderColor);
diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts
index 15f9670b6c8..683183e95a3 100644
--- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts
+++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts
@@ -27,7 +27,7 @@ import nls = require('vs/nls');
import * as labels from 'vs/base/common/labels';
import { EditorInput, toResource } from 'vs/workbench/common/editor';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { Verbosity } from 'vs/platform/editor/common/editor';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { TITLE_BAR_ACTIVE_BACKGROUND, TITLE_BAR_ACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_FOREGROUND, TITLE_BAR_INACTIVE_BACKGROUND, TITLE_BAR_BORDER } from 'vs/workbench/common/theme';
@@ -101,7 +101,7 @@ export class TitlebarPart extends Part implements ITitleService {
this.toUnbind.push(DOM.addDisposableListener(window, DOM.EventType.FOCUS, () => this.onFocus()));
this.toUnbind.push(this.configurationService.onDidUpdateConfiguration(() => this.onConfigurationChanged(true)));
this.toUnbind.push(this.editorGroupService.onEditorsChanged(() => this.onEditorsChanged()));
- this.toUnbind.push(this.contextService.onDidChangeWorkspaceRoots(() => this.onDidChangeWorkspaceRoots()));
+ this.toUnbind.push(this.contextService.onDidChangeWorkspaceFolders(() => this.onDidChangeWorkspaceFolders()));
this.toUnbind.push(this.contextService.onDidChangeWorkspaceName(() => this.onDidChangeWorkspaceName()));
}
@@ -115,7 +115,7 @@ export class TitlebarPart extends Part implements ITitleService {
this.updateStyles();
}
- private onDidChangeWorkspaceRoots(): void {
+ private onDidChangeWorkspaceFolders(): void {
this.setTitle(this.getWindowTitle());
}
@@ -192,34 +192,17 @@ export class TitlebarPart extends Part implements ITitleService {
const input = this.editorService.getActiveEditorInput();
const workspace = this.contextService.getWorkspace();
- // Compute root resource
- // Single Root Workspace: always the single root workspace in this case
- // Multi Root Workspace: workspace configuration file
- let root: URI;
- if (this.contextService.hasMultiFolderWorkspace()) {
- root = workspace.configuration;
- } else if (this.contextService.hasFolderWorkspace()) {
- root = workspace.roots[0];
- }
-
// Compute folder resource
// Single Root Workspace: always the root single workspace in this case
- // Multi Root Workspace: root folder of the currently active file if any
- let folder: URI;
- if (workspace) {
- if (workspace.roots.length === 1) {
- folder = workspace.roots[0];
- } else {
- folder = this.contextService.getRoot(toResource(input, { supportSideBySide: true, filter: 'file' }));
- }
- }
+ // Otherwise: root folder of the currently active file if any
+ let folder: URI = this.contextService.getWorkbenchState() === WorkbenchState.FOLDER ? workspace.folders[0] : this.contextService.getWorkspaceFolder(toResource(input, { supportSideBySide: true, filter: 'file' }));
// Variables
const activeEditorShort = input ? input.getTitle(Verbosity.SHORT) : '';
const activeEditorMedium = input ? input.getTitle(Verbosity.MEDIUM) : activeEditorShort;
const activeEditorLong = input ? input.getTitle(Verbosity.LONG) : activeEditorMedium;
- const rootName = workspace ? workspace.name : '';
- const rootPath = workspace ? labels.getPathLabel(root, void 0, this.environmentService) : '';
+ const rootName = workspace.name;
+ const rootPath = labels.getPathLabel(workspace.configuration || workspace.folders[0], void 0, this.environmentService) || '';
const folderName = folder ? (paths.basename(folder.fsPath) || folder.fsPath) : '';
const folderPath = folder ? labels.getPathLabel(folder, void 0, this.environmentService) : '';
const dirty = input && input.isDirty() ? TitlebarPart.TITLE_DIRTY : '';
diff --git a/src/vs/workbench/browser/parts/views/views.ts b/src/vs/workbench/browser/parts/views/views.ts
index 3fe40af888f..1c7c48aa596 100644
--- a/src/vs/workbench/browser/parts/views/views.ts
+++ b/src/vs/workbench/browser/parts/views/views.ts
@@ -28,7 +28,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { SIDE_BAR_DRAG_AND_DROP_BACKGROUND, SIDE_BAR_SECTION_HEADER_FOREGROUND, SIDE_BAR_SECTION_HEADER_BACKGROUND } from 'vs/workbench/common/theme';
@@ -739,11 +739,11 @@ export class PersistentViewsViewlet extends ViewsViewlet {
}
});
- this.storageService.store(this.viewletStateStorageId, JSON.stringify(viewsStates), this.contextService.hasWorkspace() ? StorageScope.WORKSPACE : StorageScope.GLOBAL);
+ this.storageService.store(this.viewletStateStorageId, JSON.stringify(viewsStates), this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? StorageScope.WORKSPACE : StorageScope.GLOBAL);
}
private loadViewsStates(): void {
- const viewsStates = JSON.parse(this.storageService.get(this.viewletStateStorageId, this.contextService.hasWorkspace() ? StorageScope.WORKSPACE : StorageScope.GLOBAL, '{}'));
+ const viewsStates = JSON.parse(this.storageService.get(this.viewletStateStorageId, this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? StorageScope.WORKSPACE : StorageScope.GLOBAL, '{}'));
Object.keys(viewsStates).forEach(id => this.viewsStates.set(id, viewsStates[id]));
}
}
\ No newline at end of file
diff --git a/src/vs/workbench/browser/parts/views/views2.ts b/src/vs/workbench/browser/parts/views/views2.ts
new file mode 100644
index 00000000000..e6592e5a305
--- /dev/null
+++ b/src/vs/workbench/browser/parts/views/views2.ts
@@ -0,0 +1,238 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import * as nls from 'vs/nls';
+import { TPromise } from 'vs/base/common/winjs.base';
+import Event, { Emitter } from 'vs/base/common/event';
+import { attachStyler } from 'vs/platform/theme/common/styler';
+import { Dimension, Builder } from 'vs/base/browser/builder';
+import { append, $ } from 'vs/base/browser/dom';
+import { IDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
+import { firstIndex } from 'vs/base/common/arrays';
+import { IAction, IActionRunner } from 'vs/base/common/actions';
+import { IActionItem, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
+import { Registry } from 'vs/platform/registry/common/platform';
+import { prepareActions } from 'vs/workbench/browser/actions';
+import { Viewlet, ViewletRegistry, Extensions } from 'vs/workbench/browser/viewlet';
+import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
+import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
+import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
+import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
+import { IThemeService } from 'vs/platform/theme/common/themeService';
+import { SIDE_BAR_DRAG_AND_DROP_BACKGROUND } from 'vs/workbench/common/theme';
+import { PanelView, IPanelOptions, Panel } from 'vs/base/browser/ui/splitview/panelview';
+
+export interface IViewletPanelOptions extends IPanelOptions {
+ actionRunner?: IActionRunner;
+}
+
+export abstract class ViewletPanel extends Panel {
+
+ private _onDidFocus = new Emitter();
+ readonly onDidFocus: Event = this._onDidFocus.event;
+
+ private actionRunner: IActionRunner;
+ private toolbar: ToolBar;
+
+ constructor(
+ readonly name: string,
+ initialSize: number,
+ options: IViewletPanelOptions,
+ protected keybindingService: IKeybindingService,
+ protected contextMenuService: IContextMenuService
+ ) {
+ super(options);
+
+ this.actionRunner = options.actionRunner;
+ }
+
+ render(container: HTMLElement): void {
+ super.render(container);
+
+ const title = append(this.header, $('div.title'));
+ title.textContent = this.name;
+
+ const actions = append(this.header, $('div.actions'));
+ this.toolbar = new ToolBar(actions, this.contextMenuService, {
+ orientation: ActionsOrientation.HORIZONTAL,
+ actionItemProvider: action => this.getActionItem(action),
+ ariaLabel: nls.localize('viewToolbarAriaLabel', "{0} actions", this.name),
+ getKeyBinding: action => this.keybindingService.lookupKeybinding(action.id),
+ actionRunner: this.actionRunner
+ });
+
+ this.disposables.push(this.toolbar);
+ this.updateActions();
+ }
+
+ focus(): void {
+ super.focus();
+ this._onDidFocus.fire();
+ }
+
+ protected updateActions(): void {
+ this.toolbar.setActions(prepareActions(this.getActions()), prepareActions(this.getSecondaryActions()))();
+ this.toolbar.context = this.getActionsContext();
+ }
+
+ getActions(): IAction[] {
+ return [];
+ }
+
+ getSecondaryActions(): IAction[] {
+ return [];
+ }
+
+ getActionItem(action: IAction): IActionItem {
+ return null;
+ }
+
+ getActionsContext(): any {
+ return undefined;
+ }
+
+ getOptimalWidth(): number {
+ return 0;
+ }
+}
+
+export interface IViewsViewletOptions {
+ showHeaderInTitleWhenSingleView: boolean;
+}
+
+const SplitViewThemeMapping = {
+ dropBackground: SIDE_BAR_DRAG_AND_DROP_BACKGROUND
+};
+
+interface IViewletPanelItem {
+ panel: ViewletPanel;
+ disposable: IDisposable;
+}
+
+export class PanelViewlet extends Viewlet {
+
+ protected lastFocusedPanel: ViewletPanel | undefined;
+ private panelItems: IViewletPanelItem[] = [];
+ private panelview: PanelView;
+
+ protected get isSingleView(): boolean {
+ return this.options.showHeaderInTitleWhenSingleView && this.panelItems.length === 1;
+ }
+
+ protected get length(): number {
+ return this.panelItems.length;
+ }
+
+ constructor(
+ id: string,
+ private options: Partial,
+ @ITelemetryService telemetryService: ITelemetryService,
+ @IThemeService themeService: IThemeService
+ ) {
+ super(id, telemetryService, themeService);
+ }
+
+ async create(parent: Builder): TPromise {
+ super.create(parent);
+
+ const container = parent.getHTMLElement();
+ this.panelview = this._register(new PanelView(container));
+ this._register(attachStyler(this.themeService, SplitViewThemeMapping, this.panelview));
+ // this._register(this.panelview.onFocus(view => this.lastFocusedView = view));
+ }
+
+ getTitle(): string {
+ let title = Registry.as(Extensions.Viewlets).getViewlet(this.getId()).name;
+
+ if (this.isSingleView) {
+ title += ': ' + this.panelItems[0].panel.name;
+ }
+
+ return title;
+ }
+
+ getActions(): IAction[] {
+ if (this.isSingleView) {
+ return this.panelItems[0].panel.getActions();
+ }
+
+ return [];
+ }
+
+ getSecondaryActions(): IAction[] {
+ if (this.isSingleView) {
+ return this.panelItems[0].panel.getSecondaryActions();
+ }
+
+ return [];
+ }
+
+ focus(): void {
+ super.focus();
+
+ if (this.lastFocusedPanel) {
+ this.lastFocusedPanel.focus();
+ } else if (this.panelItems.length > 0) {
+ this.panelItems[0].panel.focus();
+ }
+ }
+
+ layout(dimension: Dimension): void {
+ this.panelview.layout(dimension.height);
+ }
+
+ getOptimalWidth(): number {
+ const sizes = this.panelItems
+ .map(panelItem => panelItem.panel.getOptimalWidth() || 0);
+
+ return Math.max(...sizes);
+ }
+
+ addView(panel: ViewletPanel, index = this.panelItems.length - 1): void {
+ const disposables: IDisposable[] = [];
+ const onDidFocus = panel.onDidFocus(() => this.lastFocusedPanel = panel, null, disposables);
+ const disposable = combinedDisposable([onDidFocus]);
+ const panelItem: IViewletPanelItem = { panel, disposable };
+
+ this.panelItems.splice(index, 0, panelItem);
+ this.panelview.addPanel(panel, 200, index);
+
+ this.updateViewHeaders();
+ this.updateTitleArea();
+ }
+
+ removeView(panel: ViewletPanel): void {
+ const index = firstIndex(this.panelItems, i => i.panel === panel);
+
+ if (index === -1) {
+ return;
+ }
+
+ if (this.lastFocusedPanel === panel) {
+ this.lastFocusedPanel = undefined;
+ }
+
+ this.panelview.removePanel(panel);
+ const [panelItem] = this.panelItems.splice(index, 1);
+ panelItem.disposable.dispose();
+
+ this.updateViewHeaders();
+ this.updateTitleArea();
+ }
+
+ private updateViewHeaders(): void {
+ if (this.isSingleView) {
+ this.panelItems[0].panel.headerVisible = false;
+ } else {
+ this.panelItems.forEach(i => i.panel.headerVisible = true);
+ }
+ }
+
+ dispose(): void {
+ super.dispose();
+ this.panelItems.forEach(i => i.disposable.dispose());
+ this.panelview.dispose();
+ }
+}
\ No newline at end of file
diff --git a/src/vs/workbench/common/resources.ts b/src/vs/workbench/common/resources.ts
index 830f77fd26f..d8ae21d82d3 100644
--- a/src/vs/workbench/common/resources.ts
+++ b/src/vs/workbench/common/resources.ts
@@ -91,14 +91,14 @@ export class ResourceGlobMatcher {
private registerListeners(): void {
this.toUnbind.push(this.configurationService.onDidUpdateConfiguration(() => this.onConfigurationChanged()));
- this.toUnbind.push(this.contextService.onDidChangeWorkspaceRoots(() => this.onDidChangeWorkspaceRoots()));
+ this.toUnbind.push(this.contextService.onDidChangeWorkspaceFolders(() => this.onDidChangeWorkspaceFolders()));
}
private onConfigurationChanged(): void {
this.updateExcludes(true);
}
- private onDidChangeWorkspaceRoots(): void {
+ private onDidChangeWorkspaceFolders(): void {
this.updateExcludes(true);
}
@@ -106,17 +106,15 @@ export class ResourceGlobMatcher {
let changed = false;
// Add excludes per workspaces that got added
- if (this.contextService.hasWorkspace()) {
- this.contextService.getWorkspace().roots.forEach(root => {
- const rootExcludes = this.globFn(root);
- if (!this.mapRootToExpressionConfig.has(root.toString()) || !objects.equals(this.mapRootToExpressionConfig.get(root.toString()), rootExcludes)) {
- changed = true;
+ this.contextService.getWorkspace().folders.forEach(folder => {
+ const rootExcludes = this.globFn(folder);
+ if (!this.mapRootToExpressionConfig.has(folder.toString()) || !objects.equals(this.mapRootToExpressionConfig.get(folder.toString()), rootExcludes)) {
+ changed = true;
- this.mapRootToParsedExpression.set(root.toString(), this.parseFn(rootExcludes));
- this.mapRootToExpressionConfig.set(root.toString(), objects.clone(rootExcludes));
- }
- });
- }
+ this.mapRootToParsedExpression.set(folder.toString(), this.parseFn(rootExcludes));
+ this.mapRootToExpressionConfig.set(folder.toString(), objects.clone(rootExcludes));
+ }
+ });
// Remove excludes per workspace no longer present
this.mapRootToExpressionConfig.forEach((value, root) => {
@@ -124,7 +122,7 @@ export class ResourceGlobMatcher {
return; // always keep this one
}
- if (!this.contextService.getRoot(URI.parse(root))) {
+ if (!this.contextService.getWorkspaceFolder(URI.parse(root))) {
this.mapRootToParsedExpression.delete(root);
this.mapRootToExpressionConfig.delete(root);
@@ -147,7 +145,7 @@ export class ResourceGlobMatcher {
}
public matches(resource: URI): boolean {
- const root = this.contextService.getRoot(resource);
+ const root = this.contextService.getWorkspaceFolder(resource);
let expressionForRoot: ParsedExpression;
if (root && this.mapRootToParsedExpression.has(root.toString())) {
diff --git a/src/vs/workbench/electron-browser/actions.ts b/src/vs/workbench/electron-browser/actions.ts
index 2f7d94696bc..67796b9bc2f 100644
--- a/src/vs/workbench/electron-browser/actions.ts
+++ b/src/vs/workbench/electron-browser/actions.ts
@@ -18,7 +18,7 @@ import product from 'vs/platform/node/product';
import pkg from 'vs/platform/node/package';
import errors = require('vs/base/common/errors');
import { IMessageService, Severity } from 'vs/platform/message/common/message';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IConfigurationEditingService, ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
@@ -104,7 +104,7 @@ export class CloseWorkspaceAction extends Action {
}
run(): TPromise {
- if (!this.contextService.hasWorkspace()) {
+ if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) {
this.messageService.show(Severity.Info, nls.localize('noWorkspaceOpened', "There is currently no workspace opened in this instance to close."));
return TPromise.as(null);
@@ -759,23 +759,12 @@ export abstract class BaseOpenRecentAction extends Action {
const workspacePicks: IFilePickOpenEntry[] = recentWorkspaces.map((workspace, index) => toPick(workspace, index === 0 ? { label: nls.localize('workspaces', "workspaces") } : void 0, isSingleFolderWorkspaceIdentifier(workspace) ? FileKind.FOLDER : FileKind.ROOT_FOLDER, this.environmentService, !this.isQuickNavigate() ? this.removeAction : void 0));
const filePicks: IFilePickOpenEntry[] = recentFiles.map((p, index) => toPick(p, index === 0 ? { label: nls.localize('files', "files"), border: true } : void 0, FileKind.FILE, this.environmentService, !this.isQuickNavigate() ? this.removeAction : void 0));
- let isCurrentWorkspaceInList: boolean;
- if (!this.contextService.hasWorkspace()) {
- isCurrentWorkspaceInList = false; // we never show empty workspaces
- } else if (this.contextService.hasFolderWorkspace()) {
- isCurrentWorkspaceInList = true; // we always show folder workspaces
- } else {
- const firstWorkspace = recentWorkspaces[0];
- if (firstWorkspace && !isSingleFolderWorkspaceIdentifier(firstWorkspace)) {
- isCurrentWorkspaceInList = firstWorkspace.id === this.contextService.getWorkspace().id;
- } else {
- isCurrentWorkspaceInList = false; // this is an untitled workspace thereby
- }
- }
+ // focus second entry if the first recent workspace is the current workspace
+ let autoFocusSecondEntry: boolean = recentWorkspaces[0] && this.contextService.isCurrentWorkspace(recentWorkspaces[0]);
this.quickOpenService.pick([...workspacePicks, ...filePicks], {
contextKey: inRecentFilesPickerContextKey,
- autoFocus: { autoFocusFirstEntry: !isCurrentWorkspaceInList, autoFocusSecondEntry: isCurrentWorkspaceInList },
+ autoFocus: { autoFocusFirstEntry: !autoFocusSecondEntry, autoFocusSecondEntry: autoFocusSecondEntry },
placeHolder: isMacintosh ? nls.localize('openRecentPlaceHolderMac', "Select to open (hold Cmd-key to open in new window)") : nls.localize('openRecentPlaceHolder', "Select to open (hold Ctrl-key to open in new window)"),
matchOnDescription: true,
quickNavigateConfiguration: this.isQuickNavigate() ? { keybindings: this.keybindingService.lookupKeybindings(this.id) } : void 0
diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts
index f1b566e63da..70cbf4e7b09 100644
--- a/src/vs/workbench/electron-browser/main.ts
+++ b/src/vs/workbench/electron-browser/main.ts
@@ -16,13 +16,12 @@ import platform = require('vs/base/common/platform');
import paths = require('vs/base/common/paths');
import uri from 'vs/base/common/uri';
import strings = require('vs/base/common/strings');
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, Workspace, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { EmptyWorkspaceServiceImpl, WorkspaceServiceImpl, WorkspaceService } from 'vs/workbench/services/configuration/node/configuration';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { realpath } from 'vs/base/node/pfs';
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
-import path = require('path');
import gracefulFs = require('graceful-fs');
import { IInitData } from 'vs/workbench/services/timer/common/timerService';
import { TimerService } from 'vs/workbench/services/timer/node/timerService';
@@ -79,8 +78,8 @@ function openWorkbench(configuration: IWindowConfiguration): TPromise {
// Since the configuration service is one of the core services that is used in so many places, we initialize it
// right before startup of the workbench shell to have its data ready for consumers
return createAndInitializeWorkspaceService(configuration, environmentService, mainServices.get(IWorkspacesService)).then(workspaceService => {
- const timerService = new TimerService((window).MonacoEnvironment.timers as IInitData, !workspaceService.hasWorkspace());
- const storageService = createStorageService(configuration, workspaceService, environmentService);
+ const timerService = new TimerService((window).MonacoEnvironment.timers as IInitData, workspaceService.getWorkbenchState() === WorkbenchState.EMPTY);
+ const storageService = createStorageService(workspaceService, environmentService);
timerService.beforeDOMContentLoaded = Date.now();
@@ -116,10 +115,10 @@ function createAndInitializeWorkspaceService(configuration: IWindowConfiguration
if (configuration.workspace || configuration.folderPath) {
workspaceService = new WorkspaceServiceImpl(configuration.workspace || configuration.folderPath, environmentService, workspacesService);
} else {
- workspaceService = new EmptyWorkspaceServiceImpl(environmentService);
+ workspaceService = new EmptyWorkspaceServiceImpl(configuration, environmentService);
}
- return workspaceService.initialize().then(() => workspaceService, error => new EmptyWorkspaceServiceImpl(environmentService));
+ return workspaceService.initialize().then(() => workspaceService, error => new EmptyWorkspaceServiceImpl(configuration, environmentService));
});
}
@@ -147,33 +146,35 @@ function validateWorkspacePath(configuration: IWindowConfiguration): TPromiseworkspaceService.getWorkspace();
+ workspaceId = workspace.folders[0].toString();
+ secondaryWorkspaceId = workspace.ctime;
+ break;
+
+ // finaly, if we do not have a workspace open, we need to find another identifier for the window to store
+ // workspace UI state. if we have a backup path in the configuration we can use that because this
+ // will be a unique identifier per window that is stable between restarts as long as there are
+ // dirty files in the workspace.
+ // We use basename() to produce a short identifier, we do not need the full path. We use a custom
+ // scheme so that we can later distinguish these identifiers from the workspace one.
+ case WorkbenchState.EMPTY:
+ workspaceId = workspaceService.getWorkspace().id;
+ break;
}
const disableStorage = !!environmentService.extensionTestsPath; // never keep any state when running extension tests!
diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts
index f6bec8be10f..e188d34337d 100644
--- a/src/vs/workbench/electron-browser/shell.ts
+++ b/src/vs/workbench/electron-browser/shell.ts
@@ -63,7 +63,7 @@ import { ChoiceChannel } from 'vs/platform/message/common/messageIpc';
import { ISearchService } from 'vs/platform/search/common/search';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { CommandService } from 'vs/platform/commands/common/commandService';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
import { WorkbenchModeServiceImpl } from 'vs/workbench/services/mode/common/workbenchModeService';
import { IModeService } from 'vs/editor/common/services/modeService';
@@ -202,7 +202,7 @@ export class WorkbenchShell {
this.telemetryService.publicLog('workspaceLoad', {
userAgent: navigator.userAgent,
windowSize: { innerHeight: window.innerHeight, innerWidth: window.innerWidth, outerHeight: window.outerHeight, outerWidth: window.outerWidth },
- emptyWorkbench: !this.contextService.hasWorkspace(),
+ emptyWorkbench: this.contextService.getWorkbenchState() === WorkbenchState.EMPTY,
'workbench.filesToOpen': filesToOpen && filesToOpen.length || void 0,
'workbench.filesToCreate': filesToCreate && filesToCreate.length || void 0,
'workbench.filesToDiff': filesToDiff && filesToDiff.length || void 0,
diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts
index 947b60ef708..e3307c35999 100644
--- a/src/vs/workbench/electron-browser/window.ts
+++ b/src/vs/workbench/electron-browser/window.ts
@@ -39,7 +39,7 @@ import { IExtensionService } from 'vs/platform/extensions/common/extensions';
import { KeyboardMapperFactory } from 'vs/workbench/services/keybinding/electron-browser/keybindingService';
import { Themable } from 'vs/workbench/common/theme';
import { ipcRenderer as ipc, webFrame } from 'electron';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
const TextInputActions: IAction[] = [
@@ -288,18 +288,13 @@ export class ElectronWindow extends Themable {
const foldersToAdd = request.foldersToAdd.map(folderToAdd => URI.file(folderToAdd.filePath));
// Workspace: just add to workspace config
- if (this.contextService.hasMultiFolderWorkspace()) {
- this.workspaceEditingService.addRoots(foldersToAdd).done(null, errors.onUnexpectedError);
+ if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
+ this.workspaceEditingService.addFolders(foldersToAdd).done(null, errors.onUnexpectedError);
}
// Single folder or no workspace: create workspace and open
else {
- const workspaceFolders: URI[] = [];
-
- // Folder of workspace is the first of multi root workspace, so add it
- if (this.contextService.hasFolderWorkspace()) {
- workspaceFolders.push(...this.contextService.getWorkspace().roots);
- }
+ const workspaceFolders: URI[] = [...this.contextService.getWorkspace().folders];
// Fill in remaining ones from request
workspaceFolders.push(...request.foldersToAdd.map(folderToAdd => URI.file(folderToAdd.filePath)));
diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts
index 6fe5bb86fa8..c2a5865957f 100644
--- a/src/vs/workbench/electron-browser/workbench.ts
+++ b/src/vs/workbench/electron-browser/workbench.ts
@@ -41,7 +41,7 @@ import { QuickOpenController } from 'vs/workbench/browser/parts/quickopen/quickO
import { getServices } from 'vs/platform/instantiation/common/extensions';
import { WorkbenchEditorService } from 'vs/workbench/services/editor/browser/editorService';
import { Position, Parts, IPartService, ILayoutOptions } from 'vs/workbench/services/part/common/partService';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { ContextMenuService } from 'vs/workbench/services/contextview/electron-browser/contextmenuService';
import { WorkbenchKeybindingService } from 'vs/workbench/services/keybinding/electron-browser/keybindingService';
@@ -444,7 +444,7 @@ export class Workbench implements IPartService {
}
// Empty workbench
- else if (!this.contextService.hasWorkspace() && this.openUntitledFile()) {
+ else if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY && this.openUntitledFile()) {
if (this.editorPart.hasEditorsToRestore()) {
return TPromise.as([]); // do not open any empty untitled file if we have editors to restore
}
@@ -635,7 +635,7 @@ export class Workbench implements IPartService {
private initSettings(): void {
// Sidebar visibility
- this.sideBarHidden = this.storageService.getBoolean(Workbench.sidebarHiddenSettingKey, StorageScope.WORKSPACE, !this.contextService.hasWorkspace());
+ this.sideBarHidden = this.storageService.getBoolean(Workbench.sidebarHiddenSettingKey, StorageScope.WORKSPACE, this.contextService.getWorkbenchState() === WorkbenchState.EMPTY);
// Panel part visibility
const panelRegistry = Registry.as(PanelExtensions.Panels);
@@ -830,7 +830,7 @@ export class Workbench implements IPartService {
return promise.then(() => {
// Remember in settings
- const defaultHidden = !this.contextService.hasWorkspace();
+ const defaultHidden = this.contextService.getWorkbenchState() === WorkbenchState.EMPTY;
if (hidden !== defaultHidden) {
this.storageService.store(Workbench.sidebarHiddenSettingKey, hidden ? 'true' : 'false', StorageScope.WORKSPACE);
} else {
@@ -1054,7 +1054,7 @@ export class Workbench implements IPartService {
// Close when empty: check if we should close the window based on the setting
// Overruled by: window has a workspace opened or this window is for extension development
// or setting is disabled. Also enabled when running with --wait from the command line.
- if (visibleEditors === 0 && !this.contextService.hasWorkspace() && !this.environmentService.isExtensionDevelopment) {
+ if (visibleEditors === 0 && this.contextService.getWorkbenchState() === WorkbenchState.EMPTY && !this.environmentService.isExtensionDevelopment) {
const closeWhenEmpty = this.configurationService.lookup(Workbench.closeWhenEmptyConfigurationKey).value;
if (closeWhenEmpty || this.environmentService.args.wait) {
this.closeEmptyWindowScheduler.schedule();
diff --git a/src/vs/workbench/node/extensionHostMain.ts b/src/vs/workbench/node/extensionHostMain.ts
index b798a89d457..9bd3d58ff3d 100644
--- a/src/vs/workbench/node/extensionHostMain.ts
+++ b/src/vs/workbench/node/extensionHostMain.ts
@@ -145,7 +145,7 @@ export class ExtensionHostMain {
}
private handleWorkspaceContainsEagerExtensions(): TPromise {
- if (!this._workspace || this._workspace.roots.length === 0) {
+ if (!this._workspace || this._workspace.folders.length === 0) {
return TPromise.as(null);
}
@@ -177,7 +177,7 @@ export class ExtensionHostMain {
}
const query: ISearchQuery = {
- folderQueries: this._workspace.roots.map(root => ({ folder: root })),
+ folderQueries: this._workspace.folders.map(root => ({ folder: root })),
type: QueryType.File,
maxResults: 1,
includePattern: { [p]: true }
@@ -187,7 +187,7 @@ export class ExtensionHostMain {
} else {
// find exact path
return (async resolve => {
- for (const { fsPath } of this._workspace.roots) {
+ for (const { fsPath } of this._workspace.folders) {
if (await pfs.exists(join(fsPath, p))) {
return p;
}
diff --git a/src/vs/workbench/parts/debug/browser/debugActions.ts b/src/vs/workbench/parts/debug/browser/debugActions.ts
index b462d58e460..4b53aa781f5 100644
--- a/src/vs/workbench/parts/debug/browser/debugActions.ts
+++ b/src/vs/workbench/parts/debug/browser/debugActions.ts
@@ -11,7 +11,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { ICommandService } from 'vs/platform/commands/common/commands';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IFileService } from 'vs/platform/files/common/files';
import { IMessageService } from 'vs/platform/message/common/message';
import { IDebugService, State, IProcess, IThread, IEnablement, IBreakpoint, IStackFrame, IFunctionBreakpoint, IDebugEditorContribution, EDITOR_CONTRIBUTION_ID, IExpression, REPL_ID, ProcessState }
@@ -98,7 +98,7 @@ export class ConfigureAction extends AbstractDebugAction {
}
public run(event?: any): TPromise {
- if (!this.contextService.hasWorkspace()) {
+ if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) {
this.messageService.show(severity.Info, nls.localize('noFolderDebugConfig', "Please first open a folder in order to do advanced debug configuration."));
return TPromise.as(null);
}
@@ -140,7 +140,7 @@ export class StartAction extends AbstractDebugAction {
if (state === State.Initializing) {
return false;
}
- if (this.contextService && !this.contextService.hasWorkspace() && processes.length > 0) {
+ if (this.contextService && this.contextService.getWorkbenchState() === WorkbenchState.EMPTY && processes.length > 0) {
return false;
}
if (processes.some(p => p.getName(false) === selectedName && (!launch || p.session.root.toString() === launch.workspaceUri.toString()))) {
diff --git a/src/vs/workbench/parts/debug/browser/debugContentProvider.ts b/src/vs/workbench/parts/debug/browser/debugContentProvider.ts
index ad96768d0d5..ccf2795916f 100644
--- a/src/vs/workbench/parts/debug/browser/debugContentProvider.ts
+++ b/src/vs/workbench/parts/debug/browser/debugContentProvider.ts
@@ -32,13 +32,21 @@ export class DebugContentProvider implements IWorkbenchContribution, ITextModelC
public provideTextContent(resource: uri): TPromise {
let process: IProcess;
+ let sourceRef: number;
+
if (resource.query) {
const keyvalues = resource.query.split('&');
for (let keyvalue of keyvalues) {
const pair = keyvalue.split('=');
- if (pair.length === 2 && pair[0] === 'session') {
- process = this.debugService.findProcessByUUID(decodeURIComponent(pair[1]));
- break;
+ if (pair.length === 2) {
+ switch (pair[0]) {
+ case 'session':
+ process = this.debugService.findProcessByUUID(decodeURIComponent(pair[1]));
+ break;
+ case 'sourceRef':
+ sourceRef = parseInt(pair[1]);
+ break;
+ }
}
}
}
@@ -55,18 +63,26 @@ export class DebugContentProvider implements IWorkbenchContribution, ITextModelC
let rawSource: DebugProtocol.Source;
if (source) {
rawSource = source.raw;
+ if (!sourceRef) {
+ sourceRef = source.reference;
+ }
} else {
- // Remove debug: scheme
- rawSource = { path: resource.with({ scheme: '', query: '' }).toString(true) };
+ // create a Source
+ rawSource = {
+ path: resource.with({ scheme: '', query: '' }).toString(true), // Remove debug: scheme
+ sourceReference: sourceRef
+ };
}
- return process.session.source({ sourceReference: source ? source.reference : undefined, source: rawSource }).then(response => {
+ return process.session.source({ sourceReference: sourceRef, source: rawSource }).then(response => {
+
const mime = response.body.mimeType || guessMimeTypes(resource.toString())[0];
const modePromise = this.modeService.getOrCreateMode(mime);
const model = this.modelService.createModel(response.body.content, modePromise, resource);
return model;
}, (err: DebugProtocol.ErrorResponse) => {
+
this.debugService.sourceIsNotAvailable(resource);
const modePromise = this.modeService.getOrCreateMode(MIME_TEXT);
const model = this.modelService.createModel(err.message, modePromise, resource);
diff --git a/src/vs/workbench/parts/debug/browser/debugViewlet.ts b/src/vs/workbench/parts/debug/browser/debugViewlet.ts
index 98ac337283e..d0ff9fd24e1 100644
--- a/src/vs/workbench/parts/debug/browser/debugViewlet.ts
+++ b/src/vs/workbench/parts/debug/browser/debugViewlet.ts
@@ -16,7 +16,7 @@ import { StartDebugActionItem } from 'vs/workbench/parts/debug/browser/debugActi
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
import { IProgressService, IProgressRunner } from 'vs/platform/progress/common/progress';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IThemeService } from 'vs/platform/theme/common/themeService';
@@ -56,10 +56,6 @@ export class DebugViewlet extends PersistentViewsViewlet {
public focus(): void {
super.focus();
- if (!this.contextService.hasWorkspace()) {
- this.views[0].focusBody();
- }
-
if (this.startDebugActionItem) {
this.startDebugActionItem.focus();
}
@@ -69,7 +65,7 @@ export class DebugViewlet extends PersistentViewsViewlet {
if (!this.actions) {
this.actions = [];
this.actions.push(this.instantiationService.createInstance(StartAction, StartAction.ID, StartAction.LABEL));
- if (this.contextService.hasWorkspace()) {
+ if (this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY) {
this.actions.push(this.instantiationService.createInstance(ConfigureAction, ConfigureAction.ID, ConfigureAction.LABEL));
}
this.actions.push(this._register(this.instantiationService.createInstance(ToggleReplAction, ToggleReplAction.ID, ToggleReplAction.LABEL)));
@@ -83,7 +79,7 @@ export class DebugViewlet extends PersistentViewsViewlet {
}
public getActionItem(action: IAction): IActionItem {
- if (action.id === StartAction.ID && this.contextService.hasWorkspace()) {
+ if (action.id === StartAction.ID && this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY) {
this.startDebugActionItem = this.instantiationService.createInstance(StartDebugActionItem, null, action);
return this.startDebugActionItem;
}
diff --git a/src/vs/workbench/parts/debug/browser/exceptionWidget.ts b/src/vs/workbench/parts/debug/browser/exceptionWidget.ts
index 3719a86393b..cbb4c4e8bd9 100644
--- a/src/vs/workbench/parts/debug/browser/exceptionWidget.ts
+++ b/src/vs/workbench/parts/debug/browser/exceptionWidget.ts
@@ -21,7 +21,7 @@ const $ = dom.$;
// theming
export const debugExceptionWidgetBorder = registerColor('debugExceptionWidget.border', { dark: '#a31515', light: '#a31515', hc: '#a31515' }, nls.localize('debugExceptionWidgetBorder', 'Exception widget border color.'));
-export const debugExceptionWidgetBackground = registerColor('debugExceptionWidget.background', { dark: '#a3151540', light: '#a315150d', hc: '#a3151573' }, nls.localize('debugExceptionWidgetBackground', 'Exception widget background color.'));
+export const debugExceptionWidgetBackground = registerColor('debugExceptionWidget.background', { dark: '#420b0d', light: '#f1dfde', hc: '#420b0d' }, nls.localize('debugExceptionWidgetBackground', 'Exception widget background color.'));
export class ExceptionWidget extends ZoneWidget {
diff --git a/src/vs/workbench/parts/debug/electron-browser/debugCommands.ts b/src/vs/workbench/parts/debug/electron-browser/debugCommands.ts
index c1824de5b62..336c9d2fe87 100644
--- a/src/vs/workbench/parts/debug/electron-browser/debugCommands.ts
+++ b/src/vs/workbench/parts/debug/electron-browser/debugCommands.ts
@@ -15,7 +15,7 @@ import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation
import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { IListService } from 'vs/platform/list/browser/listService';
import { IMessageService } from 'vs/platform/message/common/message';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IDebugService, IConfig, IEnablement, CONTEXT_NOT_IN_DEBUG_MODE, CONTEXT_IN_DEBUG_MODE, CONTEXT_BREAKPOINTS_FOCUSED, CONTEXT_WATCH_EXPRESSIONS_FOCUSED, CONTEXT_VARIABLES_FOCUSED, EDITOR_CONTRIBUTION_ID, IDebugEditorContribution } from 'vs/workbench/parts/debug/common/debug';
import { Expression, Variable, Breakpoint, FunctionBreakpoint } from 'vs/workbench/parts/debug/common/debugModel';
import { IExtensionsViewlet, VIEWLET_ID as EXTENSIONS_VIEWLET_ID } from 'vs/workbench/parts/extensions/common/extensions';
@@ -204,7 +204,7 @@ export function registerCommands(): void {
primary: undefined,
handler: (accessor, workspaceUri: string) => {
const manager = accessor.get(IDebugService).getConfigurationManager();
- if (!accessor.get(IWorkspaceContextService).hasWorkspace()) {
+ if (accessor.get(IWorkspaceContextService).getWorkbenchState() === WorkbenchState.EMPTY) {
accessor.get(IMessageService).show(severity.Info, nls.localize('noFolderDebugConfig', "Please first open a folder in order to do advanced debug configuration."));
return TPromise.as(null);
}
diff --git a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts
index 980714a1412..5aa8b1e8f0a 100644
--- a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts
+++ b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts
@@ -341,7 +341,7 @@ export class ConfigurationManager implements IConfigurationManager {
});
});
- this.toDispose.push(this.contextService.onDidChangeWorkspaceRoots(() => {
+ this.toDispose.push(this.contextService.onDidChangeWorkspaceFolders(() => {
this.initLaunches();
this.selectConfiguration();
}));
@@ -353,8 +353,7 @@ export class ConfigurationManager implements IConfigurationManager {
}
private initLaunches(): void {
- const workspace = this.contextService.getWorkspace();
- this.launches = workspace ? workspace.roots.map(root => this.instantiationService.createInstance(Launch, this, root)) : [];
+ this.launches = this.contextService.getWorkspace().folders.map(folder => this.instantiationService.createInstance(Launch, this, folder));
if (this.launches.indexOf(this._selectedLaunch) === -1) {
this._selectedLaunch = undefined;
}
diff --git a/src/vs/workbench/parts/debug/electron-browser/debugEditorContribution.ts b/src/vs/workbench/parts/debug/electron-browser/debugEditorContribution.ts
index 9a2d6bfe963..bcb12909cf6 100644
--- a/src/vs/workbench/parts/debug/electron-browser/debugEditorContribution.ts
+++ b/src/vs/workbench/parts/debug/electron-browser/debugEditorContribution.ts
@@ -365,7 +365,7 @@ export class DebugEditorContribution implements IDebugEditorContribution {
// First call stack frame that is available is the frame where exception has been thrown
const exceptionSf = first(callStack, sf => sf.source && sf.source.available, undefined);
- if (!exceptionSf) {
+ if (!exceptionSf || exceptionSf !== focusedSf) {
this.closeExceptionWidget();
return;
}
diff --git a/src/vs/workbench/parts/debug/electron-browser/debugHover.ts b/src/vs/workbench/parts/debug/electron-browser/debugHover.ts
index 3af92756683..9dec498f49a 100644
--- a/src/vs/workbench/parts/debug/electron-browser/debugHover.ts
+++ b/src/vs/workbench/parts/debug/electron-browser/debugHover.ts
@@ -254,7 +254,8 @@ export class DebugHoverWidget implements IContentWidget {
this.valueContainer.hidden = false;
renderExpressionValue(expression, this.valueContainer, {
showChanged: false,
- preserveWhitespace: true
+ preserveWhitespace: true,
+ colorize: true
});
this.valueContainer.title = '';
this.editor.layoutContentWidget(this);
diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts
index 08ffc1b1b97..953b094abc8 100644
--- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts
+++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts
@@ -46,7 +46,7 @@ import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
import { IPartService, Parts } from 'vs/workbench/services/part/common/partService';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ILogEntry, EXTENSION_LOG_BROADCAST_CHANNEL, EXTENSION_ATTACH_BROADCAST_CHANNEL, EXTENSION_TERMINATE_BROADCAST_CHANNEL, EXTENSION_CLOSE_EXTHOST_BROADCAST_CHANNEL, EXTENSION_RELOAD_BROADCAST_CHANNEL } from 'vs/platform/extensions/common/extensionHost';
import { IBroadcastService, IBroadcast } from 'vs/platform/broadcast/electron-browser/broadcastService';
@@ -365,7 +365,7 @@ export class DebugService implements debug.IDebugService {
// 'Run without debugging' mode VSCode must terminate the extension host. More details: #3905
const process = this.viewModel.focusedProcess;
if (process && session && process.getId() === session.getId() && strings.equalsIgnoreCase(process.configuration.type, 'extensionhost') && this.sessionStates.get(session.getId()) === debug.State.Running &&
- process && this.contextService.hasWorkspace() && process.configuration.noDebug) {
+ process && this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY && process.configuration.noDebug) {
this.broadcastService.broadcast({
channel: EXTENSION_CLOSE_EXTHOST_BROADCAST_CHANNEL,
payload: [process.session.root.fsPath]
@@ -759,7 +759,7 @@ export class DebugService implements debug.IDebugService {
});
});
}, err => {
- if (!this.contextService.hasWorkspace()) {
+ if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) {
this.messageService.show(severity.Error, nls.localize('noFolderWorkspaceDebugError', "The active file can not be debugged. Make sure it is saved on disk and that you have a debug extension installed for that file type."));
return undefined;
}
@@ -846,7 +846,7 @@ export class DebugService implements debug.IDebugService {
this.panelService.openPanel(debug.REPL_ID, false).done(undefined, errors.onUnexpectedError);
}
- if (!this.viewModel.changedWorkbenchViewState && (this.partService.isVisible(Parts.SIDEBAR_PART) || !this.contextService.hasWorkspace())) {
+ if (!this.viewModel.changedWorkbenchViewState && (this.partService.isVisible(Parts.SIDEBAR_PART) || this.contextService.getWorkbenchState() === WorkbenchState.EMPTY)) {
// We only want to change the workbench view state on the first debug session #5738 and if the side bar is not hidden
this.viewModel.changedWorkbenchViewState = true;
this.viewletService.openViewlet(debug.VIEWLET_ID);
@@ -866,7 +866,7 @@ export class DebugService implements debug.IDebugService {
watchExpressionsCount: this.model.getWatchExpressions().length,
extensionName: `${adapter.extensionDescription.publisher}.${adapter.extensionDescription.name}`,
isBuiltin: adapter.extensionDescription.isBuiltin,
- launchJsonExists: this.contextService.hasWorkspace() && !!this.configurationService.getConfiguration('launch', { resource: root })
+ launchJsonExists: this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY && !!this.configurationService.getConfiguration('launch', { resource: root })
});
}).then(() => process, (error: any) => {
if (error instanceof Error && error.message === 'Canceled') {
diff --git a/src/vs/workbench/parts/debug/electron-browser/debugViewer.ts b/src/vs/workbench/parts/debug/electron-browser/debugViewer.ts
index 4737247e86b..5690c49421c 100644
--- a/src/vs/workbench/parts/debug/electron-browser/debugViewer.ts
+++ b/src/vs/workbench/parts/debug/electron-browser/debugViewer.ts
@@ -22,7 +22,7 @@ import { DefaultController, DefaultDragAndDrop, ClickBehavior } from 'vs/base/pa
import { Constants } from 'vs/editor/common/core/uint';
import { IContextViewService, IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IMenuService, IMenu, MenuId } from 'vs/platform/actions/common/actions';
import { fillInActions } from 'vs/platform/actions/browser/menuItemActionItem';
@@ -48,6 +48,7 @@ export interface IRenderValueOptions {
showChanged?: boolean;
maxValueLength?: number;
showHover?: boolean;
+ colorize?: boolean;
}
function replaceWhitespace(value: string): string {
@@ -66,12 +67,16 @@ export function renderExpressionValue(expressionOrValue: debug.IExpression | str
if (value !== Expression.DEFAULT_VALUE) {
dom.addClass(container, 'error');
}
- } else if (!isNaN(+value)) {
- dom.addClass(container, 'number');
- } else if (booleanRegex.test(value)) {
- dom.addClass(container, 'boolean');
- } else if (stringRegex.test(value)) {
- dom.addClass(container, 'string');
+ }
+
+ if (options.colorize) {
+ if (!isNaN(+value)) {
+ dom.addClass(container, 'number');
+ } else if (booleanRegex.test(value)) {
+ dom.addClass(container, 'boolean');
+ } else if (stringRegex.test(value)) {
+ dom.addClass(container, 'string');
+ }
}
if (options.showChanged && (expressionOrValue).valueChanged && value !== Expression.DEFAULT_VALUE) {
@@ -104,7 +109,8 @@ export function renderVariable(tree: ITree, variable: Variable, data: IVariableT
showChanged,
maxValueLength: MAX_VALUE_RENDER_LENGTH_IN_VIEWLET,
preserveWhitespace: false,
- showHover: true
+ showHover: true,
+ colorize: true
});
} else {
data.value.textContent = '';
@@ -209,7 +215,7 @@ export class BaseDebugController extends DefaultController {
this.contributedContextMenu = menuService.createMenu(menuId, contextKeyService);
}
- public onContextMenu(tree: ITree, element: debug.IEnablement, event: ContextMenuEvent): boolean {
+ public onContextMenu(tree: ITree, element: debug.IEnablement, event: ContextMenuEvent, focusElement = true): boolean {
if (event.target && event.target.tagName && event.target.tagName.toLowerCase() === 'input') {
return false;
}
@@ -217,7 +223,9 @@ export class BaseDebugController extends DefaultController {
event.preventDefault();
event.stopPropagation();
- tree.setFocus(element);
+ if (focusElement) {
+ tree.setFocus(element);
+ }
if (this.actionProvider.hasSecondaryActions(tree, element)) {
const anchor = { x: event.posx, y: event.posy };
@@ -524,7 +532,7 @@ export class CallStackRenderer implements IRenderer {
private renderProcess(process: debug.IProcess, data: IProcessTemplateData): void {
data.process.title = nls.localize({ key: 'process', comment: ['Process is a noun'] }, "Process");
- data.name.textContent = process.getName(this.contextService.hasMultiFolderWorkspace());
+ data.name.textContent = process.getName(this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE);
const stoppedThread = process.getAllThreads().filter(t => t.stopped).pop();
data.stateLabel.textContent = stoppedThread ? nls.localize('paused', "Paused")
@@ -942,7 +950,8 @@ export class WatchExpressionsRenderer implements IRenderer {
showChanged: true,
maxValueLength: MAX_VALUE_RENDER_LENGTH_IN_VIEWLET,
preserveWhitespace: false,
- showHover: true
+ showHover: true,
+ colorize: true
});
data.name.title = watchExpression.type ? watchExpression.type : watchExpression.value;
}
diff --git a/src/vs/workbench/parts/debug/electron-browser/replViewer.ts b/src/vs/workbench/parts/debug/electron-browser/replViewer.ts
index 9ae5593472c..bfe1493d1d1 100644
--- a/src/vs/workbench/parts/debug/electron-browser/replViewer.ts
+++ b/src/vs/workbench/parts/debug/electron-browser/replViewer.ts
@@ -11,7 +11,7 @@ import { IActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
import * as dom from 'vs/base/browser/dom';
import severity from 'vs/base/common/severity';
import { IMouseEvent } from 'vs/base/browser/mouseEvent';
-import { ITree, IAccessibilityProvider, IDataSource, IRenderer, IActionProvider } from 'vs/base/parts/tree/browser/tree';
+import { ITree, IAccessibilityProvider, ContextMenuEvent, IDataSource, IRenderer, IActionProvider } from 'vs/base/parts/tree/browser/tree';
import { ICancelableEvent } from 'vs/base/parts/tree/browser/treeDefaults';
import { IExpressionContainer, IExpression } from 'vs/workbench/parts/debug/common/debug';
import { Model, OutputNameValueElement, Expression, OutputElement, Variable } from 'vs/workbench/parts/debug/common/debugModel';
@@ -431,4 +431,8 @@ export class ReplExpressionsController extends BaseDebugController {
return true;
}
+
+ public onContextMenu(tree: ITree, element: any, event: ContextMenuEvent): boolean {
+ return super.onContextMenu(tree, element, event, false);
+ }
}
diff --git a/src/vs/workbench/parts/debug/electron-browser/statusbarColorProvider.ts b/src/vs/workbench/parts/debug/electron-browser/statusbarColorProvider.ts
index f5c8e2040ce..b4ae967d067 100644
--- a/src/vs/workbench/parts/debug/electron-browser/statusbarColorProvider.ts
+++ b/src/vs/workbench/parts/debug/electron-browser/statusbarColorProvider.ts
@@ -9,7 +9,7 @@ import { registerColor, contrastBorder } from 'vs/platform/theme/common/colorReg
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IPartService, Parts } from 'vs/workbench/services/part/common/partService';
import { IDebugService, State } from 'vs/workbench/parts/debug/common/debug';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { STATUS_BAR_NO_FOLDER_BACKGROUND, STATUS_BAR_NO_FOLDER_FOREGROUND, STATUS_BAR_BACKGROUND, Themable, STATUS_BAR_FOREGROUND, STATUS_BAR_NO_FOLDER_BORDER, STATUS_BAR_BORDER } from 'vs/workbench/common/theme';
import { addClass, removeClass } from 'vs/base/browser/dom';
@@ -49,7 +49,7 @@ export class StatusBarColorProvider extends Themable implements IWorkbenchContri
private registerListeners(): void {
this.toUnbind.push(this.debugService.onDidChangeState(state => this.updateStyles()));
- this.toUnbind.push(this.contextService.onDidChangeWorkspaceRoots(state => this.updateStyles()));
+ this.toUnbind.push(this.contextService.onDidChangeWorkspaceFolders(state => this.updateStyles()));
}
protected updateStyles(): void {
@@ -75,7 +75,7 @@ export class StatusBarColorProvider extends Themable implements IWorkbenchContri
// Not debugging
if (!this.isDebugging()) {
- if (this.contextService.hasWorkspace()) {
+ if (this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY) {
return normalColor;
}
diff --git a/src/vs/workbench/parts/extensions/browser/extensionsActions.ts b/src/vs/workbench/parts/extensions/browser/extensionsActions.ts
index 7251ddc6149..51d6dc2eb26 100644
--- a/src/vs/workbench/parts/extensions/browser/extensionsActions.ts
+++ b/src/vs/workbench/parts/extensions/browser/extensionsActions.ts
@@ -26,7 +26,7 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { Query } from 'vs/workbench/parts/extensions/common/extensionQuery';
import { IFileService } from 'vs/platform/files/common/files';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IWindowService } from 'vs/platform/windows/common/windows';
import { IExtensionService, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import URI from 'vs/base/common/uri';
@@ -559,7 +559,7 @@ export class DisableForWorkspaceAction extends Action implements IExtensionActio
private update(): void {
this.enabled = false;
- if (this.extension && this.workspaceContextService.hasWorkspace()) {
+ if (this.extension && this.workspaceContextService.getWorkbenchState() !== WorkbenchState.EMPTY) {
this.enabled = this.extension.type !== LocalExtensionType.System && !this.extension.disabledGlobally && !this.extension.disabledForWorkspace;
}
}
@@ -1093,7 +1093,7 @@ export class ShowWorkspaceRecommendedExtensionsAction extends Action {
@IWorkspaceContextService contextService: IWorkspaceContextService,
@IViewletService private viewletService: IViewletService
) {
- super(id, label, null, contextService.hasWorkspace());
+ super(id, label, null, contextService.getWorkbenchState() !== WorkbenchState.EMPTY);
}
run(): TPromise {
@@ -1251,7 +1251,7 @@ export class ConfigureWorkspaceRecommendedExtensionsAction extends Action {
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
@IMessageService private messageService: IMessageService
) {
- super(id, label, null, contextService.hasWorkspace());
+ super(id, label, null, contextService.getWorkbenchState() !== WorkbenchState.EMPTY);
}
public run(event: any): TPromise {
@@ -1259,7 +1259,7 @@ export class ConfigureWorkspaceRecommendedExtensionsAction extends Action {
}
private openExtensionsFile(): TPromise {
- if (!this.contextService.hasWorkspace()) {
+ if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) {
this.messageService.show(severity.Info, localize('ConfigureWorkspaceRecommendations.noWorkspace', 'Recommendations are only available on a workspace folder.'));
return TPromise.as(undefined);
}
@@ -1276,7 +1276,7 @@ export class ConfigureWorkspaceRecommendedExtensionsAction extends Action {
}
private getOrCreateExtensionsFile(): TPromise<{ created: boolean, extensionsFileResource: URI }> {
- const extensionsFileResource = URI.file(paths.join(this.contextService.getLegacyWorkspace().resource.fsPath, '.vscode', 'extensions.json')); // TODO@Sandeep (https://github.com/Microsoft/vscode/issues/29242)
+ const extensionsFileResource = URI.file(paths.join(this.contextService.getWorkspace().folders[0].fsPath, '.vscode', 'extensions.json')); // TODO@Sandeep (https://github.com/Microsoft/vscode/issues/29242)
return this.fileService.resolveContent(extensionsFileResource).then(content => {
return { created: false, extensionsFileResource };
@@ -1363,7 +1363,7 @@ export class DisableAllWorkpsaceAction extends Action {
}
private update(): void {
- this.enabled = this.workspaceContextService.hasWorkspace() && this.extensionsWorkbenchService.local.some(e => e.type === LocalExtensionType.User && !e.disabledForWorkspace && !e.disabledGlobally);
+ this.enabled = this.workspaceContextService.getWorkbenchState() !== WorkbenchState.EMPTY && this.extensionsWorkbenchService.local.some(e => e.type === LocalExtensionType.User && !e.disabledForWorkspace && !e.disabledGlobally);
}
run(): TPromise {
@@ -1426,7 +1426,7 @@ export class EnableAllWorkpsaceAction extends Action {
}
private update(): void {
- this.enabled = this.workspaceContextService.hasWorkspace() && this.extensionsWorkbenchService.local.some(e => this.extensionEnablementService.canEnable(e.id) && !e.disabledGlobally && e.disabledForWorkspace);
+ this.enabled = this.workspaceContextService.getWorkbenchState() !== WorkbenchState.EMPTY && this.extensionsWorkbenchService.local.some(e => this.extensionEnablementService.canEnable(e.id) && !e.disabledGlobally && e.disabledForWorkspace);
}
run(): TPromise {
diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts
index 75ef396df9d..6761e846ab6 100644
--- a/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts
+++ b/src/vs/workbench/parts/extensions/electron-browser/extensionTipsService.ts
@@ -19,14 +19,14 @@ import { IChoiceService, IMessageService } from 'vs/platform/message/common/mess
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ShowRecommendedExtensionsAction, ShowWorkspaceRecommendedExtensionsAction } from 'vs/workbench/parts/extensions/browser/extensionsActions';
import Severity from 'vs/base/common/severity';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { Schemas } from 'vs/base/common/network';
import { IFileService } from 'vs/platform/files/common/files';
import { IExtensionsConfiguration, ConfigurationKey } from 'vs/workbench/parts/extensions/common/extensions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IConfigurationEditingService, ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
-import * as cp from 'child_process';
+import * as fs from 'fs';
import { distinct } from 'vs/base/common/arrays';
interface IExtensionsContent {
@@ -68,11 +68,10 @@ export class ExtensionTipsService implements IExtensionTipsService {
this._suggestTips();
this._suggestWorkspaceRecommendations();
- this._suggestBasedOnExecutables();
}
getWorkspaceRecommendations(): TPromise {
- if (!this.contextService.hasWorkspace()) {
+ if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) {
return TPromise.as([]);
}
return this.fileService.resolveContent(this.contextService.toResource(paths.join('.vscode', 'extensions.json'))).then(content => { //TODO@Sandeep (https://github.com/Microsoft/vscode/issues/29242)
@@ -92,7 +91,7 @@ export class ExtensionTipsService implements IExtensionTipsService {
const fileBased = Object.keys(this._fileBasedRecommendations)
.filter(recommendation => allRecomendations.indexOf(recommendation) !== -1);
- const exeBased = distinct(this._exeBasedRecommendations);
+ const exeBased = distinct(this._suggestBasedOnExecutables());
this.telemetryService.publicLog('extensionRecommendations:unfiltered', { fileBased, exeBased });
@@ -319,15 +318,42 @@ export class ExtensionTipsService implements IExtensionTipsService {
});
}
- private _suggestBasedOnExecutables() {
- const cmd = process.platform === 'win32' ? 'where' : 'which';
+ private _suggestBasedOnExecutables(): string[] {
+ if (!process.env.PATH || this._exeBasedRecommendations.length > 0) {
+ return this._exeBasedRecommendations;
+ }
+
+ let envpaths = process.env.PATH.split(process.platform === 'win32' ? ';' : ':');
+ let foundExecutables: Set = new Set();
+
+ // Loop through recommended extensions
forEach(product.exeBasedExtensionTips, entry => {
- cp.exec(`${cmd} ${entry.value.replace(/,/g, ' ')}`, (err, stdout, stderr) => {
- if (stdout) {
- this._exeBasedRecommendations.push(entry.key);
+ let executables = entry.value.split(',');
+
+ // Loop through executables that would result in recommending current extension
+ for (let i = 0; i < executables.length; i++) {
+ if (!foundExecutables.has(executables[i])) {
+
+ // Loop through paths in PATH to find current executable
+ for (let pathEntry of envpaths) {
+ let fullPath = paths.join(pathEntry, executables[i]);
+ if (process.platform === 'win32') {
+ fullPath += '.exe';
+ }
+ if (fs.existsSync(fullPath)) {
+ foundExecutables.add(executables[i]);
+ break;
+ }
+ }
}
- });
+ if (foundExecutables.has(executables[i])) {
+ this._exeBasedRecommendations.push(entry.key);
+ break;
+ }
+ }
});
+
+ return this._exeBasedRecommendations;
}
private setIgnoreRecommendationsConfig(configVal: boolean) {
diff --git a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts
index 029bed45771..192350635c5 100644
--- a/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts
+++ b/src/vs/workbench/parts/extensions/node/extensionsWorkbenchService.ts
@@ -34,7 +34,7 @@ import { IExtension, IExtensionDependencies, ExtensionState, IExtensionsWorkbenc
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IURLService } from 'vs/platform/url/common/url';
import { ExtensionsInput } from 'vs/workbench/parts/extensions/common/extensionsInput';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import product from 'vs/platform/node/product';
interface IExtensionStateProvider {
@@ -663,7 +663,7 @@ export class ExtensionsWorkbenchService implements IExtensionsWorkbenchService {
}
const globalElablement = this.extensionEnablementService.setEnablement(extension.id, enable, false);
- if (enable && this.workspaceContextService.hasWorkspace()) {
+ if (enable && this.workspaceContextService.getWorkbenchState() !== WorkbenchState.EMPTY) {
const workspaceEnablement = this.extensionEnablementService.setEnablement(extension.id, enable, true);
return TPromise.join([globalElablement, workspaceEnablement]).then(values => values[0] || values[1]);
}
diff --git a/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.ts b/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.ts
index 7a93025af9d..873ab35c441 100644
--- a/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.ts
+++ b/src/vs/workbench/parts/feedback/electron-browser/feedbackStatusbarItem.ts
@@ -13,7 +13,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import product from 'vs/platform/node/product';
import { Themable, STATUS_BAR_FOREGROUND, STATUS_BAR_NO_FOLDER_FOREGROUND } from 'vs/workbench/common/theme';
import { IThemeService } from 'vs/platform/theme/common/themeService';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
class TwitterFeedbackService implements IFeedbackService {
@@ -63,14 +63,14 @@ export class FeedbackStatusbarItem extends Themable implements IStatusbarItem {
}
private registerListeners(): void {
- this.toUnbind.push(this.contextService.onDidChangeWorkspaceRoots(() => this.updateStyles()));
+ this.toUnbind.push(this.contextService.onDidChangeWorkspaceFolders(() => this.updateStyles()));
}
protected updateStyles(): void {
super.updateStyles();
if (this.dropdown) {
- this.dropdown.label.style('background-color', this.getColor(this.contextService.hasWorkspace() ? STATUS_BAR_FOREGROUND : STATUS_BAR_NO_FOLDER_FOREGROUND));
+ this.dropdown.label.style('background-color', this.getColor(this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? STATUS_BAR_FOREGROUND : STATUS_BAR_NO_FOLDER_FOREGROUND));
}
}
diff --git a/src/vs/workbench/parts/files/browser/explorerViewlet.ts b/src/vs/workbench/parts/files/browser/explorerViewlet.ts
index 2374bdd2558..4db3893c1b1 100644
--- a/src/vs/workbench/parts/files/browser/explorerViewlet.ts
+++ b/src/vs/workbench/parts/files/browser/explorerViewlet.ts
@@ -22,7 +22,7 @@ import { OpenEditorsView } from 'vs/workbench/parts/files/browser/views/openEdit
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { DelegatingWorkbenchEditorService } from 'vs/workbench/services/editor/browser/editorService';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
@@ -78,7 +78,7 @@ export class ExplorerViewlet extends PersistentViewsViewlet {
viewDescriptors.push(this.createOpenEditorsViewDescriptor());
- if (this.contextService.hasWorkspace()) {
+ if (this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY) {
viewDescriptors.push(this.createExplorerViewDescriptor());
} else {
viewDescriptors.push(this.createEmptyViewDescriptor());
@@ -122,7 +122,7 @@ export class ExplorerViewlet extends PersistentViewsViewlet {
}
private onConfigurationUpdated(): void {
- this.openEditorsVisibleContextKey.set(!this.contextService.hasWorkspace() || (this.configurationService.getConfiguration()).explorer.openEditors.visible !== 0);
+ this.openEditorsVisibleContextKey.set(this.contextService.getWorkbenchState() === WorkbenchState.EMPTY || (this.configurationService.getConfiguration()).explorer.openEditors.visible !== 0);
}
protected createView(viewDescriptor: IViewDescriptor, initialSize: number, options: IViewletViewOptions): IViewletView {
diff --git a/src/vs/workbench/parts/files/browser/fileActions.contribution.ts b/src/vs/workbench/parts/files/browser/fileActions.contribution.ts
index 11385383db6..b72884929b5 100644
--- a/src/vs/workbench/parts/files/browser/fileActions.contribution.ts
+++ b/src/vs/workbench/parts/files/browser/fileActions.contribution.ts
@@ -95,7 +95,7 @@ class FilesViewerActionContributor extends ActionBarContributor {
let action: Action = this.instantiationService.createInstance(AddRootFolderAction, AddRootFolderAction.ID, AddRootFolderAction.LABEL);
action.order = 52;
actions.push(action);
- if (this.contextService.getWorkspace().roots.length > 1) {
+ if (this.contextService.getWorkspace().folders.length > 1) {
action = this.instantiationService.createInstance(RemoveRootFolderAction, stat.resource, RemoveRootFolderAction.ID, RemoveRootFolderAction.LABEL);
action.order = 53;
actions.push(action);
diff --git a/src/vs/workbench/parts/files/browser/views/explorerView.ts b/src/vs/workbench/parts/files/browser/views/explorerView.ts
index e99e1d220a8..85fe8e72a8a 100644
--- a/src/vs/workbench/parts/files/browser/views/explorerView.ts
+++ b/src/vs/workbench/parts/files/browser/views/explorerView.ts
@@ -32,7 +32,7 @@ import { FileStat, Model } from 'vs/workbench/parts/files/common/explorerModel';
import { IListService } from 'vs/platform/list/browser/listService';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IPartService } from 'vs/workbench/services/part/common/partService';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
@@ -133,7 +133,7 @@ export class ExplorerView extends CollapsibleView {
const titleSpan = $('span').appendTo(titleDiv);
const setHeader = () => {
const workspace = this.contextService.getWorkspace();
- const title = workspace.roots.map(root => labels.getPathLabel(root.fsPath, void 0, this.environmentService)).join();
+ const title = workspace.folders.map(folder => labels.getPathLabel(folder.fsPath, void 0, this.environmentService)).join();
titleSpan.text(this.name).title(title);
};
this.toDispose.push(this.contextService.onDidChangeWorkspaceName(() => setHeader()));
@@ -166,7 +166,7 @@ export class ExplorerView extends CollapsibleView {
};
this.toDispose.push(this.themeService.onDidFileIconThemeChange(onFileIconThemeChange));
- this.toDispose.push(this.contextService.onDidChangeWorkspaceRoots(() => this.refreshFromEvent()));
+ this.toDispose.push(this.contextService.onDidChangeWorkspaceFolders(() => this.refreshFromEvent()));
onFileIconThemeChange(this.themeService.getFileIconTheme());
}
@@ -727,25 +727,25 @@ export class ExplorerView extends CollapsibleView {
let targetsToExpand: URI[] = [];
if (this.settings[ExplorerView.MEMENTO_EXPANDED_FOLDER_RESOURCES]) {
targetsToExpand = this.settings[ExplorerView.MEMENTO_EXPANDED_FOLDER_RESOURCES].map((e: string) => URI.parse(e));
- } else if (this.contextService.hasFolderWorkspace() || (this.contextService.hasMultiFolderWorkspace() && this.model.roots.length === 1)) {
- targetsToExpand = this.model.roots.map(root => root.resource); // always expand single folder workspace and multi folder workspace with only 1 root
+ } else if (this.model.roots.length === 1) {
+ targetsToExpand = this.model.roots.map(root => root.resource); // always expand if there is just one root
}
// First time refresh: Receive target through active editor input or selection and also include settings from previous session
if (!this.isCreated) {
const activeFile = this.getActiveFile();
if (activeFile) {
- const root = this.contextService.getRoot(activeFile);
- if (root) {
- const found = targetsToResolve.filter(t => t.root.resource.toString() === root.toString()).pop();
+ const workspaceFolder = this.contextService.getWorkspaceFolder(activeFile);
+ if (workspaceFolder) {
+ const found = targetsToResolve.filter(t => t.root.resource.toString() === workspaceFolder.toString()).pop();
found.options.resolveTo.push(activeFile);
}
}
targetsToExpand.forEach(toExpand => {
- const root = this.contextService.getRoot(toExpand);
- if (root) {
- const found = targetsToResolve.filter(ttr => ttr.resource.toString() === root.toString()).pop();
+ const workspaceFolder = this.contextService.getWorkspaceFolder(toExpand);
+ if (workspaceFolder) {
+ const found = targetsToResolve.filter(ttr => ttr.resource.toString() === workspaceFolder.toString()).pop();
found.options.resolveTo.push(toExpand);
}
});
@@ -778,7 +778,7 @@ export class ExplorerView extends CollapsibleView {
// Subsequent refresh: Merge stat into our local model and refresh tree
modelStats.forEach((modelStat, index) => FileStat.mergeLocalWithDisk(modelStat, this.model.roots[index]));
- const input = this.contextService.hasFolderWorkspace() ? this.model.roots[0] : this.model;
+ const input = this.contextService.getWorkbenchState() === WorkbenchState.FOLDER ? this.model.roots[0] : this.model;
if (input === this.explorerViewer.getInput()) {
return this.explorerViewer.refresh();
}
@@ -855,7 +855,7 @@ export class ExplorerView extends CollapsibleView {
// Stat needs to be resolved first and then revealed
const options: IResolveFileOptions = { resolveTo: [resource] };
- const rootUri = this.contextService.getRoot(resource) || this.model.roots[0].resource;
+ const rootUri = this.contextService.getWorkspaceFolder(resource) || this.model.roots[0].resource;
return this.fileService.resolveFile(rootUri, options).then(stat => {
// Convert to model
diff --git a/src/vs/workbench/parts/files/browser/views/explorerViewer.ts b/src/vs/workbench/parts/files/browser/views/explorerViewer.ts
index d67a2880f86..5061faf54cf 100644
--- a/src/vs/workbench/parts/files/browser/views/explorerViewer.ts
+++ b/src/vs/workbench/parts/files/browser/views/explorerViewer.ts
@@ -35,7 +35,7 @@ import { FileStat, NewStatPlaceholder, Model } from 'vs/workbench/parts/files/co
import { DragMouseEvent, IMouseEvent } from 'vs/base/browser/mouseEvent';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IPartService } from 'vs/workbench/services/part/common/partService';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IContextViewService, IContextMenuService } from 'vs/platform/contextview/browser/contextView';
@@ -549,7 +549,8 @@ export class FileSorter implements ISorter {
private sortOrder: SortOrder;
constructor(
- @IConfigurationService private configurationService: IConfigurationService
+ @IConfigurationService private configurationService: IConfigurationService,
+ @IWorkspaceContextService private contextService: IWorkspaceContextService
) {
this.toDispose = [];
@@ -570,6 +571,10 @@ export class FileSorter implements ISorter {
// Do not sort roots
if (statA.isRoot) {
+ if (statB.isRoot) {
+ const ws = this.contextService.getWorkspace();
+ return ws.folders.indexOf(statA.resource) - ws.folders.indexOf(statB.resource);
+ }
return -1;
}
if (statB.isRoot) {
@@ -655,16 +660,16 @@ export class FileFilter implements IFilter {
@IConfigurationService private configurationService: IConfigurationService
) {
this.hiddenExpressionPerRoot = new Map();
- this.contextService.onDidChangeWorkspaceRoots(() => this.updateConfiguration());
+ this.contextService.onDidChangeWorkspaceFolders(() => this.updateConfiguration());
}
public updateConfiguration(): boolean {
let needsRefresh = false;
- this.contextService.getWorkspace().roots.forEach(root => {
- const configuration = this.configurationService.getConfiguration(undefined, { resource: root });
+ this.contextService.getWorkspace().folders.forEach(folder => {
+ const configuration = this.configurationService.getConfiguration(undefined, { resource: folder });
const excludesConfig = (configuration && configuration.files && configuration.files.exclude) || Object.create(null);
- needsRefresh = needsRefresh || !objects.equals(this.hiddenExpressionPerRoot.get(root.toString()), excludesConfig);
- this.hiddenExpressionPerRoot.set(root.toString(), objects.clone(excludesConfig)); // do not keep the config, as it gets mutated under our hoods
+ needsRefresh = needsRefresh || !objects.equals(this.hiddenExpressionPerRoot.get(folder.toString()), excludesConfig);
+ this.hiddenExpressionPerRoot.set(folder.toString(), objects.clone(excludesConfig)); // do not keep the config, as it gets mutated under our hoods
});
return needsRefresh;
@@ -829,7 +834,7 @@ export class FileDragAndDrop extends SimpleFileResourceDragAndDrop {
// All (target = model)
if (target instanceof Model) {
- return this.contextService.hasMultiFolderWorkspace() ? DRAG_OVER_ACCEPT_BUBBLE_DOWN_COPY(false) : DRAG_OVER_REJECT; // can only drop folders to workspace
+ return this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE ? DRAG_OVER_ACCEPT_BUBBLE_DOWN_COPY(false) : DRAG_OVER_REJECT; // can only drop folders to workspace
}
// All (target = file/folder)
@@ -838,8 +843,7 @@ export class FileDragAndDrop extends SimpleFileResourceDragAndDrop {
return fromDesktop || isCopy ? DRAG_OVER_ACCEPT_BUBBLE_DOWN_COPY(true) : DRAG_OVER_ACCEPT_BUBBLE_DOWN(true);
}
- const workspace = this.contextService.getWorkspace();
- if (workspace && workspace.roots.every(r => r.toString() !== target.resource.toString())) {
+ if (this.contextService.getWorkspace().folders.every(r => r.toString() !== target.resource.toString())) {
return fromDesktop || isCopy ? DRAG_OVER_ACCEPT_BUBBLE_UP_COPY : DRAG_OVER_ACCEPT_BUBBLE_UP;
}
}
@@ -883,8 +887,8 @@ export class FileDragAndDrop extends SimpleFileResourceDragAndDrop {
return void 0; // TODO@Ben multi root
}
- if (this.contextService.hasMultiFolderWorkspace()) {
- return this.workspaceEditingService.addRoots(folders);
+ if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
+ return this.workspaceEditingService.addFolders(folders);
}
// If we are in single-folder context, ask for confirmation to create a workspace
@@ -895,8 +899,8 @@ export class FileDragAndDrop extends SimpleFileResourceDragAndDrop {
});
if (result) {
- const currentRoots = this.contextService.getWorkspace().roots;
- const newRoots = [...currentRoots, ...folders];
+ const currentFolders = this.contextService.getWorkspace().folders;
+ const newRoots = [...currentFolders, ...folders];
return this.windowService.createAndOpenWorkspace(distinct(newRoots.map(root => root.fsPath)));
}
diff --git a/src/vs/workbench/parts/files/common/explorerModel.ts b/src/vs/workbench/parts/files/common/explorerModel.ts
index e3d97b1d97b..cbcbad4b33d 100644
--- a/src/vs/workbench/parts/files/common/explorerModel.ts
+++ b/src/vs/workbench/parts/files/common/explorerModel.ts
@@ -25,8 +25,8 @@ export class Model {
private _roots: FileStat[];
constructor( @IWorkspaceContextService private contextService: IWorkspaceContextService) {
- const setRoots = () => this._roots = this.contextService.getWorkspace().roots.map(uri => new FileStat(uri, undefined));
- this.contextService.onDidChangeWorkspaceRoots(() => setRoots());
+ const setRoots = () => this._roots = this.contextService.getWorkspace().folders.map(uri => new FileStat(uri, undefined));
+ this.contextService.onDidChangeWorkspaceFolders(() => setRoots());
setRoots();
}
@@ -49,9 +49,9 @@ export class Model {
* Will return null in case the FileStat does not exist.
*/
public findClosest(resource: URI): FileStat {
- const rootUri = this.contextService.getRoot(resource);
- if (rootUri) {
- const root = this.roots.filter(r => r.resource.toString() === rootUri.toString()).pop();
+ const folder = this.contextService.getWorkspaceFolder(resource);
+ if (folder) {
+ const root = this.roots.filter(r => r.resource.toString() === folder.toString()).pop();
if (root) {
return root.find(resource);
}
diff --git a/src/vs/workbench/parts/output/common/outputLinkProvider.ts b/src/vs/workbench/parts/output/common/outputLinkProvider.ts
index abdd048bdad..e457e1073c4 100644
--- a/src/vs/workbench/parts/output/common/outputLinkProvider.ts
+++ b/src/vs/workbench/parts/output/common/outputLinkProvider.ts
@@ -10,7 +10,7 @@ import URI from 'vs/base/common/uri';
import { RunOnceScheduler, wireCancellationToken } from 'vs/base/common/async';
import { IModelService } from 'vs/editor/common/services/modelService';
import { LinkProviderRegistry, ILink } from 'vs/editor/common/modes';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { OUTPUT_MODE_ID } from 'vs/workbench/parts/output/common/output';
import { MonacoWebWorker, createWebWorker } from 'vs/editor/common/services/webWorker';
import { ICreateData, OutputLinkComputer } from 'vs/workbench/parts/output/common/outputLinkComputer';
@@ -37,13 +37,13 @@ export class OutputLinkProvider {
}
private registerListeners(): void {
- this.contextService.onDidChangeWorkspaceRoots(() => this.updateLinkProviderWorker());
+ this.contextService.onDidChangeWorkspaceFolders(() => this.updateLinkProviderWorker());
}
private updateLinkProviderWorker(): void {
// We have a workspace
- if (this.contextService.hasWorkspace()) {
+ if (this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY) {
// Register link provider unless done already
if (!this.linkProviderRegistration) {
@@ -55,7 +55,7 @@ export class OutputLinkProvider {
}
// Update link provider worker if workspace roots changed
- const newWorkspacesCount = this.contextService.getWorkspace().roots.length;
+ const newWorkspacesCount = this.contextService.getWorkspace().folders.length;
if (this.workspacesCount !== newWorkspacesCount) {
this.workspacesCount = newWorkspacesCount;
@@ -80,7 +80,7 @@ export class OutputLinkProvider {
if (!this.worker) {
const createData: ICreateData = {
- workspaceFolders: this.contextService.getWorkspace().roots.map(root => root.toString())
+ workspaceFolders: this.contextService.getWorkspace().folders.map(folder => folder.toString())
};
this.worker = createWebWorker(this.modelService, {
diff --git a/src/vs/workbench/parts/preferences/browser/preferencesActions.ts b/src/vs/workbench/parts/preferences/browser/preferencesActions.ts
index 1cee1d5d6c2..aeee25d30bf 100644
--- a/src/vs/workbench/parts/preferences/browser/preferencesActions.ts
+++ b/src/vs/workbench/parts/preferences/browser/preferencesActions.ts
@@ -11,7 +11,7 @@ import { Action } from 'vs/base/common/actions';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IQuickOpenService, IPickOpenEntry, IFilePickOpenEntry } from 'vs/platform/quickOpen/common/quickOpen';
import { IPreferencesService, getSettingsTargetName } from 'vs/workbench/parts/preferences/common/preferences';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { ConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditing';
export class OpenGlobalSettingsAction extends Action {
@@ -80,7 +80,7 @@ export class OpenWorkspaceSettingsAction extends Action {
@IWorkspaceContextService private workspaceContextService: IWorkspaceContextService
) {
super(id, label);
- this.enabled = this.workspaceContextService.hasWorkspace();
+ this.enabled = this.workspaceContextService.getWorkbenchState() !== WorkbenchState.EMPTY;
}
public run(event?: any): TPromise {
@@ -101,13 +101,13 @@ export class OpenFolderSettingsAction extends Action {
@IQuickOpenService private quickOpenService: IQuickOpenService
) {
super(id, label);
- this.enabled = this.workspaceContextService.hasMultiFolderWorkspace();
+ this.enabled = this.workspaceContextService.getWorkbenchState() === WorkbenchState.WORKSPACE;
}
public run(): TPromise {
- const picks: IPickOpenEntry[] = this.workspaceContextService.getWorkspace().roots.map((root, index) => {
+ const picks: IPickOpenEntry[] = this.workspaceContextService.getWorkspace().folders.map((folder, index) => {
return {
- label: getSettingsTargetName(ConfigurationTarget.FOLDER, root, this.workspaceContextService),
+ label: getSettingsTargetName(ConfigurationTarget.FOLDER, folder, this.workspaceContextService),
id: `${index}`
};
});
@@ -115,7 +115,7 @@ export class OpenFolderSettingsAction extends Action {
return this.quickOpenService.pick(picks, { placeHolder: nls.localize('pickFolder', "Select Folder") })
.then(pick => {
if (pick) {
- return this.preferencesService.openFolderSettings(this.workspaceContextService.getWorkspace().roots[parseInt(pick.id)]);
+ return this.preferencesService.openFolderSettings(this.workspaceContextService.getWorkspace().folders[parseInt(pick.id)]);
}
return undefined;
});
diff --git a/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts b/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts
index 7b92f7a36ff..624ab8f0ef9 100644
--- a/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts
+++ b/src/vs/workbench/parts/preferences/browser/preferencesEditor.ts
@@ -152,7 +152,7 @@ export class PreferencesEditor extends BaseEditor {
this._register(this.sideBySidePreferencesWidget.onFocus(() => this.lastFocusedWidget = this.sideBySidePreferencesWidget));
this.preferencesRenderers = this._register(new PreferencesRenderers());
- this._register(this.workspaceContextService.onDidChangeWorkspaceRoots(() => this.onWorkspaceRootsChanged()));
+ this._register(this.workspaceContextService.onDidChangeWorkspaceFolders(() => this.onWorkspaceFoldersChanged()));
}
public setInput(newInput: PreferencesEditorInput, options?: EditorOptions): TPromise {
@@ -226,7 +226,7 @@ export class PreferencesEditor extends BaseEditor {
if (this.preferencesService.workspaceSettingsResource.fsPath === resource.fsPath) {
return ConfigurationTarget.WORKSPACE;
}
- if (this.workspaceContextService.getRoot(resource)) {
+ if (this.workspaceContextService.getWorkspaceFolder(resource)) {
return ConfigurationTarget.FOLDER;
}
return null;
@@ -240,10 +240,10 @@ export class PreferencesEditor extends BaseEditor {
return resource;
}
- return this.workspaceContextService.getRoot(resource);
+ return this.workspaceContextService.getWorkspaceFolder(resource);
}
- private onWorkspaceRootsChanged(): void {
+ private onWorkspaceFoldersChanged(): void {
if (this.input) {
const settingsResource = toResource((this.input).master);
const targetResource = this.getSettingsConfigurationTargetUri(settingsResource);
@@ -886,13 +886,10 @@ class SettingsEditorContribution extends AbstractSettingsEditorContribution impl
return true;
}
- const workspace = this.workspaceContextService.getWorkspace();
- if (workspace) {
- for (const root of workspace.roots) {
- const folderSettingsResource = this.preferencesService.getFolderSettingsResource(root);
- if (folderSettingsResource && folderSettingsResource.fsPath === model.uri.fsPath) {
- return true;
- }
+ for (const folder of this.workspaceContextService.getWorkspace().folders) {
+ const folderSettingsResource = this.preferencesService.getFolderSettingsResource(folder);
+ if (folderSettingsResource && folderSettingsResource.fsPath === model.uri.fsPath) {
+ return true;
}
}
diff --git a/src/vs/workbench/parts/preferences/browser/preferencesRenderers.ts b/src/vs/workbench/parts/preferences/browser/preferencesRenderers.ts
index ad7e9950cfe..142d611efc6 100644
--- a/src/vs/workbench/parts/preferences/browser/preferencesRenderers.ts
+++ b/src/vs/workbench/parts/preferences/browser/preferencesRenderers.ts
@@ -31,7 +31,7 @@ import { IMessageService, Severity } from 'vs/platform/message/common/message';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
import { ModelDecorationOptions } from 'vs/editor/common/model/textModelWithDecorations';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { MarkdownString } from 'vs/base/common/htmlContent';
export interface IPreferencesRenderer extends IDisposable {
@@ -1064,7 +1064,7 @@ class WorkspaceConfigurationRenderer extends Disposable {
}
public render(): void {
- if (this.workspaceContextService.hasMultiFolderWorkspace()) {
+ if (this.workspaceContextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
this.editor.changeDecorations(changeAccessor => this.decorationIds = changeAccessor.deltaDecorations(this.decorationIds, []));
const ranges: IRange[] = [];
diff --git a/src/vs/workbench/parts/preferences/browser/preferencesService.ts b/src/vs/workbench/parts/preferences/browser/preferencesService.ts
index d37e517d962..e820df5ea27 100644
--- a/src/vs/workbench/parts/preferences/browser/preferencesService.ts
+++ b/src/vs/workbench/parts/preferences/browser/preferencesService.ts
@@ -16,7 +16,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
import { Emitter } from 'vs/base/common/event';
import { EditorInput } from 'vs/workbench/common/editor';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
import { Position as EditorPosition, IEditor } from 'vs/platform/editor/common/editor';
import { ICommonCodeEditor } from 'vs/editor/common/editorCommon';
@@ -179,7 +179,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic
return this.createEditableSettingsEditorModel(ConfigurationTarget.WORKSPACE, workspaceSettingsUri);
}
- if (this.contextService.hasMultiFolderWorkspace()) {
+ if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
return this.createEditableSettingsEditorModel(ConfigurationTarget.FOLDER, uri);
}
@@ -191,7 +191,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic
}
openWorkspaceSettings(): TPromise {
- if (!this.contextService.hasWorkspace()) {
+ if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) {
this.messageService.show(Severity.Info, nls.localize('openFolderFirst', "Open a folder first to create workspace settings"));
return TPromise.as(null);
}
@@ -299,7 +299,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic
}
private resolveSettingsContentFromWorkspaceConfiguration(): TPromise {
- if (this.contextService.hasMultiFolderWorkspace()) {
+ if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
return this.textModelResolverService.createModelReference(this.contextService.getWorkspace().configuration)
.then(reference => {
const model = reference.object.textEditorModel;
@@ -316,17 +316,14 @@ export class PreferencesService extends Disposable implements IPreferencesServic
case ConfigurationTarget.USER:
return URI.file(this.environmentService.appSettingsPath);
case ConfigurationTarget.WORKSPACE:
+ if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) {
+ return null;
+ }
const workspace = this.contextService.getWorkspace();
- if (this.contextService.hasFolderWorkspace()) {
- return this.toResource(paths.join('.vscode', 'settings.json'), workspace.roots[0]);
- }
- if (this.contextService.hasMultiFolderWorkspace()) {
- return workspace.configuration;
- }
- return null;
+ return workspace.configuration || this.toResource(paths.join('.vscode', 'settings.json'), workspace.folders[0]);
case ConfigurationTarget.FOLDER:
- const root = this.contextService.getRoot(resource);
- return root ? this.toResource(paths.join('.vscode', 'settings.json'), root) : null;
+ const folder = this.contextService.getWorkspaceFolder(resource);
+ return folder ? this.toResource(paths.join('.vscode', 'settings.json'), folder) : null;
}
return null;
}
@@ -336,7 +333,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic
}
private createSettingsIfNotExists(target: ConfigurationTarget, resource: URI): TPromise {
- if (this.contextService.hasMultiFolderWorkspace() && target === ConfigurationTarget.WORKSPACE) {
+ if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE && target === ConfigurationTarget.WORKSPACE) {
if (!this.configurationService.keys().workspace.length) {
return this.jsonEditingService.write(resource, { key: 'settings', value: {} }, true).then(null, () => { });
}
diff --git a/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts b/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts
index c2212fcb657..cb4392d3c8c 100644
--- a/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts
+++ b/src/vs/workbench/parts/preferences/browser/preferencesWidgets.ts
@@ -20,7 +20,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IContextViewService, IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { ISettingsGroup, IPreferencesService, getSettingsTargetName } from 'vs/workbench/parts/preferences/common/preferences';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IAction, IActionRunner } from 'vs/base/common/actions';
import { attachInputBoxStyler, attachStylerCallback, attachSelectBoxStyler } from 'vs/platform/theme/common/styler';
import { IThemeService } from 'vs/platform/theme/common/themeService';
@@ -293,7 +293,7 @@ export class SettingsTargetsWidget extends Widget {
private create(parent: HTMLElement): void {
this.settingsTargetsContainer = DOM.append(parent, DOM.$('.settings-targets-widget'));
- this.settingsTargetsContainer.style.width = this.workspaceContextService.hasMultiFolderWorkspace() ? '200px' : '150px';
+ this.settingsTargetsContainer.style.width = this.workspaceContextService.getWorkbenchState() === WorkbenchState.WORKSPACE ? '200px' : '150px';
const targetElement = DOM.append(this.settingsTargetsContainer, DOM.$('.settings-target'));
this.targetLabel = DOM.append(targetElement, DOM.$('.settings-target-label'));
@@ -337,7 +337,7 @@ export class SettingsTargetsWidget extends Widget {
run: () => this.onTargetClicked(userSettingsResource)
});
- if (this.workspaceContextService.hasWorkspace()) {
+ if (this.workspaceContextService.getWorkbenchState() !== WorkbenchState.EMPTY) {
const workspaceSettingsResource = this.preferencesService.workspaceSettingsResource;
actions.push({
id: 'workspaceSettingsTarget',
@@ -348,15 +348,15 @@ export class SettingsTargetsWidget extends Widget {
});
}
- if (this.workspaceContextService.hasMultiFolderWorkspace()) {
+ if (this.workspaceContextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
actions.push(new Separator());
- actions.push(...this.workspaceContextService.getWorkspace().roots.map((root, index) => {
+ actions.push(...this.workspaceContextService.getWorkspace().folders.map((folder, index) => {
return {
id: 'folderSettingsTarget' + index,
- label: getSettingsTargetName(ConfigurationTarget.FOLDER, root, this.workspaceContextService),
- checked: this.uri.fsPath === root.fsPath,
+ label: getSettingsTargetName(ConfigurationTarget.FOLDER, folder, this.workspaceContextService),
+ checked: this.uri.fsPath === folder.fsPath,
enabled: true,
- run: () => this.onTargetClicked(root)
+ run: () => this.onTargetClicked(folder)
};
}));
}
diff --git a/src/vs/workbench/parts/preferences/common/preferences.ts b/src/vs/workbench/parts/preferences/common/preferences.ts
index 7037e86c7e7..ec69c7a8cb8 100644
--- a/src/vs/workbench/parts/preferences/common/preferences.ts
+++ b/src/vs/workbench/parts/preferences/common/preferences.ts
@@ -107,8 +107,8 @@ export function getSettingsTargetName(target: ConfigurationTarget, resource: URI
case ConfigurationTarget.WORKSPACE:
return localize('workspaceSettingsTarget', "Workspace Settings");
case ConfigurationTarget.FOLDER:
- const root = workspaceContextService.getRoot(resource);
- return root ? paths.basename(root.fsPath) : '';
+ const folder = workspaceContextService.getWorkspaceFolder(resource);
+ return folder ? paths.basename(folder.fsPath) : '';
}
}
diff --git a/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts b/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts
index f83349ff4f7..f5dc4573e53 100644
--- a/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts
+++ b/src/vs/workbench/parts/relauncher/electron-browser/relauncher.contribution.ts
@@ -30,8 +30,8 @@ export class SettingsChangeRelauncher implements IWorkbenchContribution {
private nativeTabs: boolean;
private updateChannel: string;
private enableCrashReporter: boolean;
- private rootCount: number;
- private firstRootPath: string;
+ private foldersCount: number;
+ private firstFolderPath: string;
constructor(
@IWindowsService private windowsService: IWindowsService,
@@ -44,12 +44,8 @@ export class SettingsChangeRelauncher implements IWorkbenchContribution {
@IExtensionService private extensionService: IExtensionService
) {
const workspace = this.contextService.getWorkspace();
- if (workspace) {
- this.rootCount = workspace.roots.length;
- this.firstRootPath = workspace.roots.length > 0 ? workspace.roots[0].fsPath : void 0;
- } else {
- this.rootCount = 0;
- }
+ this.foldersCount = workspace.folders.length;
+ this.firstFolderPath = workspace.folders.length > 0 ? workspace.folders[0].fsPath : void 0;
this.onConfigurationChange(configurationService.getConfiguration(), false);
@@ -58,7 +54,7 @@ export class SettingsChangeRelauncher implements IWorkbenchContribution {
private registerListeners(): void {
this.toDispose.push(this.configurationService.onDidUpdateConfiguration(e => this.onConfigurationChange(this.configurationService.getConfiguration(), true)));
- this.toDispose.push(this.contextService.onDidChangeWorkspaceRoots(() => this.onDidChangeWorkspaceRoots()));
+ this.toDispose.push(this.contextService.onDidChangeWorkspaceFolders(() => this.onDidChangeWorkspaceFolders()));
}
private onConfigurationChange(config: IConfiguration, notify: boolean): void {
@@ -99,27 +95,27 @@ export class SettingsChangeRelauncher implements IWorkbenchContribution {
}
}
- private onDidChangeWorkspaceRoots(): void {
+ private onDidChangeWorkspaceFolders(): void {
const workspace = this.contextService.getWorkspace();
- const newRootCount = workspace ? workspace.roots.length : 0;
- const newFirstRootPath = workspace && workspace.roots.length > 0 ? workspace.roots[0].fsPath : void 0;
+ const newFoldersCount = workspace.folders.length;
+ const newFirstFolderPath = workspace.folders.length > 0 ? workspace.folders[0].fsPath : void 0;
let reloadWindow = false;
let reloadExtensionHost = false;
- if (this.rootCount === 0 && newRootCount > 0) {
+ if (this.foldersCount === 0 && newFoldersCount > 0) {
reloadWindow = true; // transition: from 0 folders to 1+
- } else if (this.rootCount > 0 && newRootCount === 0) {
+ } else if (this.foldersCount > 0 && newFoldersCount === 0) {
reloadWindow = true; // transition: from 1+ folders to 0
}
- if (this.firstRootPath !== newFirstRootPath) {
+ if (this.firstFolderPath !== newFirstFolderPath) {
reloadExtensionHost = true; // first root folder changed (impact on deprecated workspace.rootPath API)
}
- this.rootCount = newRootCount;
- this.firstRootPath = newFirstRootPath;
+ this.foldersCount = newFoldersCount;
+ this.firstFolderPath = newFirstFolderPath;
// Reload window if this is needed
if (reloadWindow) {
diff --git a/src/vs/workbench/parts/search/browser/openFileHandler.ts b/src/vs/workbench/parts/search/browser/openFileHandler.ts
index bb19b6d2ce7..7fbbcfdbe2c 100644
--- a/src/vs/workbench/parts/search/browser/openFileHandler.ts
+++ b/src/vs/workbench/parts/search/browser/openFileHandler.ts
@@ -164,7 +164,7 @@ export class OpenFileHandler extends QuickOpenHandler {
iconClass = 'file'; // only use a generic file icon if we are forced to use an icon and have no icon theme set otherwise
}
- const folderResources = this.contextService.hasWorkspace() ? this.contextService.getWorkspace().roots : [];
+ const folderResources = this.contextService.getWorkspace().folders;
return this.searchService.search(this.queryBuilder.file(folderResources, query)).then((complete) => {
const results: QuickOpenEntry[] = [];
for (let i = 0; i < complete.results.length; i++) {
@@ -199,7 +199,7 @@ export class OpenFileHandler extends QuickOpenHandler {
useRipgrep: this.experimentService.getExperiments().ripgrepQuickSearch
};
- const folderResources = this.contextService.hasWorkspace() ? this.contextService.getWorkspace().roots : [];
+ const folderResources = this.contextService.getWorkspace().folders;
const query = this.queryBuilder.file(folderResources, options);
return query;
diff --git a/src/vs/workbench/parts/search/browser/searchViewlet.ts b/src/vs/workbench/parts/search/browser/searchViewlet.ts
index 6f6dce24526..e550acb92fb 100644
--- a/src/vs/workbench/parts/search/browser/searchViewlet.ts
+++ b/src/vs/workbench/parts/search/browser/searchViewlet.ts
@@ -41,7 +41,7 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IMessageService, IConfirmation } from 'vs/platform/message/common/message';
import { IProgressService } from 'vs/platform/progress/common/progress';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { KeyCode } from 'vs/base/common/keyCodes';
@@ -239,7 +239,7 @@ export class SearchViewlet extends Viewlet {
}).getHTMLElement();
this.messages = builder.div({ 'class': 'messages' }).hide().clone();
- if (!this.contextService.hasWorkspace()) {
+ if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) {
this.searchWithoutFolderMessage(this.clearMessage());
}
@@ -468,7 +468,7 @@ export class SearchViewlet extends Viewlet {
this.results = div;
this.results.addClass('show-file-icons');
- let dataSource = new SearchDataSource(this.contextService.hasMultiFolderWorkspace());
+ let dataSource = new SearchDataSource(this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE);
let renderer = this.instantiationService.createInstance(SearchRenderer, this.getActionRunner(), this);
let dnd = new SimpleFileResourceDragAndDrop(obj => obj instanceof FileMatch ? obj.resource() : void 0);
@@ -753,7 +753,7 @@ export class SearchViewlet extends Viewlet {
public clearSearchResults(): void {
this.viewModel.searchResult.clear();
this.showEmptyStage();
- if (!this.contextService.hasWorkspace()) {
+ if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) {
this.searchWithoutFolderMessage(this.clearMessage());
}
this.searchWidget.clear();
@@ -871,22 +871,22 @@ export class SearchViewlet extends Viewlet {
public searchInFolder(resource: URI): void {
let folderPath = null;
const workspace = this.contextService.getWorkspace();
- if (workspace && resource) {
- if (this.contextService.hasFolderWorkspace()) {
+ if (resource) {
+ if (this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) {
// Show relative path from the root for single-root mode
- folderPath = paths.relative(workspace.roots[0].fsPath, resource.fsPath);
+ folderPath = paths.relative(workspace.folders[0].fsPath, resource.fsPath);
if (folderPath && folderPath !== '.') {
folderPath = './' + folderPath;
}
} else {
- const owningRoot = this.contextService.getRoot(resource);
- if (owningRoot) {
- const owningRootBasename = paths.basename(owningRoot.fsPath);
+ const owningFolder = this.contextService.getWorkspaceFolder(resource);
+ if (owningFolder) {
+ const owningRootBasename = paths.basename(owningFolder.fsPath);
// If this root is the only one with its basename, use a relative ./ path. If there is another, use an absolute path
- const isUniqueRoot = workspace.roots.filter(root => paths.basename(root.fsPath) === owningRootBasename).length === 1;
- if (isUniqueRoot) {
- folderPath = `./${owningRootBasename}/${paths.relative(owningRoot.fsPath, resource.fsPath)}`;
+ const isUniqueFolder = workspace.folders.filter(root => paths.basename(root.fsPath) === owningRootBasename).length === 1;
+ if (isUniqueFolder) {
+ folderPath = `./${owningRootBasename}/${paths.relative(owningFolder.fsPath, resource.fsPath)}`;
} else {
folderPath = resource.fsPath;
}
@@ -960,7 +960,7 @@ export class SearchViewlet extends Viewlet {
excludePattern,
includePattern
};
- const folderResources = this.contextService.hasWorkspace() ? this.contextService.getWorkspace().roots : [];
+ const folderResources = this.contextService.getWorkspace().folders;
const onQueryValidationError = (err: Error) => {
this.searchWidget.searchInput.showMessage({ content: err.message, type: MessageType.ERROR });
@@ -1123,7 +1123,7 @@ export class SearchViewlet extends Viewlet {
}).on(dom.EventType.CLICK, (e: MouseEvent) => {
dom.EventHelper.stop(e, false);
- let editorPromise = this.contextService.hasWorkspace() ? this.preferencesService.openWorkspaceSettings() : this.preferencesService.openGlobalSettings();
+ let editorPromise = this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? this.preferencesService.openWorkspaceSettings() : this.preferencesService.openGlobalSettings();
editorPromise.done(editor => {
if (editor instanceof PreferencesEditor) {
editor.focusSearch('.exclude');
@@ -1148,7 +1148,7 @@ export class SearchViewlet extends Viewlet {
});
}
- if (!this.contextService.hasWorkspace()) {
+ if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) {
this.searchWithoutFolderMessage(div);
}
} else {
diff --git a/src/vs/workbench/parts/search/common/queryBuilder.ts b/src/vs/workbench/parts/search/common/queryBuilder.ts
index 51e17c9a4fb..49fa52d03d5 100644
--- a/src/vs/workbench/parts/search/common/queryBuilder.ts
+++ b/src/vs/workbench/parts/search/common/queryBuilder.ts
@@ -12,7 +12,7 @@ import * as glob from 'vs/base/common/glob';
import * as paths from 'vs/base/common/paths';
import * as strings from 'vs/base/common/strings';
import uri from 'vs/base/common/uri';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IPatternInfo, IQueryOptions, IFolderQuery, ISearchQuery, QueryType, ISearchConfiguration, getExcludes, pathIncludedInQuery } from 'vs/platform/search/common/search';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
@@ -184,7 +184,7 @@ export class QueryBuilder {
* Split search paths (./ or absolute paths in the includePatterns) into absolute paths and globs applied to those paths
*/
private expandSearchPathPatterns(searchPaths: string[]): ISearchPathPattern[] {
- if (!this.workspaceContextService.hasWorkspace() || !searchPaths || !searchPaths.length) {
+ if (this.workspaceContextService.getWorkbenchState() === WorkbenchState.EMPTY || !searchPaths || !searchPaths.length) {
// No workspace => ignore search paths
return [];
}
@@ -212,17 +212,16 @@ export class QueryBuilder {
return [paths.normalize(searchPath)];
}
- const workspace = this.workspaceContextService.getWorkspace();
- if (this.workspaceContextService.hasFolderWorkspace()) {
+ if (this.workspaceContextService.getWorkbenchState() === WorkbenchState.FOLDER) { // TODO: @Sandy Try checking workspace folders length instead.
return [paths.normalize(
- paths.join(workspace.roots[0].fsPath, searchPath))];
+ paths.join(this.workspaceContextService.getWorkspace().folders[0].fsPath, searchPath))];
} else if (searchPath === './') {
return []; // ./ or ./**/foo makes sense for single-folder but not multi-folder workspaces
} else {
const relativeSearchPathMatch = searchPath.match(/\.[\/\\]([^\/\\]+)([\/\\].+)?/);
if (relativeSearchPathMatch) {
const searchPathRoot = relativeSearchPathMatch[1];
- const matchingRoots = workspace.roots.filter(root => paths.basename(root.fsPath) === searchPathRoot);
+ const matchingRoots = this.workspaceContextService.getWorkspace().folders.filter(folder => paths.basename(folder.fsPath) === searchPathRoot);
if (matchingRoots.length) {
return matchingRoots.map(root => {
return relativeSearchPathMatch[2] ?
diff --git a/src/vs/workbench/parts/search/test/common/queryBuilder.test.ts b/src/vs/workbench/parts/search/test/common/queryBuilder.test.ts
index 9a492fa3f65..8c79981d63f 100644
--- a/src/vs/workbench/parts/search/test/common/queryBuilder.test.ts
+++ b/src/vs/workbench/parts/search/test/common/queryBuilder.test.ts
@@ -154,7 +154,7 @@ suite('QueryBuilder', () => {
const ROOT_2_URI = getUri(ROOT_2);
const ROOT_3 = fixPath('/project/root3');
const ROOT_3_URI = getUri(ROOT_3);
- mockWorkspace.roots = [ROOT_1_URI, ROOT_2_URI, ROOT_3_URI];
+ mockWorkspace.folders = [ROOT_1_URI, ROOT_2_URI, ROOT_3_URI];
mockWorkspace.configuration = uri.file(fixPath('/config'));
mockConfigService.setUserConfiguration('search', {
@@ -473,7 +473,7 @@ suite('QueryBuilder', () => {
test('relative includes w/two root folders', () => {
const ROOT_2 = '/project/root2';
- mockWorkspace.roots = [ROOT_1_URI, getUri(ROOT_2)];
+ mockWorkspace.folders = [ROOT_1_URI, getUri(ROOT_2)];
mockWorkspace.configuration = uri.file(fixPath('config'));
[
@@ -513,7 +513,7 @@ suite('QueryBuilder', () => {
test('relative includes w/multiple ambiguous root folders', () => {
const ROOT_2 = '/project/rootB';
const ROOT_3 = '/otherproject/rootB';
- mockWorkspace.roots = [ROOT_1_URI, getUri(ROOT_2), getUri(ROOT_3)];
+ mockWorkspace.folders = [ROOT_1_URI, getUri(ROOT_2), getUri(ROOT_3)];
mockWorkspace.configuration = uri.file(fixPath('/config'));
[
diff --git a/src/vs/workbench/parts/tasks/browser/quickOpen.ts b/src/vs/workbench/parts/tasks/browser/quickOpen.ts
index 2f64e812655..32a4d495b83 100644
--- a/src/vs/workbench/parts/tasks/browser/quickOpen.ts
+++ b/src/vs/workbench/parts/tasks/browser/quickOpen.ts
@@ -21,7 +21,7 @@ import { ActionBarContributor, ContributableActionProvider } from 'vs/workbench/
export class TaskEntry extends Model.QuickOpenEntry {
- constructor(protected taskService: ITaskService, protected quickOpenService: IQuickOpenService, protected _task: CustomTask | ContributedTask, highlights: Model.IHighlight[] = []) {
+ constructor(protected quickOpenService: IQuickOpenService, protected taskService: ITaskService, protected _task: CustomTask | ContributedTask, highlights: Model.IHighlight[] = []) {
super(highlights);
}
@@ -29,6 +29,17 @@ export class TaskEntry extends Model.QuickOpenEntry {
return this.task._label;
}
+ public getDescription(): string {
+ if (!this.taskService.hasMultipleFolders()) {
+ return null;
+ }
+ let workspaceFolder = Task.getWorkspaceFolder(this.task);
+ if (!workspaceFolder) {
+ return null;
+ }
+ return workspaceFolder.uri.fsPath;
+ }
+
public getAriaLabel(): string {
return nls.localize('entryAriaLabel', "{0}, tasks", this.getLabel());
}
diff --git a/src/vs/workbench/parts/tasks/browser/taskQuickOpen.ts b/src/vs/workbench/parts/tasks/browser/taskQuickOpen.ts
index 46d3c023200..b7325389b2b 100644
--- a/src/vs/workbench/parts/tasks/browser/taskQuickOpen.ts
+++ b/src/vs/workbench/parts/tasks/browser/taskQuickOpen.ts
@@ -14,12 +14,11 @@ import { CustomTask, ContributedTask } from 'vs/workbench/parts/tasks/common/tas
import { ITaskService } from 'vs/workbench/parts/tasks/common/taskService';
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
-
import * as base from './quickOpen';
class TaskEntry extends base.TaskEntry {
- constructor(taskService: ITaskService, quickOpenService: IQuickOpenService, task: CustomTask | ContributedTask, highlights: Model.IHighlight[] = []) {
- super(taskService, quickOpenService, task, highlights);
+ constructor(quickOpenService: IQuickOpenService, taskService: ITaskService, task: CustomTask | ContributedTask, highlights: Model.IHighlight[] = []) {
+ super(quickOpenService, taskService, task, highlights);
}
public run(mode: QuickOpen.Mode, context: Model.IContext): boolean {
@@ -36,8 +35,8 @@ export class QuickOpenHandler extends base.QuickOpenHandler {
constructor(
@IQuickOpenService quickOpenService: IQuickOpenService,
- @ITaskService taskService: ITaskService,
- @IExtensionService extensionService: IExtensionService
+ @IExtensionService extensionService: IExtensionService,
+ @ITaskService taskService: ITaskService
) {
super(quickOpenService, taskService);
this.activationPromise = extensionService.activateByEvent('onCommand:workbench.action.tasks.runTask');
@@ -54,7 +53,7 @@ export class QuickOpenHandler extends base.QuickOpenHandler {
}
protected createEntry(task: CustomTask | ContributedTask, highlights: Model.IHighlight[]): base.TaskEntry {
- return new TaskEntry(this.taskService, this.quickOpenService, task, highlights);
+ return new TaskEntry(this.quickOpenService, this.taskService, task, highlights);
}
public getEmptyLabel(searchString: string): string {
diff --git a/src/vs/workbench/parts/tasks/common/taskService.ts b/src/vs/workbench/parts/tasks/common/taskService.ts
index 7598b170398..d56ad59ce58 100644
--- a/src/vs/workbench/parts/tasks/common/taskService.ts
+++ b/src/vs/workbench/parts/tasks/common/taskService.ts
@@ -59,7 +59,8 @@ export interface ITaskService extends IEventEmitter {
getTasksForGroup(group: string): TPromise;
getRecentlyUsedTasks(): LinkedMap;
- canCustomize(): boolean;
+ hasMultipleFolders();
+ canCustomize(task: ContributedTask | CustomTask): boolean;
customize(task: ContributedTask | CustomTask, properties?: {}, openConfig?: boolean): TPromise;
openConfig(task: CustomTask): TPromise;
diff --git a/src/vs/workbench/parts/tasks/common/tasks.ts b/src/vs/workbench/parts/tasks/common/tasks.ts
index fd9b28ce2d5..9c15a51436b 100644
--- a/src/vs/workbench/parts/tasks/common/tasks.ts
+++ b/src/vs/workbench/parts/tasks/common/tasks.ts
@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
+import URI from 'vs/base/common/uri';
import * as Types from 'vs/base/common/types';
import { IJSONSchemaMap } from 'vs/base/common/jsonSchema';
@@ -215,34 +216,47 @@ export namespace TaskGroup {
export type TaskGroup = 'clean' | 'build' | 'rebuild' | 'test';
+export enum TaskScope {
+ Global = 1,
+ Workspace = 2,
+ Folder = 3
+}
+
export namespace TaskSourceKind {
export const Workspace: 'workspace' = 'workspace';
export const Extension: 'extension' = 'extension';
export const Composite: 'composite' = 'composite';
}
+export interface WorkspaceFolder {
+ uri: URI;
+}
+
export interface TaskSourceConfigElement {
+ workspaceFolder: WorkspaceFolder;
file: string;
index: number;
element: any;
}
export interface WorkspaceTaskSource {
- kind: 'workspace';
- label: string;
- config: TaskSourceConfigElement;
- customizes?: TaskIdentifier;
+ readonly kind: 'workspace';
+ readonly label: string;
+ readonly config: TaskSourceConfigElement;
+ readonly customizes?: TaskIdentifier;
}
export interface ExtensionTaskSource {
- kind: 'extension';
- label: string;
- extension: string;
+ readonly kind: 'extension';
+ readonly label: string;
+ readonly extension: string;
+ readonly scope: TaskScope;
+ readonly workspaceFolder: WorkspaceFolder | undefined;
}
export interface CompositeTaskSource {
- kind: 'composite';
- label: string;
+ readonly kind: 'composite';
+ readonly label: string;
}
export type TaskSource = WorkspaceTaskSource | ExtensionTaskSource | CompositeTaskSource;
@@ -411,6 +425,16 @@ export namespace Task {
}
}
+ export function getWorkspaceFolder(task: Task): WorkspaceFolder | undefined {
+ if (CustomTask.is(task)) {
+ return task._source.config.workspaceFolder;
+ } else if (ContributedTask.is(task)) {
+ return task._source.workspaceFolder;
+ } else {
+ return undefined;
+ }
+ }
+
export function getTelemetryKind(task: Task): string {
if (ContributedTask.is(task)) {
return 'extension';
diff --git a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts
index b96413b5374..c02e59693d7 100644
--- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts
+++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts
@@ -67,7 +67,7 @@ import { IPartService } from 'vs/workbench/services/part/common/partService';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
import { IConfigurationEditingService, ConfigurationTarget, IConfigurationValue } from 'vs/workbench/services/configuration/common/configurationEditing';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { IOutputService, IOutputChannelRegistry, Extensions as OutputExt, IOutputChannel } from 'vs/workbench/parts/output/common/output';
@@ -76,7 +76,7 @@ import { Scope, IActionBarRegistry, Extensions as ActionBarExtensions } from 'vs
import { ITerminalService } from 'vs/workbench/parts/terminal/common/terminal';
import { ITaskSystem, ITaskResolver, ITaskSummary, ITaskExecuteResult, TaskExecuteKind, TaskError, TaskErrors, TaskSystemEvents, TaskTerminateResponse } from 'vs/workbench/parts/tasks/common/taskSystem';
-import { Task, CustomTask, ConfiguringTask, ContributedTask, CompositeTask, TaskSet, TaskGroup, ExecutionEngine, JsonSchemaVersion, TaskSourceKind, TaskIdentifier } from 'vs/workbench/parts/tasks/common/tasks';
+import { Task, CustomTask, ConfiguringTask, ContributedTask, CompositeTask, TaskSet, TaskGroup, ExecutionEngine, JsonSchemaVersion, TaskSourceKind, TaskIdentifier, WorkspaceFolder } from 'vs/workbench/parts/tasks/common/tasks';
import { ITaskService, TaskServiceEvents, ITaskProvider, TaskEvent, RunOptions, CustomizationProperties } from 'vs/workbench/parts/tasks/common/taskService';
import { templates as taskTemplates } from 'vs/workbench/parts/tasks/common/taskTemplates';
@@ -113,7 +113,7 @@ abstract class OpenTaskConfigurationAction extends Action {
}
public run(event?: any): TPromise {
- if (!this.contextService.hasWorkspace()) {
+ if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) {
this.messageService.show(Severity.Info, nls.localize('ConfigureTaskRunnerAction.noWorkspace', 'Tasks are only available on a workspace folder.'));
return TPromise.as(undefined);
}
@@ -301,14 +301,14 @@ class BuildStatusBarItem extends Themable implements IStatusbarItem {
}
private registerListeners(): void {
- this.toUnbind.push(this.contextService.onDidChangeWorkspaceRoots(() => this.updateStyles()));
+ this.toUnbind.push(this.contextService.onDidChangeWorkspaceFolders(() => this.updateStyles()));
}
protected updateStyles(): void {
super.updateStyles();
this.icons.forEach(icon => {
- icon.style.backgroundColor = this.getColor(this.contextService.hasWorkspace() ? STATUS_BAR_FOREGROUND : STATUS_BAR_NO_FOLDER_FOREGROUND);
+ icon.style.backgroundColor = this.getColor(this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? STATUS_BAR_FOREGROUND : STATUS_BAR_NO_FOLDER_FOREGROUND);
});
}
@@ -618,7 +618,12 @@ interface WorkspaceTaskResult {
hasErrors: boolean;
}
-interface WorkspaceConfigurationResult {
+interface WorkspaceFolderTaskResult extends WorkspaceTaskResult {
+ workspaceFolder: WorkspaceFolder;
+}
+
+interface WorkspaceFolderConfigurationResult {
+ workspaceFolder: WorkspaceFolder;
config: TaskConfig.ExternalTaskRunnerConfiguration;
hasErrors: boolean;
}
@@ -657,9 +662,12 @@ class TaskService extends EventEmitter implements ITaskService {
private quickOpenService: IQuickOpenService;
private _configHasErrors: boolean;
+ private _schemaVersion: JsonSchemaVersion;
+ private _executionEngine: ExecutionEngine;
+ private _workspaceFolders: WorkspaceFolder[];
private _providers: Map;
- private _workspaceTasksPromise: TPromise;
+ private _workspaceTasksPromise: TPromise>;
private _taskSystem: ITaskSystem;
private _taskSystemListeners: IDisposable[];
@@ -711,22 +719,14 @@ class TaskService extends EventEmitter implements ITaskService {
if (!this._taskSystem && !this._workspaceTasksPromise) {
return;
}
- this.updateWorkspaceTasks();
- if (!this._taskSystem) {
- return;
- }
- let currentExecutionEngine = this._taskSystem instanceof TerminalTaskSystem
- ? ExecutionEngine.Terminal
- : this._taskSystem instanceof ProcessTaskSystem
- ? ExecutionEngine.Process
- : ExecutionEngine._default;
- if (currentExecutionEngine !== this.getExecutionEngine()) {
+ let folderSetup = this.computeWorkspaceFolders();
+ if (this._executionEngine !== folderSetup[1] && this._taskSystem && this._taskSystem.getActiveTasks().length > 0) {
this.messageService.show(
Severity.Info,
{
message: nls.localize(
'TaskSystem.noHotSwap',
- 'Changing the task execution engine requires to reload the Window'
+ 'Changing the task execution engine with an active task running requires to reload the Window'
),
actions: [
new ReloadWindowAction(ReloadWindowAction.ID, ReloadWindowAction.LABEL, this._windowServive),
@@ -734,8 +734,17 @@ class TaskService extends EventEmitter implements ITaskService {
]
}
);
+ return;
}
+ this._workspaceFolders = folderSetup[0];
+ this._executionEngine = folderSetup[1];
+ this._schemaVersion = folderSetup[2];
+ this.updateWorkspaceTasks();
});
+ let folderSetup = this.computeWorkspaceFolders();
+ this._workspaceFolders = folderSetup[0];
+ this._executionEngine = folderSetup[1];
+ this._schemaVersion = folderSetup[2];
lifecycleService.onWillShutdown(event => event.veto(this.beforeShutdown()));
this.registerCommands();
}
@@ -814,20 +823,14 @@ class TaskService extends EventEmitter implements ITaskService {
}
public getTask(identifier: string): TPromise {
- return this.getTaskSets().then((sets) => {
- let resolver = this.createResolver(sets);
+ return this.getAllTasks().then((tasks) => {
+ let resolver = this.createResolver(tasks);
return resolver.resolve(identifier);
});
}
public tasks(): TPromise {
- return this.getTaskSets().then((sets) => {
- let result: Task[] = [];
- for (let set of sets) {
- result.push(...set.tasks);
- }
- return result;
- });
+ return this.getAllTasks();
};
public isActive(): TPromise {
@@ -881,10 +884,10 @@ class TaskService extends EventEmitter implements ITaskService {
}
public build(): TPromise {
- return this.getTaskSets().then((values) => {
- let runnable = this.createRunnableTask(values, TaskGroup.Build);
+ return this.getAllTasks().then((tasks) => {
+ let runnable = this.createRunnableTask(tasks, TaskGroup.Build);
if (!runnable || !runnable.task) {
- if (this.getJsonSchemaVersion() === JsonSchemaVersion.V0_1_0) {
+ if (this._schemaVersion === JsonSchemaVersion.V0_1_0) {
throw new TaskError(Severity.Info, nls.localize('TaskService.noBuildTask1', 'No build task defined. Mark a task with \'isBuildCommand\' in the tasks.json file.'), TaskErrors.NoBuildTask);
} else {
throw new TaskError(Severity.Info, nls.localize('TaskService.noBuildTask2', 'No build task defined. Mark a task with as a \'build\' group in the tasks.json file.'), TaskErrors.NoBuildTask);
@@ -906,10 +909,10 @@ class TaskService extends EventEmitter implements ITaskService {
}
public runTest(): TPromise {
- return this.getTaskSets().then((values) => {
- let runnable = this.createRunnableTask(values, TaskGroup.Test);
+ return this.getAllTasks().then((tasks) => {
+ let runnable = this.createRunnableTask(tasks, TaskGroup.Test);
if (!runnable || !runnable.task) {
- if (this.getJsonSchemaVersion() === JsonSchemaVersion.V0_1_0) {
+ if (this._schemaVersion === JsonSchemaVersion.V0_1_0) {
throw new TaskError(Severity.Info, nls.localize('TaskService.noTestTask1', 'No test task defined. Mark a task with \'isTestCommand\' in the tasks.json file.'), TaskErrors.NoTestTask);
} else {
throw new TaskError(Severity.Info, nls.localize('TaskService.noTestTask2', 'No test task defined. Mark a task with as a \'test\' group in the tasks.json file.'), TaskErrors.NoTestTask);
@@ -923,8 +926,8 @@ class TaskService extends EventEmitter implements ITaskService {
}
public run(task: string | Task, options?: RunOptions): TPromise {
- return this.getTaskSets().then((values) => {
- let resolver = this.createResolver(values);
+ return this.getAllTasks().then((tasks) => {
+ let resolver = this.createResolver(tasks);
let requested: string;
let toExecute: Task;
if (Types.isString(task)) {
@@ -955,7 +958,7 @@ class TaskService extends EventEmitter implements ITaskService {
}
private shouldAttachProblemMatcher(task: Task): boolean {
- if (!this.canCustomize()) {
+ if (!this.canCustomize(task)) {
return false;
}
if (task.group !== void 0 && task.group !== TaskGroup.Build) {
@@ -1033,25 +1036,40 @@ class TaskService extends EventEmitter implements ITaskService {
}
public getTasksForGroup(group: string): TPromise {
- return this.getTaskSets().then((values) => {
+ return this.getAllTasks().then((tasks) => {
let result: Task[] = [];
- for (let value of values) {
- for (let task of value.tasks) {
- if (task.group === group) {
- result.push(task);
- }
+ for (let task of tasks) {
+ if (task.group === group) {
+ result.push(task);
}
}
return result;
});
}
- public canCustomize(): boolean {
- return this.getJsonSchemaVersion() === JsonSchemaVersion.V2_0_0;
+ public hasMultipleFolders(): boolean {
+ return this._workspaceFolders && this._workspaceFolders.length > 1;
+ }
+
+ public canCustomize(task: Task): boolean {
+ if (this._schemaVersion !== JsonSchemaVersion.V2_0_0) {
+ return false;
+ }
+ if (CustomTask.is(task)) {
+ return true;
+ }
+ if (ContributedTask.is(task)) {
+ return !!Task.getWorkspaceFolder(task);
+ }
+ return false;
}
public customize(task: ContributedTask | CustomTask, properties?: CustomizationProperties, openConfig?: boolean): TPromise {
- let configuration = this.getConfiguration();
+ let workspaceFolder = Task.getWorkspaceFolder(task);
+ if (!workspaceFolder) {
+ return TPromise.as(undefined);
+ }
+ let configuration = this.getConfiguration(workspaceFolder);
if (configuration.hasParseErrors) {
this.messageService.show(Severity.Warning, nls.localize('customizeParseErrors', 'The current task configuration has errors. Please fix the errors first before customizing a task.'));
return TPromise.as(undefined);
@@ -1114,12 +1132,12 @@ class TaskService extends EventEmitter implements ITaskService {
fileConfig.problemMatcher = properties.problemMatcher;
value.key = 'tasks.problemMatchers';
value.value = fileConfig.problemMatcher;
- promise = this.configurationEditingService.writeConfiguration(ConfigurationTarget.WORKSPACE, value);
+ promise = this.writeConfiguration(workspaceFolder, value);
} else if (properties.group !== void 0) {
fileConfig.group = properties.group;
value.key = 'tasks.group';
value.value = fileConfig.group;
- promise = this.configurationEditingService.writeConfiguration(ConfigurationTarget.WORKSPACE, value);
+ promise = this.writeConfiguration(workspaceFolder, value);
}
} else {
if (!Array.isArray(fileConfig.tasks)) {
@@ -1132,7 +1150,7 @@ class TaskService extends EventEmitter implements ITaskService {
} else {
fileConfig.tasks[index] = toCustomize;
}
- promise = this.configurationEditingService.writeConfiguration(ConfigurationTarget.WORKSPACE, value);
+ promise = this.writeConfiguration(workspaceFolder, value);
}
};
if (!promise) {
@@ -1156,7 +1174,18 @@ class TaskService extends EventEmitter implements ITaskService {
});
}
+ private writeConfiguration(workspaceFolder: WorkspaceFolder, value: IConfigurationValue): TPromise {
+ if (this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) {
+ return this.configurationEditingService.writeConfiguration(ConfigurationTarget.WORKSPACE, value);
+ } else if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
+ return this.configurationEditingService.writeConfiguration(ConfigurationTarget.FOLDER, value, { scopes: { resource: workspaceFolder.uri } });
+ } else {
+ return undefined;
+ }
+ }
+
public openConfig(task: CustomTask): TPromise {
+ // @ToDo need to adopt since this is not working anymore
let resource = this.contextService.toResource(task._source.config.file);
return this.editorService.openEditor({
resource: resource,
@@ -1167,26 +1196,24 @@ class TaskService extends EventEmitter implements ITaskService {
}, false).then(() => undefined);
}
- private createRunnableTask(sets: TaskSet[], group: TaskGroup): { task: Task; resolver: ITaskResolver } {
+ private createRunnableTask(tasks: Task[], group: TaskGroup): { task: Task; resolver: ITaskResolver } {
let idMap: IStringDictionary = Object.create(null);
let labelMap: IStringDictionary = Object.create(null);
let identifierMap: IStringDictionary = Object.create(null);
let workspaceTasks: Task[] = [];
let extensionTasks: Task[] = [];
- sets.forEach((set) => {
- set.tasks.forEach((task) => {
- idMap[task._id] = task;
- labelMap[task._label] = task;
- identifierMap[task.identifier] = task;
- if (group && task.group === group) {
- if (task._source.kind === TaskSourceKind.Workspace) {
- workspaceTasks.push(task);
- } else {
- extensionTasks.push(task);
- }
+ tasks.forEach((task) => {
+ idMap[task._id] = task;
+ labelMap[task._label] = task;
+ identifierMap[task.identifier] = task;
+ if (group && task.group === group) {
+ if (task._source.kind === TaskSourceKind.Workspace) {
+ workspaceTasks.push(task);
+ } else {
+ extensionTasks.push(task);
}
- });
+ }
});
let resolver: ITaskResolver = {
resolve: (id: string) => {
@@ -1222,15 +1249,13 @@ class TaskService extends EventEmitter implements ITaskService {
}
}
- private createResolver(sets: TaskSet[]): ITaskResolver {
+ private createResolver(tasks: Task[]): ITaskResolver {
let labelMap: IStringDictionary = Object.create(null);
let identifierMap: IStringDictionary = Object.create(null);
- sets.forEach((set) => {
- set.tasks.forEach((task) => {
- labelMap[task._label] = task;
- identifierMap[task.identifier] = task;
- });
+ tasks.forEach((task) => {
+ labelMap[task._label] = task;
+ identifierMap[task.identifier] = task;
});
return {
resolve: (id: string) => {
@@ -1299,8 +1324,7 @@ class TaskService extends EventEmitter implements ITaskService {
if (this._taskSystem) {
return this._taskSystem;
}
- let engine = this.getExecutionEngine();
- if (engine === ExecutionEngine.Terminal) {
+ if (this._executionEngine === ExecutionEngine.Terminal) {
this._taskSystem = new TerminalTaskSystem(
this.terminalService, this.outputService, this.markerService,
this.modelService, this.configurationResolverService, this.telemetryService,
@@ -1322,7 +1346,7 @@ class TaskService extends EventEmitter implements ITaskService {
return this._taskSystem;
}
- private getTaskSets(): TPromise {
+ private getAllTasks(): TPromise {
return this.extensionService.activateByEvent('onCommand:workbench.action.tasks.runTask').then(() => {
return new TPromise((resolve, reject) => {
let result: TaskSet[] = [];
@@ -1340,7 +1364,7 @@ class TaskService extends EventEmitter implements ITaskService {
resolve(result);
}
};
- if (this.getJsonSchemaVersion() === JsonSchemaVersion.V2_0_0 && this._providers.size > 0) {
+ if (this._schemaVersion === JsonSchemaVersion.V2_0_0 && this._providers.size > 0) {
this._providers.forEach((provider) => {
counter++;
provider.provideTasks().done(done, error);
@@ -1349,57 +1373,95 @@ class TaskService extends EventEmitter implements ITaskService {
resolve(result);
}
});
- }).then((result) => {
- return this.getWorkspaceTasks().then((workspaceTaskResult) => {
- let workspaceTasksToDelete: Task[] = [];
- let configurations = workspaceTaskResult.configurations;
- let legacyTaskConfigurations = workspaceTaskResult.set ? this.getLegacyTaskConfigurations(workspaceTaskResult.set) : undefined;
- if (configurations || legacyTaskConfigurations) {
- for (let set of result) {
- for (let i = 0; i < set.tasks.length; i++) {
- let task = set.tasks[i];
- if (!ContributedTask.is(task)) {
- continue;
- }
- if (configurations) {
- let configuringTask = configurations.byIdentifier[task.defines._key];
- if (configuringTask) {
- set.tasks[i] = TaskConfig.createCustomTask(task, configuringTask);
+ }).then((contributedTaskSets) => {
+ let result: Task[] = [];
+ let contributedTasks: Map = new Map();
+ for (let set of contributedTaskSets) {
+ for (let task of set.tasks) {
+ if (!ContributedTask.is(task)) {
+ continue;
+ }
+ let workspaceFolder = task._source.workspaceFolder;
+ if (workspaceFolder) {
+ let values = contributedTasks.get(workspaceFolder.uri.toString());
+ if (!values) {
+ values = [task];
+ contributedTasks.set(workspaceFolder.uri.toString(), values);
+ } else {
+ values.push(task);
+ }
+ } else {
+ result.push(task);
+ }
+ }
+ }
+ return this.getWorkspaceTasks().then((customTasks) => {
+ customTasks.forEach((folderTasks, key) => {
+ let contributed = contributedTasks.get(key);
+ if (!folderTasks.set) {
+ if (contributed) {
+ result.push(...contributed);
+ }
+ return;
+ }
+
+ if (!contributed) {
+ result.push(...folderTasks.set.tasks);
+ } else {
+ let configurations = folderTasks.configurations;
+ let legacyTaskConfigurations = folderTasks.set ? this.getLegacyTaskConfigurations(folderTasks.set) : undefined;
+ let customTasksToDelete: Task[] = [];
+ if (configurations || legacyTaskConfigurations) {
+ for (let task of contributed) {
+ if (!ContributedTask.is(task)) {
continue;
}
- }
- if (legacyTaskConfigurations) {
- let configuringTask = legacyTaskConfigurations[task.defines._key];
- if (configuringTask) {
- set.tasks[i] = TaskConfig.createCustomTask(task, configuringTask);
- workspaceTasksToDelete.push(configuringTask);
- set.tasks[i] = configuringTask;
- continue;
+ if (configurations) {
+ let configuringTask = configurations.byIdentifier[task.defines._key];
+ if (configuringTask) {
+ result.push(TaskConfig.createCustomTask(task, configuringTask));
+ } else {
+ result.push(task);
+ }
+ } else if (legacyTaskConfigurations) {
+ let configuringTask = legacyTaskConfigurations[task.defines._key];
+ if (configuringTask) {
+ result.push(TaskConfig.createCustomTask(task, configuringTask));
+ customTasksToDelete.push(configuringTask);
+ } else {
+ result.push(task);
+ }
+ } else {
+ result.push(task);
}
}
+ if (customTasksToDelete.length > 0) {
+ let toDelete = customTasksToDelete.reduce>((map, task) => {
+ map[task._id] = true;
+ return map;
+ }, Object.create(null));
+ for (let task of folderTasks.set.tasks) {
+ if (toDelete[task._id]) {
+ continue;
+ }
+ result.push(task);
+ }
+ } else {
+ result.push(...folderTasks.set.tasks);
+ }
+ } else {
+ result.push(...folderTasks.set.tasks);
+ result.push(...contributed);
}
}
- }
- if (workspaceTaskResult.set) {
- if (workspaceTasksToDelete.length > 0) {
- let tasks = workspaceTaskResult.set.tasks;
- let newSet: TaskSet = {
- extension: workspaceTaskResult.set.extension,
- tasks: []
- };
- let toDelete = workspaceTasksToDelete.reduce>((map, task) => {
- map[task._id] = true;
- return map;
- }, Object.create(null));
- newSet.tasks = tasks.filter(task => !toDelete[task._id]);
- result.push(newSet);
- } else {
- result.push(workspaceTaskResult.set);
- }
- }
+ });
return result;
}, () => {
// If we can't read the tasks.json file provide at least the contributed tasks
+ let result: Task[] = [];
+ for (let set of contributedTaskSets) {
+ result.push(...set.tasks);
+ }
return result;
});
});
@@ -1431,7 +1493,7 @@ class TaskService extends EventEmitter implements ITaskService {
return result;
}
- private getWorkspaceTasks(): TPromise {
+ private getWorkspaceTasks(): TPromise> {
if (this._workspaceTasksPromise) {
return this._workspaceTasksPromise;
}
@@ -1441,113 +1503,162 @@ class TaskService extends EventEmitter implements ITaskService {
private updateWorkspaceTasks(): void {
this._workspaceTasksPromise = this.computeWorkspaceTasks().then(value => {
- this._configHasErrors = value.hasErrors;
- if (this._taskSystem instanceof ProcessTaskSystem) {
- this._taskSystem.hasErrors(this._configHasErrors);
+ if (this._executionEngine === ExecutionEngine.Process && this._taskSystem instanceof ProcessTaskSystem) {
+ // We can only have a process engine if we have one folder.
+ value.forEach((value) => {
+ this._configHasErrors = value.hasErrors;
+ (this._taskSystem as ProcessTaskSystem).hasErrors(this._configHasErrors);
+ });
}
return value;
});
}
- private computeWorkspaceTasks(): TPromise {
- let configPromise: TPromise;
- {
- let { config, hasParseErrors } = this.getConfiguration();
- if (hasParseErrors) {
- return TPromise.as({ set: undefined, hasErrors: true, configurations: undefined });
+ private computeWorkspaceTasks(): TPromise> {
+ if (this._workspaceFolders.length === 0) {
+ return TPromise.as(new Map());
+ } else {
+ let promises: TPromise[] = [];
+ for (let folder of this._workspaceFolders) {
+ promises.push(this.computeWorkspaceFolderTasks(folder).then((value) => value, () => undefined));
}
- let engine = ExecutionEngine._default;
- if (config) {
- engine = TaskConfig.ExecutionEngine.from(config);
- if (engine === ExecutionEngine.Process) {
- if (this.hasDetectorSupport(config)) {
- configPromise = new ProcessRunnerDetector(this.fileService, this.contextService, this.configurationResolverService, config).detect(true).then((value): WorkspaceConfigurationResult => {
- let hasErrors = this.printStderr(value.stderr);
- let detectedConfig = value.config;
- if (!detectedConfig) {
- return { config, hasErrors };
- }
- let result: TaskConfig.ExternalTaskRunnerConfiguration = Objects.clone(config);
- let configuredTasks: IStringDictionary = Object.create(null);
- if (!result.tasks) {
- if (detectedConfig.tasks) {
- result.tasks = detectedConfig.tasks;
- }
- } else {
- result.tasks.forEach(task => configuredTasks[task.taskName] = task);
- detectedConfig.tasks.forEach((task) => {
- if (!configuredTasks[task.taskName]) {
- result.tasks.push(task);
- }
- });
- }
- return { config: result, hasErrors };
- });
- } else {
- configPromise = TPromise.as({ config, hasErrors: false });
+ return TPromise.join(promises).then((values) => {
+ let result = new Map();
+ for (let value of values) {
+ if (value) {
+ result.set(value.workspaceFolder.uri.toString(), value);
}
- } else {
- configPromise = TPromise.as({ config, hasErrors: false });
}
+ return result;
+ });
+ }
+ }
+
+ private computeWorkspaceFolderTasks(workspaceFolder: WorkspaceFolder): TPromise {
+ return (this._executionEngine === ExecutionEngine.Process
+ ? this.computeLegacyConfiguration(workspaceFolder)
+ : this.computeConfiguration(workspaceFolder)).
+ then((workspaceFolderConfiguration) => {
+ if (!workspaceFolderConfiguration || !workspaceFolderConfiguration.config || workspaceFolderConfiguration.hasErrors) {
+ return TPromise.as({ workspaceFolder, set: undefined, configurations: undefined, hasErrors: workspaceFolderConfiguration ? workspaceFolderConfiguration.hasErrors : false });
+ }
+ return ProblemMatcherRegistry.onReady().then((): WorkspaceFolderTaskResult => {
+ let problemReporter = new ProblemReporter(this._outputChannel);
+ let parseResult = TaskConfig.parse(workspaceFolder, workspaceFolderConfiguration.config, problemReporter);
+ let hasErrors = false;
+ if (!parseResult.validationStatus.isOK()) {
+ hasErrors = true;
+ this.showOutput();
+ }
+ if (problemReporter.status.isFatal()) {
+ problemReporter.fatal(nls.localize('TaskSystem.configurationErrors', 'Error: the provided task configuration has validation errors and can\'t not be used. Please correct the errors first.'));
+ return { workspaceFolder, set: undefined, configurations: undefined, hasErrors };
+ }
+ let customizedTasks: { byIdentifier: IStringDictionary; };
+ if (parseResult.configured && parseResult.configured.length > 0) {
+ customizedTasks = {
+ byIdentifier: Object.create(null)
+ };
+ for (let task of parseResult.configured) {
+ customizedTasks.byIdentifier[task.configures._key] = task;
+ }
+ }
+ return { workspaceFolder, set: { tasks: parseResult.custom }, configurations: customizedTasks, hasErrors };
+ });
+ });
+ }
+
+ private computeConfiguration(workspaceFolder: WorkspaceFolder): TPromise {
+ let { config, hasParseErrors } = this.getConfiguration(workspaceFolder);
+ return TPromise.as({ workspaceFolder, config, hasErrors: hasParseErrors });
+ }
+
+ private computeLegacyConfiguration(workspaceFolder: WorkspaceFolder): TPromise {
+ let { config, hasParseErrors } = this.getConfiguration(workspaceFolder);
+ if (hasParseErrors) {
+ return TPromise.as({ workspaceFolder: workspaceFolder, hasErrors: true, config: undefined });
+ }
+ if (config) {
+ if (this.hasDetectorSupport(config)) {
+ return new ProcessRunnerDetector(this.fileService, this.contextService, this.configurationResolverService, config).detect(true).then((value): WorkspaceFolderConfigurationResult => {
+ let hasErrors = this.printStderr(value.stderr);
+ let detectedConfig = value.config;
+ if (!detectedConfig) {
+ return { workspaceFolder, config, hasErrors };
+ }
+ let result: TaskConfig.ExternalTaskRunnerConfiguration = Objects.clone(config);
+ let configuredTasks: IStringDictionary = Object.create(null);
+ if (!result.tasks) {
+ if (detectedConfig.tasks) {
+ result.tasks = detectedConfig.tasks;
+ }
+ } else {
+ result.tasks.forEach(task => configuredTasks[task.taskName] = task);
+ detectedConfig.tasks.forEach((task) => {
+ if (!configuredTasks[task.taskName]) {
+ result.tasks.push(task);
+ }
+ });
+ }
+ return { workspaceFolder, config: result, hasErrors };
+ });
} else {
- if (engine === ExecutionEngine.Terminal) {
- configPromise = TPromise.as({ config, hasErrors: false });
+ return TPromise.as({ workspaceFolder, config, hasErrors: false });
+ }
+ } else {
+ return new ProcessRunnerDetector(this.fileService, this.contextService, this.configurationResolverService).detect(true).then((value) => {
+ let hasErrors = this.printStderr(value.stderr);
+ return { workspaceFolder, config: value.config, hasErrors };
+ });
+ }
+ }
+
+ private computeWorkspaceFolders(): [WorkspaceFolder[], ExecutionEngine, JsonSchemaVersion] {
+ let workspaceFolders: WorkspaceFolder[] = [];
+ let executionEngine = ExecutionEngine.Terminal;
+ let schemaVersion = JsonSchemaVersion.V2_0_0;
+
+ if (this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) {
+ let workspaceFolder: WorkspaceFolder = { uri: this.contextService.getWorkspace().folders[0] };
+ workspaceFolders.push(workspaceFolder);
+ executionEngine = this.computeExecutionEngine(workspaceFolder);
+ schemaVersion = this.computeJsonSchemaVersion(workspaceFolder);
+ } else if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
+ for (let folder of this.contextService.getWorkspace().folders) {
+ let workspaceFolder = { uri: folder };
+ if (schemaVersion === this.computeJsonSchemaVersion(workspaceFolder)) {
+ workspaceFolders.push(workspaceFolder);
} else {
- configPromise = new ProcessRunnerDetector(this.fileService, this.contextService, this.configurationResolverService).detect(true).then((value) => {
- let hasErrors = this.printStderr(value.stderr);
- return { config: value.config, hasErrors };
- });
+ this._outputChannel.append(nls.localize(
+ 'taskService.ignoreingFolder',
+ 'Ignoring task configurations for workspace folder {0}. Multi root folder support requires that all folders use task version 2.0.',
+ folder.fsPath));
}
}
}
- return configPromise.then((resolved) => {
- return ProblemMatcherRegistry.onReady().then((): WorkspaceTaskResult => {
- if (!resolved || !resolved.config) {
- return { set: undefined, configurations: undefined, hasErrors: resolved !== void 0 ? resolved.hasErrors : false };
- }
- let problemReporter = new ProblemReporter(this._outputChannel);
- let parseResult = TaskConfig.parse(resolved.config, problemReporter);
- let hasErrors = false;
- if (!parseResult.validationStatus.isOK()) {
- hasErrors = true;
- this.showOutput();
- }
- if (problemReporter.status.isFatal()) {
- problemReporter.fatal(nls.localize('TaskSystem.configurationErrors', 'Error: the provided task configuration has validation errors and can\'t not be used. Please correct the errors first.'));
- return { set: undefined, configurations: undefined, hasErrors };
- }
- let customizedTasks: { byIdentifier: IStringDictionary; };
- if (parseResult.configured && parseResult.configured.length > 0) {
- customizedTasks = {
- byIdentifier: Object.create(null)
- };
- for (let task of parseResult.configured) {
- customizedTasks.byIdentifier[task.configures._key] = task;
- }
- }
- return { set: { tasks: parseResult.custom }, configurations: customizedTasks, hasErrors };
- });
- });
+ return [workspaceFolders, executionEngine, schemaVersion];
}
- private getExecutionEngine(): ExecutionEngine {
- let { config } = this.getConfiguration();
+ private computeExecutionEngine(workspaceFolder: WorkspaceFolder): ExecutionEngine {
+ let { config } = this.getConfiguration(workspaceFolder);
if (!config) {
return ExecutionEngine._default;
}
return TaskConfig.ExecutionEngine.from(config);
}
- private getJsonSchemaVersion(): JsonSchemaVersion {
- let { config } = this.getConfiguration();
+ private computeJsonSchemaVersion(workspaceFolder: WorkspaceFolder): JsonSchemaVersion {
+ let { config } = this.getConfiguration(workspaceFolder);
if (!config) {
return JsonSchemaVersion.V2_0_0;
}
return TaskConfig.JsonSchemaVersion.from(config);
}
- private getConfiguration(): { config: TaskConfig.ExternalTaskRunnerConfiguration; hasParseErrors: boolean } {
- let result = this.contextService.hasWorkspace() ? this.configurationService.getConfiguration('tasks', { resource: this.contextService.getLegacyWorkspace().resource }) : undefined;
+ private getConfiguration(workspaceFolder: WorkspaceFolder): { config: TaskConfig.ExternalTaskRunnerConfiguration; hasParseErrors: boolean } {
+ let result = this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY
+ ? this.configurationService.getConfiguration('tasks', { resource: workspaceFolder.uri })
+ : undefined;
if (!result) {
return { config: undefined, hasParseErrors: false };
}
@@ -1585,11 +1696,11 @@ class TaskService extends EventEmitter implements ITaskService {
if (this._taskSystem) {
return this._taskSystem instanceof TerminalTaskSystem;
}
- return this.getExecutionEngine() === ExecutionEngine.Terminal;
+ return this._executionEngine === ExecutionEngine.Terminal;
}
private hasDetectorSupport(config: TaskConfig.ExternalTaskRunnerConfiguration): boolean {
- if (!config.command || !this.contextService.hasWorkspace()) {
+ if (!config.command || this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) {
return false;
}
return ProcessRunnerDetector.supports(config.command);
@@ -1700,7 +1811,7 @@ class TaskService extends EventEmitter implements ITaskService {
}
private canRunCommand(): boolean {
- if (!this.contextService.hasWorkspace()) {
+ if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) {
this.messageService.show(Severity.Info, nls.localize('TaskService.noWorkspace', 'Tasks are only available on a workspace folder.'));
return false;
}
@@ -1797,7 +1908,7 @@ class TaskService extends EventEmitter implements ITaskService {
if (!this.canRunCommand()) {
return;
}
- if (this.getJsonSchemaVersion() === JsonSchemaVersion.V0_1_0) {
+ if (this._schemaVersion === JsonSchemaVersion.V0_1_0) {
this.build();
return;
}
@@ -1840,7 +1951,7 @@ class TaskService extends EventEmitter implements ITaskService {
if (!this.canRunCommand()) {
return;
}
- if (this.getJsonSchemaVersion() === JsonSchemaVersion.V0_1_0) {
+ if (this._schemaVersion === JsonSchemaVersion.V0_1_0) {
this.runTest();
return;
}
@@ -1946,7 +2057,7 @@ class TaskService extends EventEmitter implements ITaskService {
if (!this.canRunCommand()) {
return;
}
- if (this.getJsonSchemaVersion() === JsonSchemaVersion.V2_0_0) {
+ if (this._schemaVersion === JsonSchemaVersion.V2_0_0) {
this.tasks().then((tasks => {
if (tasks.length === 0) {
this.configureBuildTask().run();
@@ -1981,7 +2092,7 @@ class TaskService extends EventEmitter implements ITaskService {
if (!this.canRunCommand()) {
return;
}
- if (this.getJsonSchemaVersion() === JsonSchemaVersion.V2_0_0) {
+ if (this._schemaVersion === JsonSchemaVersion.V2_0_0) {
this.tasks().then((tasks => {
if (tasks.length === 0) {
this.configureAction().run();
diff --git a/src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts b/src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts
index 39bd49ba690..cf38b3bcb18 100644
--- a/src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts
+++ b/src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts
@@ -647,7 +647,7 @@ export class TerminalTaskSystem extends EventEmitter implements ITaskSystem {
private resolveVariable(value: string): string {
// TODO@Dirk adopt new configuration resolver service https://github.com/Microsoft/vscode/issues/31365
- return this.configurationResolverService.resolve(this.contextService.getLegacyWorkspace().resource, value);
+ return this.configurationResolverService.resolve(this.contextService.getWorkspace().folders[0], value);
}
private resolveOptions(options: CommandOptions): CommandOptions {
diff --git a/src/vs/workbench/parts/tasks/node/processRunnerDetector.ts b/src/vs/workbench/parts/tasks/node/processRunnerDetector.ts
index bbc05d0d7d4..e0e81b063ff 100644
--- a/src/vs/workbench/parts/tasks/node/processRunnerDetector.ts
+++ b/src/vs/workbench/parts/tasks/node/processRunnerDetector.ts
@@ -18,7 +18,7 @@ import { IFileService } from 'vs/platform/files/common/files';
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import * as Tasks from '../common/tasks';
import * as TaskConfig from './taskConfiguration';
@@ -156,7 +156,7 @@ export class ProcessRunnerDetector {
this.taskConfiguration = config;
this._stderr = [];
this._stdout = [];
- this._cwd = this.contextService.hasWorkspace() ? Paths.normalize(this.contextService.getLegacyWorkspace().resource.fsPath, true) : '';
+ this._cwd = this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? Paths.normalize(this.contextService.getWorkspace().folders[0].fsPath, true) : '';
}
public get stderr(): string[] {
@@ -175,7 +175,7 @@ export class ProcessRunnerDetector {
let isShellCommand = !!this.taskConfiguration.isShellCommand;
// TODO@Dirk adopt new configuration resolver service https://github.com/Microsoft/vscode/issues/31365
return this.runDetection(
- new LineProcess(this.taskConfiguration.command, this.configurationResolverService.resolve(this.contextService.getLegacyWorkspace().resource, args), isShellCommand, options),
+ new LineProcess(this.taskConfiguration.command, this.configurationResolverService.resolve(this.contextService.getWorkspace().folders[0], args), isShellCommand, options),
this.taskConfiguration.command, isShellCommand, config.matcher, ProcessRunnerDetector.DefaultProblemMatchers, list);
} else {
if (detectSpecific) {
@@ -219,10 +219,10 @@ export class ProcessRunnerDetector {
// TODO@Dirk adopt new configuration resolver service https://github.com/Microsoft/vscode/issues/31365
let result = Objects.clone(options);
if (result.cwd) {
- result.cwd = this.configurationResolverService.resolve(this.contextService.getLegacyWorkspace().resource, result.cwd);
+ result.cwd = this.configurationResolverService.resolve(this.contextService.getWorkspace().folders[0], result.cwd);
}
if (result.env) {
- result.env = this.configurationResolverService.resolve(this.contextService.getLegacyWorkspace().resource, result.env);
+ result.env = this.configurationResolverService.resolve(this.contextService.getWorkspace().folders[0], result.env);
}
return result;
}
diff --git a/src/vs/workbench/parts/tasks/node/processTaskSystem.ts b/src/vs/workbench/parts/tasks/node/processTaskSystem.ts
index b15509838dc..e0006516a31 100644
--- a/src/vs/workbench/parts/tasks/node/processTaskSystem.ts
+++ b/src/vs/workbench/parts/tasks/node/processTaskSystem.ts
@@ -382,7 +382,7 @@ export class ProcessTaskSystem extends EventEmitter implements ITaskSystem {
private resolveVariable(value: string): string {
// TODO@Dirk adopt new configuration resolver service https://github.com/Microsoft/vscode/issues/31365
- return this.configurationResolverService.resolve(this.contextService.getLegacyWorkspace().resource, value);
+ return this.configurationResolverService.resolve(this.contextService.getWorkspace().folders[0], value);
}
public log(value: string): void {
diff --git a/src/vs/workbench/parts/tasks/node/taskConfiguration.ts b/src/vs/workbench/parts/tasks/node/taskConfiguration.ts
index 513e890116a..9bd43c3080f 100644
--- a/src/vs/workbench/parts/tasks/node/taskConfiguration.ts
+++ b/src/vs/workbench/parts/tasks/node/taskConfiguration.ts
@@ -561,6 +561,7 @@ function _freeze(this: void, target: T, properties: MetaData[]): Read
}
interface ParseContext {
+ workspaceFolder: Tasks.WorkspaceFolder;
problemReporter: IProblemReporter;
namedProblemMatchers: IStringDictionary;
uuidMap: UUIDMap;
@@ -1160,6 +1161,7 @@ namespace ConfiguringTask {
}
let taskIdentifier = TaskIdentifier.from(identifier);
let configElement: Tasks.TaskSourceConfigElement = {
+ workspaceFolder: context.workspaceFolder,
file: '.vscode\\tasks.json',
index,
element: external
@@ -1220,7 +1222,7 @@ namespace CustomTask {
let result: Tasks.CustomTask = {
type: 'custom',
_id: context.uuidMap.getUUID(taskName),
- _source: Objects.assign({}, source, { config: { index, element: external, file: '.vscode\\tasks.json' } }),
+ _source: Objects.assign({}, source, { config: { index, element: external, file: '.vscode\\tasks.json', workspaceFolder: context.workspaceFolder } }),
_label: taskName,
name: taskName,
identifier: taskName,
@@ -1678,10 +1680,12 @@ class UUIDMap {
class ConfigurationParser {
+ private workspaceFolder: Tasks.WorkspaceFolder;
private problemReporter: IProblemReporter;
private uuidMap: UUIDMap;
- constructor(problemReporter: IProblemReporter, uuidMap: UUIDMap) {
+ constructor(workspaceFolder: Tasks.WorkspaceFolder, problemReporter: IProblemReporter, uuidMap: UUIDMap) {
+ this.workspaceFolder = workspaceFolder;
this.problemReporter = problemReporter;
this.uuidMap = uuidMap;
}
@@ -1693,6 +1697,7 @@ class ConfigurationParser {
this.problemReporter.clearOutput();
}
let context: ParseContext = {
+ workspaceFolder: this.workspaceFolder,
problemReporter: this.problemReporter,
uuidMap: this.uuidMap,
namedProblemMatchers: undefined,
@@ -1751,7 +1756,7 @@ class ConfigurationParser {
let isBackground = fileConfig.isBackground ? !!fileConfig.isBackground : fileConfig.isWatching ? !!fileConfig.isWatching : undefined;
let task: Tasks.CustomTask = {
_id: context.uuidMap.getUUID(globals.command.name),
- _source: Objects.assign({}, source, { config: { index: -1, element: fileConfig } }),
+ _source: Objects.assign({}, source, { config: { index: -1, element: fileConfig, workspaceFolder: context.workspaceFolder } }),
_label: globals.command.name,
type: 'custom',
name: globals.command.name,
@@ -1783,11 +1788,16 @@ class ConfigurationParser {
}
}
-let uuidMap: UUIDMap = new UUIDMap();
-export function parse(configuration: ExternalTaskRunnerConfiguration, logger: IProblemReporter): ParseResult {
+let uuidMaps: Map = new Map();
+export function parse(workspaceFolder: Tasks.WorkspaceFolder, configuration: ExternalTaskRunnerConfiguration, logger: IProblemReporter): ParseResult {
+ let uuidMap = uuidMaps.get(workspaceFolder.uri.toString());
+ if (!uuidMap) {
+ uuidMap = new UUIDMap();
+ uuidMaps.set(workspaceFolder.uri.toString(), uuidMap);
+ }
try {
uuidMap.start();
- return (new ConfigurationParser(logger, uuidMap)).run(configuration);
+ return (new ConfigurationParser(workspaceFolder, logger, uuidMap)).run(configuration);
} finally {
uuidMap.finish();
}
@@ -1801,35 +1811,6 @@ export function getTaskIdentifier(value: TaskIdentifier): Tasks.TaskIdentifier {
return TaskIdentifier.from(value);
}
-export function findTaskIndex(fileConfig: ExternalTaskRunnerConfiguration, task: Tasks.Task): number {
- if (!fileConfig || !fileConfig.tasks) {
- return undefined;
- }
- if (fileConfig.tasks.length === 0) {
- return -1;
- }
- let localMap = new UUIDMap(uuidMap);
- let context: ParseContext = {
- problemReporter: this.problemReporter,
- uuidMap: localMap,
- namedProblemMatchers: undefined,
- engine: ExecutionEngine.from(fileConfig),
- schemaVersion: JsonSchemaVersion.from(fileConfig)
- };
- try {
- localMap.start();
- let tasks = TaskParser.quickParse(fileConfig.tasks, context);
- for (let i = 0; i < tasks.length; i++) {
- if (task._id === tasks[i]._id) {
- return i;
- }
- }
- return -1;
- } finally {
- localMap.finish();
- }
-}
-
/*
class VersionConverter {
constructor(private problemReporter: IProblemReporter) {
diff --git a/src/vs/workbench/parts/tasks/test/electron-browser/configuration.test.ts b/src/vs/workbench/parts/tasks/test/electron-browser/configuration.test.ts
index c89319b81dd..c9601239fb1 100644
--- a/src/vs/workbench/parts/tasks/test/electron-browser/configuration.test.ts
+++ b/src/vs/workbench/parts/tasks/test/electron-browser/configuration.test.ts
@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
+import URI from 'vs/base/common/uri';
import * as assert from 'assert';
import Severity from 'vs/base/common/severity';
import * as UUID from 'vs/base/common/uuid';
@@ -177,7 +178,7 @@ class CustomTaskBuilder {
this.commandBuilder = new CommandConfigurationBuilder(this, command);
this.result = {
_id: name,
- _source: { kind: Tasks.TaskSourceKind.Workspace, label: 'workspace', config: { element: undefined, index: -1, file: '.vscode/tasks.json' } },
+ _source: { kind: Tasks.TaskSourceKind.Workspace, label: 'workspace', config: { workspaceFolder: { uri: undefined }, element: undefined, index: -1, file: '.vscode/tasks.json' } },
_label: name,
type: 'custom',
identifier: name,
@@ -347,7 +348,7 @@ class PatternBuilder {
function testDefaultProblemMatcher(external: ExternalTaskRunnerConfiguration, resolved: number) {
let reporter = new ProblemReporter();
- let result = parse(external, reporter);
+ let result = parse({ uri: URI.file('/Workspace/folderOne') }, external, reporter);
assert.ok(!reporter.receivedMessage);
assert.strictEqual(result.custom.length, 1);
let task = result.custom[0];
@@ -358,7 +359,7 @@ function testDefaultProblemMatcher(external: ExternalTaskRunnerConfiguration, re
function testConfiguration(external: ExternalTaskRunnerConfiguration, builder: ConfiguationBuilder): void {
builder.done();
let reporter = new ProblemReporter();
- let result = parse(external, reporter);
+ let result = parse({ uri: URI.file('/Workspace/folderOne') }, external, reporter);
if (reporter.receivedMessage) {
assert.ok(false, reporter.lastMessage);
}
diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalConfigHelper.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalConfigHelper.ts
index d949eaec21d..90ae98f2274 100644
--- a/src/vs/workbench/parts/terminal/electron-browser/terminalConfigHelper.ts
+++ b/src/vs/workbench/parts/terminal/electron-browser/terminalConfigHelper.ts
@@ -74,7 +74,7 @@ export class TerminalConfigHelper implements ITerminalConfigHelper {
fontFamily,
fontSize,
lineHeight,
- charWidth: Math.ceil(rect.width),
+ charWidth: rect.width,
charHeight: Math.ceil(rect.height)
};
return this._lastFontMeasurement;
diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts
index 5ec52de5602..dd9d79a8c17 100644
--- a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts
+++ b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts
@@ -206,7 +206,16 @@ export class TerminalInstance implements ITerminalInstance {
}
const font = this._configHelper.getFont();
this._cols = Math.max(Math.floor(dimension.width / font.charWidth), 1);
- this._rows = Math.max(Math.floor(dimension.height / Math.floor(font.charHeight * font.lineHeight)), 1);
+
+ // xterm.js does the horizontal space calculation using values scaled
+ // with window.devicePixelRatio. In these calculations, ceil and floor
+ // are used which require us to check it on this side as well or we
+ // would lose that precision.
+ const scaledSpaceAvailable = dimension.height * window.devicePixelRatio;
+ const scaledCharHeight = Math.ceil(font.charHeight * window.devicePixelRatio);
+ const scaledLineHeight = Math.floor(scaledCharHeight * font.lineHeight);
+ this._rows = Math.floor(scaledSpaceAvailable / scaledLineHeight);
+
return dimension.width;
}
diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalLinkHandler.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalLinkHandler.ts
index d16a97535cc..811bf77c390 100644
--- a/src/vs/workbench/parts/terminal/electron-browser/terminalLinkHandler.ts
+++ b/src/vs/workbench/parts/terminal/electron-browser/terminalLinkHandler.ts
@@ -41,7 +41,7 @@ const lineAndColumnClause = [
// Changing any regex may effect this value, hence changes this as well if required.
const winLineAndColumnMatchIndex = 12;
-const unixLineAndColumnMatchIndex = 15;
+const unixLineAndColumnMatchIndex = 23;
// Each line and column clause have 6 groups (ie no. of expressions in round brackets)
const lineAndColumnClauseGroupCount = 6;
diff --git a/src/vs/workbench/parts/terminal/electron-browser/windowsShellHelper.ts b/src/vs/workbench/parts/terminal/electron-browser/windowsShellHelper.ts
index 1fbb6bb2cd8..b4a2d55c42a 100644
--- a/src/vs/workbench/parts/terminal/electron-browser/windowsShellHelper.ts
+++ b/src/vs/workbench/parts/terminal/electron-browser/windowsShellHelper.ts
@@ -18,6 +18,7 @@ export class WindowsShellHelper {
private _onCheckShell: Emitter>;
private _isDisposed: boolean;
private _currentRequest: TPromise;
+ private _newLineFeed: boolean;
public constructor(
private _rootProcessId: number,
@@ -44,7 +45,19 @@ export class WindowsShellHelper {
}, 50);
});
- this._xterm.on('lineFeed', () => this._onCheckShell.fire());
+ // We want to fire a new check for the shell on a lineFeed, but only
+ // when parsing has finished which is indicated by the cursormove event.
+ // If this is done on every lineFeed, parsing ends up taking
+ // significantly longer due to resetting timers. Note that this is
+ // private API.
+ this._xterm.on('lineFeed', () => this._newLineFeed = true);
+ this._xterm.on('cursormove', () => {
+ if (this._newLineFeed) {
+ this._onCheckShell.fire();
+ }
+ });
+
+ // Fire a new check for the shell when any key is pressed.
this._xterm.on('keypress', () => this._onCheckShell.fire());
}
diff --git a/src/vs/workbench/parts/terminal/test/electron-browser/terminalLinkHandler.test.ts b/src/vs/workbench/parts/terminal/test/electron-browser/terminalLinkHandler.test.ts
index d351ba0dc6d..77d9fed7145 100644
--- a/src/vs/workbench/parts/terminal/test/electron-browser/terminalLinkHandler.test.ts
+++ b/src/vs/workbench/parts/terminal/test/electron-browser/terminalLinkHandler.test.ts
@@ -138,21 +138,21 @@ suite('Workbench - TerminalLinkHandler', () => {
// { urlFormat: '{0} on line {1}, column {2}', line: '5', column: '3' },
// { urlFormat: '{0}:line {1}', line: '5' },
// { urlFormat: '{0}:line {1}, column {2}', line: '5', column: '3' },
- // { urlFormat: '{0}({1})', line: '5' },
- // { urlFormat: '{0} ({1})', line: '5' },
- // { urlFormat: '{0}({1},{2})', line: '5', column: '3' },
- // { urlFormat: '{0} ({1},{2})', line: '5', column: '3' },
- // { urlFormat: '{0}:{1}', line: '5' },
- // { urlFormat: '{0}:{1}:{2}', line: '5', column: '3' },
- // { urlFormat: '{0}[{1}]', line: '5' },
- // { urlFormat: '{0} [{1}]', line: '5' },
- // { urlFormat: '{0}[{1},{2}]', line: '5', column: '3' },
- // { urlFormat: '{0} [{1},{2}]', line: '5', column: '3' }
+ { urlFormat: '{0}({1})', line: '5' },
+ { urlFormat: '{0} ({1})', line: '5' },
+ { urlFormat: '{0}({1},{2})', line: '5', column: '3' },
+ { urlFormat: '{0} ({1},{2})', line: '5', column: '3' },
+ { urlFormat: '{0}:{1}', line: '5' },
+ { urlFormat: '{0}:{1}:{2}', line: '5', column: '3' },
+ { urlFormat: '{0}[{1}]', line: '5' },
+ { urlFormat: '{0} [{1}]', line: '5' },
+ { urlFormat: '{0}[{1},{2}]', line: '5', column: '3' },
+ { urlFormat: '{0} [{1},{2}]', line: '5', column: '3' }
];
linkUrls.forEach(linkUrl => {
supportedLinkFormats.forEach(linkFormatInfo => {
- console.log('linkFormatInfo: ', linkFormatInfo);
+ // console.log('linkFormatInfo: ', linkFormatInfo);
testLink(
strings.format(linkFormatInfo.urlFormat, linkUrl, linkFormatInfo.line, linkFormatInfo.column),
linkUrl,
diff --git a/src/vs/workbench/parts/watermark/electron-browser/watermark.ts b/src/vs/workbench/parts/watermark/electron-browser/watermark.ts
index 8d108a933d7..96585270fa8 100644
--- a/src/vs/workbench/parts/watermark/electron-browser/watermark.ts
+++ b/src/vs/workbench/parts/watermark/electron-browser/watermark.ts
@@ -14,7 +14,7 @@ import * as nls from 'vs/nls';
import { Registry } from 'vs/platform/registry/common/platform';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry';
-import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
@@ -147,7 +147,7 @@ export class WatermarkContribution implements IWorkbenchContribution {
.div({ 'class': 'watermark' });
const box = $(this.watermark)
.div({ 'class': 'watermark-box' });
- const folder = this.contextService.hasWorkspace();
+ const folder = this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY;
const selected = folder ? folderEntries : noFolderEntries
.filter(entry => !('mac' in entry) || entry.mac === isMacintosh);
const update = () => {
diff --git a/src/vs/workbench/parts/welcome/page/electron-browser/vs_code_welcome_page.ts b/src/vs/workbench/parts/welcome/page/electron-browser/vs_code_welcome_page.ts
index 1f09a886909..7672c53a798 100644
--- a/src/vs/workbench/parts/welcome/page/electron-browser/vs_code_welcome_page.ts
+++ b/src/vs/workbench/parts/welcome/page/electron-browser/vs_code_welcome_page.ts
@@ -70,7 +70,6 @@ export default () => `
${escape(localize('welcomePage.showCommands', "Find and run all commands"))} ${escape(localize('welcomePage.showCommandsDescription', "Rapidly access and search commands from the Command Palette ({0})")).replace('{0}', ' ')}
${escape(localize('welcomePage.interfaceOverview', "Interface overview"))} ${escape(localize('welcomePage.interfaceOverviewDescription', "Get a visual overlay highlighting the major components of the UI"))}
- ${escape(localize('welcomePage.deployToAzure', "Deploy applications to the cloud"))} ${escape(localize('welcomePage.deployToAzureDescription', "Learn how to deploy your Node apps to Azure App Service"))}
${escape(localize('welcomePage.interactivePlayground', "Interactive playground"))} ${escape(localize('welcomePage.interactivePlaygroundDescription', "Try essential editor features out in a short walkthrough"))}
diff --git a/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts b/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts
index 452f9863d31..d98c51565d7 100644
--- a/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts
+++ b/src/vs/workbench/parts/welcome/page/electron-browser/welcomePage.ts
@@ -35,7 +35,6 @@ import { used } from 'vs/workbench/parts/welcome/page/electron-browser/vs_code_w
import { ILifecycleService, StartupKind } from 'vs/platform/lifecycle/common/lifecycle';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { tildify } from 'vs/base/common/labels';
-import { isLinux } from 'vs/base/common/platform';
import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { registerColor, focusBorder, textLinkForeground, textLinkActiveForeground, foreground, descriptionForeground, contrastBorder, activeContrastBorder } from 'vs/platform/theme/common/colorRegistry';
import { getExtraColor } from 'vs/workbench/parts/welcome/walkThrough/node/walkThroughUtils';
@@ -232,18 +231,8 @@ class WelcomePage {
});
recentlyOpened.then(({ workspaces }) => {
- const context = this.contextService.getWorkspace();
- workspaces = workspaces.filter(workspace => {
- if (this.contextService.hasMultiFolderWorkspace() && typeof workspace !== 'string' && context.id === workspace.id) {
- return false; // do not show current workspace
- }
-
- if (this.contextService.hasFolderWorkspace() && isSingleFolderWorkspaceIdentifier(workspace) && this.pathEquals(context.roots[0].fsPath, workspace)) {
- return false; // do not show current workspace (single folder case)
- }
-
- return true;
- });
+ // Filter out the current workspace
+ workspaces = workspaces.filter(workspace => !this.contextService.isCurrentWorkspace(workspace));
if (!workspaces.length) {
const recent = container.querySelector('.welcomePage') as HTMLElement;
recent.classList.add('emptyRecent');
@@ -317,12 +306,6 @@ class WelcomePage {
};
}));
- if (this.experimentService.getExperiments().deployToAzureQuickLink) {
- container.querySelector('.showInterfaceOverview').remove();
- } else {
- container.querySelector('.deployToAzure').remove();
- }
-
if (product.quality !== 'stable') {
container.querySelector('.stable-only').remove();
} else {
@@ -366,15 +349,6 @@ class WelcomePage {
}
}
- private pathEquals(path1: string, path2: string): boolean {
- if (!isLinux) {
- path1 = path1.toLowerCase();
- path2 = path2.toLowerCase();
- }
-
- return path1 === path2;
- }
-
private installExtension(extensionSuggestion: ExtensionSuggestion, strings: Strings): void {
this.telemetryService.publicLog(strings.installEvent, {
from: telemetryFrom,
diff --git a/src/vs/workbench/services/configuration/node/configuration.ts b/src/vs/workbench/services/configuration/node/configuration.ts
index 0f45a64cd69..102b1824712 100644
--- a/src/vs/workbench/services/configuration/node/configuration.ts
+++ b/src/vs/workbench/services/configuration/node/configuration.ts
@@ -13,12 +13,12 @@ import { equals, coalesce } from 'vs/base/common/arrays';
import * as objects from 'vs/base/common/objects';
import * as errors from 'vs/base/common/errors';
import * as collections from 'vs/base/common/collections';
-import { Disposable, toDisposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
+import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
import { RunOnceScheduler } from 'vs/base/common/async';
import { readFile, stat } from 'vs/base/node/pfs';
import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
import * as extfs from 'vs/base/node/extfs';
-import { IWorkspaceContextService, IWorkspace, Workspace, ILegacyWorkspace, LegacyWorkspace } from 'vs/platform/workspace/common/workspace';
+import { IWorkspaceContextService, IWorkspace, Workspace, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { FileChangeType, FileChangesEvent } from 'vs/platform/files/common/files';
import { isLinux } from 'vs/base/common/platform';
import { ConfigWatcher } from 'vs/base/node/config';
@@ -33,7 +33,9 @@ import { Registry } from 'vs/platform/registry/common/platform';
import { ExtensionsRegistry, ExtensionMessageCollector } from 'vs/platform/extensions/common/extensionsRegistry';
import { IConfigurationNode, IConfigurationRegistry, Extensions, editorConfigurationSchemaId, IDefaultConfigurationExtension, validateProperty, ConfigurationScope, schemaId } from 'vs/platform/configuration/common/configurationRegistry';
import { createHash } from 'crypto';
-import { getWorkspaceLabel, IWorkspacesService, IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces';
+import { getWorkspaceLabel, IWorkspacesService, IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IStoredWorkspaceFolder, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
+import { IWindowConfiguration } from 'vs/platform/windows/common/windows';
+import { IJSONSchema } from 'vs/base/common/jsonSchema';
interface IStat {
resource: URI;
@@ -55,9 +57,7 @@ type IWorkspaceFoldersConfiguration = { [rootFolder: string]: { folders: string[
const configurationRegistry = Registry.as(Extensions.Configuration);
-// BEGIN VSCode extension point `configuration`
-const configurationExtPoint = ExtensionsRegistry.registerExtensionPoint('configuration', [], {
- description: nls.localize('vscode.extension.contributes.configuration', 'Contributes configuration settings.'),
+const configurationEntrySchema: IJSONSchema = {
type: 'object',
defaultSnippets: [{ body: { title: '', properties: {} } }],
properties: {
@@ -93,20 +93,25 @@ const configurationExtPoint = ExtensionsRegistry.registerExtensionPoint('configuration', [], {
+ description: nls.localize('vscode.extension.contributes.configuration', 'Contributes configuration settings.'),
+ oneOf: [
+ configurationEntrySchema,
+ {
+ type: 'array',
+ items: configurationEntrySchema
+ }
+ ]
});
configurationExtPoint.setHandler(extensions => {
const configurations: IConfigurationNode[] = [];
-
- for (let i = 0; i < extensions.length; i++) {
- const configuration = objects.clone(extensions[i].value);
- const collector = extensions[i].collector;
-
- if (configuration.type && configuration.type !== 'object') {
- collector.warn(nls.localize('invalid.type', "if set, 'configuration.type' must be set to 'object"));
- } else {
- configuration.type = 'object';
- }
+ function handleConfiguration(node: IConfigurationNode, id: string, collector: ExtensionMessageCollector) {
+ let configuration = objects.clone(node);
if (configuration.title && (typeof configuration.title !== 'string')) {
collector.error(nls.localize('invalid.title', "'configuration.title' must be a string"));
@@ -114,10 +119,20 @@ configurationExtPoint.setHandler(extensions => {
validateProperties(configuration, collector);
- configuration.id = extensions[i].description.id;
+ configuration.id = id;
configurations.push(configuration);
- }
+ };
+ for (let extension of extensions) {
+ const collector = extension.collector;
+ const value = extension.value;
+ const id = extension.description.id;
+ if (!Array.isArray(value)) {
+ handleConfiguration(value, id, collector);
+ } else {
+ value.forEach(v => handleConfiguration(v, id, collector));
+ }
+ }
configurationRegistry.registerConfigurations(configurations, false);
});
// END VSCode extension point `configuration`
@@ -167,6 +182,7 @@ function validateProperties(configuration: IConfigurationNode, collector: Extens
}
let subNodes = configuration.allOf;
if (subNodes) {
+ collector.error(nls.localize('invalid.allOf', "'configuration.allOf' is deprecated and should no longer be used. Instead, pass multiple configuration sections as an array to the 'configuration' contribution point."));
for (let node of subNodes) {
validateProperties(node, collector);
}
@@ -178,14 +194,13 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat
public _serviceBrand: any;
protected workspace: Workspace = null;
- protected legacyWorkspace: LegacyWorkspace = null;
protected _configuration: Configuration;
protected readonly _onDidUpdateConfiguration: Emitter = this._register(new Emitter());
public readonly onDidUpdateConfiguration: Event = this._onDidUpdateConfiguration.event;
- protected readonly _onDidChangeWorkspaceRoots: Emitter = this._register(new Emitter());
- public readonly onDidChangeWorkspaceRoots: Event = this._onDidChangeWorkspaceRoots.event;
+ protected readonly _onDidChangeWorkspaceFolders: Emitter = this._register(new Emitter());
+ public readonly onDidChangeWorkspaceFolders: Event = this._onDidChangeWorkspaceFolders.event;
protected readonly _onDidChangeWorkspaceName: Emitter = this._register(new Emitter());
public readonly onDidChangeWorkspaceName: Event = this._onDidChangeWorkspaceName.event;
@@ -195,40 +210,48 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat
this._configuration = new Configuration(new BaseConfiguration(new ConfigurationModel(), new ConfigurationModel()), new ConfigurationModel(), new StrictResourceMap>(), this.workspace);
}
- public getLegacyWorkspace(): ILegacyWorkspace {
- return this.legacyWorkspace;
- }
-
public getWorkspace(): IWorkspace {
return this.workspace;
}
- public hasWorkspace(): boolean {
- return !!this.workspace;
+ public getWorkbenchState(): WorkbenchState {
+ // Workspace has configuration file
+ if (this.workspace.configuration) {
+ return WorkbenchState.WORKSPACE;
+ }
+
+ // Folder has single root
+ if (this.workspace.folders.length === 1) {
+ return WorkbenchState.FOLDER;
+ }
+
+ // Empty
+ return WorkbenchState.EMPTY;
}
- public hasFolderWorkspace(): boolean {
- return this.workspace && !this.workspace.configuration;
- }
-
- public hasMultiFolderWorkspace(): boolean {
- return this.workspace && !!this.workspace.configuration;
- }
-
- public getRoot(resource: URI): URI {
- return this.workspace ? this.workspace.getRoot(resource) : null;
- }
-
- private get workspaceUri(): URI {
- return this.workspace ? this.workspace.roots[0] : null;
+ public getWorkspaceFolder(resource: URI): URI {
+ return this.workspace.getFolder(resource);
}
public isInsideWorkspace(resource: URI): boolean {
- return !!this.getRoot(resource);
+ return !!this.getWorkspaceFolder(resource);
+ }
+
+ public isCurrentWorkspace(workspaceIdentifier: ISingleFolderWorkspaceIdentifier | IWorkspaceIdentifier): boolean {
+ switch (this.getWorkbenchState()) {
+ case WorkbenchState.FOLDER:
+ return isSingleFolderWorkspaceIdentifier(workspaceIdentifier) && this.pathEquals(this.workspace.folders[0].fsPath, workspaceIdentifier);
+ case WorkbenchState.WORKSPACE:
+ return isWorkspaceIdentifier(workspaceIdentifier) && this.workspace.id === workspaceIdentifier.id;
+ }
+ return false;
}
public toResource(workspaceRelativePath: string): URI {
- return this.workspace ? this.legacyWorkspace.toResource(workspaceRelativePath) : null;
+ if (this.workspace.folders.length) {
+ return URI.file(paths.join(this.workspace.folders[0].fsPath, workspaceRelativePath));
+ }
+ return null;
}
public initialize(trigger: boolean = true): TPromise {
@@ -289,14 +312,25 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat
// implemented by sub classes
return TPromise.as(false);
}
+
+ private pathEquals(path1: string, path2: string): boolean {
+ if (!isLinux) {
+ path1 = path1.toLowerCase();
+ path2 = path2.toLowerCase();
+ }
+
+ return path1 === path2;
+ }
}
export class EmptyWorkspaceServiceImpl extends WorkspaceService {
private baseConfigurationService: GlobalConfigurationService;
- constructor(environmentService: IEnvironmentService) {
+ constructor(configuration: IWindowConfiguration, environmentService: IEnvironmentService) {
super();
+ let id = configuration.backupPath ? URI.from({ path: paths.basename(configuration.backupPath), scheme: 'empty' }).toString() : '';
+ this.workspace = new Workspace(id, '', []);
this.baseConfigurationService = this._register(new GlobalConfigurationService(environmentService));
this._register(this.baseConfigurationService.onDidUpdateConfiguration(e => this.onBaseConfigurationChanged(e)));
this.resetCaches();
@@ -354,7 +388,7 @@ export class WorkspaceServiceImpl extends WorkspaceService {
}
public getUnsupportedWorkspaceKeys(): string[] {
- return this.hasFolderWorkspace() ? this._configuration.getFolderConfigurationModel(this.workspace.roots[0]).workspaceSettingsConfig.unsupportedKeys : [];
+ return this.getWorkbenchState() === WorkbenchState.FOLDER ? this._configuration.getFolderConfigurationModel(this.workspace.folders[0]).workspaceSettingsConfig.unsupportedKeys : [];
}
public initialize(trigger: boolean = true): TPromise {
@@ -363,7 +397,7 @@ export class WorkspaceServiceImpl extends WorkspaceService {
.then(() => super.initialize(trigger));
}
- if (this.hasMultiFolderWorkspace()) {
+ if (this.workspaceConfigPath) {
return this.workspaceConfiguration.load(this.workspaceConfigPath)
.then(() => super.initialize(trigger));
}
@@ -385,9 +419,9 @@ export class WorkspaceServiceImpl extends WorkspaceService {
}
public handleWorkspaceFileEvents(event: FileChangesEvent): void {
- TPromise.join(this.workspace.roots.map(folder => this.cachedFolderConfigs.get(folder).handleWorkspaceFileEvents(event))) // handle file event for each folder
+ TPromise.join(this.workspace.folders.map(folder => this.cachedFolderConfigs.get(folder).handleWorkspaceFileEvents(event))) // handle file event for each folder
.then(folderConfigurations =>
- folderConfigurations.map((configuration, index) => ({ configuration, folder: this.workspace.roots[index] }))
+ folderConfigurations.map((configuration, index) => ({ configuration, folder: this.workspace.folders[index] }))
.filter(folderConfiguration => !!folderConfiguration.configuration) // Filter folders which are not impacted by events
.map(folderConfiguration => this.updateFolderConfiguration(folderConfiguration.folder, folderConfiguration.configuration, true)) // Update the configuration of impacted folders
.reduce((result, value) => result || value, false)) // Check if the effective configuration of folder is changed
@@ -397,7 +431,7 @@ export class WorkspaceServiceImpl extends WorkspaceService {
protected resetCaches(): void {
this.cachedFolderConfigs = new StrictResourceMap>();
this._configuration = new Configuration(this.baseConfigurationService.configuration(), new ConfigurationModel