)",
+ "end": "((?|\\))",
"endComment": "The group (? when using SRTP synthax",
"beginCaptures": {
"1": {
@@ -792,6 +857,9 @@
}
]
},
+ {
+ "include": "#anonymous_record_declaration"
+ },
{
"begin": "({)",
"end": "(})",
@@ -814,6 +882,14 @@
{
"include": "#definition"
},
+ {
+ "match": "(?<=>)\\s*(``([[:alpha:]0-9'^._ ]+)``|[[:alpha:]0-9'`^._]+)",
+ "captures": {
+ "1": {
+ "name": "entity.name.type.fsharp"
+ }
+ }
+ },
{
"include": "#variables"
},
@@ -826,7 +902,7 @@
"patterns": [
{
"name": "binding.fsharp",
- "begin": "\\b(let mutable|static let mutable|let inline|let|member val|static member inline|static member|default|member|override|let!)(\\s+rec|mutable)?(\\s+\\[\\<.*\\>\\])?\\s*(private|internal|public)?\\s+(\\[[^-=]*\\]|[_[:alpha:]]([_[:alpha:]0-9,\\._]+)*|``[_[:alpha:]]([_[:alpha:]0-9,\\._`\\s]+|(?<=,)\\s)*)?",
+ "begin": "\\b(let mutable|static let mutable|let inline|let|member val|static member inline|static member|default|member|override|let!)(\\s+rec|mutable)?(\\s+\\[\\<.*\\>\\])?\\s*(private|internal|public)?\\s+(\\[[^-=]*\\]|[_[:alpha:]]([_[:alpha:]0-9\\._]+)*|``[_[:alpha:]]([_[:alpha:]0-9\\._`\\s]+|(?<=,)\\s)*)?",
"end": "\\s*(with\\b|=|\\n+=|(?<=\\=))",
"beginCaptures": {
"1": {
@@ -856,6 +932,26 @@
}
]
},
+ {
+ "name": "binding.fsharp",
+ "begin": "\\b((get|set)\\s*(?=\\())(\\[[^-=]*\\]|[_[:alpha:]]([_[:alpha:]0-9\\._]+)*|``[_[:alpha:]]([_[:alpha:]0-9\\._`\\s]+|(?<=,)\\s)*)?",
+ "end": "\\s*(=|\\n+=|(?<=\\=))",
+ "beginCaptures": {
+ "3": {
+ "name": "variable.fsharp"
+ }
+ },
+ "endCaptures": {
+ "1": {
+ "name": "keyword.fsharp"
+ }
+ },
+ "patterns": [
+ {
+ "include": "#common_binding_definition"
+ }
+ ]
+ },
{
"name": "binding.fsharp",
"begin": "\\b(static val mutable|val mutable|val)(\\s+rec|mutable)?(\\s+\\[\\<.*\\>\\])?\\s*(private|internal|public)?\\s+(\\[[^-=]*\\]|[_[:alpha:]]([_[:alpha:]0-9,\\._]+)*|``[_[:alpha:]]([_[:alpha:]0-9,\\._`\\s]+|(?<=,)\\s)*)?",
@@ -920,13 +1016,16 @@
}
},
{
- "match": "([[:alpha:]0-9'`^._]+)|``([[:alpha:]0-9'^._ ]+)``",
+ "match": "(``([[:alpha:]0-9'^._ ]+)``|[[:alpha:]0-9'`^._]+)",
"captures": {
"1": {
"name": "entity.name.type.fsharp"
}
}
},
+ {
+ "include": "#anonymous_record_declaration"
+ },
{
"include": "#keywords"
}
@@ -1007,6 +1106,9 @@
"name": "entity.name.section.fsharp"
}
}
+ },
+ {
+ "include": "#comments"
}
]
},
@@ -1142,7 +1244,7 @@
"match": "\\(\\)"
},
{
- "match": "(\\?{0,1})(``[[:alpha:]0-9'`^:,._ ]+``|[[:alpha:]0-9'`<>^._ ]\\w*)",
+ "match": "(\\?{0,1})(``[[:alpha:]0-9'`^:,._ ]+``|(?!private\\b)\\b[\\w[:alpha:]0-9'`<>^._ ]+)",
"captures": {
"1": {
"name": "keyword.symbol.fsharp"
@@ -1200,6 +1302,9 @@
}
}
},
+ {
+ "include": "#anonymous_record_declaration"
+ },
{
"begin": "(\\?{0,1})([[:alpha:]0-9'`^._ ]+)\\s*(:)(\\s*([?[:alpha:]0-9'`^._ ]+)(<))",
"end": "(>)",
diff --git a/extensions/fsharp/test/colorize-results/test_fs.json b/extensions/fsharp/test/colorize-results/test_fs.json
index 37c0b61c14a..e5736fc10aa 100644
--- a/extensions/fsharp/test/colorize-results/test_fs.json
+++ b/extensions/fsharp/test/colorize-results/test_fs.json
@@ -604,28 +604,6 @@
"hc_black": "keyword: #569CD6"
}
},
- {
- "c": " get",
- "t": "source.fsharp",
- "r": {
- "dark_plus": "default: #D4D4D4",
- "light_plus": "default: #000000",
- "dark_vs": "default: #D4D4D4",
- "light_vs": "default: #000000",
- "hc_black": "default: #FFFFFF"
- }
- },
- {
- "c": "()",
- "t": "source.fsharp constant.language.unit.fsharp",
- "r": {
- "dark_plus": "constant.language: #569CD6",
- "light_plus": "constant.language: #0000FF",
- "dark_vs": "constant.language: #569CD6",
- "light_vs": "constant.language: #0000FF",
- "hc_black": "constant.language: #569CD6"
- }
- },
{
"c": " ",
"t": "source.fsharp",
@@ -637,9 +615,42 @@
"hc_black": "default: #FFFFFF"
}
},
+ {
+ "c": "get",
+ "t": "source.fsharp binding.fsharp",
+ "r": {
+ "dark_plus": "default: #D4D4D4",
+ "light_plus": "default: #000000",
+ "dark_vs": "default: #D4D4D4",
+ "light_vs": "default: #000000",
+ "hc_black": "default: #FFFFFF"
+ }
+ },
+ {
+ "c": "()",
+ "t": "source.fsharp binding.fsharp constant.language.unit.fsharp",
+ "r": {
+ "dark_plus": "constant.language: #569CD6",
+ "light_plus": "constant.language: #0000FF",
+ "dark_vs": "constant.language: #569CD6",
+ "light_vs": "constant.language: #0000FF",
+ "hc_black": "constant.language: #569CD6"
+ }
+ },
+ {
+ "c": " ",
+ "t": "source.fsharp binding.fsharp",
+ "r": {
+ "dark_plus": "default: #D4D4D4",
+ "light_plus": "default: #000000",
+ "dark_vs": "default: #D4D4D4",
+ "light_vs": "default: #000000",
+ "hc_black": "default: #FFFFFF"
+ }
+ },
{
"c": "=",
- "t": "source.fsharp keyword.symbol.fsharp",
+ "t": "source.fsharp binding.fsharp keyword.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@@ -681,50 +692,6 @@
"hc_black": "keyword: #569CD6"
}
},
- {
- "c": " set",
- "t": "source.fsharp",
- "r": {
- "dark_plus": "default: #D4D4D4",
- "light_plus": "default: #000000",
- "dark_vs": "default: #D4D4D4",
- "light_vs": "default: #000000",
- "hc_black": "default: #FFFFFF"
- }
- },
- {
- "c": "(",
- "t": "source.fsharp keyword.symbol.fsharp",
- "r": {
- "dark_plus": "keyword: #569CD6",
- "light_plus": "keyword: #0000FF",
- "dark_vs": "keyword: #569CD6",
- "light_vs": "keyword: #0000FF",
- "hc_black": "keyword: #569CD6"
- }
- },
- {
- "c": "value",
- "t": "source.fsharp",
- "r": {
- "dark_plus": "default: #D4D4D4",
- "light_plus": "default: #000000",
- "dark_vs": "default: #D4D4D4",
- "light_vs": "default: #000000",
- "hc_black": "default: #FFFFFF"
- }
- },
- {
- "c": ")",
- "t": "source.fsharp keyword.symbol.fsharp",
- "r": {
- "dark_plus": "keyword: #569CD6",
- "light_plus": "keyword: #0000FF",
- "dark_vs": "keyword: #569CD6",
- "light_vs": "keyword: #0000FF",
- "hc_black": "keyword: #569CD6"
- }
- },
{
"c": " ",
"t": "source.fsharp",
@@ -736,9 +703,64 @@
"hc_black": "default: #FFFFFF"
}
},
+ {
+ "c": "set",
+ "t": "source.fsharp binding.fsharp",
+ "r": {
+ "dark_plus": "default: #D4D4D4",
+ "light_plus": "default: #000000",
+ "dark_vs": "default: #D4D4D4",
+ "light_vs": "default: #000000",
+ "hc_black": "default: #FFFFFF"
+ }
+ },
+ {
+ "c": "(",
+ "t": "source.fsharp binding.fsharp keyword.symbol.fsharp",
+ "r": {
+ "dark_plus": "keyword: #569CD6",
+ "light_plus": "keyword: #0000FF",
+ "dark_vs": "keyword: #569CD6",
+ "light_vs": "keyword: #0000FF",
+ "hc_black": "keyword: #569CD6"
+ }
+ },
+ {
+ "c": "value",
+ "t": "source.fsharp binding.fsharp variable.parameter.fsharp",
+ "r": {
+ "dark_plus": "variable: #9CDCFE",
+ "light_plus": "variable: #001080",
+ "dark_vs": "default: #D4D4D4",
+ "light_vs": "default: #000000",
+ "hc_black": "variable: #9CDCFE"
+ }
+ },
+ {
+ "c": ")",
+ "t": "source.fsharp binding.fsharp keyword.symbol.fsharp",
+ "r": {
+ "dark_plus": "keyword: #569CD6",
+ "light_plus": "keyword: #0000FF",
+ "dark_vs": "keyword: #569CD6",
+ "light_vs": "keyword: #0000FF",
+ "hc_black": "keyword: #569CD6"
+ }
+ },
+ {
+ "c": " ",
+ "t": "source.fsharp binding.fsharp",
+ "r": {
+ "dark_plus": "default: #D4D4D4",
+ "light_plus": "default: #000000",
+ "dark_vs": "default: #D4D4D4",
+ "light_vs": "default: #000000",
+ "hc_black": "default: #FFFFFF"
+ }
+ },
{
"c": "=",
- "t": "source.fsharp keyword.symbol.fsharp",
+ "t": "source.fsharp binding.fsharp keyword.fsharp",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@@ -979,7 +1001,7 @@
}
},
{
- "c": " targetAge",
+ "c": " targetAge ",
"t": "source.fsharp binding.fsharp variable.parameter.fsharp",
"r": {
"dark_plus": "variable: #9CDCFE",
@@ -989,17 +1011,6 @@
"hc_black": "variable: #9CDCFE"
}
},
- {
- "c": " ",
- "t": "source.fsharp binding.fsharp",
- "r": {
- "dark_plus": "default: #D4D4D4",
- "light_plus": "default: #000000",
- "dark_vs": "default: #D4D4D4",
- "light_vs": "default: #000000",
- "hc_black": "default: #FFFFFF"
- }
- },
{
"c": "=",
"t": "source.fsharp binding.fsharp keyword.fsharp",
diff --git a/extensions/git-ui/.vscodeignore b/extensions/git-ui/.vscodeignore
new file mode 100644
index 00000000000..7462f7448d3
--- /dev/null
+++ b/extensions/git-ui/.vscodeignore
@@ -0,0 +1,8 @@
+src/**
+test/**
+out/**
+tsconfig.json
+build/**
+extension.webpack.config.js
+cgmanifest.json
+yarn.lock
diff --git a/extensions/git-ui/README.md b/extensions/git-ui/README.md
new file mode 100644
index 00000000000..d418425acfe
--- /dev/null
+++ b/extensions/git-ui/README.md
@@ -0,0 +1,7 @@
+# Git UI integration for Visual Studio Code
+
+**Notice:** This extension is bundled with Visual Studio Code. It can be disabled but not uninstalled.
+
+## Features
+
+See [Git support in VS Code](https://code.visualstudio.com/docs/editor/versioncontrol#_git-support) to learn about the features of this extension.
diff --git a/extensions/git-ui/cgmanifest.json b/extensions/git-ui/cgmanifest.json
new file mode 100644
index 00000000000..f3071eb691a
--- /dev/null
+++ b/extensions/git-ui/cgmanifest.json
@@ -0,0 +1,4 @@
+{
+ "registrations": [],
+ "version": 1
+}
\ No newline at end of file
diff --git a/extensions/git-ui/extension.webpack.config.js b/extensions/git-ui/extension.webpack.config.js
new file mode 100644
index 00000000000..19c0ea3042d
--- /dev/null
+++ b/extensions/git-ui/extension.webpack.config.js
@@ -0,0 +1,17 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+//@ts-check
+
+'use strict';
+
+const withDefaults = require('../shared.webpack.config');
+
+module.exports = withDefaults({
+ context: __dirname,
+ entry: {
+ main: './src/main.ts'
+ }
+});
diff --git a/extensions/git-ui/package.json b/extensions/git-ui/package.json
new file mode 100644
index 00000000000..2f1ab43f892
--- /dev/null
+++ b/extensions/git-ui/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "git-ui",
+ "displayName": "%displayName%",
+ "description": "%description%",
+ "publisher": "vscode",
+ "version": "1.0.0",
+ "engines": {
+ "vscode": "^1.5.0"
+ },
+ "extensionKind": "ui",
+ "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
+ "enableProposedApi": true,
+ "categories": [
+ "Other"
+ ],
+ "activationEvents": [
+ "onCommand:git.credential"
+ ],
+ "main": "./out/main",
+ "icon": "resources/icons/git.png",
+ "scripts": {
+ "compile": "gulp compile-extension:git-ui",
+ "watch": "gulp watch-extension:git-ui"
+ },
+ "devDependencies": {
+ "@types/node": "^10.14.8"
+ }
+}
\ No newline at end of file
diff --git a/extensions/git-ui/package.nls.json b/extensions/git-ui/package.nls.json
new file mode 100644
index 00000000000..5303e91f4cd
--- /dev/null
+++ b/extensions/git-ui/package.nls.json
@@ -0,0 +1,4 @@
+{
+ "displayName": "Git UI",
+ "description": "Git SCM UI Integration"
+}
\ No newline at end of file
diff --git a/extensions/git-ui/resources/icons/git.png b/extensions/git-ui/resources/icons/git.png
new file mode 100644
index 00000000000..51f4ae5404f
Binary files /dev/null and b/extensions/git-ui/resources/icons/git.png differ
diff --git a/extensions/git-ui/src/main.ts b/extensions/git-ui/src/main.ts
new file mode 100644
index 00000000000..d233b753be2
--- /dev/null
+++ b/extensions/git-ui/src/main.ts
@@ -0,0 +1,57 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { ExtensionContext, commands } from 'vscode';
+
+import * as cp from 'child_process';
+
+export async function deactivate(): Promise
{
+}
+
+export async function activate(context: ExtensionContext): Promise {
+ context.subscriptions.push(commands.registerCommand('git.credential', async (data: any) => {
+ try {
+ const { stdout, stderr } = await exec(`git credential ${data.command}`, {
+ stdin: data.stdin,
+ env: Object.assign(process.env, { GIT_TERMINAL_PROMPT: '0' })
+ });
+ return { stdout, stderr, code: 0 };
+ } catch ({ stdout, stderr, error }) {
+ const code = error.code || 0;
+ if (stderr.indexOf('terminal prompts disabled') !== -1) {
+ stderr = '';
+ }
+ return { stdout, stderr, code };
+ }
+ }));
+}
+
+export interface ExecResult {
+ error: Error | null;
+ stdout: string;
+ stderr: string;
+}
+
+
+export function exec(command: string, options: cp.ExecOptions & { stdin?: string } = {}) {
+ return new Promise((resolve, reject) => {
+ const child = cp.exec(command, options, (error, stdout, stderr) => {
+ (error ? reject : resolve)({ error, stdout, stderr });
+ });
+ if (options.stdin) {
+ child.stdin.write(options.stdin, (err: any) => {
+ if (err) {
+ reject(err);
+ return;
+ }
+ child.stdin.end((err: any) => {
+ if (err) {
+ reject(err);
+ }
+ });
+ });
+ }
+ });
+}
diff --git a/extensions/git-ui/src/typings/refs.d.ts b/extensions/git-ui/src/typings/refs.d.ts
new file mode 100644
index 00000000000..a933431220b
--- /dev/null
+++ b/extensions/git-ui/src/typings/refs.d.ts
@@ -0,0 +1,8 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+///
+///
+///
\ No newline at end of file
diff --git a/extensions/git-ui/tsconfig.json b/extensions/git-ui/tsconfig.json
new file mode 100644
index 00000000000..27e9268b39b
--- /dev/null
+++ b/extensions/git-ui/tsconfig.json
@@ -0,0 +1,13 @@
+{
+ "extends": "../shared.tsconfig.json",
+ "compilerOptions": {
+ "outDir": "./out",
+ "experimentalDecorators": true,
+ "typeRoots": [
+ "./node_modules/@types"
+ ]
+ },
+ "include": [
+ "src/**/*"
+ ]
+}
\ No newline at end of file
diff --git a/extensions/git-ui/yarn.lock b/extensions/git-ui/yarn.lock
new file mode 100644
index 00000000000..b23b0ac0392
--- /dev/null
+++ b/extensions/git-ui/yarn.lock
@@ -0,0 +1,8 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@types/node@^10.14.8":
+ version "10.14.8"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.8.tgz#fe444203ecef1162348cd6deb76c62477b2cc6e9"
+ integrity sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==
diff --git a/extensions/git/package.json b/extensions/git/package.json
index 4395d306bb5..f85fd49c1d7 100644
--- a/extensions/git/package.json
+++ b/extensions/git/package.json
@@ -3,6 +3,7 @@
"displayName": "%displayName%",
"description": "%description%",
"publisher": "vscode",
+ "license": "MIT",
"version": "1.0.0",
"engines": {
"vscode": "^1.5.0"
@@ -20,7 +21,8 @@
"scripts": {
"compile": "gulp compile-extension:git",
"watch": "gulp watch-extension:git",
- "update-grammar": "node ./build/update-grammars.js"
+ "update-grammar": "node ./build/update-grammars.js",
+ "test": "mocha"
},
"contributes": {
"commands": [
@@ -317,12 +319,12 @@
},
{
"command": "git.pushWithTags",
- "title": "%command.pushWithTags%",
+ "title": "%command.pushFollowTags%",
"category": "Git"
},
{
"command": "git.pushWithTagsForce",
- "title": "%command.pushWithTagsForce%",
+ "title": "%command.pushFollowTagsForce%",
"category": "Git"
},
{
@@ -1272,6 +1274,12 @@
"default": false,
"description": "%config.fetchOnPull%"
},
+ "git.pullTags": {
+ "type": "boolean",
+ "scope": "resource",
+ "default": true,
+ "description": "%config.pullTags%"
+ },
"git.autoStash": {
"type": "boolean",
"scope": "resource",
@@ -1452,13 +1460,14 @@
"jschardet": "^1.6.0",
"vscode-extension-telemetry": "0.1.1",
"vscode-nls": "^4.0.0",
+ "vscode-uri": "^2.0.0",
"which": "^1.3.0"
},
"devDependencies": {
"@types/byline": "4.2.31",
"@types/file-type": "^5.2.1",
"@types/mocha": "2.2.43",
- "@types/node": "^10.12.21",
+ "@types/node": "^10.14.8",
"@types/which": "^1.0.28",
"mocha": "^3.2.0"
}
diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json
index 892e3519cd1..adff0134ed9 100644
--- a/extensions/git/package.nls.json
+++ b/extensions/git/package.nls.json
@@ -47,8 +47,8 @@
"command.pushForce": "Push (Force)",
"command.pushTo": "Push to...",
"command.pushToForce": "Push to... (Force)",
- "command.pushWithTags": "Push With Tags",
- "command.pushWithTagsForce": "Push With Tags (Force)",
+ "command.pushFollowTags": "Push (Follow Tags)",
+ "command.pushFollowTagsForce": "Push (Follow Tags, Force)",
"command.addRemote": "Add Remote",
"command.removeRemote": "Remove Remote",
"command.sync": "Sync",
@@ -112,6 +112,7 @@
"config.rebaseWhenSync": "Force git to use rebase when running the sync command.",
"config.confirmEmptyCommits": "Always confirm the creation of empty commits.",
"config.fetchOnPull": "Fetch all branches when pulling or just the current one.",
+ "config.pullTags": "Fetch all tags when pulling.",
"config.autoStash": "Stash any changes before pulling and restore them after successful pull.",
"config.allowForcePush": "Controls whether force push (with or without lease) is enabled.",
"config.useForcePushWithLease": "Controls whether force pushing uses the safer force-with-lease variant.",
diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts
index ae8eb5315bc..9444ea1fada 100644
--- a/extensions/git/src/api/git.d.ts
+++ b/extensions/git/src/api/git.d.ts
@@ -235,4 +235,4 @@ export const enum GitErrorCodes {
CantRebaseMultipleBranches = 'CantRebaseMultipleBranches',
PatchDoesNotApply = 'PatchDoesNotApply',
NoPathFound = 'NoPathFound'
-}
\ No newline at end of file
+}
diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts
index f6e00e9abdd..85ec8ce866a 100755
--- a/extensions/git/src/commands.ts
+++ b/extensions/git/src/commands.ts
@@ -56,7 +56,13 @@ class CheckoutRemoteHeadItem extends CheckoutItem {
return;
}
- await repository.checkoutTracking(this.ref.name);
+ const branches = await repository.findTrackingBranches(this.ref.name);
+
+ if (branches.length > 0) {
+ await repository.checkout(branches[0].name!);
+ } else {
+ await repository.checkoutTracking(this.ref.name);
+ }
}
}
@@ -196,7 +202,7 @@ function createCheckoutItems(repository: Repository): CheckoutItem[] {
enum PushType {
Push,
PushTo,
- PushTags,
+ PushFollowTags,
}
interface PushOptions {
@@ -481,10 +487,10 @@ export class CommandCenter {
(_, token) => this.git.clone(url!, parentPath, token)
);
- const choices = [];
let message = localize('proposeopen', "Would you like to open the cloned repository?");
- const open = localize('openrepo', "Open Repository");
- choices.push(open);
+ const open = localize('openrepo', "Open");
+ const openNewWindow = localize('openreponew', "Open in New Window");
+ const choices = [open, openNewWindow];
const addToWorkspace = localize('add', "Add to Workspace");
if (workspace.workspaceFolders) {
@@ -509,6 +515,8 @@ export class CommandCenter {
commands.executeCommand('vscode.openFolder', uri);
} else if (result === addToWorkspace) {
workspace.updateWorkspaceFolders(workspace.workspaceFolders!.length, 0, { uri });
+ } else if (result === openNewWindow) {
+ commands.executeCommand('vscode.openFolder', uri, true);
}
} catch (err) {
if (/already exists and is not an empty directory/.test(err && err.stderr || '')) {
@@ -593,10 +601,10 @@ export class CommandCenter {
await this.git.init(repositoryPath);
- const choices = [];
let message = localize('proposeopen init', "Would you like to open the initialized repository?");
- const open = localize('openrepo', "Open Repository");
- choices.push(open);
+ const open = localize('openrepo', "Open");
+ const openNewWindow = localize('openreponew', "Open in New Window");
+ const choices = [open, openNewWindow];
if (!askToOpen) {
return;
@@ -615,6 +623,8 @@ export class CommandCenter {
commands.executeCommand('vscode.openFolder', uri);
} else if (result === addToWorkspace) {
workspace.updateWorkspaceFolders(workspace.workspaceFolders!.length, 0, { uri });
+ } else if (result === openNewWindow) {
+ commands.executeCommand('vscode.openFolder', uri, true);
} else {
await this.model.openRepository(repositoryPath);
}
@@ -1753,10 +1763,8 @@ export class CommandCenter {
}
}
- if (pushOptions.pushType === PushType.PushTags) {
- await repository.pushTags(undefined, forcePushMode);
-
- window.showInformationMessage(localize('push with tags success', "Successfully pushed with tags."));
+ if (pushOptions.pushType === PushType.PushFollowTags) {
+ await repository.pushFollowTags(undefined, forcePushMode);
return;
}
@@ -1813,13 +1821,13 @@ export class CommandCenter {
}
@command('git.pushWithTags', { repository: true })
- async pushWithTags(repository: Repository): Promise {
- await this._push(repository, { pushType: PushType.PushTags });
+ async pushFollowTags(repository: Repository): Promise {
+ await this._push(repository, { pushType: PushType.PushFollowTags });
}
@command('git.pushWithTagsForce', { repository: true })
- async pushWithTagsForce(repository: Repository): Promise {
- await this._push(repository, { pushType: PushType.PushTags, forcePush: true });
+ async pushFollowTagsForce(repository: Repository): Promise {
+ await this._push(repository, { pushType: PushType.PushFollowTags, forcePush: true });
}
@command('git.pushTo', { repository: true })
diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts
index 3132b8cdf86..30348608dd0 100644
--- a/extensions/git/src/git.ts
+++ b/extensions/git/src/git.ts
@@ -12,7 +12,8 @@ import { EventEmitter } from 'events';
import iconv = require('iconv-lite');
import * as filetype from 'file-type';
import { assign, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent } from './util';
-import { CancellationToken, Uri } from 'vscode';
+import { CancellationToken } from 'vscode';
+import { URI } from 'vscode-uri';
import { detectEncoding } from './encoding';
import { Ref, RefType, Branch, Remote, GitErrorCodes, LogOptions, Change, Status } from './api/git';
@@ -306,6 +307,8 @@ function getGitErrorCode(stderr: string): string | undefined {
return GitErrorCodes.BranchAlreadyExists;
} else if (/'.+' is not a valid branch name/.test(stderr)) {
return GitErrorCodes.InvalidBranchName;
+ } else if (/Please,? commit your changes or stash them/.test(stderr)) {
+ return GitErrorCodes.DirtyWorkTree;
}
return undefined;
@@ -326,8 +329,8 @@ export class Git {
this.env = options.env || {};
}
- open(repository: string): Repository {
- return new Repository(this, repository);
+ open(repository: string, dotGit: string): Repository {
+ return new Repository(this, repository, dotGit);
}
async init(repository: string): Promise {
@@ -336,7 +339,7 @@ export class Git {
}
async clone(url: string, parentPath: string, cancellationToken?: CancellationToken): Promise {
- let baseFolderName = decodeURI(url).replace(/^.*\//, '').replace(/\.git$/, '') || 'repository';
+ let baseFolderName = decodeURI(url).replace(/[\/]+$/, '').replace(/^.*\//, '').replace(/\.git$/, '') || 'repository';
let folderName = baseFolderName;
let folderPath = path.join(parentPath, folderName);
let count = 1;
@@ -367,6 +370,17 @@ export class Git {
return path.normalize(result.stdout.trim());
}
+ async getRepositoryDotGit(repositoryPath: string): Promise {
+ const result = await this.exec(repositoryPath, ['rev-parse', '--git-dir']);
+ let dotGitPath = result.stdout.trim();
+
+ if (!path.isAbsolute(dotGitPath)) {
+ dotGitPath = path.join(repositoryPath, dotGitPath);
+ }
+
+ return path.normalize(dotGitPath);
+ }
+
async exec(cwd: string, args: string[], options: SpawnOptions = {}): Promise> {
options = assign({ cwd }, options || {});
return await this._exec(args, options);
@@ -555,7 +569,7 @@ export function parseGitmodules(raw: string): Submodule[] {
return;
}
- const propertyMatch = /^\s*(\w+) = (.*)$/.exec(line);
+ const propertyMatch = /^\s*(\w+)\s+=\s+(.*)$/.exec(line);
if (!propertyMatch) {
return;
@@ -634,6 +648,7 @@ export interface CommitOptions {
export interface PullOptions {
unshallow?: boolean;
+ tags?: boolean;
}
export enum ForcePushMode {
@@ -645,7 +660,8 @@ export class Repository {
constructor(
private _git: Git,
- private repositoryRoot: string
+ private repositoryRoot: string,
+ readonly dotGit: string
) { }
get git(): Git {
@@ -993,7 +1009,7 @@ export class Repository {
break;
}
- const originalUri = Uri.file(path.isAbsolute(resourcePath) ? resourcePath : path.join(this.repositoryRoot, resourcePath));
+ const originalUri = URI.file(path.isAbsolute(resourcePath) ? resourcePath : path.join(this.repositoryRoot, resourcePath));
let status: Status = Status.UNTRACKED;
// Copy or Rename status comes with a number, e.g. 'R100'. We don't need the number, so we use only first character of the status.
@@ -1021,7 +1037,7 @@ export class Repository {
break;
}
- const uri = Uri.file(path.isAbsolute(newPath) ? newPath : path.join(this.repositoryRoot, newPath));
+ const uri = URI.file(path.isAbsolute(newPath) ? newPath : path.join(this.repositoryRoot, newPath));
result.push({
uri,
renameUri: uri,
@@ -1360,7 +1376,11 @@ export class Repository {
}
async pull(rebase?: boolean, remote?: string, branch?: string, options: PullOptions = {}): Promise {
- const args = ['pull', '--tags'];
+ const args = ['pull'];
+
+ if (options.tags) {
+ args.push('--tags');
+ }
if (options.unshallow) {
args.push('--unshallow');
@@ -1411,7 +1431,7 @@ export class Repository {
}
if (tags) {
- args.push('--tags');
+ args.push('--follow-tags');
}
if (remote) {
@@ -1571,6 +1591,14 @@ export class Repository {
}
}
+ async findTrackingBranches(upstreamBranch: string): Promise {
+ const result = await this.run(['for-each-ref', '--format', '%(refname:short)%00%(upstream:short)', 'refs/heads']);
+ return result.stdout.trim().split('\n')
+ .map(line => line.trim().split('\0'))
+ .filter(([_, upstream]) => upstream === upstreamBranch)
+ .map(([ref]) => ({ name: ref, type: RefType.Head } as Branch));
+ }
+
async getRefs(): Promise[ {
const result = await this.run(['for-each-ref', '--format', '%(refname) %(objectname)', '--sort', '-committerdate']);
diff --git a/extensions/git/src/model.ts b/extensions/git/src/model.ts
index 22c690a5dfd..a04dc33c8be 100644
--- a/extensions/git/src/model.ts
+++ b/extensions/git/src/model.ts
@@ -78,7 +78,7 @@ export class Model {
this.disposables.push(fsWatcher);
const onWorkspaceChange = anyEvent(fsWatcher.onDidChange, fsWatcher.onDidCreate, fsWatcher.onDidDelete);
- const onGitRepositoryChange = filterEvent(onWorkspaceChange, uri => /\/\.git\//.test(uri.path));
+ const onGitRepositoryChange = filterEvent(onWorkspaceChange, uri => /\/\.git/.test(uri.path));
const onPossibleGitRepositoryChange = filterEvent(onGitRepositoryChange, uri => !this.getRepository(uri));
onPossibleGitRepositoryChange(this.onPossibleGitRepositoryChange, this, this.disposables);
@@ -232,7 +232,8 @@ export class Model {
return;
}
- const repository = new Repository(this.git.open(repositoryRoot), this.globalState);
+ const dotGit = await this.git.getRepositoryDotGit(repositoryRoot);
+ const repository = new Repository(this.git.open(repositoryRoot, dotGit), this.globalState, this.outputChannel);
this.open(repository);
} catch (err) {
diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts
index 2fac9e2a39f..a581f9f5fd4 100644
--- a/extensions/git/src/repository.ts
+++ b/extensions/git/src/repository.ts
@@ -3,9 +3,9 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import { commands, Uri, Command, EventEmitter, Event, scm, SourceControl, SourceControlInputBox, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, SourceControlInputBoxValidation, Disposable, ProgressLocation, window, workspace, WorkspaceEdit, ThemeColor, DecorationData, Memento, SourceControlInputBoxValidationType } from 'vscode';
+import { commands, Uri, Command, EventEmitter, Event, scm, SourceControl, SourceControlInputBox, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, SourceControlInputBoxValidation, Disposable, ProgressLocation, window, workspace, WorkspaceEdit, ThemeColor, DecorationData, Memento, SourceControlInputBoxValidationType, OutputChannel, LogLevel, env } from 'vscode';
import { Repository as BaseRepository, Commit, Stash, GitError, Submodule, CommitOptions, ForcePushMode } from './git';
-import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent } from './util';
+import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent, combinedDisposable, watch, IFileWatcher } from './util';
import { memoize, throttle, debounce } from './decorators';
import { toGitUri } from './uri';
import { AutoFetcher } from './autofetch';
@@ -299,6 +299,7 @@ export const enum Operation {
GetObjectDetails = 'GetObjectDetails',
SubmoduleUpdate = 'SubmoduleUpdate',
RebaseContinue = 'RebaseContinue',
+ FindTrackingBranches = 'GetTracking',
Apply = 'Apply',
Blame = 'Blame',
Log = 'Log',
@@ -446,6 +447,91 @@ class ProgressManager {
}
}
+class FileEventLogger {
+
+ private eventDisposable: IDisposable = EmptyDisposable;
+ private logLevelDisposable: IDisposable = EmptyDisposable;
+
+ constructor(
+ private onWorkspaceWorkingTreeFileChange: Event,
+ private onDotGitFileChange: Event,
+ private outputChannel: OutputChannel
+ ) {
+ this.logLevelDisposable = env.onDidChangeLogLevel(this.onDidChangeLogLevel, this);
+ this.onDidChangeLogLevel(env.logLevel);
+ }
+
+ private onDidChangeLogLevel(level: LogLevel): void {
+ this.eventDisposable.dispose();
+
+ if (level > LogLevel.Debug) {
+ return;
+ }
+
+ this.eventDisposable = combinedDisposable([
+ this.onWorkspaceWorkingTreeFileChange(uri => this.outputChannel.appendLine(`[debug] [wt] Change: ${uri.fsPath}`)),
+ this.onDotGitFileChange(uri => this.outputChannel.appendLine(`[debug] [.git] Change: ${uri.fsPath}`))
+ ]);
+ }
+
+ dispose(): void {
+ this.eventDisposable.dispose();
+ this.logLevelDisposable.dispose();
+ }
+}
+
+class DotGitWatcher implements IFileWatcher {
+
+ readonly event: Event;
+
+ private emitter = new EventEmitter();
+ private transientDisposables: IDisposable[] = [];
+ private disposables: IDisposable[] = [];
+
+ constructor(
+ private repository: Repository,
+ private outputChannel: OutputChannel
+ ) {
+ const rootWatcher = watch(repository.dotGit);
+ this.disposables.push(rootWatcher);
+
+ const filteredRootWatcher = filterEvent(rootWatcher.event, uri => !/\/\.git(\/index\.lock)?$/.test(uri.path));
+ this.event = anyEvent(filteredRootWatcher, this.emitter.event);
+
+ repository.onDidRunGitStatus(this.updateTransientWatchers, this, this.disposables);
+ this.updateTransientWatchers();
+ }
+
+ private updateTransientWatchers() {
+ this.transientDisposables = dispose(this.transientDisposables);
+
+ if (!this.repository.HEAD || !this.repository.HEAD.upstream) {
+ return;
+ }
+
+ this.transientDisposables = dispose(this.transientDisposables);
+
+ const { name, remote } = this.repository.HEAD.upstream;
+ const upstreamPath = path.join(this.repository.dotGit, 'refs', 'remotes', remote, name);
+
+ try {
+ const upstreamWatcher = watch(upstreamPath);
+ this.transientDisposables.push(upstreamWatcher);
+ upstreamWatcher.event(this.emitter.fire, this.emitter, this.transientDisposables);
+ } catch (err) {
+ if (env.logLevel <= LogLevel.Info) {
+ this.outputChannel.appendLine(`Failed to watch ref '${upstreamPath}'. Ref is most likely packed.`);
+ }
+ }
+ }
+
+ dispose() {
+ this.emitter.dispose();
+ this.transientDisposables = dispose(this.transientDisposables);
+ this.disposables = dispose(this.disposables);
+ }
+}
+
export class Repository implements Disposable {
private _onDidChangeRepository = new EventEmitter();
@@ -543,36 +629,41 @@ export class Repository implements Disposable {
return this.repository.root;
}
+ get dotGit(): string {
+ return this.repository.dotGit;
+ }
+
private isRepositoryHuge = false;
private didWarnAboutLimit = false;
private isFreshRepository: boolean | undefined = undefined;
+
private disposables: Disposable[] = [];
constructor(
private readonly repository: BaseRepository,
- globalState: Memento
+ globalState: Memento,
+ outputChannel: OutputChannel
) {
- const fsWatcher = workspace.createFileSystemWatcher('**');
- this.disposables.push(fsWatcher);
+ const workspaceWatcher = workspace.createFileSystemWatcher('**');
+ this.disposables.push(workspaceWatcher);
- const workspaceFilter = (uri: Uri) => isDescendant(repository.root, uri.fsPath);
- const onWorkspaceDelete = filterEvent(fsWatcher.onDidDelete, workspaceFilter);
- const onWorkspaceChange = filterEvent(anyEvent(fsWatcher.onDidChange, fsWatcher.onDidCreate), workspaceFilter);
- const onRepositoryDotGitDelete = filterEvent(onWorkspaceDelete, uri => /\/\.git$/.test(uri.path));
- const onRepositoryChange = anyEvent(onWorkspaceDelete, onWorkspaceChange);
+ const onWorkspaceFileChange = anyEvent(workspaceWatcher.onDidChange, workspaceWatcher.onDidCreate, workspaceWatcher.onDidDelete);
+ const onWorkspaceRepositoryFileChange = filterEvent(onWorkspaceFileChange, uri => isDescendant(repository.root, uri.fsPath));
+ const onWorkspaceWorkingTreeFileChange = filterEvent(onWorkspaceRepositoryFileChange, uri => !/\/\.git($|\/)/.test(uri.path));
- // relevant repository changes are:
- // - DELETE .git folder
- // - ANY CHANGE within .git folder except .git itself and .git/index.lock
- const onRelevantRepositoryChange = anyEvent(
- onRepositoryDotGitDelete,
- filterEvent(onRepositoryChange, uri => !/\/\.git(\/index\.lock)?$/.test(uri.path))
- );
+ const dotGitFileWatcher = new DotGitWatcher(this, outputChannel);
+ this.disposables.push(dotGitFileWatcher);
- onRelevantRepositoryChange(this.onFSChange, this, this.disposables);
+ // FS changes should trigger `git status`:
+ // - any change inside the repository working tree
+ // - any change whithin the first level of the `.git` folder, except the folder itself and `index.lock`
+ const onFileChange = anyEvent(onWorkspaceWorkingTreeFileChange, dotGitFileWatcher.event);
+ onFileChange(this.onFileChange, this, this.disposables);
- const onRelevantGitChange = filterEvent(onRelevantRepositoryChange, uri => /\/\.git\//.test(uri.path));
- onRelevantGitChange(this._onDidChangeRepository.fire, this._onDidChangeRepository, this.disposables);
+ // Relevate repository changes should trigger virtual document change events
+ dotGitFileWatcher.event(this._onDidChangeRepository.fire, this._onDidChangeRepository, this.disposables);
+
+ this.disposables.push(new FileEventLogger(onWorkspaceWorkingTreeFileChange, dotGitFileWatcher.event, outputChannel));
const root = Uri.file(repository.root);
this._sourceControl = scm.createSourceControl('git', 'Git', root);
@@ -582,9 +673,9 @@ export class Repository implements Disposable {
this._sourceControl.inputBox.validateInput = this.validateInput.bind(this);
this.disposables.push(this._sourceControl);
- this._mergeGroup = this._sourceControl.createResourceGroup('merge', localize('merge changes', "Merge Changes"));
- this._indexGroup = this._sourceControl.createResourceGroup('index', localize('staged changes', "Staged Changes"));
- this._workingTreeGroup = this._sourceControl.createResourceGroup('workingTree', localize('changes', "Changes"));
+ this._mergeGroup = this._sourceControl.createResourceGroup('merge', localize('merge changes', "MERGE CHANGES"));
+ this._indexGroup = this._sourceControl.createResourceGroup('index', localize('staged changes', "STAGED CHANGES"));
+ this._workingTreeGroup = this._sourceControl.createResourceGroup('workingTree', localize('changes', "CHANGES"));
const updateIndexGroupVisibility = () => {
const config = workspace.getConfiguration('git', root);
@@ -909,6 +1000,10 @@ export class Repository implements Disposable {
await this.run(Operation.CheckoutTracking, () => this.repository.checkout(treeish, [], { track: true }));
}
+ async findTrackingBranches(upstreamRef: string): Promise {
+ return await this.run(Operation.FindTrackingBranches, () => this.repository.findTrackingBranches(upstreamRef));
+ }
+
async getCommit(ref: string): Promise {
return await this.repository.getCommit(ref);
}
@@ -979,11 +1074,12 @@ export class Repository implements Disposable {
await this.maybeAutoStash(async () => {
const config = workspace.getConfiguration('git', Uri.file(this.root));
const fetchOnPull = config.get('fetchOnPull');
+ const tags = config.get('pullTags');
if (fetchOnPull) {
- await this.repository.pull(rebase, undefined, undefined, { unshallow });
+ await this.repository.pull(rebase, undefined, undefined, { unshallow, tags });
} else {
- await this.repository.pull(rebase, remote, branch, { unshallow });
+ await this.repository.pull(rebase, remote, branch, { unshallow, tags });
}
});
});
@@ -1006,7 +1102,7 @@ export class Repository implements Disposable {
await this.run(Operation.Push, () => this.repository.push(remote, name, setUpstream, undefined, forcePushMode));
}
- async pushTags(remote?: string, forcePushMode?: ForcePushMode): Promise {
+ async pushFollowTags(remote?: string, forcePushMode?: ForcePushMode): Promise {
await this.run(Operation.Push, () => this.repository.push(remote, undefined, false, true, forcePushMode));
}
@@ -1039,11 +1135,12 @@ export class Repository implements Disposable {
await this.maybeAutoStash(async () => {
const config = workspace.getConfiguration('git', Uri.file(this.root));
const fetchOnPull = config.get('fetchOnPull');
+ const tags = config.get('pullTags');
if (fetchOnPull) {
- await this.repository.pull(rebase);
+ await this.repository.pull(rebase, undefined, undefined, { tags });
} else {
- await this.repository.pull(rebase, remoteName, pullBranch);
+ await this.repository.pull(rebase, remoteName, pullBranch, { tags });
}
const remote = this.remotes.find(r => r.name === remoteName);
@@ -1156,7 +1253,7 @@ export class Repository implements Disposable {
}
// https://git-scm.com/docs/git-check-ignore#git-check-ignore--z
- const child = this.repository.stream(['check-ignore', '-z', '--stdin'], { stdio: [null, null, null] });
+ const child = this.repository.stream(['check-ignore', '-v', '-z', '--stdin'], { stdio: [null, null, null] });
child.stdin.end(filePaths.join('\0'), 'utf8');
const onExit = (exitCode: number) => {
@@ -1164,8 +1261,7 @@ export class Repository implements Disposable {
// nothing ignored
resolve(new Set());
} else if (exitCode === 0) {
- // paths are separated by the null-character
- resolve(new Set(data.split('\0')));
+ resolve(new Set(this.parseIgnoreCheck(data)));
} else {
if (/ is in submodule /.test(stderr)) {
reject(new GitError({ stdout: data, stderr, exitCode, gitErrorCode: GitErrorCodes.IsInSubmodule }));
@@ -1193,6 +1289,23 @@ export class Repository implements Disposable {
});
}
+ // Parses output of `git check-ignore -v -z` and returns only those paths
+ // that are actually ignored by git.
+ // Matches to a negative pattern (starting with '!') are filtered out.
+ // See also https://git-scm.com/docs/git-check-ignore#_output.
+ private parseIgnoreCheck(raw: string): string[] {
+ const ignored = [];
+ const elements = raw.split('\0');
+ for (let i = 0; i < elements.length; i += 4) {
+ const pattern = elements[i + 2];
+ const path = elements[i + 3];
+ if (pattern && !pattern.startsWith('!')) {
+ ignored.push(path);
+ }
+ }
+ return ignored;
+ }
+
private async run(operation: Operation, runOperation: () => Promise = () => Promise.resolve(null)): Promise {
if (this.state !== RepositoryState.Idle) {
throw new Error('Repository not initialized');
@@ -1430,7 +1543,7 @@ export class Repository implements Disposable {
return result;
}
- private onFSChange(_uri: Uri): void {
+ private onFileChange(_uri: Uri): void {
const config = workspace.getConfiguration('git');
const autorefresh = config.get('autorefresh');
diff --git a/extensions/git/src/test/git.test.ts b/extensions/git/src/test/git.test.ts
index e28cf10d192..f0444ce5795 100644
--- a/extensions/git/src/test/git.test.ts
+++ b/extensions/git/src/test/git.test.ts
@@ -172,6 +172,17 @@ suite('git', () => {
{ name: 'deps/spdlog4', path: 'deps/spdlog4', url: 'https://github.com/gabime/spdlog4.git' }
]);
});
+
+ test('whitespace #74844', () => {
+ const sample = `[submodule "deps/spdlog"]
+ path = deps/spdlog
+ url = https://github.com/gabime/spdlog.git
+`;
+
+ assert.deepEqual(parseGitmodules(sample), [
+ { name: 'deps/spdlog', path: 'deps/spdlog', url: 'https://github.com/gabime/spdlog.git' }
+ ]);
+ });
});
suite('parseGitCommit', () => {
diff --git a/extensions/git/src/util.ts b/extensions/git/src/util.ts
index 7bf81adccd9..c4e93850619 100644
--- a/extensions/git/src/util.ts
+++ b/extensions/git/src/util.ts
@@ -3,8 +3,8 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import { Event } from 'vscode';
-import { dirname, sep } from 'path';
+import { Event, EventEmitter, Uri } from 'vscode';
+import { dirname, sep, join } from 'path';
import { Readable } from 'stream';
import * as fs from 'fs';
import * as byline from 'byline';
@@ -343,4 +343,20 @@ export function pathEquals(a: string, b: string): boolean {
}
return a === b;
-}
\ No newline at end of file
+}
+
+export interface IFileWatcher extends IDisposable {
+ readonly event: Event;
+}
+
+export function watch(location: string): IFileWatcher {
+ const dotGitWatcher = fs.watch(location);
+ const onDotGitFileChangeEmitter = new EventEmitter();
+ dotGitWatcher.on('change', (_, e) => onDotGitFileChangeEmitter.fire(Uri.file(join(location, e as string))));
+ dotGitWatcher.on('error', err => console.error(err));
+
+ return new class implements IFileWatcher {
+ event = onDotGitFileChangeEmitter.event;
+ dispose() { dotGitWatcher.close(); }
+ };
+}
diff --git a/extensions/git/yarn.lock b/extensions/git/yarn.lock
index f13ef93c34f..1f2ea8aed42 100644
--- a/extensions/git/yarn.lock
+++ b/extensions/git/yarn.lock
@@ -26,10 +26,10 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.51.tgz#b31d716fb8d58eeb95c068a039b9b6292817d5fb"
integrity sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==
-"@types/node@^10.12.21":
- version "10.12.21"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.21.tgz#7e8a0c34cf29f4e17a36e9bd0ea72d45ba03908e"
- integrity sha512-CBgLNk4o3XMnqMc0rhb6lc77IwShMEglz05deDcn2lQxyXEZivfwgYJu7SMha9V5XcrP6qZuevTHV/QrN2vjKQ==
+"@types/node@^10.14.8":
+ version "10.14.8"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.8.tgz#fe444203ecef1162348cd6deb76c62477b2cc6e9"
+ integrity sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==
"@types/which@^1.0.28":
version "1.0.28"
@@ -325,6 +325,11 @@ vscode-nls@^4.0.0:
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.0.0.tgz#4001c8a6caba5cedb23a9c5ce1090395c0e44002"
integrity sha512-qCfdzcH+0LgQnBpZA53bA32kzp9rpq/f66Som577ObeuDlFIrtbEJ+A/+CCxjIh4G8dpJYNCKIsxpRAHIfsbNw==
+vscode-uri@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.0.0.tgz#2df704222f72b8a71ff266ba0830ed6c51ac1542"
+ integrity sha512-lWXWofDSYD8r/TIyu64MdwB4FaSirQ608PP/TzUyslyOeHGwQ0eTHUZeJrK1ILOmwUHaJtV693m2JoUYroUDpw==
+
which@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a"
diff --git a/extensions/go/language-configuration.json b/extensions/go/language-configuration.json
index cf20e02f307..a5e06a56bad 100644
--- a/extensions/go/language-configuration.json
+++ b/extensions/go/language-configuration.json
@@ -27,5 +27,11 @@
"indentationRules": {
"increaseIndentPattern": "^.*(\\bcase\\b.*:|\\bdefault\\b:|(\\b(func|if|else|switch|select|for|struct)\\b.*)?{[^}\"'`]*|\\([^)\"'`]*)$",
"decreaseIndentPattern": "^\\s*(\\bcase\\b.*:|\\bdefault\\b:|}[)}]*[),]?|\\)[,]?)$"
+ },
+ "folding": {
+ "markers": {
+ "start": "^\\s*//\\s*#?region\\b",
+ "end": "^\\s*//\\s*#?endregion\\b"
+ }
}
}
\ No newline at end of file
diff --git a/extensions/go/package.json b/extensions/go/package.json
index 97aced567ae..a91d729adaf 100644
--- a/extensions/go/package.json
+++ b/extensions/go/package.json
@@ -4,6 +4,7 @@
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
+ "license": "MIT",
"engines": { "vscode": "*" },
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js atom/language-go grammars/go.cson ./syntaxes/go.tmLanguage.json"
diff --git a/extensions/groovy/package.json b/extensions/groovy/package.json
index 9cb93f29956..9bed5780419 100644
--- a/extensions/groovy/package.json
+++ b/extensions/groovy/package.json
@@ -4,6 +4,7 @@
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
+ "license": "MIT",
"engines": { "vscode": "*" },
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js textmate/groovy.tmbundle Syntaxes/Groovy.tmLanguage ./syntaxes/groovy.tmLanguage.json"
diff --git a/extensions/grunt/package.json b/extensions/grunt/package.json
index 74fa452028a..f65cc6e62b0 100644
--- a/extensions/grunt/package.json
+++ b/extensions/grunt/package.json
@@ -5,6 +5,7 @@
"displayName": "Grunt support for VS Code",
"version": "1.0.0",
"icon": "images/grunt.png",
+ "license": "MIT",
"engines": {
"vscode": "*"
},
@@ -19,7 +20,7 @@
"vscode-nls": "^4.0.0"
},
"devDependencies": {
- "@types/node": "^10.12.21"
+ "@types/node": "^10.14.8"
},
"main": "./out/main",
"activationEvents": [
diff --git a/extensions/grunt/src/main.ts b/extensions/grunt/src/main.ts
index 09a812ac06f..60dd60839a9 100644
--- a/extensions/grunt/src/main.ts
+++ b/extensions/grunt/src/main.ts
@@ -230,7 +230,7 @@ class TaskDetector {
this.detectors.clear();
}
- private updateWorkspaceFolders(added: vscode.WorkspaceFolder[], removed: vscode.WorkspaceFolder[]): void {
+ private updateWorkspaceFolders(added: readonly vscode.WorkspaceFolder[], removed: readonly vscode.WorkspaceFolder[]): void {
for (let remove of removed) {
let detector = this.detectors.get(remove.uri.toString());
if (detector) {
diff --git a/extensions/grunt/yarn.lock b/extensions/grunt/yarn.lock
index 1bcd757b8a1..e6247e29255 100644
--- a/extensions/grunt/yarn.lock
+++ b/extensions/grunt/yarn.lock
@@ -2,10 +2,10 @@
# yarn lockfile v1
-"@types/node@^10.12.21":
- version "10.12.21"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.21.tgz#7e8a0c34cf29f4e17a36e9bd0ea72d45ba03908e"
- integrity sha512-CBgLNk4o3XMnqMc0rhb6lc77IwShMEglz05deDcn2lQxyXEZivfwgYJu7SMha9V5XcrP6qZuevTHV/QrN2vjKQ==
+"@types/node@^10.14.8":
+ version "10.14.8"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.8.tgz#fe444203ecef1162348cd6deb76c62477b2cc6e9"
+ integrity sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==
vscode-nls@^4.0.0:
version "4.0.0"
diff --git a/extensions/gulp/package.json b/extensions/gulp/package.json
index a9139780f7a..b602bf30c7d 100644
--- a/extensions/gulp/package.json
+++ b/extensions/gulp/package.json
@@ -5,6 +5,7 @@
"displayName": "%displayName%",
"version": "1.0.0",
"icon": "images/gulp.png",
+ "license": "MIT",
"engines": {
"vscode": "*"
},
@@ -19,7 +20,7 @@
"vscode-nls": "^4.0.0"
},
"devDependencies": {
- "@types/node": "^10.12.21"
+ "@types/node": "^10.14.8"
},
"main": "./out/main",
"activationEvents": [
diff --git a/extensions/gulp/src/main.ts b/extensions/gulp/src/main.ts
index 653e34bd27f..49011bf7d68 100644
--- a/extensions/gulp/src/main.ts
+++ b/extensions/gulp/src/main.ts
@@ -151,7 +151,7 @@ class FolderDetector {
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));
+ 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)) {
@@ -209,7 +209,7 @@ class TaskDetector {
this.detectors.clear();
}
- private updateWorkspaceFolders(added: vscode.WorkspaceFolder[], removed: vscode.WorkspaceFolder[]): void {
+ private updateWorkspaceFolders(added: readonly vscode.WorkspaceFolder[], removed: readonly vscode.WorkspaceFolder[]): void {
for (let remove of removed) {
let detector = this.detectors.get(remove.uri.toString());
if (detector) {
diff --git a/extensions/gulp/yarn.lock b/extensions/gulp/yarn.lock
index 1bcd757b8a1..e6247e29255 100644
--- a/extensions/gulp/yarn.lock
+++ b/extensions/gulp/yarn.lock
@@ -2,10 +2,10 @@
# yarn lockfile v1
-"@types/node@^10.12.21":
- version "10.12.21"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.21.tgz#7e8a0c34cf29f4e17a36e9bd0ea72d45ba03908e"
- integrity sha512-CBgLNk4o3XMnqMc0rhb6lc77IwShMEglz05deDcn2lQxyXEZivfwgYJu7SMha9V5XcrP6qZuevTHV/QrN2vjKQ==
+"@types/node@^10.14.8":
+ version "10.14.8"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.8.tgz#fe444203ecef1162348cd6deb76c62477b2cc6e9"
+ integrity sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw==
vscode-nls@^4.0.0:
version "4.0.0"
diff --git a/extensions/handlebars/cgmanifest.json b/extensions/handlebars/cgmanifest.json
index 4d30387e915..39f8efc676d 100644
--- a/extensions/handlebars/cgmanifest.json
+++ b/extensions/handlebars/cgmanifest.json
@@ -6,7 +6,7 @@
"git": {
"name": "daaain/Handlebars",
"repositoryUrl": "https://github.com/daaain/Handlebars",
- "commitHash": "790f2b0222098a3a236bd9e91bb9a039eeca4d8e"
+ "commitHash": "85a153a6f759df4e8da7533e1b3651f007867c51"
}
},
"licenseDetail": [
@@ -29,7 +29,7 @@
"THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
],
"license": "MIT",
- "version": "1.7.1"
+ "version": "1.8.0"
}
],
"version": 1
diff --git a/extensions/handlebars/package.json b/extensions/handlebars/package.json
index fdb8d4fc734..37b63ee54ce 100644
--- a/extensions/handlebars/package.json
+++ b/extensions/handlebars/package.json
@@ -4,6 +4,7 @@
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
+ "license": "MIT",
"engines": {
"vscode": "0.10.x"
},
diff --git a/extensions/handlebars/syntaxes/Handlebars.tmLanguage.json b/extensions/handlebars/syntaxes/Handlebars.tmLanguage.json
index 957f16ae035..be8b06fa085 100644
--- a/extensions/handlebars/syntaxes/Handlebars.tmLanguage.json
+++ b/extensions/handlebars/syntaxes/Handlebars.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/daaain/Handlebars/commit/790f2b0222098a3a236bd9e91bb9a039eeca4d8e",
+ "version": "https://github.com/daaain/Handlebars/commit/85a153a6f759df4e8da7533e1b3651f007867c51",
"name": "Handlebars",
"scopeName": "text.html.handlebars",
"patterns": [
@@ -653,7 +653,7 @@
]
},
"else_token": {
- "begin": "(\\{\\{)(~?else)(@?\\s(if)\\s([-a-zA-Z0-9_\\./]+))?",
+ "begin": "(\\{\\{)(~?else)(@?\\s(if)\\s([-a-zA-Z0-9_\\.\\(\\s\\)/]+))?",
"end": "(~?\\}\\}\\}*)",
"name": "meta.function.inline.else.handlebars",
"beginCaptures": {
diff --git a/extensions/hlsl/package.json b/extensions/hlsl/package.json
index f68ce50ee72..b2f635b4aa0 100644
--- a/extensions/hlsl/package.json
+++ b/extensions/hlsl/package.json
@@ -4,6 +4,7 @@
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
+ "license": "MIT",
"engines": { "vscode": "*" },
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js tgjones/shaders-tmLanguage grammars/hlsl.json ./syntaxes/hlsl.tmLanguage.json"
diff --git a/extensions/html-language-features/client/src/tagClosing.ts b/extensions/html-language-features/client/src/tagClosing.ts
index 35511e63f43..298edcdaa0a 100644
--- a/extensions/html-language-features/client/src/tagClosing.ts
+++ b/extensions/html-language-features/client/src/tagClosing.ts
@@ -32,7 +32,7 @@ export function activateTagClosing(tagProvider: (document: TextDocument, positio
isEnabled = true;
}
- function onDidChangeTextDocument(document: TextDocument, changes: TextDocumentContentChangeEvent[]) {
+ function onDidChangeTextDocument(document: TextDocument, changes: readonly TextDocumentContentChangeEvent[]) {
if (!isEnabled) {
return;
}
diff --git a/extensions/html-language-features/package.json b/extensions/html-language-features/package.json
index e44dc9f7102..e2d06c20860 100644
--- a/extensions/html-language-features/package.json
+++ b/extensions/html-language-features/package.json
@@ -5,6 +5,7 @@
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
+ "license": "MIT",
"aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
"engines": {
"vscode": "0.10.x"
@@ -176,10 +177,10 @@
},
"dependencies": {
"vscode-extension-telemetry": "0.1.1",
- "vscode-languageclient": "^5.2.1",
- "vscode-nls": "^4.0.0"
+ "vscode-languageclient": "^5.3.0-next.6",
+ "vscode-nls": "^4.1.1"
},
"devDependencies": {
- "@types/node": "^10.12.21"
+ "@types/node": "^10.14.8"
}
}
diff --git a/extensions/html-language-features/server/package.json b/extensions/html-language-features/server/package.json
index 74aa5e694a1..e97a42ab0a6 100644
--- a/extensions/html-language-features/server/package.json
+++ b/extensions/html-language-features/server/package.json
@@ -9,16 +9,16 @@
},
"main": "./out/htmlServerMain",
"dependencies": {
- "vscode-css-languageservice": "^4.0.2-next.3",
- "vscode-html-languageservice": "^3.0.0-next.6",
- "vscode-languageserver": "^5.3.0-next.2",
- "vscode-languageserver-types": "^3.14.0",
- "vscode-nls": "^4.0.0",
- "vscode-uri": "^1.0.6"
+ "vscode-css-languageservice": "^4.0.2",
+ "vscode-html-languageservice": "^3.0.0",
+ "vscode-languageserver": "^5.3.0-next.8",
+ "vscode-languageserver-types": "3.15.0-next.2",
+ "vscode-nls": "^4.1.1",
+ "vscode-uri": "^2.0.1"
},
"devDependencies": {
"@types/mocha": "2.2.33",
- "@types/node": "^10.12.21",
+ "@types/node": "^10.14.8",
"glob": "^7.1.2",
"mocha": "^5.2.0",
"mocha-junit-reporter": "^1.17.0",
diff --git a/extensions/html-language-features/server/src/htmlServerMain.ts b/extensions/html-language-features/server/src/htmlServerMain.ts
index 7974284bd77..46bd6e8d090 100644
--- a/extensions/html-language-features/server/src/htmlServerMain.ts
+++ b/extensions/html-language-features/server/src/htmlServerMain.ts
@@ -7,7 +7,7 @@ import {
createConnection, IConnection, TextDocuments, InitializeParams, InitializeResult, RequestType,
DocumentRangeFormattingRequest, Disposable, DocumentSelector, TextDocumentPositionParams, ServerCapabilities,
Position, ConfigurationRequest, ConfigurationParams, DidChangeWorkspaceFoldersNotification,
- WorkspaceFolder, DocumentColorRequest, ColorInformation, ColorPresentationRequest
+ WorkspaceFolder, DocumentColorRequest, ColorInformation, ColorPresentationRequest, TextDocumentSyncKind
} from 'vscode-languageserver';
import { TextDocument, Diagnostic, DocumentLink, SymbolInformation } from 'vscode-languageserver-types';
import { getLanguageModes, LanguageModes, Settings } from './modes/languageModes';
@@ -15,7 +15,7 @@ import { getLanguageModes, LanguageModes, Settings } from './modes/languageModes
import { format } from './modes/formatting';
import { pushAll } from './utils/arrays';
import { getDocumentContext } from './utils/documentContext';
-import uri from 'vscode-uri';
+import { URI } from 'vscode-uri';
import { formatError, runSafe, runSafeAsync } from './utils/runner';
import { getFoldingRanges } from './modes/htmlFolding';
@@ -38,9 +38,8 @@ process.on('uncaughtException', (e: any) => {
console.error(formatError(`Unhandled exception`, e));
});
-// Create a simple text document manager. The text document manager
-// supports full document sync only
-const documents: TextDocuments = new TextDocuments();
+// Create a text document manager.
+const documents: TextDocuments = new TextDocuments(TextDocumentSyncKind.Incremental);
// Make the text document manager listen on the connection
// for open, change and close text document events
documents.listen(connection);
@@ -85,7 +84,7 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
if (!Array.isArray(workspaceFolders)) {
workspaceFolders = [];
if (params.rootPath) {
- workspaceFolders.push({ name: '', uri: uri.file(params.rootPath).toString() });
+ workspaceFolders.push({ name: '', uri: URI.file(params.rootPath).toString() });
}
}
diff --git a/extensions/html-language-features/server/src/modes/htmlMode.ts b/extensions/html-language-features/server/src/modes/htmlMode.ts
index 09efb996f6e..57249a65b8a 100644
--- a/extensions/html-language-features/server/src/modes/htmlMode.ts
+++ b/extensions/html-language-features/server/src/modes/htmlMode.ts
@@ -15,7 +15,7 @@ export function getHTMLMode(htmlLanguageService: HTMLLanguageService, workspace:
getId() {
return 'html';
},
- getSelectionRanges(document: TextDocument, positions: Position[]): SelectionRange[][] {
+ getSelectionRanges(document: TextDocument, positions: Position[]): SelectionRange[] {
return htmlLanguageService.getSelectionRanges(document, positions);
},
doComplete(document: TextDocument, position: Position, settings = workspace.settings) {
diff --git a/extensions/html-language-features/server/src/modes/languageModes.ts b/extensions/html-language-features/server/src/modes/languageModes.ts
index 94c0b04a293..b44b2442420 100644
--- a/extensions/html-language-features/server/src/modes/languageModes.ts
+++ b/extensions/html-language-features/server/src/modes/languageModes.ts
@@ -31,7 +31,7 @@ export interface Workspace {
export interface LanguageMode {
getId(): string;
- getSelectionRanges?: (document: TextDocument, positions: Position[]) => SelectionRange[][];
+ getSelectionRanges?: (document: TextDocument, positions: Position[]) => SelectionRange[];
doValidation?: (document: TextDocument, settings?: Settings) => Diagnostic[];
doComplete?: (document: TextDocument, position: Position, settings?: Settings) => CompletionList;
doResolve?: (document: TextDocument, item: CompletionItem) => CompletionItem;
diff --git a/extensions/html-language-features/server/src/modes/pathCompletion.ts b/extensions/html-language-features/server/src/modes/pathCompletion.ts
index cb3a20f8e4c..7451fee1d93 100644
--- a/extensions/html-language-features/server/src/modes/pathCompletion.ts
+++ b/extensions/html-language-features/server/src/modes/pathCompletion.ts
@@ -7,7 +7,7 @@ import { TextDocument, CompletionItemKind, CompletionItem, TextEdit, Range, Posi
import { WorkspaceFolder } from 'vscode-languageserver';
import * as path from 'path';
import * as fs from 'fs';
-import URI from 'vscode-uri';
+import { URI } from 'vscode-uri';
import { ICompletionParticipant } from 'vscode-html-languageservice';
import { startsWith } from '../utils/strings';
import { contains } from '../utils/arrays';
@@ -160,6 +160,7 @@ function shiftRange(range: Range, startOffset: number, endOffset: number): Range
const PATH_TAG_AND_ATTR: { [tag: string]: string | string[] } = {
// HTML 4
a: 'href',
+ area: 'href',
body: 'background',
del: 'cite',
form: 'action',
@@ -176,7 +177,7 @@ const PATH_TAG_AND_ATTR: { [tag: string]: string | string[] } = {
command: 'icon',
embed: 'src',
html: 'manifest',
- input: 'formaction',
+ input: ['src', 'formaction'],
source: 'src',
track: 'src',
video: ['src', 'poster']
diff --git a/extensions/html-language-features/server/src/test/completions.test.ts b/extensions/html-language-features/server/src/test/completions.test.ts
index c28daf9f0c2..de056ed3c1e 100644
--- a/extensions/html-language-features/server/src/test/completions.test.ts
+++ b/extensions/html-language-features/server/src/test/completions.test.ts
@@ -5,7 +5,7 @@
import 'mocha';
import * as assert from 'assert';
import * as path from 'path';
-import Uri from 'vscode-uri';
+import { URI } from 'vscode-uri';
import { TextDocument, CompletionList, CompletionItemKind } from 'vscode-languageserver-types';
import { getLanguageModes } from '../modes/languageModes';
import { WorkspaceFolder } from 'vscode-languageserver';
@@ -58,8 +58,8 @@ export function testCompletionFor(value: string, expected: { count?: number, ite
let document = TextDocument.create(uri, 'html', 0, value);
let position = document.positionAt(offset);
- var languageModes = getLanguageModes({ css: true, javascript: true }, workspace);
- var mode = languageModes.getModeAtPosition(document, position)!;
+ const languageModes = getLanguageModes({ css: true, javascript: true }, workspace);
+ const mode = languageModes.getModeAtPosition(document, position)!;
let list = mode.doComplete!(document, position);
@@ -95,9 +95,9 @@ suite('HTML Path Completion', () => {
};
const fixtureRoot = path.resolve(__dirname, '../../src/test/pathCompletionFixtures');
- const fixtureWorkspace = { name: 'fixture', uri: Uri.file(fixtureRoot).toString() };
- const indexHtmlUri = Uri.file(path.resolve(fixtureRoot, 'index.html')).toString();
- const aboutHtmlUri = Uri.file(path.resolve(fixtureRoot, 'about/about.html')).toString();
+ const fixtureWorkspace = { name: 'fixture', uri: URI.file(fixtureRoot).toString() };
+ const indexHtmlUri = URI.file(path.resolve(fixtureRoot, 'index.html')).toString();
+ const aboutHtmlUri = URI.file(path.resolve(fixtureRoot, 'about/about.html')).toString();
test('Basics - Correct label/kind/result/command', () => {
testCompletionFor('
- ${this.getStyles(sourceUri, nonce, config, state)}
-
+ data-settings="${escapeAttribute(JSON.stringify(initialData))}"
+ data-strings="${escapeAttribute(JSON.stringify(previewStrings))}"
+ data-state="${escapeAttribute(JSON.stringify(state || {}))}">
+
+ ${this.getStyles(webviewResourceRoot, sourceUri, nonce, config, state)}
+
${body}
- ${this.getScripts(nonce)}
+ ${this.getScripts(webviewResourceRoot, nonce)}
]