From e002fc6afa04975b6176da6a79ae7722a259bfcd Mon Sep 17 00:00:00 2001 From: OneThatWalks Date: Wed, 17 Oct 2018 00:30:39 -0400 Subject: [PATCH 001/861] Git clone fix to use basename --- extensions/git/src/git.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 0deb723c9d0..9434370ae6b 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -334,7 +334,7 @@ export class Git { } async clone(url: string, parentPath: string, cancellationToken?: CancellationToken): Promise { - let baseFolderName = decodeURI(url).replace(/^.*\//, '').replace(/\.git$/, '') || 'repository'; + let baseFolderName = path.win32.basename(decodeURI(url), '.git') || 'repository'; let folderName = baseFolderName; let folderPath = path.join(parentPath, folderName); let count = 1; From 2bae0e925e7fa2a8766ad0d8b0131ce050c4ed15 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 27 Oct 2018 13:32:23 -0500 Subject: [PATCH 002/861] Make launch config 'Launch VS Code (Main Process)' cross platform --- .vscode/launch.json | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index a117e3ed45d..0a1c0ad927c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -159,14 +159,22 @@ "type": "node", "request": "launch", "name": "Launch VS Code (Main Process)", - "runtimeExecutable": "${workspaceFolder}/scripts/code.sh", + "windows": { + "runtimeExecutable": "${workspaceFolder}/scripts/code.bat" + }, + "osx": { + "runtimeExecutable": "${workspaceFolder}/scripts/code.sh" + }, + "linux": { + "runtimeExecutable": "${workspaceFolder}/scripts/code.sh" + }, "runtimeArgs": [ - "--no-cached-data" + "", "--no-cached-data" ], "smartStep": true, "outFiles": [ "${workspaceFolder}/out/**/*.js" - ] + ] }, { "type": "node", From 64286ca313358c6a6633990143ca621c00862012 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 27 Oct 2018 13:32:47 -0500 Subject: [PATCH 003/861] Ignore empty string for code-cli path arg --- src/vs/platform/environment/node/argv.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index 3618a0b25c8..c06ebbafdf8 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -106,6 +106,15 @@ function validate(args: ParsedArgs): ParsedArgs { return args; } +function stripEmptyPath(argv: string[]): string[] | undefined { + const index = firstIndex(argv, a => !/^-/.test(a)); + + if (index > -1 && argv[index] === '') { + argv.splice(index, 1); + } + return argv; +} + function stripAppPath(argv: string[]): string[] | undefined { const index = firstIndex(argv, a => !/^-/.test(a)); @@ -126,6 +135,9 @@ export function parseMainProcessArgv(processArgv: string[]): ParsedArgs { args = stripAppPath(args) || []; } + // Ignore empty path arg + stripEmptyPath(args); + return validate(parseArgs(args)); } From 7e3ad32006a7df0d6cfcdf74bdd3cd38a6350741 Mon Sep 17 00:00:00 2001 From: Yisrael Date: Mon, 5 Nov 2018 13:24:07 +0200 Subject: [PATCH 004/861] if there is no documentation don't show border --- .../parameterHints/parameterHintsWidget.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts b/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts index 7c5475da647..07f9ecb755d 100644 --- a/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts +++ b/src/vs/editor/contrib/parameterHints/parameterHintsWidget.ts @@ -419,8 +419,6 @@ export class ParameterHintsWidget implements IContentWidget, IDisposable { dom.append(this.docs, $('p', null, documentation)); } - dom.toggleClass(this.signature, 'has-docs', !!signature.documentation); - if (typeof signature.documentation === 'string') { dom.append(this.docs, $('p', null, signature.documentation)); } else { @@ -430,6 +428,21 @@ export class ParameterHintsWidget implements IContentWidget, IDisposable { dom.append(this.docs, renderedContents.element); } + let hasDocs = false; + if (activeParameter && typeof (activeParameter.documentation) === 'string' && activeParameter.documentation.length > 0) { + hasDocs = true; + } + if (activeParameter && typeof (activeParameter.documentation) === 'object' && activeParameter.documentation.value.length > 0) { + hasDocs = true; + } + if (typeof (signature.documentation) === 'string' && signature.documentation.length > 0) { + hasDocs = true; + } + if (typeof (signature.documentation) === 'object' && signature.documentation.value.length > 0) { + hasDocs = true; + } + dom.toggleClass(this.signature, 'has-docs', hasDocs); + let currentOverload = String(this.currentSignature + 1); if (this.hints.signatures.length < 10) { From fe6864f64974bc96d17f28e0d0a8f7f382454f77 Mon Sep 17 00:00:00 2001 From: "m.zaretski" Date: Sun, 25 Nov 2018 17:32:09 +0300 Subject: [PATCH 005/861] 'suggestSmartCommit' configuration setting was introduced --- extensions/git/package.json | 6 ++++++ extensions/git/package.nls.json | 1 + extensions/git/src/commands.ts | 11 ++++++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index ef4385ef3db..f0d86ef1d87 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1097,6 +1097,12 @@ "description": "%config.enableSmartCommit%", "default": false }, + "git.suggestSmartCommit": { + "type": "boolean", + "scope": "resource", + "description": "%config.suggestSmartCommit%", + "default": true + }, "git.enableCommitSigning": { "type": "boolean", "scope": "resource", diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 356d1473bbc..5c76ad62c33 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -85,6 +85,7 @@ "config.ignoreLimitWarning": "Ignores the warning when there are too many changes in a repository.", "config.defaultCloneDirectory": "The default location to clone a git repository.", "config.enableSmartCommit": "Commit all changes when there are no staged changes.", + "config.suggestSmartCommit": "Suggests to enable smart commit (commit all changes when there are no staged changes).", "config.enableCommitSigning": "Enables commit signing with GPG.", "config.discardAllScope": "Controls what changes are discarded by the `Discard all changes` command. `all` discards all changes. `tracked` discards only tracked files. `prompt` shows a prompt dialog every time the action is run.", "config.decorations.enabled": "Controls whether Git contributes colors and badges to the explorer and the open editors view.", diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index e41a8161c56..11ff3cdd0ce 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1192,14 +1192,23 @@ export class CommandCenter { // no changes, and the user has not configured to commit all in this case if (!noUnstagedChanges && noStagedChanges && !enableSmartCommit) { + const suggestSmartCommit = config.get('suggestSmartCommit') === true; + if (!suggestSmartCommit) { + return false; + } + // prompt the user if we want to commit all or not const message = localize('no staged changes', "There are no staged changes to commit.\n\nWould you like to automatically stage all your changes and commit them directly?"); const yes = localize('yes', "Yes"); const always = localize('always', "Always"); - const pick = await window.showWarningMessage(message, { modal: true }, yes, always); + const never = localize('never', "Never"); + const pick = await window.showWarningMessage(message, { modal: true }, yes, always, never); if (pick === always) { config.update('enableSmartCommit', true, true); + } else if (pick === never) { + config.update('suggestSmartCommit', false, true); + return false; } else if (pick !== yes) { return false; // do not commit on cancel } From 6dbf6b5857f466ff2b51c71afb3e20431c5268a3 Mon Sep 17 00:00:00 2001 From: joaorreis Date: Mon, 17 Dec 2018 14:47:35 +0000 Subject: [PATCH 006/861] fixed --- extensions/git/src/git.ts | 4 ++-- extensions/git/src/repository.ts | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 380ee42f411..cc4458f2e3d 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -1197,7 +1197,7 @@ export class Repository { } } - async pull(rebase?: boolean, remote?: string, branch?: string): Promise { + async pull(rebase?: boolean, remote?: string, branch?: string, cancellationToken?: CancellationToken): Promise { const args = ['pull', '--tags']; if (rebase) { @@ -1210,7 +1210,7 @@ export class Repository { } try { - await this.run(args); + await this.run(args, { cancellationToken }); } catch (err) { if (/^CONFLICT \([^)]+\): \b/m.test(err.stdout || '')) { err.gitErrorCode = GitErrorCodes.Conflict; diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index d188eea026e..66d03ebc42b 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -1004,11 +1004,22 @@ export class Repository implements Disposable { await this.run(Operation.Sync, async () => { const config = workspace.getConfiguration('git', Uri.file(this.root)); const fetchOnPull = config.get('fetchOnPull'); + const opts = { + location: ProgressLocation.Notification, + title: localize('sync is unpredictable', "Syncing. Cancelling may cause serious damages to the repository"), + cancellable: true + }; if (fetchOnPull) { - await this.repository.pull(rebase); + await window.withProgress( + opts, + (_, token) => this.repository.pull(rebase, undefined, undefined, token) + ); } else { - await this.repository.pull(rebase, remoteName, pullBranch); + await window.withProgress( + opts, + (_, token) => this.repository.pull(rebase, remoteName, pullBranch, token) + ); } const remote = this.remotes.find(r => r.name === remoteName); From 7a69cd07c02fba7c52248ebc5ba7fbb4d49cbeb4 Mon Sep 17 00:00:00 2001 From: Tito Date: Tue, 18 Dec 2018 02:27:38 +0000 Subject: [PATCH 007/861] Git sync now publishes branch upon confirmation (#64183 issue fix) --- extensions/git/src/commands.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index e41a8161c56..7aad89d6b09 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1764,7 +1764,17 @@ export class CommandCenter { private async _sync(repository: Repository, rebase: boolean): Promise { const HEAD = repository.HEAD; - if (!HEAD || !HEAD.upstream) { + if (!HEAD) { + return; + } else if (!HEAD.upstream) { + const branchName = HEAD.name; + const message = localize('confirm publish branch', "The branch '{0}' has no upstream branch. Would you like to publish this branch?", branchName); + const yes = localize('ok', "OK"); + const pick = await window.showWarningMessage(message, { modal: true }, yes); + + if (pick === yes) { + await this.publish(repository); + } return; } From 6208e8441e43e175db0bbf7d2412ff15690d88a3 Mon Sep 17 00:00:00 2001 From: Dan Wood Date: Thu, 3 Jan 2019 00:10:44 +1100 Subject: [PATCH 008/861] Clean user input for git clone extension Strip whitespace and "git clone " from start of string. This will allow VSCode to intelligently handle copy and paste from command line instructions being pasted into the clone input box. --- extensions/git/src/commands.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index c07517aa21b..7cd02c525c1 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -405,6 +405,8 @@ export class CommandCenter { return; } + url = this.cleanCloneUrlInput(url); + const config = workspace.getConfiguration('git'); let defaultCloneDirectory = config.get('defaultCloneDirectory') || os.homedir(); defaultCloneDirectory = defaultCloneDirectory.replace(/^~/, os.homedir()); @@ -494,6 +496,14 @@ export class CommandCenter { } } + private cleanCloneUrlInput(url: string): string { + url = url.trim(); + if (url.startsWith('git clone ')) { + return url.replace('git clone ', ''); + } + return url; + } + @command('git.init') async init(): Promise { let repositoryPath: string | undefined = undefined; From fc488dd86cf9a97c99b8dd1971978af839abfd53 Mon Sep 17 00:00:00 2001 From: Rich Evans Date: Sat, 5 Jan 2019 13:04:18 -0800 Subject: [PATCH 009/861] Chunk clean, checkout and update submodule commands within repository.ts to ensure the length of the files passed to the repository are less than 30k characters to avoid ENAMETOOLONG failures on Windows when working with very large changesets --- extensions/git/src/repository.ts | 61 ++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 6a57806ac12..6e4a2c34c0b 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -844,21 +844,70 @@ export class Repository implements Disposable { } }); - const promises: Promise[] = []; + const maxCommandLineLength: number = 30000; if (toClean.length > 0) { - promises.push(this.repository.clean(toClean)); + let sliceStart: number = 0; + let sliceEnd: number = 1; + let accumulatedStringLength = 0; + + while (sliceEnd < toClean.length) { + if ((accumulatedStringLength + (toClean[sliceEnd - 1].length + 1)) > maxCommandLineLength) { + await this.repository.clean(toClean.slice(sliceStart, sliceEnd)); + sliceStart = sliceEnd; + sliceEnd++; + accumulatedStringLength = 0; + } + else { + accumulatedStringLength += toClean[sliceEnd - 1].length + 1; + sliceEnd++; + } + } + + await this.repository.clean(toClean.slice(sliceStart, sliceEnd)); } if (toCheckout.length > 0) { - promises.push(this.repository.checkout('', toCheckout)); + let sliceStart: number = 0; + let sliceEnd: number = 1; + let accumulatedStringLength = 0; + + while (sliceEnd < toCheckout.length) { + if ((accumulatedStringLength + (toCheckout[sliceEnd - 1].length + 1)) > maxCommandLineLength) { + await this.repository.checkout('', toCheckout.slice(sliceStart, sliceEnd)); + sliceStart = sliceEnd; + sliceEnd++; + accumulatedStringLength = 0; + } + else { + accumulatedStringLength += toCheckout[sliceEnd - 1].length + 1; + sliceEnd++; + } + } + + await this.repository.checkout('', toCheckout.slice(sliceStart, sliceEnd)); } if (submodulesToUpdate.length > 0) { - promises.push(this.repository.updateSubmodules(submodulesToUpdate)); - } + let sliceStart: number = 0; + let sliceEnd: number = 1; + let accumulatedStringLength = 0; - await Promise.all(promises); + while (sliceEnd < submodulesToUpdate.length) { + if ((accumulatedStringLength + (submodulesToUpdate[sliceEnd - 1].length + 1)) > maxCommandLineLength) { + await this.repository.updateSubmodules(submodulesToUpdate.slice(sliceStart, sliceEnd)); + sliceStart = sliceEnd; + sliceEnd++; + accumulatedStringLength = 0; + } + else { + accumulatedStringLength += submodulesToUpdate[sliceEnd - 1].length + 1; + sliceEnd++; + } + } + + await this.repository.updateSubmodules(submodulesToUpdate.slice(sliceStart, sliceEnd)); + } }); } From f1e2a0a2b57b8df271fe6ab10426a8c76a27233b Mon Sep 17 00:00:00 2001 From: Rich Evans Date: Sat, 5 Jan 2019 16:05:13 -0800 Subject: [PATCH 010/861] Try naiive rev-parse for branches beginning with @ to see if they resolve, before replacing with symbolic full name version. --- extensions/git/src/git.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 941e308719c..2ed2c487376 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -1458,13 +1458,16 @@ export class Repository { async getBranch(name: string): Promise { if (name === 'HEAD') { return this.getHEAD(); - } else if (/^@/.test(name)) { - const symbolicFullNameResult = await this.run(['rev-parse', '--symbolic-full-name', name]); - const symbolicFullName = symbolicFullNameResult.stdout.trim(); - name = symbolicFullName || name; } - const result = await this.run(['rev-parse', name]); + let result = await this.run(['rev-parse', name]); + + if (!result.stdout && /^@/.test(name)) { + const symbolicFullNameResult = await this.run(['rev-parse', '--symbolic-full-name', name]); + name = symbolicFullNameResult.stdout.trim(); + + result = await this.run(['rev-parse', name]); + } if (!result.stdout) { return Promise.reject(new Error('No such branch')); From a0a5c9cbeecc40dbaaf3c0bba73f1475ba65f494 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Tue, 8 Jan 2019 00:40:15 +0200 Subject: [PATCH 011/861] Bundle/Install completions with the correct appname Fixes #66154 --- build/gulpfile.vscode.js | 7 ++++++- build/gulpfile.vscode.linux.js | 24 ++++++++++++++---------- resources/completions/bash/code | 4 ++-- resources/completions/zsh/_code | 2 +- resources/linux/rpm/code.spec.template | 12 ++++++------ 5 files changed, 29 insertions(+), 20 deletions(-) diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 2a39f8196bf..0b6bc57404e 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -385,7 +385,12 @@ function packageTask(platform, arch, opts) { .pipe(electron(_.extend({}, config, { platform, arch, ffmpegChromium: true }))) .pipe(filter(['**', '!LICENSE', '!LICENSES.chromium.html', '!version'])); - // result = es.merge(result, gulp.src('resources/completions/**', { base: '.' })); + result = es.merge(result, gulp.src('resources/completions/bash/code', { base: '.' }) + .pipe(replace('@@APPNAME@@', product.applicationName)) + .pipe(rename(function (f) { f.basename = product.applicationName; }))); + result = es.merge(result, gulp.src('resources/completions/zsh/_code', { base: '.' }) + .pipe(replace('@@APPNAME@@', product.applicationName)) + .pipe(rename(function (f) { f.basename = '_' + product.applicationName; }))); if (platform === 'win32') { result = es.merge(result, gulp.src('resources/win32/bin/code.js', { base: 'resources/win32' })); diff --git a/build/gulpfile.vscode.linux.js b/build/gulpfile.vscode.linux.js index 006235ebeaf..212dda85624 100644 --- a/build/gulpfile.vscode.linux.js +++ b/build/gulpfile.vscode.linux.js @@ -53,11 +53,13 @@ function prepareDebPackage(arch) { const icon = gulp.src('resources/linux/code.png', { base: '.' }) .pipe(rename('usr/share/pixmaps/' + product.applicationName + '.png')); - // const bash_completion = gulp.src('resources/completions/bash/code') - // .pipe(rename('usr/share/bash-completion/completions/code')); + const bash_completion = gulp.src('resources/completions/bash/code') + .pipe(replace('@@APPNAME@@', product.applicationName)) + .pipe(rename('usr/share/bash-completion/completions/' + product.applicationName)); - // const zsh_completion = gulp.src('resources/completions/zsh/_code') - // .pipe(rename('usr/share/zsh/vendor-completions/_code')); + const zsh_completion = gulp.src('resources/completions/zsh/_code') + .pipe(replace('@@APPNAME@@', product.applicationName)) + .pipe(rename('usr/share/zsh/vendor-completions/_' + product.applicationName)); const code = gulp.src(binaryDir + '/**/*', { base: binaryDir }) .pipe(rename(function (p) { p.dirname = 'usr/share/' + product.applicationName + '/' + p.dirname; })); @@ -93,7 +95,7 @@ function prepareDebPackage(arch) { .pipe(replace('@@UPDATEURL@@', product.updateUrl || '@@UPDATEURL@@')) .pipe(rename('DEBIAN/postinst')); - const all = es.merge(control, postinst, postrm, prerm, desktops, appdata, icon, /* bash_completion, zsh_completion, */ code); + const all = es.merge(control, postinst, postrm, prerm, desktops, appdata, icon, bash_completion, zsh_completion, code); return all.pipe(vfs.dest(destination)); }; @@ -143,11 +145,13 @@ function prepareRpmPackage(arch) { const icon = gulp.src('resources/linux/code.png', { base: '.' }) .pipe(rename('BUILD/usr/share/pixmaps/' + product.applicationName + '.png')); - // const bash_completion = gulp.src('resources/completions/bash/code') - // .pipe(rename('BUILD/usr/share/bash-completion/completions/code')); + const bash_completion = gulp.src('resources/completions/bash/code') + .pipe(replace('@@APPNAME@@', product.applicationName)) + .pipe(rename('BUILD/usr/share/bash-completion/completions/' + product.applicationName)); - // const zsh_completion = gulp.src('resources/completions/zsh/_code') - // .pipe(rename('BUILD/usr/share/zsh/site-functions/_code')); + const zsh_completion = gulp.src('resources/completions/zsh/_code') + .pipe(replace('@@APPNAME@@', product.applicationName)) + .pipe(rename('BUILD/usr/share/zsh/site-functions/_' + product.applicationName)); const code = gulp.src(binaryDir + '/**/*', { base: binaryDir }) .pipe(rename(function (p) { p.dirname = 'BUILD/usr/share/' + product.applicationName + '/' + p.dirname; })); @@ -169,7 +173,7 @@ function prepareRpmPackage(arch) { const specIcon = gulp.src('resources/linux/rpm/code.xpm', { base: '.' }) .pipe(rename('SOURCES/' + product.applicationName + '.xpm')); - const all = es.merge(code, desktops, appdata, icon, /* bash_completion, zsh_completion, */ spec, specIcon); + const all = es.merge(code, desktops, appdata, icon, bash_completion, zsh_completion, spec, specIcon); return all.pipe(vfs.dest(getRpmBuildPath(rpmArch))); }; diff --git a/resources/completions/bash/code b/resources/completions/bash/code index e377c5d24e2..9340e946ea6 100644 --- a/resources/completions/bash/code +++ b/resources/completions/bash/code @@ -1,4 +1,4 @@ -_code() +_@@APPNAME@@() { local cur prev words cword split _init_completion -s || return @@ -58,4 +58,4 @@ _code() _filedir } && -complete -F _code code +complete -F _@@APPNAME@@ @@APPNAME@@ diff --git a/resources/completions/zsh/_code b/resources/completions/zsh/_code index 9579cffb2f6..a3526e262d3 100644 --- a/resources/completions/zsh/_code +++ b/resources/completions/zsh/_code @@ -1,4 +1,4 @@ -#compdef code +#compdef @@APPNAME@@ local arguments diff --git a/resources/linux/rpm/code.spec.template b/resources/linux/rpm/code.spec.template index 350c05516e2..a9bcc3af830 100644 --- a/resources/linux/rpm/code.spec.template +++ b/resources/linux/rpm/code.spec.template @@ -18,14 +18,14 @@ Visual Studio Code is a new choice of tool that combines the simplicity of a cod mkdir -p %{buildroot}/usr/share/@@NAME@@ mkdir -p %{buildroot}/usr/share/applications mkdir -p %{buildroot}/usr/share/pixmaps -#mkdir -p %{buildroot}/usr/share/bash-completion/completions -#mkdir -p %{buildroot}/usr/share/zsh/site-functions +mkdir -p %{buildroot}/usr/share/bash-completion/completions +mkdir -p %{buildroot}/usr/share/zsh/site-functions cp -r usr/share/@@NAME@@/* %{buildroot}/usr/share/@@NAME@@ cp -r usr/share/applications/@@NAME@@.desktop %{buildroot}/usr/share/applications cp -r usr/share/applications/@@NAME@@-url-handler.desktop %{buildroot}/usr/share/applications cp -r usr/share/pixmaps/@@NAME@@.png %{buildroot}/usr/share/pixmaps -#cp usr/share/bash-completion/completions/code %{buildroot}/usr/share/bash-completion/completions/code -#cp usr/share/zsh/site-functions/_code %{buildroot}/usr/share/zsh/site-functions/_code +cp usr/share/bash-completion/completions/@@NAME@@ %{buildroot}/usr/share/bash-completion/completions/@@NAME@@ +cp usr/share/zsh/site-functions/_@@NAME@@ %{buildroot}/usr/share/zsh/site-functions/_@@NAME@@ %post # Remove the legacy bin command if this is the stable build @@ -58,5 +58,5 @@ fi /usr/share/applications/@@NAME@@.desktop /usr/share/applications/@@NAME@@-url-handler.desktop /usr/share/pixmaps/@@NAME@@.png -#/usr/share/bash-completion/completions/code -#/usr/share/zsh/site-functions/_code +/usr/share/bash-completion/completions/@@NAME@@ +/usr/share/zsh/site-functions/_@@NAME@@ From 3cfd86034464cf2526b5ef5b20da2f1e05fac933 Mon Sep 17 00:00:00 2001 From: Phil Marshall Date: Tue, 15 Jan 2019 19:58:07 -0600 Subject: [PATCH 012/861] git prompts to save only staged files --- extensions/git/src/commands.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index eb45f107f4b..26685a0afa3 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1200,19 +1200,21 @@ export class CommandCenter { const promptToSaveFilesBeforeCommit = config.get('promptToSaveFilesBeforeCommit') === true; if (promptToSaveFilesBeforeCommit) { - const unsavedTextDocuments = workspace.textDocuments - .filter(d => !d.isUntitled && d.isDirty && isDescendant(repository.root, d.uri.fsPath)); + const stagedUnsavedTextDocuments = workspace.textDocuments + .filter(d => !d.isUntitled && d.isDirty && isDescendant(repository.root, d.uri.fsPath)) + .filter(d => repository.indexGroup.resourceStates.some(s => + s.resourceUri.path === d.uri.fsPath)); - if (unsavedTextDocuments.length > 0) { - const message = unsavedTextDocuments.length === 1 - ? localize('unsaved files single', "The following file is unsaved: {0}.\n\nWould you like to save it before committing?", path.basename(unsavedTextDocuments[0].uri.fsPath)) - : localize('unsaved files', "There are {0} unsaved files.\n\nWould you like to save them before committing?", unsavedTextDocuments.length); + if (stagedUnsavedTextDocuments.length > 0) { + const message = stagedUnsavedTextDocuments.length === 1 + ? localize('unsaved files single', "The following file is unsaved: {0}.\n\nWould you like to save it before committing?", path.basename(stagedUnsavedTextDocuments[0].uri.fsPath)) + : localize('unsaved files', "There are {0} unsaved files.\n\nWould you like to save them before committing?", stagedUnsavedTextDocuments.length); const saveAndCommit = localize('save and commit', "Save All & Commit"); const commit = localize('commit', "Commit Anyway"); const pick = await window.showWarningMessage(message, { modal: true }, saveAndCommit, commit); if (pick === saveAndCommit) { - await Promise.all(unsavedTextDocuments.map(d => d.save())); + await Promise.all(stagedUnsavedTextDocuments.map(d => d.save())); await repository.status(); } else if (pick !== commit) { return false; // do not commit on cancel From 957f809e4dd54bc85620fa5e480465c2b38d9a5b Mon Sep 17 00:00:00 2001 From: Phil Marshall Date: Wed, 16 Jan 2019 00:18:15 -0600 Subject: [PATCH 013/861] update strings for prompt to save staged files --- extensions/git/src/commands.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 26685a0afa3..14a3e8b2cf8 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1207,8 +1207,8 @@ export class CommandCenter { if (stagedUnsavedTextDocuments.length > 0) { const message = stagedUnsavedTextDocuments.length === 1 - ? localize('unsaved files single', "The following file is unsaved: {0}.\n\nWould you like to save it before committing?", path.basename(stagedUnsavedTextDocuments[0].uri.fsPath)) - : localize('unsaved files', "There are {0} unsaved files.\n\nWould you like to save them before committing?", stagedUnsavedTextDocuments.length); + ? localize('unsaved files single', "The following staged file is unsaved: {0}.\n\nWould you like to save it before committing?", path.basename(stagedUnsavedTextDocuments[0].uri.fsPath)) + : localize('unsaved files', "There are {0} unsaved staged files.\n\nWould you like to save them before committing?", stagedUnsavedTextDocuments.length); const saveAndCommit = localize('save and commit', "Save All & Commit"); const commit = localize('commit', "Commit Anyway"); const pick = await window.showWarningMessage(message, { modal: true }, saveAndCommit, commit); From dbbe1a98c0c97bffbdee60cd3e86ad1deb875b9e Mon Sep 17 00:00:00 2001 From: matthew Date: Thu, 31 Jan 2019 01:05:45 -0600 Subject: [PATCH 014/861] set screencast to display 15 characters check if textContent is null --- src/vs/workbench/electron-browser/actions/developerActions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/electron-browser/actions/developerActions.ts b/src/vs/workbench/electron-browser/actions/developerActions.ts index 8b9c5485b63..bb84cca076b 100644 --- a/src/vs/workbench/electron-browser/actions/developerActions.ts +++ b/src/vs/workbench/electron-browser/actions/developerActions.ts @@ -184,7 +184,7 @@ export class ToggleScreencastModeAction extends Action { const keybinding = this.keybindingService.resolveKeyboardEvent(event); const label = keybinding.getLabel(); - if (!event.ctrlKey && !event.altKey && !event.metaKey && !event.shiftKey && this.keybindingService.mightProducePrintableCharacter(event) && label) { + if (!event.ctrlKey && !event.altKey && !event.metaKey && !event.shiftKey && (this.keybindingService.mightProducePrintableCharacter(event) || !keyboardMarker.textContent || keyboardMarker.textContent.length < 15) && label) { keyboardMarker.textContent += ' ' + label; } else { keyboardMarker.textContent = label; From 7568cde4014bb0c274f36a757f41f9979ca0890a Mon Sep 17 00:00:00 2001 From: al Date: Thu, 31 Jan 2019 14:47:44 +0300 Subject: [PATCH 015/861] Add border for keys --- .../electron-browser/actions/developerActions.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/electron-browser/actions/developerActions.ts b/src/vs/workbench/electron-browser/actions/developerActions.ts index 8b9c5485b63..cae11269325 100644 --- a/src/vs/workbench/electron-browser/actions/developerActions.ts +++ b/src/vs/workbench/electron-browser/actions/developerActions.ts @@ -183,11 +183,18 @@ export class ToggleScreencastModeAction extends Action { const event = new StandardKeyboardEvent(e); const keybinding = this.keybindingService.resolveKeyboardEvent(event); const label = keybinding.getLabel(); + const key = $('span'); + key.style.paddingLeft = '10px'; + key.style.paddingRight = '10px'; + key.style.boxShadow = '0 0 0 1px rgba(255, 255, 255, 0.2)'; + key.style.marginRight = '1px'; + key.textContent = label; if (!event.ctrlKey && !event.altKey && !event.metaKey && !event.shiftKey && this.keybindingService.mightProducePrintableCharacter(event) && label) { - keyboardMarker.textContent += ' ' + label; + append(keyboardMarker, key); } else { - keyboardMarker.textContent = label; + keyboardMarker.textContent = ''; + append(keyboardMarker, key); } keyboardMarker.style.display = 'block'; From f9ff4b56656cda483a1b7ab41597f29f3c06ec9a Mon Sep 17 00:00:00 2001 From: al Date: Thu, 31 Jan 2019 16:50:02 +0300 Subject: [PATCH 016/861] Using style closer to Keybindings GUI --- .../electron-browser/actions/developerActions.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/electron-browser/actions/developerActions.ts b/src/vs/workbench/electron-browser/actions/developerActions.ts index cae11269325..c2a5bb752fe 100644 --- a/src/vs/workbench/electron-browser/actions/developerActions.ts +++ b/src/vs/workbench/electron-browser/actions/developerActions.ts @@ -184,10 +184,13 @@ export class ToggleScreencastModeAction extends Action { const keybinding = this.keybindingService.resolveKeyboardEvent(event); const label = keybinding.getLabel(); const key = $('span'); - key.style.paddingLeft = '10px'; - key.style.paddingRight = '10px'; - key.style.boxShadow = '0 0 0 1px rgba(255, 255, 255, 0.2)'; - key.style.marginRight = '1px'; + key.style.paddingLeft = '8px'; + key.style.paddingRight = '8px'; + key.style.boxShadow = 'inset 0 -3px 0 hsla(0,0%,73%,.4)'; + key.style.marginRight = '6px'; + key.style.border = '1px solid hsla(0,0%,80%,.4)'; + key.style.borderRadius = '5px'; + key.style.backgroundColor = 'rgba(255, 255, 255, 0.1)'; key.textContent = label; if (!event.ctrlKey && !event.altKey && !event.metaKey && !event.shiftKey && this.keybindingService.mightProducePrintableCharacter(event) && label) { From 46cb407f6acb91ce6087f0b21b011687a7662bae Mon Sep 17 00:00:00 2001 From: al Date: Thu, 31 Jan 2019 17:15:56 +0300 Subject: [PATCH 017/861] More transparency for key --- src/vs/workbench/electron-browser/actions/developerActions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/electron-browser/actions/developerActions.ts b/src/vs/workbench/electron-browser/actions/developerActions.ts index c2a5bb752fe..ff41d1112ce 100644 --- a/src/vs/workbench/electron-browser/actions/developerActions.ts +++ b/src/vs/workbench/electron-browser/actions/developerActions.ts @@ -190,7 +190,7 @@ export class ToggleScreencastModeAction extends Action { key.style.marginRight = '6px'; key.style.border = '1px solid hsla(0,0%,80%,.4)'; key.style.borderRadius = '5px'; - key.style.backgroundColor = 'rgba(255, 255, 255, 0.1)'; + key.style.backgroundColor = 'rgba(255, 255, 255, 0.05)'; key.textContent = label; if (!event.ctrlKey && !event.altKey && !event.metaKey && !event.shiftKey && this.keybindingService.mightProducePrintableCharacter(event) && label) { From 2ca7f22d1b02856e24966b3deab0d9a10545a165 Mon Sep 17 00:00:00 2001 From: al Date: Thu, 31 Jan 2019 17:32:50 +0300 Subject: [PATCH 018/861] White is too bright --- src/vs/workbench/electron-browser/actions/developerActions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/electron-browser/actions/developerActions.ts b/src/vs/workbench/electron-browser/actions/developerActions.ts index ff41d1112ce..809b394873e 100644 --- a/src/vs/workbench/electron-browser/actions/developerActions.ts +++ b/src/vs/workbench/electron-browser/actions/developerActions.ts @@ -168,7 +168,7 @@ export class ToggleScreencastModeAction extends Action { keyboardMarker.style.left = '0'; keyboardMarker.style.zIndex = '100000'; keyboardMarker.style.pointerEvents = 'none'; - keyboardMarker.style.color = 'white'; + keyboardMarker.style.color = '#eee'; keyboardMarker.style.lineHeight = '100px'; keyboardMarker.style.textAlign = 'center'; keyboardMarker.style.fontSize = '56px'; From 1cebcd0cc2db9c3086189b8a18392e1d8598ed83 Mon Sep 17 00:00:00 2001 From: al Date: Mon, 4 Feb 2019 01:09:08 +0300 Subject: [PATCH 019/861] Smooth showing/hiding of screencast marker --- .../electron-browser/actions/developerActions.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/electron-browser/actions/developerActions.ts b/src/vs/workbench/electron-browser/actions/developerActions.ts index 8b9c5485b63..4739933e7ca 100644 --- a/src/vs/workbench/electron-browser/actions/developerActions.ts +++ b/src/vs/workbench/electron-browser/actions/developerActions.ts @@ -172,7 +172,10 @@ export class ToggleScreencastModeAction extends Action { keyboardMarker.style.lineHeight = '100px'; keyboardMarker.style.textAlign = 'center'; keyboardMarker.style.fontSize = '56px'; - keyboardMarker.style.display = 'none'; + keyboardMarker.style.transitionProperty = 'opacity'; + keyboardMarker.style.transitionDuration = '0.4s'; + keyboardMarker.style.pointerEvents = 'none'; + keyboardMarker.style.opacity = '0'; const onKeyDown = domEvent(document.body, 'keydown', true); let keyboardTimeout: IDisposable = Disposable.None; @@ -190,14 +193,14 @@ export class ToggleScreencastModeAction extends Action { keyboardMarker.textContent = label; } - keyboardMarker.style.display = 'block'; + keyboardMarker.style.opacity = '1'; const promise = timeout(800); keyboardTimeout = toDisposable(() => promise.cancel()); promise.then(() => { keyboardMarker.textContent = ''; - keyboardMarker.style.display = 'none'; + keyboardMarker.style.opacity = '0'; }); }); From 22592a29efbb80af372831c278b8bb5df008b9a5 Mon Sep 17 00:00:00 2001 From: Phil Marshall Date: Thu, 7 Feb 2019 01:04:28 -0600 Subject: [PATCH 020/861] hide keyboardMarker overflow --- src/vs/workbench/electron-browser/actions/developerActions.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/electron-browser/actions/developerActions.ts b/src/vs/workbench/electron-browser/actions/developerActions.ts index 8b9c5485b63..589e82edb95 100644 --- a/src/vs/workbench/electron-browser/actions/developerActions.ts +++ b/src/vs/workbench/electron-browser/actions/developerActions.ts @@ -173,6 +173,7 @@ export class ToggleScreencastModeAction extends Action { keyboardMarker.style.textAlign = 'center'; keyboardMarker.style.fontSize = '56px'; keyboardMarker.style.display = 'none'; + keyboardMarker.style.overflow = 'hidden'; const onKeyDown = domEvent(document.body, 'keydown', true); let keyboardTimeout: IDisposable = Disposable.None; From eca450439030bd4ba57610d98c0d82108db38e54 Mon Sep 17 00:00:00 2001 From: Phil Marshall Date: Sat, 9 Feb 2019 16:58:14 -0600 Subject: [PATCH 021/861] truncate screencast keyboard marker when overflowing --- src/vs/workbench/electron-browser/actions/developerActions.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/workbench/electron-browser/actions/developerActions.ts b/src/vs/workbench/electron-browser/actions/developerActions.ts index 589e82edb95..c2056eeb555 100644 --- a/src/vs/workbench/electron-browser/actions/developerActions.ts +++ b/src/vs/workbench/electron-browser/actions/developerActions.ts @@ -190,6 +190,9 @@ export class ToggleScreencastModeAction extends Action { } else { keyboardMarker.textContent = label; } + while (keyboardMarker.scrollHeight > keyboardMarker.clientHeight) { + keyboardMarker.textContent = keyboardMarker.textContent.slice(1); + } keyboardMarker.style.display = 'block'; From ba1cc46449e48e3eb045fedefed98257ea9df510 Mon Sep 17 00:00:00 2001 From: Phil Marshall Date: Thu, 14 Feb 2019 15:58:02 -0600 Subject: [PATCH 022/861] remove while loop and just use css to scroll start text --- .../workbench/electron-browser/actions/developerActions.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/electron-browser/actions/developerActions.ts b/src/vs/workbench/electron-browser/actions/developerActions.ts index c2056eeb555..d486fab26ca 100644 --- a/src/vs/workbench/electron-browser/actions/developerActions.ts +++ b/src/vs/workbench/electron-browser/actions/developerActions.ts @@ -173,7 +173,10 @@ export class ToggleScreencastModeAction extends Action { keyboardMarker.style.textAlign = 'center'; keyboardMarker.style.fontSize = '56px'; keyboardMarker.style.display = 'none'; + keyboardMarker.style.whiteSpace = 'nowrap'; keyboardMarker.style.overflow = 'hidden'; + keyboardMarker.style.textOverflow = 'ellipsis'; + keyboardMarker.style.direction = 'rtl'; const onKeyDown = domEvent(document.body, 'keydown', true); let keyboardTimeout: IDisposable = Disposable.None; @@ -190,9 +193,6 @@ export class ToggleScreencastModeAction extends Action { } else { keyboardMarker.textContent = label; } - while (keyboardMarker.scrollHeight > keyboardMarker.clientHeight) { - keyboardMarker.textContent = keyboardMarker.textContent.slice(1); - } keyboardMarker.style.display = 'block'; From eba1955b77a0e3bd01d735792a344bf954a4038f Mon Sep 17 00:00:00 2001 From: Matthew Kwiecien Date: Sun, 24 Feb 2019 11:13:22 -0600 Subject: [PATCH 023/861] Pulling screencast styles from settings. --- .../electron-browser/actions/developerActions.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/electron-browser/actions/developerActions.ts b/src/vs/workbench/electron-browser/actions/developerActions.ts index 3e5d7fbddda..eef42f51d81 100644 --- a/src/vs/workbench/electron-browser/actions/developerActions.ts +++ b/src/vs/workbench/electron-browser/actions/developerActions.ts @@ -16,6 +16,7 @@ import { Context } from 'vs/platform/contextkey/browser/contextKeyService'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { timeout } from 'vs/base/common/async'; import { IPartService } from 'vs/workbench/services/part/common/partService'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; export class ToggleDevToolsAction extends Action { @@ -120,7 +121,8 @@ export class ToggleScreencastModeAction extends Action { id: string, label: string, @IKeybindingService private readonly keybindingService: IKeybindingService, - @IPartService private readonly partService: IPartService + @IPartService private readonly partService: IPartService, + @IConfigurationService private readonly configurationService: IConfigurationService ) { super(id, label); } @@ -170,10 +172,10 @@ export class ToggleScreencastModeAction extends Action { const keyboardMarker = append(container, $('div')); keyboardMarker.style.position = 'absolute'; keyboardMarker.style.backgroundColor = 'rgba(0, 0, 0 ,0.5)'; - keyboardMarker.style.width = '100%'; - keyboardMarker.style.height = '100px'; - keyboardMarker.style.bottom = '20%'; - keyboardMarker.style.left = '0'; + keyboardMarker.style.width = `${this.configurationService.getValue('screencastMode.overlay.width')}%`; + keyboardMarker.style.height = `${this.configurationService.getValue('screencastMode.overlay.height')}%`; + keyboardMarker.style.bottom = `${this.configurationService.getValue('screencastMode.location.verticalPosition')}%`; + keyboardMarker.style.left = `${this.configurationService.getValue('screencastMode.location.horizontalPosition')}%`; keyboardMarker.style.zIndex = '100000'; keyboardMarker.style.pointerEvents = 'none'; keyboardMarker.style.color = 'white'; From f54021d12ff8905c72d84d3f3892720715b5005c Mon Sep 17 00:00:00 2001 From: Matthew Kwiecien Date: Sun, 24 Feb 2019 11:14:18 -0600 Subject: [PATCH 024/861] Adding screencast settings to settinsg layout --- .../preferences/browser/settingsLayout.ts | 5 ++++ .../electron-browser/main.contribution.ts | 30 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsLayout.ts b/src/vs/workbench/contrib/preferences/browser/settingsLayout.ts index 8749fd5dbac..58d2df06786 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsLayout.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsLayout.ts @@ -100,6 +100,11 @@ export const tocData: ITOCEntry = { id: 'workbench/zenmode', label: localize('zenMode', "Zen Mode"), settings: ['zenmode.*'] + }, + { + id: 'application/screencastmode', + label: localize('screencastMode', "Screencast Mode"), + settings: ['screencastMode.location.*', 'screencastMode.overlay.*'] } ] }, diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 0d9d443dc16..fc27767c530 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -677,6 +677,36 @@ import { LogStorageAction } from 'vs/platform/storage/node/storageService'; } }); + // Screencast Mode + registry.registerConfiguration({ + 'id': 'screencastMode', + 'order': 9, + 'title': nls.localize('screencastModeConfigurationTitle', "Screencast Mode"), + 'type': 'object', + 'properties': { + 'screencastMode.location.verticalPosition': { + 'type': 'number', + 'default': 20, + 'description': nls.localize('screencastMode.location.verticalPosition', "Controls the vertical position of the screencast mode overlay from the bottom as a percentage of the editor height.") + }, + 'screencastMode.location.horizontalPosition': { + 'type': 'number', + 'default': 0, + 'description': nls.localize('screencastMode.location.horizontalPosition', "Controls the horizontal position of the screencast mode overlay from the left as a percentage of the editor width.") + }, + 'screencastMode.overlay.height': { + 'type': 'number', + 'default': 12, + 'description': nls.localize('screencastMode.overlay.height', "Controls the height of the screencast overlay as a percentage of the editor height..") + }, + 'screencastMode.overlay.width': { + 'type': 'number', + 'default': 100, + 'description': nls.localize('screencastMode.overlay.width', "Controls the width of the screencast overlay as a percentage of the editor width.") + } + } + }); + // Telemetry registry.registerConfiguration({ 'id': 'telemetry', From 1cec8ddb60d7ccb08b55b976fc4c815615cf831f Mon Sep 17 00:00:00 2001 From: matthew Date: Sun, 24 Feb 2019 00:20:53 -0600 Subject: [PATCH 025/861] Add screencast setting to only display control characters --- .../contrib/preferences/browser/settingsLayout.ts | 5 +++++ .../electron-browser/actions/developerActions.ts | 13 +++++++++---- .../electron-browser/main.contribution.ts | 14 ++++++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsLayout.ts b/src/vs/workbench/contrib/preferences/browser/settingsLayout.ts index 8749fd5dbac..3386255a613 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsLayout.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsLayout.ts @@ -100,6 +100,11 @@ export const tocData: ITOCEntry = { id: 'workbench/zenmode', label: localize('zenMode', "Zen Mode"), settings: ['zenmode.*'] + }, + { + id: 'workbench/screencastmode', + label: localize('screencastMode', "Screencast Mode"), + settings: ['screencastMode.*'] } ] }, diff --git a/src/vs/workbench/electron-browser/actions/developerActions.ts b/src/vs/workbench/electron-browser/actions/developerActions.ts index 3e5d7fbddda..6ed0c95f8ab 100644 --- a/src/vs/workbench/electron-browser/actions/developerActions.ts +++ b/src/vs/workbench/electron-browser/actions/developerActions.ts @@ -16,6 +16,8 @@ import { Context } from 'vs/platform/contextkey/browser/contextKeyService'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { timeout } from 'vs/base/common/async'; import { IPartService } from 'vs/workbench/services/part/common/partService'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { ConfigurationService } from 'vs/platform/configuration/node/configurationService'; export class ToggleDevToolsAction extends Action { @@ -120,7 +122,8 @@ export class ToggleScreencastModeAction extends Action { id: string, label: string, @IKeybindingService private readonly keybindingService: IKeybindingService, - @IPartService private readonly partService: IPartService + @IPartService private readonly partService: IPartService, + @IConfigurationService private readonly configurationService: ConfigurationService, ) { super(id, label); } @@ -193,13 +196,15 @@ export class ToggleScreencastModeAction extends Action { const label = keybinding.getLabel(); if (!event.ctrlKey && !event.altKey && !event.metaKey && !event.shiftKey && this.keybindingService.mightProducePrintableCharacter(event) && label) { - keyboardMarker.textContent += ' ' + label; + if (!this.configurationService.getValue('screencastMode.onlyControlKeys')) { + keyboardMarker.textContent += ' ' + label; + keyboardMarker.style.display = 'block'; + } } else { keyboardMarker.textContent = label; + keyboardMarker.style.display = 'block'; } - keyboardMarker.style.display = 'block'; - const promise = timeout(800); keyboardTimeout = toDisposable(() => promise.cancel()); diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 0d9d443dc16..04038399f66 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -692,4 +692,18 @@ import { LogStorageAction } from 'vs/platform/storage/node/storageService'; } } }); + + // Screencast + registry.registerConfiguration({ + 'id': 'screencastMode', + 'title': nls.localize('screencastModeConfigurationTitle', "Screencast Mode"), + 'type': 'object', + 'properties': { + 'screencastMode.onlyControlKeys': { + 'type': 'boolean', + 'description': nls.localize('screencastMode.onlyControlKeys', "Only show control keys in Screencast Mode."), + 'default': false + } + } + }); })(); \ No newline at end of file From 57453375060c740573dfdc349a2aa8e399d5730c Mon Sep 17 00:00:00 2001 From: Neeson Date: Wed, 27 Feb 2019 16:08:14 +0800 Subject: [PATCH 026/861] Fixes #69240 --- extensions/git/src/commands.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 8344525db3d..fdd6fe7998e 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1213,6 +1213,7 @@ export class CommandCenter { if (pick === saveAndCommit) { await Promise.all(unsavedTextDocuments.map(d => d.save())); + await Promise.all(unsavedTextDocuments.map(d => repository.stage(d.uri, d.getText()))); await repository.status(); } else if (pick !== commit) { return false; // do not commit on cancel From 7eede97643a3b892d9fd59b8c3a2109b62e1dd61 Mon Sep 17 00:00:00 2001 From: Carson McManus Date: Wed, 6 Mar 2019 09:51:36 -0500 Subject: [PATCH 027/861] fixes #68849 : Screencast: Some keys do not get special treatment --- .../workbench/electron-browser/actions/developerActions.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/electron-browser/actions/developerActions.ts b/src/vs/workbench/electron-browser/actions/developerActions.ts index 3e5d7fbddda..b5d26de9773 100644 --- a/src/vs/workbench/electron-browser/actions/developerActions.ts +++ b/src/vs/workbench/electron-browser/actions/developerActions.ts @@ -16,6 +16,7 @@ import { Context } from 'vs/platform/contextkey/browser/contextKeyService'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { timeout } from 'vs/base/common/async'; import { IPartService } from 'vs/workbench/services/part/common/partService'; +import { KeyCode } from 'vs/base/common/keyCodes'; export class ToggleDevToolsAction extends Action { @@ -192,7 +193,9 @@ export class ToggleScreencastModeAction extends Action { const keybinding = this.keybindingService.resolveKeyboardEvent(event); const label = keybinding.getLabel(); - if (!event.ctrlKey && !event.altKey && !event.metaKey && !event.shiftKey && this.keybindingService.mightProducePrintableCharacter(event) && label) { + if (!event.ctrlKey && !event.altKey && !event.metaKey && !event.shiftKey && + this.keybindingService.mightProducePrintableCharacter(event) && label && + !(event.keyCode === KeyCode.Backspace || event.keyCode === KeyCode.Escape)) { keyboardMarker.textContent += ' ' + label; } else { keyboardMarker.textContent = label; From 05ed3df9b8066c1ecf792cb6ce621c44f6e3bf66 Mon Sep 17 00:00:00 2001 From: Josh Leeb-du Toit Date: Fri, 15 Mar 2019 16:33:05 +1100 Subject: [PATCH 028/861] Add option to hide git sync button in status bar This PR adds the option `git.statusBarSync.enabled` which when set to `false` will hide the `SyncStatusBar` icon that is, by default, visible in the status bar. --- extensions/git/package.json | 5 +++++ extensions/git/package.nls.json | 1 + extensions/git/src/statusbar.ts | 20 ++++++++++++++++++-- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index b6f31076e76..6a5c93314d0 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1149,6 +1149,11 @@ "default": true, "description": "%config.decorations.enabled%" }, + "git.statusBarSync.enabled": { + "type": "boolean", + "default": true, + "description": "%config.statusBarSync.enabled%" + }, "git.promptToSaveFilesBeforeCommit": { "type": "boolean", "scope": "resource", diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 21ac86d8fbd..53b22c8f721 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -91,6 +91,7 @@ "config.enableCommitSigning": "Enables commit signing with GPG.", "config.discardAllScope": "Controls what changes are discarded by the `Discard all changes` command. `all` discards all changes. `tracked` discards only tracked files. `prompt` shows a prompt dialog every time the action is run.", "config.decorations.enabled": "Controls whether Git contributes colors and badges to the explorer and the open editors view.", + "config.statusBarSync.enabled": "Controls whether Git sync appears in the status bar.", "config.promptToSaveFilesBeforeCommit": "Controls whether Git should check for unsaved files before committing.", "config.postCommitCommand": "Runs a git command after a successful commit.", "config.postCommitCommand.none": "Don't run any command after a commit.", diff --git a/extensions/git/src/statusbar.ts b/extensions/git/src/statusbar.ts index cc007172d5f..e89e1ff9c9b 100644 --- a/extensions/git/src/statusbar.ts +++ b/extensions/git/src/statusbar.ts @@ -5,7 +5,7 @@ import { Disposable, Command, EventEmitter, Event, workspace, Uri } from 'vscode'; import { Repository, Operation } from './repository'; -import { anyEvent, dispose } from './util'; +import { anyEvent, dispose, filterEvent } from './util'; import * as nls from 'vscode-nls'; import { Branch } from './api/git'; @@ -39,6 +39,7 @@ class CheckoutStatusBar { } interface SyncStatusBarState { + isEnabled: boolean; isSyncRunning: boolean; hasRemotes: boolean; HEAD: Branch | undefined; @@ -47,6 +48,7 @@ interface SyncStatusBarState { class SyncStatusBar { private static StartState: SyncStatusBarState = { + isEnabled: true, isSyncRunning: false, hasRemotes: false, HEAD: undefined @@ -66,9 +68,23 @@ class SyncStatusBar { constructor(private repository: Repository) { repository.onDidRunGitStatus(this.onModelChange, this, this.disposables); repository.onDidChangeOperations(this.onOperationsChange, this, this.disposables); + + const onEnablementChange = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.statusBarSync.enabled')); + onEnablementChange(this.updateEnablement, this, this.disposables); + this._onDidChange.fire(); } + private updateEnablement(): void { + const isEnabled = workspace.getConfiguration('git').get('statusBarSync.enabled'); + + if (isEnabled) { + this.state = { ... this.state, isEnabled: true }; + } else { + this.state = { ... this.state, isEnabled: false }; + } + } + private onOperationsChange(): void { const isSyncRunning = this.repository.operations.isRunning(Operation.Sync) || this.repository.operations.isRunning(Operation.Push) || @@ -86,7 +102,7 @@ class SyncStatusBar { } get command(): Command | undefined { - if (!this.state.hasRemotes) { + if (!this.state.isEnabled || !this.state.hasRemotes) { return undefined; } From 4935612fe6f54dd3f37cc2fd7a280296d3a93989 Mon Sep 17 00:00:00 2001 From: ipmsteven Date: Thu, 14 Mar 2019 23:23:11 -0700 Subject: [PATCH 029/861] introduce onlyTrackedFilesCanBeAutoStaged feature flag --- extensions/git/package.json | 6 ++++++ extensions/git/package.nls.json | 1 + 2 files changed, 7 insertions(+) diff --git a/extensions/git/package.json b/extensions/git/package.json index b6f31076e76..33c964bcba8 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1222,6 +1222,12 @@ "default": false, "description": "%config.alwaysShowStagedChangesResourceGroup%" }, + "git.onlyTrackedFilesCanBeAutoStaged": { + "type": "boolean", + "scope": "resource", + "default": false, + "description": "%config.onlyTrackedFilesCanBeAutoStaged%" + }, "git.alwaysSignOff": { "type": "boolean", "scope": "resource", diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 21ac86d8fbd..1c1f2552168 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -104,6 +104,7 @@ "config.detectSubmodules": "Controls whether to automatically detect git submodules.", "config.detectSubmodulesLimit": "Controls the limit of git submodules detected.", "config.alwaysShowStagedChangesResourceGroup": "Always show the Staged Changes resource group.", + "config.onlyTrackedFilesCanBeAutoStaged": "Only tracked files can be auto staged", "config.alwaysSignOff": "Controls the signoff flag for all commits.", "config.ignoredRepositories": "List of git repositories to ignore.", "config.scanRepositories": "List of paths to search for git repositories in.", From 49e0e2607cb396f57d478d4a03ac6581081270ab Mon Sep 17 00:00:00 2001 From: ipmsteven Date: Thu, 14 Mar 2019 23:48:24 -0700 Subject: [PATCH 030/861] add logic to skip staging untracked files when onlyTrackedFilesCanBeAutoStaged is on --- extensions/git/src/repository.ts | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 2fac9e2a39f..e3d8ec3ccab 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -801,10 +801,22 @@ export class Repository implements Disposable { } async commit(message: string, opts: CommitOptions = Object.create(null)): Promise { + const config = workspace.getConfiguration('git'); + const onlyTrackStagedFile = config.get('onlyTrackedFilesCanBeAutoStaged'); + if (this.rebaseCommit) { await this.run(Operation.RebaseContinue, async () => { if (opts.all) { - await this.repository.add([]); + if (onlyTrackStagedFile) { + const unstageFiles = await this.trackedUnstagedFiles(); + if (unstageFiles.length === 0) { + window.showInformationMessage(localize('no changes', "There are no changes to commit.")); + return false; + } + await this.repository.add(unstageFiles); + } else { + await this.repository.add([]); + } } await this.repository.rebaseContinue(); @@ -812,7 +824,16 @@ export class Repository implements Disposable { } else { await this.run(Operation.Commit, async () => { if (opts.all) { - await this.repository.add([]); + if (onlyTrackStagedFile) { + const unstageFiles = await this.trackedUnstagedFiles(); + if (unstageFiles.length === 0) { + window.showInformationMessage(localize('no changes', "There are no changes to commit.")); + return false; + } + await this.repository.add(unstageFiles); + } else { + await this.repository.add([]); + } } await this.repository.commit(message, opts); @@ -1449,6 +1470,12 @@ export class Repository implements Disposable { this.eventuallyUpdateWhenIdleAndWait(); } + private async trackedUnstagedFiles(): Promise { + const rawChangedFiles = await this.repository.run(['ls-files', '.', '-m']); + const parsedFiles = rawChangedFiles.stdout.split('\n').filter(l => !!l); + return parsedFiles; + } + @debounce(1000) private eventuallyUpdateWhenIdleAndWait(): void { this.updateWhenIdleAndWait(); From b3401b21634d3ef85e2f137f37fa950dddb10183 Mon Sep 17 00:00:00 2001 From: Vitaliy Mazurenko Date: Thu, 4 Apr 2019 12:00:13 +0300 Subject: [PATCH 031/861] fix commit template message whitespace removing #71312 --- extensions/git/src/git.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 3132b8cdf86..9de7226a652 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -1704,7 +1704,7 @@ export class Repository { } const raw = await readfile(templatePath, 'utf8'); - return raw.replace(/^\s*#.*$\n?/gm, '').trim(); + return raw.replace(/\n?#.*/g, ''); } catch (err) { return ''; From d5b2a5cdf10a5f0b4f8c7b36058e6bc7a431495b Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 9 Apr 2019 12:10:04 +0200 Subject: [PATCH 032/861] wip --- src/vs/base/common/worker/simpleWorker.ts | 4 +- .../browser/workerExtensions.contribution.ts | 49 +++++++++++++++++++ .../worker/extensionWorker.ts | 20 ++++++++ src/vs/workbench/workbench.main.ts | 2 + 4 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 src/vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution.ts create mode 100644 src/vs/workbench/contrib/workerExtensions/worker/extensionWorker.ts diff --git a/src/vs/base/common/worker/simpleWorker.ts b/src/vs/base/common/worker/simpleWorker.ts index fa19fff26e9..7cccfe184ad 100644 --- a/src/vs/base/common/worker/simpleWorker.ts +++ b/src/vs/base/common/worker/simpleWorker.ts @@ -12,12 +12,12 @@ const INITIALIZE = '$initialize'; export interface IWorker { getId(): number; - postMessage(message: string): void; + postMessage(message: any, transfer?: Transferable[]): void; dispose(): void; } export interface IWorkerCallback { - (message: string): void; + (message: any): void; } export interface IWorkerFactory { diff --git a/src/vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution.ts b/src/vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution.ts new file mode 100644 index 00000000000..646daa6375c --- /dev/null +++ b/src/vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution.ts @@ -0,0 +1,49 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IWorkbenchContribution, Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; +import { DefaultWorkerFactory } from 'vs/base/worker/defaultWorkerFactory'; +import { IWorker } from 'vs/base/common/worker/simpleWorker'; +import { Event, Emitter } from 'vs/base/common/event'; +import { Disposable } from 'vs/base/common/lifecycle'; + +interface IWorker2 extends IWorker { + onMessage: Event; +} + +class WorkerExtensionHost extends Disposable implements IWorkbenchContribution { + + readonly worker: IWorker2; + + constructor() { + super(); + + const emitter = new Emitter(); + const worker = new DefaultWorkerFactory('WorkerExtensionHost').create( + 'vs/workbench/contrib/workerExtensions/worker/extensionWorker', + msg => emitter.fire(msg), + err => console.error(err) + ); + + this.worker = { + dispose() { worker.dispose(); }, + getId() { return worker.getId(); }, + postMessage(msg, transfer?) { worker.postMessage(msg, transfer); }, + onMessage: emitter.event + }; + + this._register(worker); + this._register(emitter); + } + +} + +Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution( + WorkerExtensionHost, + LifecyclePhase.Ready +); + diff --git a/src/vs/workbench/contrib/workerExtensions/worker/extensionWorker.ts b/src/vs/workbench/contrib/workerExtensions/worker/extensionWorker.ts new file mode 100644 index 00000000000..1f4d6a5e17f --- /dev/null +++ b/src/vs/workbench/contrib/workerExtensions/worker/extensionWorker.ts @@ -0,0 +1,20 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IRequestHandler } from 'vs/base/common/worker/simpleWorker'; + + +class ExtensionWorker implements IRequestHandler { + + readonly _requestHandlerBrand: any; + + constructor() { + console.log('HERE'); + } +} + +export function create(): IRequestHandler { + return new ExtensionWorker(); +} diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index 09627b78382..f9fe0b0bf4e 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -322,4 +322,6 @@ import 'vs/workbench/contrib/codeinset/electron-browser/codeInset.contribution'; // Issues import 'vs/workbench/contrib/issue/electron-browser/issue.contribution'; +import 'vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution'; + //#endregion From 8118a2b2929ccb39a010988413f6aaa440b5b986 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 9 Apr 2019 15:12:32 +0200 Subject: [PATCH 033/861] implement IMEssagePassingProtocol for web workers --- src/vs/base/common/worker/simpleWorker.ts | 4 +- src/vs/base/worker/workerMain.ts | 4 +- .../browser/workerExtensions.contribution.ts | 39 +++++++++------- .../worker/extensionHostWorker.ts | 46 +++++++++++++++++++ .../worker/extensionWorker.ts | 20 -------- 5 files changed, 73 insertions(+), 40 deletions(-) create mode 100644 src/vs/workbench/contrib/workerExtensions/worker/extensionHostWorker.ts delete mode 100644 src/vs/workbench/contrib/workerExtensions/worker/extensionWorker.ts diff --git a/src/vs/base/common/worker/simpleWorker.ts b/src/vs/base/common/worker/simpleWorker.ts index 7cccfe184ad..f0008eb4f9f 100644 --- a/src/vs/base/common/worker/simpleWorker.ts +++ b/src/vs/base/common/worker/simpleWorker.ts @@ -204,8 +204,8 @@ export class SimpleWorkerClient extends Disposable { )); this._protocol = new SimpleWorkerProtocol({ - sendMessage: (msg: string): void => { - this._worker.postMessage(msg); + sendMessage: (msg: any, transfer?: Transferable[]): void => { + this._worker.postMessage(msg, transfer); }, handleMessage: (method: string, args: any[]): Promise => { // Intentionally not supporting worker -> main requests diff --git a/src/vs/base/worker/workerMain.ts b/src/vs/base/worker/workerMain.ts index 0ec8b7834dc..8d51252951a 100644 --- a/src/vs/base/worker/workerMain.ts +++ b/src/vs/base/worker/workerMain.ts @@ -20,8 +20,8 @@ let loadCode = function (moduleId: string) { require([moduleId], function (ws) { setTimeout(function () { - let messageHandler = ws.create((msg: any) => { - (self).postMessage(msg); + let messageHandler = ws.create((msg: any, transfer?: Transferable[]) => { + (self).postMessage(msg, transfer); }, null); self.onmessage = (e) => messageHandler.onmessage(e.data); diff --git a/src/vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution.ts b/src/vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution.ts index 646daa6375c..3b7185edeff 100644 --- a/src/vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution.ts +++ b/src/vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution.ts @@ -7,39 +7,46 @@ import { IWorkbenchContribution, Extensions as WorkbenchExtensions, IWorkbenchCo import { Registry } from 'vs/platform/registry/common/platform'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { DefaultWorkerFactory } from 'vs/base/worker/defaultWorkerFactory'; -import { IWorker } from 'vs/base/common/worker/simpleWorker'; -import { Event, Emitter } from 'vs/base/common/event'; +import { Emitter } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; - -interface IWorker2 extends IWorker { - onMessage: Event; -} +import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; +import { VSBuffer } from 'vs/base/common/buffer'; class WorkerExtensionHost extends Disposable implements IWorkbenchContribution { - readonly worker: IWorker2; + readonly protocol: IMessagePassingProtocol; constructor() { super(); - const emitter = new Emitter(); + const emitter = new Emitter(); const worker = new DefaultWorkerFactory('WorkerExtensionHost').create( - 'vs/workbench/contrib/workerExtensions/worker/extensionWorker', - msg => emitter.fire(msg), + 'vs/workbench/contrib/workerExtensions/worker/extensionHostWorker', + data => { + if (data instanceof ArrayBuffer) { + emitter.fire(VSBuffer.wrap(new Uint8Array(data, 0, data.byteLength))); + } else { + console.warn('UNKNOWN data received', data); + } + }, err => console.error(err) ); - this.worker = { - dispose() { worker.dispose(); }, - getId() { return worker.getId(); }, - postMessage(msg, transfer?) { worker.postMessage(msg, transfer); }, - onMessage: emitter.event + this.protocol = { + onMessage: emitter.event, + send: vsbuf => { + const data = vsbuf.buffer.buffer.slice(vsbuf.buffer.byteOffset, vsbuf.buffer.byteOffset + vsbuf.buffer.byteLength); + worker.postMessage(data, [data]); + } }; + // this._register(worker); this._register(emitter); - } + // this.protocol.send(VSBuffer.fromString('HELLO from Main')); + // this.protocol.onMessage(buff => console.log(buff.toString())); + } } Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution( diff --git a/src/vs/workbench/contrib/workerExtensions/worker/extensionHostWorker.ts b/src/vs/workbench/contrib/workerExtensions/worker/extensionHostWorker.ts new file mode 100644 index 00000000000..569eaf8ae2c --- /dev/null +++ b/src/vs/workbench/contrib/workerExtensions/worker/extensionHostWorker.ts @@ -0,0 +1,46 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IRequestHandler } from 'vs/base/common/worker/simpleWorker'; +import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; +import { VSBuffer } from 'vs/base/common/buffer'; +import { Emitter } from 'vs/base/common/event'; + +class ExtensionWorker implements IRequestHandler { + + // worker-contract + readonly _requestHandlerBrand: any; + readonly onmessage: (data: any) => any; + + // protocol + readonly protocol: IMessagePassingProtocol; + + constructor(postMessage: (message: any, transfer?: Transferable[]) => any) { + + const emitter = new Emitter(); + this.onmessage = data => { + if (data instanceof ArrayBuffer) { + emitter.fire(VSBuffer.wrap(new Uint8Array(data, 0, data.byteLength))); + } else { + console.warn('UNKNOWN data received', data); + } + }; + + this.protocol = { + onMessage: emitter.event, + send: vsbuf => { + const data = vsbuf.buffer.buffer.slice(vsbuf.buffer.byteOffset, vsbuf.buffer.byteOffset + vsbuf.buffer.byteLength); + postMessage(data, [data]); + } + }; + } +} + +export function create(postMessage: (message: any, transfer?: Transferable[]) => any): IRequestHandler { + const res = new ExtensionWorker(postMessage); + // res.protocol.onMessage(buff => console.log(buff.toString())); + // res.protocol.send(VSBuffer.fromString('HELLO from WORKER')); + return res; +} diff --git a/src/vs/workbench/contrib/workerExtensions/worker/extensionWorker.ts b/src/vs/workbench/contrib/workerExtensions/worker/extensionWorker.ts deleted file mode 100644 index 1f4d6a5e17f..00000000000 --- a/src/vs/workbench/contrib/workerExtensions/worker/extensionWorker.ts +++ /dev/null @@ -1,20 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IRequestHandler } from 'vs/base/common/worker/simpleWorker'; - - -class ExtensionWorker implements IRequestHandler { - - readonly _requestHandlerBrand: any; - - constructor() { - console.log('HERE'); - } -} - -export function create(): IRequestHandler { - return new ExtensionWorker(); -} From 9487e5f247473bcf74de4c430cc6de0f871e4111 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 9 Apr 2019 15:54:06 +0200 Subject: [PATCH 034/861] implement extension host starter interface --- .../browser/workerExtensions.contribution.ts | 77 ++++++++++++------- .../worker/extensionHostWorker.ts | 4 +- .../extensions/common/extensionHostStarter.ts | 14 ++++ .../electron-browser/extensionHost.ts | 8 +- .../extensionHostProcessManager.ts | 2 +- 5 files changed, 69 insertions(+), 36 deletions(-) create mode 100644 src/vs/workbench/services/extensions/common/extensionHostStarter.ts diff --git a/src/vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution.ts b/src/vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution.ts index 3b7185edeff..f9fae164be6 100644 --- a/src/vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution.ts +++ b/src/vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution.ts @@ -7,45 +7,70 @@ import { IWorkbenchContribution, Extensions as WorkbenchExtensions, IWorkbenchCo import { Registry } from 'vs/platform/registry/common/platform'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { DefaultWorkerFactory } from 'vs/base/worker/defaultWorkerFactory'; -import { Emitter } from 'vs/base/common/event'; +import { Emitter, Event } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; import { VSBuffer } from 'vs/base/common/buffer'; +import { IExtensionHostStarter } from 'vs/workbench/services/extensions/common/extensionHostStarter'; -class WorkerExtensionHost extends Disposable implements IWorkbenchContribution { +export class ExtensionHostWebWorker extends Disposable implements IExtensionHostStarter { - readonly protocol: IMessagePassingProtocol; + private _protocol?: IMessagePassingProtocol; + private readonly _onDidCrashed = new Emitter<[number, string | null]>(); - constructor() { - super(); + readonly onCrashed: Event<[number, string | null]> = this._onDidCrashed.event; - const emitter = new Emitter(); - const worker = new DefaultWorkerFactory('WorkerExtensionHost').create( - 'vs/workbench/contrib/workerExtensions/worker/extensionHostWorker', - data => { - if (data instanceof ArrayBuffer) { - emitter.fire(VSBuffer.wrap(new Uint8Array(data, 0, data.byteLength))); - } else { - console.warn('UNKNOWN data received', data); + start(): Promise { + + if (!this._protocol) { + + const emitter = new Emitter(); + const worker = new DefaultWorkerFactory('WorkerExtensionHost').create( + 'vs/workbench/contrib/workerExtensions/worker/extensionHostWorker', data => { + if (data instanceof ArrayBuffer) { + emitter.fire(VSBuffer.wrap(new Uint8Array(data, 0, data.byteLength))); + } else { + console.warn('UNKNOWN data received', data); + } + }, err => { + this._onDidCrashed.fire([81, err]); + console.error(err); } - }, - err => console.error(err) - ); + ); - this.protocol = { - onMessage: emitter.event, - send: vsbuf => { - const data = vsbuf.buffer.buffer.slice(vsbuf.buffer.byteOffset, vsbuf.buffer.byteOffset + vsbuf.buffer.byteLength); - worker.postMessage(data, [data]); - } - }; + this._protocol = { + onMessage: emitter.event, + send: vsbuf => { + const data = vsbuf.buffer.buffer.slice(vsbuf.buffer.byteOffset, vsbuf.buffer.byteOffset + vsbuf.buffer.byteLength); + worker.postMessage(data, [data]); + } + }; - // - this._register(worker); - this._register(emitter); + // + this._register(worker); + this._register(emitter); + } // this.protocol.send(VSBuffer.fromString('HELLO from Main')); // this.protocol.onMessage(buff => console.log(buff.toString())); + return Promise.resolve(this._protocol); + } + + getInspectPort(): number | undefined { + return undefined; + } +} + + + +class WorkerExtensionHost extends Disposable implements IWorkbenchContribution { + + constructor() { + super(); + new ExtensionHostWebWorker().start().then(protocol => { + protocol.send(VSBuffer.fromString('HELLO from Main')); + protocol.onMessage(buff => console.log(buff.toString())); + }); } } diff --git a/src/vs/workbench/contrib/workerExtensions/worker/extensionHostWorker.ts b/src/vs/workbench/contrib/workerExtensions/worker/extensionHostWorker.ts index 569eaf8ae2c..1655e57c926 100644 --- a/src/vs/workbench/contrib/workerExtensions/worker/extensionHostWorker.ts +++ b/src/vs/workbench/contrib/workerExtensions/worker/extensionHostWorker.ts @@ -40,7 +40,7 @@ class ExtensionWorker implements IRequestHandler { export function create(postMessage: (message: any, transfer?: Transferable[]) => any): IRequestHandler { const res = new ExtensionWorker(postMessage); - // res.protocol.onMessage(buff => console.log(buff.toString())); - // res.protocol.send(VSBuffer.fromString('HELLO from WORKER')); + res.protocol.onMessage(buff => console.log(buff.toString())); + res.protocol.send(VSBuffer.fromString('HELLO from WORKER')); return res; } diff --git a/src/vs/workbench/services/extensions/common/extensionHostStarter.ts b/src/vs/workbench/services/extensions/common/extensionHostStarter.ts new file mode 100644 index 00000000000..32551aaba2d --- /dev/null +++ b/src/vs/workbench/services/extensions/common/extensionHostStarter.ts @@ -0,0 +1,14 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Event } from 'vs/base/common/event'; +import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; + +export interface IExtensionHostStarter { + readonly onCrashed: Event<[number, string | null]>; + start(): Promise | null; + getInspectPort(): number | undefined; + dispose(): void; +} diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index 3757b8515d4..a1429e88ed5 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -38,13 +38,7 @@ import { IExtensionDescription } from 'vs/platform/extensions/common/extensions' import { parseExtensionDevOptions } from '../common/extensionDevOptions'; import { VSBuffer } from 'vs/base/common/buffer'; import { IExtensionHostDebugService } from 'vs/workbench/services/extensions/common/extensionHostDebug'; - -export interface IExtensionHostStarter { - readonly onCrashed: Event<[number, string | null]>; - start(): Promise | null; - getInspectPort(): number | undefined; - dispose(): void; -} +import { IExtensionHostStarter } from 'vs/workbench/services/extensions/common/extensionHostStarter'; export class ExtensionHostProcessWorker implements IExtensionHostStarter { diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHostProcessManager.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHostProcessManager.ts index 6d1976eb9b2..c66747f77c0 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHostProcessManager.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHostProcessManager.ts @@ -13,7 +13,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { ExtHostCustomersRegistry } from 'vs/workbench/api/common/extHostCustomers'; import { ExtHostContext, ExtHostExtensionServiceShape, IExtHostContext, MainContext } from 'vs/workbench/api/common/extHost.protocol'; import { ProfileSession } from 'vs/workbench/services/extensions/common/extensions'; -import { IExtensionHostStarter } from 'vs/workbench/services/extensions/electron-browser/extensionHost'; +import { IExtensionHostStarter } from 'vs/workbench/services/extensions/common/extensionHostStarter'; import { ExtensionHostProfiler } from 'vs/workbench/services/extensions/electron-browser/extensionHostProfiler'; import { ProxyIdentifier } from 'vs/workbench/services/extensions/common/proxyIdentifier'; import { IRPCProtocolLogger, RPCProtocol, RequestInitiator, ResponsiveState } from 'vs/workbench/services/extensions/node/rpcProtocol'; From a623755f4a121e9075502bfc2f449e929d0f8b98 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 9 Apr 2019 20:11:19 +0200 Subject: [PATCH 035/861] wip --- .../electron-browser/workbench/workbench.html | 18 +++++++------- .../worker/extensionHostWorker.ts | 12 ++++++++++ .../worker/extensionLoader.ts | 24 +++++++++++++++++++ 3 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 src/vs/workbench/contrib/workerExtensions/worker/extensionLoader.ts diff --git a/src/vs/code/electron-browser/workbench/workbench.html b/src/vs/code/electron-browser/workbench/workbench.html index 13232577758..56f63b41d48 100644 --- a/src/vs/code/electron-browser/workbench/workbench.html +++ b/src/vs/code/electron-browser/workbench/workbench.html @@ -1,13 +1,13 @@ - - - - - - + + + + + + - - - \ No newline at end of file + + + diff --git a/src/vs/workbench/contrib/workerExtensions/worker/extensionHostWorker.ts b/src/vs/workbench/contrib/workerExtensions/worker/extensionHostWorker.ts index 1655e57c926..e7883f3cdf2 100644 --- a/src/vs/workbench/contrib/workerExtensions/worker/extensionHostWorker.ts +++ b/src/vs/workbench/contrib/workerExtensions/worker/extensionHostWorker.ts @@ -7,6 +7,7 @@ import { IRequestHandler } from 'vs/base/common/worker/simpleWorker'; import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; import { VSBuffer } from 'vs/base/common/buffer'; import { Emitter } from 'vs/base/common/event'; +import { importWrappedScript } from 'vs/workbench/contrib/workerExtensions/worker/extensionLoader'; class ExtensionWorker implements IRequestHandler { @@ -42,5 +43,16 @@ export function create(postMessage: (message: any, transfer?: Transferable[]) => const res = new ExtensionWorker(postMessage); res.protocol.onMessage(buff => console.log(buff.toString())); res.protocol.send(VSBuffer.fromString('HELLO from WORKER')); + + const source = `Object.defineProperty(exports, "__esModule", { value: true }); +const model = require('./model'); +const vscode = require('vscode'); +function activate() { +\tconsole.log('HELLO'); +} +exports.activate = activate;`; + + importWrappedScript(source, 'somepath'); + return res; } diff --git a/src/vs/workbench/contrib/workerExtensions/worker/extensionLoader.ts b/src/vs/workbench/contrib/workerExtensions/worker/extensionLoader.ts new file mode 100644 index 00000000000..088fa872920 --- /dev/null +++ b/src/vs/workbench/contrib/workerExtensions/worker/extensionLoader.ts @@ -0,0 +1,24 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + + +self['extensions'] = {}; +function wrap(name: string, script: string) { + //https://github.com/nodejs/node/blob/master/lib/internal/modules/cjs/loader.js#L125 + return `self['extensions']['${name}']= (function (exports, require) { ${script}\n});`; +} + +export function importWrappedScript(scriptSrc: string, scriptPath: string) { + + importScripts(`data:text/javascript;charset=utf-8,${encodeURIComponent(wrap(scriptPath, scriptSrc))}`); + + // const fn = new Function('exports', 'require', 'module', scriptSrc); + // const exports = Object.create(null); + // const thisRequire = function (path: string) { + // console.log(path); + // }; + // fn(exports, thisRequire, undefined); + // console.log(exports); +} From 92a43a7d0383879955211ebd1b8603731a479793 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 10 Apr 2019 10:01:13 +0200 Subject: [PATCH 036/861] update sample --- .../workerExtensions/browser/workerExtensions.contribution.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution.ts b/src/vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution.ts index f9fae164be6..b3dbeb9827a 100644 --- a/src/vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution.ts +++ b/src/vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution.ts @@ -51,8 +51,8 @@ export class ExtensionHostWebWorker extends Disposable implements IExtensionHost this._register(emitter); } - // this.protocol.send(VSBuffer.fromString('HELLO from Main')); - // this.protocol.onMessage(buff => console.log(buff.toString())); + // this._protocol.send(VSBuffer.fromString('HELLO from Main')); + // this._protocol.onMessage(buff => console.log(buff.toString())); return Promise.resolve(this._protocol); } From 24ef8bd5e9966b7722ecf0fd745c3288784e7d00 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 10 Apr 2019 18:35:57 +0200 Subject: [PATCH 037/861] send init data, wire up starter --- .../browser/workerExtensions.contribution.ts | 81 --------- .../worker/extensionHostWorker.ts | 74 ++++++-- .../electron-browser/extensionService.ts | 21 ++- .../webWorkerExtensionHostStarter.ts | 164 ++++++++++++++++++ src/vs/workbench/workbench.main.ts | 2 - tslint.json | 2 +- 6 files changed, 237 insertions(+), 107 deletions(-) delete mode 100644 src/vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution.ts create mode 100644 src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts diff --git a/src/vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution.ts b/src/vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution.ts deleted file mode 100644 index b3dbeb9827a..00000000000 --- a/src/vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution.ts +++ /dev/null @@ -1,81 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IWorkbenchContribution, Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; -import { Registry } from 'vs/platform/registry/common/platform'; -import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; -import { DefaultWorkerFactory } from 'vs/base/worker/defaultWorkerFactory'; -import { Emitter, Event } from 'vs/base/common/event'; -import { Disposable } from 'vs/base/common/lifecycle'; -import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; -import { VSBuffer } from 'vs/base/common/buffer'; -import { IExtensionHostStarter } from 'vs/workbench/services/extensions/common/extensionHostStarter'; - -export class ExtensionHostWebWorker extends Disposable implements IExtensionHostStarter { - - private _protocol?: IMessagePassingProtocol; - private readonly _onDidCrashed = new Emitter<[number, string | null]>(); - - readonly onCrashed: Event<[number, string | null]> = this._onDidCrashed.event; - - start(): Promise { - - if (!this._protocol) { - - const emitter = new Emitter(); - const worker = new DefaultWorkerFactory('WorkerExtensionHost').create( - 'vs/workbench/contrib/workerExtensions/worker/extensionHostWorker', data => { - if (data instanceof ArrayBuffer) { - emitter.fire(VSBuffer.wrap(new Uint8Array(data, 0, data.byteLength))); - } else { - console.warn('UNKNOWN data received', data); - } - }, err => { - this._onDidCrashed.fire([81, err]); - console.error(err); - } - ); - - this._protocol = { - onMessage: emitter.event, - send: vsbuf => { - const data = vsbuf.buffer.buffer.slice(vsbuf.buffer.byteOffset, vsbuf.buffer.byteOffset + vsbuf.buffer.byteLength); - worker.postMessage(data, [data]); - } - }; - - // - this._register(worker); - this._register(emitter); - } - - // this._protocol.send(VSBuffer.fromString('HELLO from Main')); - // this._protocol.onMessage(buff => console.log(buff.toString())); - return Promise.resolve(this._protocol); - } - - getInspectPort(): number | undefined { - return undefined; - } -} - - - -class WorkerExtensionHost extends Disposable implements IWorkbenchContribution { - - constructor() { - super(); - new ExtensionHostWebWorker().start().then(protocol => { - protocol.send(VSBuffer.fromString('HELLO from Main')); - protocol.onMessage(buff => console.log(buff.toString())); - }); - } -} - -Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution( - WorkerExtensionHost, - LifecyclePhase.Ready -); - diff --git a/src/vs/workbench/contrib/workerExtensions/worker/extensionHostWorker.ts b/src/vs/workbench/contrib/workerExtensions/worker/extensionHostWorker.ts index e7883f3cdf2..0e6081d7b21 100644 --- a/src/vs/workbench/contrib/workerExtensions/worker/extensionHostWorker.ts +++ b/src/vs/workbench/contrib/workerExtensions/worker/extensionHostWorker.ts @@ -7,7 +7,21 @@ import { IRequestHandler } from 'vs/base/common/worker/simpleWorker'; import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; import { VSBuffer } from 'vs/base/common/buffer'; import { Emitter } from 'vs/base/common/event'; -import { importWrappedScript } from 'vs/workbench/contrib/workerExtensions/worker/extensionLoader'; +import { IExitFn } from 'vs/workbench/services/extensions/node/extensionHostMain'; +import { isMessageOfType, MessageType, createMessageOfType } from 'vs/workbench/services/extensions/common/extensionHostProtocol'; +import { IInitData } from 'vs/workbench/api/common/extHost.protocol'; + +// worker-self +declare namespace self { + function close(): void; +} + +// do not allow extensions to call terminate +const nativeTerminate: IExitFn = self.close.bind(self); +self.close = () => console.trace('An extension called terminate and this was prevented'); +let onTerminate = nativeTerminate; + +//todo@joh do not allow extensions to call postMessage and other globals... class ExtensionWorker implements IRequestHandler { @@ -20,39 +34,65 @@ class ExtensionWorker implements IRequestHandler { constructor(postMessage: (message: any, transfer?: Transferable[]) => any) { - const emitter = new Emitter(); + let emitter = new Emitter(); + let terminating = false; + this.onmessage = data => { - if (data instanceof ArrayBuffer) { - emitter.fire(VSBuffer.wrap(new Uint8Array(data, 0, data.byteLength))); - } else { + if (!(data instanceof ArrayBuffer)) { console.warn('UNKNOWN data received', data); + return; } + + const msg = VSBuffer.wrap(new Uint8Array(data, 0, data.byteLength)); + if (isMessageOfType(msg, MessageType.Terminate)) { + // handle terminate-message right here + terminating = true; + onTerminate(); + return; + } + + // emit non-terminate messages to the outside + emitter.fire(msg); }; this.protocol = { onMessage: emitter.event, send: vsbuf => { - const data = vsbuf.buffer.buffer.slice(vsbuf.buffer.byteOffset, vsbuf.buffer.byteOffset + vsbuf.buffer.byteLength); - postMessage(data, [data]); + if (!terminating) { + const data = vsbuf.buffer.buffer.slice(vsbuf.buffer.byteOffset, vsbuf.buffer.byteOffset + vsbuf.buffer.byteLength); + postMessage(data, [data]); + } } }; } } +interface IRendererConnection { + protocol: IMessagePassingProtocol; + initData: IInitData; +} +function connectToRenderer(protocol: IMessagePassingProtocol): Promise { + return new Promise(resolve => { + const once = protocol.onMessage(raw => { + once.dispose(); + const initData = JSON.parse(raw.toString()); + protocol.send(createMessageOfType(MessageType.Initialized)); + resolve({ protocol, initData }); + }); + protocol.send(createMessageOfType(MessageType.Ready)); + }); +} + export function create(postMessage: (message: any, transfer?: Transferable[]) => any): IRequestHandler { const res = new ExtensionWorker(postMessage); - res.protocol.onMessage(buff => console.log(buff.toString())); - res.protocol.send(VSBuffer.fromString('HELLO from WORKER')); - const source = `Object.defineProperty(exports, "__esModule", { value: true }); -const model = require('./model'); -const vscode = require('vscode'); -function activate() { -\tconsole.log('HELLO'); -} -exports.activate = activate;`; + connectToRenderer(res.protocol).then(data => { + console.log('INIT_DATA', data.initData); - importWrappedScript(source, 'somepath'); + data.protocol.onMessage(msg => { + // console.log('SOME MSG', msg.toString()); + }); + }); return res; } diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index 8483f12b35c..5cfe7f0024d 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -35,6 +35,7 @@ import { Schemas } from 'vs/base/common/network'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IFileService } from 'vs/platform/files/common/files'; import { parseExtensionDevOptions } from 'vs/workbench/services/extensions/common/extensionDevOptions'; +import { WebWorkerExtensionHostStarter } from './webWorkerExtensionHostStarter'; const hasOwnProperty = Object.hasOwnProperty; const NO_OP_VOID_PROMISE = Promise.resolve(undefined); @@ -438,12 +439,20 @@ export class ExtensionService extends Disposable implements IExtensionService { autoStart = true; extensions = this.getExtensions(); } - - const extHostProcessWorker = this._instantiationService.createInstance(ExtensionHostProcessWorker, autoStart, extensions, this._extensionHostLogsLocation); - const extHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, extHostProcessWorker, null, initialActivationEvents); - extHostProcessManager.onDidCrash(([code, signal]) => this._onExtensionHostCrashed(code, signal)); - extHostProcessManager.onDidChangeResponsiveState((responsiveState) => { this._onDidChangeResponsiveChange.fire({ target: extHostProcessManager, isResponsive: responsiveState === ResponsiveState.Responsive }); }); - this._extensionHostProcessManagers.push(extHostProcessManager); + { + const extHostProcessWorker = this._instantiationService.createInstance(ExtensionHostProcessWorker, autoStart, extensions, this._extensionHostLogsLocation); + const extHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, extHostProcessWorker, null, initialActivationEvents); + extHostProcessManager.onDidCrash(([code, signal]) => this._onExtensionHostCrashed(code, signal)); + extHostProcessManager.onDidChangeResponsiveState((responsiveState) => { this._onDidChangeResponsiveChange.fire({ target: extHostProcessManager, isResponsive: responsiveState === ResponsiveState.Responsive }); }); + this._extensionHostProcessManagers.push(extHostProcessManager); + } + { + const extHostWebWorkerWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, autoStart, extensions, this._extensionHostLogsLocation); + const extHostWebWorkerManager = this._instantiationService.createInstance(ExtensionHostProcessManager, extHostWebWorkerWorker, null, initialActivationEvents); + extHostWebWorkerManager.onDidCrash(([code, signal]) => this._onExtensionHostCrashed(code, signal)); + extHostWebWorkerManager.onDidChangeResponsiveState((responsiveState) => { this._onDidChangeResponsiveChange.fire({ target: extHostWebWorkerManager, isResponsive: responsiveState === ResponsiveState.Responsive }); }); + this._extensionHostProcessManagers.push(extHostWebWorkerManager); + } } private _onExtensionHostCrashed(code: number, signal: string | null): void { diff --git a/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts b/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts new file mode 100644 index 00000000000..fc843bab3b8 --- /dev/null +++ b/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts @@ -0,0 +1,164 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IWorkbenchContribution, Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; +import { DefaultWorkerFactory } from 'vs/base/worker/defaultWorkerFactory'; +import { Emitter, Event } from 'vs/base/common/event'; +import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; +import { VSBuffer } from 'vs/base/common/buffer'; +import { IExtensionHostStarter } from 'vs/workbench/services/extensions/common/extensionHostStarter'; +import { createMessageOfType, MessageType, isMessageOfType } from 'vs/workbench/services/extensions/common/extensionHostProtocol'; +import { IInitData } from 'vs/workbench/api/common/extHost.protocol'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; +import { ILabelService } from 'vs/platform/label/common/label'; +import { ILogService } from 'vs/platform/log/common/log'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import * as platform from 'vs/base/common/platform'; +import { URI } from 'vs/base/common/uri'; +import product from 'vs/platform/product/node/product'; +import pkg from 'vs/platform/product/node/package'; + +export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { + + private _protocol?: IMessagePassingProtocol; + private _isTerminating?: boolean; + private _toDispose: IDisposable[] = []; + + private readonly _onDidCrashed = new Emitter<[number, string | null]>(); + readonly onCrashed: Event<[number, string | null]> = this._onDidCrashed.event; + + constructor( + private readonly _autoStart: boolean, + private readonly _extensions: Promise, + private readonly _extensionHostLogsLocation: URI, + @ITelemetryService private readonly _telemetryService: ITelemetryService, + @IWorkspaceContextService private readonly _contextService: IWorkspaceContextService, + @ILabelService private readonly _labelService: ILabelService, + @ILogService private readonly _logService: ILogService, + @IEnvironmentService private readonly _environmentService: IEnvironmentService, + ) { + + } + + async start(): Promise { + + if (!this._protocol) { + + const emitter = new Emitter(); + const worker = new DefaultWorkerFactory('WorkerExtensionHost').create( + 'vs/workbench/contrib/workerExtensions/worker/extensionHostWorker', data => { + if (data instanceof ArrayBuffer) { + emitter.fire(VSBuffer.wrap(new Uint8Array(data, 0, data.byteLength))); + } else { + console.warn('UNKNOWN data received', data); + } + }, err => { + this._onDidCrashed.fire([81, err]); + console.error(err); + } + ); + + // keep for cleanup + this._toDispose.push(worker, emitter); + + const protocol: IMessagePassingProtocol = { + onMessage: emitter.event, + send: vsbuf => { + const data = vsbuf.buffer.buffer.slice(vsbuf.buffer.byteOffset, vsbuf.buffer.byteOffset + vsbuf.buffer.byteLength); + worker.postMessage(data, [data]); + } + }; + + // extension host handshake happens below + // (1) <== wait for: Ready + // (2) ==> send: init data + // (3) <== wait for: Initialized + + await Event.toPromise(Event.filter(protocol.onMessage, msg => isMessageOfType(msg, MessageType.Ready))); + protocol.send(VSBuffer.fromString(JSON.stringify(await this._createExtHostInitData()))); + await Event.toPromise(Event.filter(protocol.onMessage, msg => isMessageOfType(msg, MessageType.Initialized))); + + this._protocol = protocol; + } + return this._protocol; + + } + + dispose(): void { + if (!this._protocol) { + // nothing else to do + dispose(this._toDispose); + return; + } + if (!this._isTerminating) { + this._isTerminating = true; + + this._protocol.send(createMessageOfType(MessageType.Terminate)); + setTimeout(() => dispose(this._toDispose), 10 * 1000); + } + } + + getInspectPort(): number | undefined { + return undefined; + } + + private _createExtHostInitData(): Promise { + return Promise.all([this._telemetryService.getTelemetryInfo(), this._extensions]) + .then(([telemetryInfo, extensionDescriptions]) => { + const workspace = this._contextService.getWorkspace(); + const r: IInitData = { + commit: product.commit, + version: pkg.version, + parentPid: process.pid, + environment: { + isExtensionDevelopmentDebug: false, // < todo@joh + appRoot: this._environmentService.appRoot ? URI.file(this._environmentService.appRoot) : undefined, + appSettingsHome: this._environmentService.appSettingsHome ? URI.file(this._environmentService.appSettingsHome) : undefined, + appName: product.nameLong, + appUriScheme: product.urlProtocol, + appLanguage: platform.language, + extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI, + extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI, + globalStorageHome: URI.file(this._environmentService.globalStorageHome), + userHome: URI.file(this._environmentService.userHome) + }, + workspace: this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? undefined : { + configuration: workspace.configuration || undefined, + id: workspace.id, + name: this._labelService.getWorkspaceLabel(workspace) + }, + resolvedExtensions: [], + hostExtensions: [], + extensions: extensionDescriptions, + telemetryInfo, + logLevel: this._logService.getLevel(), + logsLocation: this._extensionHostLogsLocation, + autoStart: this._autoStart + }; + return r; + }); + } +} + +class WorkerExtensionHost extends Disposable implements IWorkbenchContribution { + + constructor() { + super(); + // new ExtensionHostWebWorker().start().then(protocol => { + + // }); + } +} + +Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution( + WorkerExtensionHost, + LifecyclePhase.Ready +); + diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index 6a4257f81d7..1232c5b68bf 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -329,6 +329,4 @@ import 'vs/workbench/contrib/codeinset/electron-browser/codeInset.contribution'; // Issues import 'vs/workbench/contrib/issue/electron-browser/issue.contribution'; -import 'vs/workbench/contrib/workerExtensions/browser/workerExtensions.contribution'; - //#endregion diff --git a/tslint.json b/tslint.json index f45bfed2444..b18e616921c 100644 --- a/tslint.json +++ b/tslint.json @@ -461,7 +461,7 @@ "restrictions": [ "vs/nls", "vs/css!./**/*", - "**/vs/base/**/{common,browser,node,electron-browser}/**", + "**/vs/base/**/{common,browser,worker,node,electron-browser}/**", "**/vs/platform/**/{common,browser,node,electron-browser}/**", "**/vs/editor/**", "**/vs/workbench/{common,browser,node,electron-browser,api}/**", From 4aaaf3dc6aa28ed9bc15ad26175af68775a94d06 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 11 Apr 2019 10:02:18 +0200 Subject: [PATCH 038/861] move things around --- .../electron-browser/webWorkerExtensionHostStarter.ts | 3 ++- .../extensions}/worker/extensionHostWorker.ts | 0 .../extensions}/worker/extensionLoader.ts | 0 3 files changed, 2 insertions(+), 1 deletion(-) rename src/vs/workbench/{contrib/workerExtensions => services/extensions}/worker/extensionHostWorker.ts (100%) rename src/vs/workbench/{contrib/workerExtensions => services/extensions}/worker/extensionLoader.ts (100%) diff --git a/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts b/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts index fc843bab3b8..e16de3ab4e1 100644 --- a/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts +++ b/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts @@ -53,11 +53,12 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { const emitter = new Emitter(); const worker = new DefaultWorkerFactory('WorkerExtensionHost').create( - 'vs/workbench/contrib/workerExtensions/worker/extensionHostWorker', data => { + 'vs/workbench/services/extensions/worker/extensionHostWorker', data => { if (data instanceof ArrayBuffer) { emitter.fire(VSBuffer.wrap(new Uint8Array(data, 0, data.byteLength))); } else { console.warn('UNKNOWN data received', data); + this._onDidCrashed.fire([77, 'UNKNOWN data received']); } }, err => { this._onDidCrashed.fire([81, err]); diff --git a/src/vs/workbench/contrib/workerExtensions/worker/extensionHostWorker.ts b/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts similarity index 100% rename from src/vs/workbench/contrib/workerExtensions/worker/extensionHostWorker.ts rename to src/vs/workbench/services/extensions/worker/extensionHostWorker.ts diff --git a/src/vs/workbench/contrib/workerExtensions/worker/extensionLoader.ts b/src/vs/workbench/services/extensions/worker/extensionLoader.ts similarity index 100% rename from src/vs/workbench/contrib/workerExtensions/worker/extensionLoader.ts rename to src/vs/workbench/services/extensions/worker/extensionLoader.ts From 1038ae7f40eb32b01d4e4a077c9e6a3ecc5160e7 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 11 Apr 2019 13:00:34 +0200 Subject: [PATCH 039/861] wip --- .../electron-browser/extensionService.ts | 2 +- .../webWorkerExtensionHostStarter.ts | 6 +- .../extensions/worker/extHost.api.impl.ts | 897 ++++++++++++++++++ .../worker/extHostExtensionService.ts | 721 ++++++++++++++ .../extensions/worker/extensionHostMain.ts | 163 ++++ .../extensions/worker/extensionHostWorker.ts | 41 +- tslint.json | 13 + 7 files changed, 1832 insertions(+), 11 deletions(-) create mode 100644 src/vs/workbench/services/extensions/worker/extHost.api.impl.ts create mode 100644 src/vs/workbench/services/extensions/worker/extHostExtensionService.ts create mode 100644 src/vs/workbench/services/extensions/worker/extensionHostMain.ts diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index 5cfe7f0024d..42136f9e2c9 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -447,7 +447,7 @@ export class ExtensionService extends Disposable implements IExtensionService { this._extensionHostProcessManagers.push(extHostProcessManager); } { - const extHostWebWorkerWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, autoStart, extensions, this._extensionHostLogsLocation); + const extHostWebWorkerWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, /* autoStart, */ extensions, this._extensionHostLogsLocation); const extHostWebWorkerManager = this._instantiationService.createInstance(ExtensionHostProcessManager, extHostWebWorkerWorker, null, initialActivationEvents); extHostWebWorkerManager.onDidCrash(([code, signal]) => this._onExtensionHostCrashed(code, signal)); extHostWebWorkerManager.onDidChangeResponsiveState((responsiveState) => { this._onDidChangeResponsiveChange.fire({ target: extHostWebWorkerManager, isResponsive: responsiveState === ResponsiveState.Responsive }); }); diff --git a/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts b/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts index e16de3ab4e1..b8bec5612c8 100644 --- a/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts +++ b/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts @@ -35,7 +35,7 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { readonly onCrashed: Event<[number, string | null]> = this._onDidCrashed.event; constructor( - private readonly _autoStart: boolean, + // private readonly _autoStart: boolean, private readonly _extensions: Promise, private readonly _extensionHostLogsLocation: URI, @ITelemetryService private readonly _telemetryService: ITelemetryService, @@ -137,11 +137,11 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { }, resolvedExtensions: [], hostExtensions: [], - extensions: extensionDescriptions, + extensions: [], // < todo@joh extensionDescriptions, telemetryInfo, logLevel: this._logService.getLevel(), logsLocation: this._extensionHostLogsLocation, - autoStart: this._autoStart + autoStart: true// < todo@joh this._autoStart }; return r; }); diff --git a/src/vs/workbench/services/extensions/worker/extHost.api.impl.ts b/src/vs/workbench/services/extensions/worker/extHost.api.impl.ts new file mode 100644 index 00000000000..50c5ed11a0d --- /dev/null +++ b/src/vs/workbench/services/extensions/worker/extHost.api.impl.ts @@ -0,0 +1,897 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { CancellationTokenSource } from 'vs/base/common/cancellation'; +import * as errors from 'vs/base/common/errors'; +import { Emitter, Event } from 'vs/base/common/event'; +import * as path from 'vs/base/common/path'; +import Severity from 'vs/base/common/severity'; +import { URI } from 'vs/base/common/uri'; +import { TextEditorCursorStyle } from 'vs/editor/common/config/editorOptions'; +import { OverviewRulerLane } from 'vs/editor/common/model'; +import * as languageConfiguration from 'vs/editor/common/modes/languageConfiguration'; +import { score } from 'vs/editor/common/modes/languageSelector'; +import * as files from 'vs/platform/files/common/files'; +import { ExtHostContext, IInitData, IMainContext, MainContext } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostApiCommands } from 'vs/workbench/api/common/extHostApiCommands'; +import { ExtHostClipboard } from 'vs/workbench/api/common/extHostClipboard'; +import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; +import { ExtHostComments } from 'vs/workbench/api/common/extHostComments'; +import { ExtHostConfiguration, ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration'; +// import { ExtHostDebugService } from 'vs/workbench/api/node/extHostDebugService'; +import { ExtHostDecorations } from 'vs/workbench/api/common/extHostDecorations'; +import { ExtHostDiagnostics } from 'vs/workbench/api/common/extHostDiagnostics'; +import { ExtHostDialogs } from 'vs/workbench/api/common/extHostDialogs'; +import { ExtHostDocumentContentProvider } from 'vs/workbench/api/common/extHostDocumentContentProviders'; +import { ExtHostDocumentSaveParticipant } from 'vs/workbench/api/common/extHostDocumentSaveParticipant'; +import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments'; +import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; +import { ExtensionActivatedByAPI } from 'vs/workbench/api/common/extHostExtensionActivator'; +import { ExtHostExtensionService } from './extHostExtensionService'; +import { ExtHostFileSystem } from 'vs/workbench/api/common/extHostFileSystem'; +import { ExtHostFileSystemEventService } from 'vs/workbench/api/common/extHostFileSystemEventService'; +import { ExtHostHeapService } from 'vs/workbench/api/common/extHostHeapService'; +import { ExtHostLanguageFeatures, ISchemeTransformer } from 'vs/workbench/api/common/extHostLanguageFeatures'; +import { ExtHostLanguages } from 'vs/workbench/api/common/extHostLanguages'; +import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; +import { ExtHostMessageService } from 'vs/workbench/api/common/extHostMessageService'; +import { ExtHostOutputService, PushOutputChannelFactory } from 'vs/workbench/api/common/extHostOutput'; +// import { LogOutputChannelFactory } from 'vs/workbench/api/node/extHostOutputService'; +import { ExtHostProgress } from 'vs/workbench/api/common/extHostProgress'; +import { ExtHostQuickOpen } from 'vs/workbench/api/common/extHostQuickOpen'; +import { ExtHostSCM } from 'vs/workbench/api/common/extHostSCM'; +// import { ExtHostSearch, registerEHSearchProviders } from 'vs/workbench/api/node/extHostSearch'; +import { ExtHostStatusBar } from 'vs/workbench/api/common/extHostStatusBar'; +import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; +// import { ExtHostTask } from 'vs/workbench/api/node/extHostTask'; +// import { ExtHostTerminalService } from 'vs/workbench/api/node/extHostTerminalService'; +import { ExtHostEditors } from 'vs/workbench/api/common/extHostTextEditors'; +import { ExtHostTreeViews } from 'vs/workbench/api/common/extHostTreeViews'; +import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters'; +import * as extHostTypes from 'vs/workbench/api/common/extHostTypes'; +import { ExtHostUrls } from 'vs/workbench/api/common/extHostUrls'; +import { ExtHostWebviews } from 'vs/workbench/api/common/extHostWebview'; +import { ExtHostWindow } from 'vs/workbench/api/common/extHostWindow'; +import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; +import { throwProposedApiError, checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions'; +import { ProxyIdentifier } from 'vs/workbench/services/extensions/common/proxyIdentifier'; +import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; +import * as vscode from 'vscode'; +import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { originalFSPath } from 'vs/base/common/resources'; +// import { CLIServer } from 'vs/workbench/api/node/extHostCLIServer'; +import { withNullAsUndefined } from 'vs/base/common/types'; +import { values } from 'vs/base/common/collections'; +// import { Schemas } from 'vs/base/common/network'; + +export interface IExtensionApiFactory { + (extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode; +} + +function proposedApiFunction(extension: IExtensionDescription, fn: T): T { + if (extension.enableProposedApi) { + return fn; + } else { + return throwProposedApiError.bind(null, extension) as any as T; + } +} + +/** + * This method instantiates and returns the extension API surface + */ +export function createApiFactory( + initData: IInitData, + rpcProtocol: IMainContext, + extHostWorkspace: ExtHostWorkspace, + extHostConfiguration: ExtHostConfiguration, + extensionService: ExtHostExtensionService, + extHostLogService: ExtHostLogService, + extHostStorage: ExtHostStorage, + schemeTransformer: ISchemeTransformer | null, + outputChannelName: string +): IExtensionApiFactory { + + // Addressable instances + rpcProtocol.set(ExtHostContext.ExtHostLogService, extHostLogService); + const extHostHeapService = rpcProtocol.set(ExtHostContext.ExtHostHeapService, new ExtHostHeapService()); + const extHostDecorations = rpcProtocol.set(ExtHostContext.ExtHostDecorations, new ExtHostDecorations(rpcProtocol)); + const extHostWebviews = rpcProtocol.set(ExtHostContext.ExtHostWebviews, new ExtHostWebviews(rpcProtocol)); + const extHostUrls = rpcProtocol.set(ExtHostContext.ExtHostUrls, new ExtHostUrls(rpcProtocol)); + const extHostDocumentsAndEditors = rpcProtocol.set(ExtHostContext.ExtHostDocumentsAndEditors, new ExtHostDocumentsAndEditors(rpcProtocol)); + const extHostDocuments = rpcProtocol.set(ExtHostContext.ExtHostDocuments, new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors)); + const extHostDocumentContentProviders = rpcProtocol.set(ExtHostContext.ExtHostDocumentContentProviders, new ExtHostDocumentContentProvider(rpcProtocol, extHostDocumentsAndEditors, extHostLogService)); + const extHostDocumentSaveParticipant = rpcProtocol.set(ExtHostContext.ExtHostDocumentSaveParticipant, new ExtHostDocumentSaveParticipant(extHostLogService, extHostDocuments, rpcProtocol.getProxy(MainContext.MainThreadTextEditors))); + const extHostEditors = rpcProtocol.set(ExtHostContext.ExtHostEditors, new ExtHostEditors(rpcProtocol, extHostDocumentsAndEditors)); + const extHostCommands = rpcProtocol.set(ExtHostContext.ExtHostCommands, new ExtHostCommands(rpcProtocol, extHostHeapService, extHostLogService)); + const extHostTreeViews = rpcProtocol.set(ExtHostContext.ExtHostTreeViews, new ExtHostTreeViews(rpcProtocol.getProxy(MainContext.MainThreadTreeViews), extHostCommands, extHostLogService)); + rpcProtocol.set(ExtHostContext.ExtHostWorkspace, extHostWorkspace); + rpcProtocol.set(ExtHostContext.ExtHostConfiguration, extHostConfiguration); + const extHostDiagnostics = rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, new ExtHostDiagnostics(rpcProtocol)); + const extHostLanguageFeatures = rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, new ExtHostLanguageFeatures(rpcProtocol, schemeTransformer, extHostDocuments, extHostCommands, extHostHeapService, extHostDiagnostics, extHostLogService)); + const extHostFileSystem = rpcProtocol.set(ExtHostContext.ExtHostFileSystem, new ExtHostFileSystem(rpcProtocol, extHostLanguageFeatures)); + const extHostFileSystemEvent = rpcProtocol.set(ExtHostContext.ExtHostFileSystemEventService, new ExtHostFileSystemEventService(rpcProtocol, extHostDocumentsAndEditors)); + const extHostQuickOpen = rpcProtocol.set(ExtHostContext.ExtHostQuickOpen, new ExtHostQuickOpen(rpcProtocol, extHostWorkspace, extHostCommands)); + // const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(rpcProtocol, extHostConfiguration, extHostLogService)); + // const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, new ExtHostDebugService(rpcProtocol, extHostWorkspace, extensionService, extHostDocumentsAndEditors, extHostConfiguration, extHostTerminalService, extHostCommands)); + const extHostSCM = rpcProtocol.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(rpcProtocol, extHostCommands, extHostLogService)); + const extHostComment = rpcProtocol.set(ExtHostContext.ExtHostComments, new ExtHostComments(rpcProtocol, extHostCommands, extHostDocuments)); + // const extHostSearch = rpcProtocol.set(ExtHostContext.ExtHostSearch, new ExtHostSearch(rpcProtocol, schemeTransformer, extHostLogService)); + // const extHostTask = rpcProtocol.set(ExtHostContext.ExtHostTask, new ExtHostTask(rpcProtocol, extHostWorkspace, extHostDocumentsAndEditors, extHostConfiguration, extHostTerminalService)); + const extHostWindow = rpcProtocol.set(ExtHostContext.ExtHostWindow, new ExtHostWindow(rpcProtocol)); + rpcProtocol.set(ExtHostContext.ExtHostExtensionService, extensionService); + const extHostProgress = rpcProtocol.set(ExtHostContext.ExtHostProgress, new ExtHostProgress(rpcProtocol.getProxy(MainContext.MainThreadProgress))); + const extHostOutputService = rpcProtocol.set(ExtHostContext.ExtHostOutputService, new ExtHostOutputService(PushOutputChannelFactory, initData.logsLocation, rpcProtocol)); + rpcProtocol.set(ExtHostContext.ExtHostStorage, extHostStorage); + // if (initData.remoteAuthority) { + // extHostTask.registerTaskSystem(Schemas.vscodeRemote, { + // scheme: Schemas.vscodeRemote, + // authority: initData.remoteAuthority, + // platform: process.platform + // }); + + // registerEHSearchProviders(extHostSearch, extHostLogService); + + // const cliServer = new CLIServer(extHostCommands); + // process.env['VSCODE_IPC_HOOK_CLI'] = cliServer.ipcHandlePath; + // } + + // todo@joh + const proxy: any = new Proxy({}, {}); + rpcProtocol.set(ExtHostContext.ExtHostTerminalService, proxy); + rpcProtocol.set(ExtHostContext.ExtHostDebugService, proxy); + rpcProtocol.set(ExtHostContext.ExtHostSearch, proxy); + rpcProtocol.set(ExtHostContext.ExtHostTask, proxy); + + // Check that no named customers are missing + const expected: ProxyIdentifier[] = values(ExtHostContext); + rpcProtocol.assertRegistered(expected); + + // Other instances + const extHostClipboard = new ExtHostClipboard(rpcProtocol); + const extHostMessageService = new ExtHostMessageService(rpcProtocol); + const extHostDialogs = new ExtHostDialogs(rpcProtocol); + const extHostStatusBar = new ExtHostStatusBar(rpcProtocol); + const extHostLanguages = new ExtHostLanguages(rpcProtocol, extHostDocuments); + + // Register an output channel for exthost log + extHostOutputService.createOutputChannelFromLogFile(outputChannelName, extHostLogService.logFile); + + // Register API-ish commands + ExtHostApiCommands.register(extHostCommands); + + return function (extension: IExtensionDescription, extensionRegistry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode { + + // Check document selectors for being overly generic. Technically this isn't a problem but + // in practice many extensions say they support `fooLang` but need fs-access to do so. Those + // extension should specify then the `file`-scheme, e.g `{ scheme: 'fooLang', language: 'fooLang' }` + // We only inform once, it is not a warning because we just want to raise awareness and because + // we cannot say if the extension is doing it right or wrong... + const checkSelector = (function () { + let done = (!extension.isUnderDevelopment); + function informOnce(selector: vscode.DocumentSelector) { + if (!done) { + console.info(`Extension '${extension.identifier.value}' uses a document selector without scheme. Learn more about this: https://go.microsoft.com/fwlink/?linkid=872305`); + done = true; + } + } + return function perform(selector: vscode.DocumentSelector): vscode.DocumentSelector { + if (Array.isArray(selector)) { + selector.forEach(perform); + } else if (typeof selector === 'string') { + informOnce(selector); + } else { + if (typeof selector.scheme === 'undefined') { + informOnce(selector); + } + if (!extension.enableProposedApi && typeof selector.exclusive === 'boolean') { + throwProposedApiError(extension); + } + } + return selector; + }; + })(); + + + // namespace: commands + const commands: typeof vscode.commands = { + registerCommand(id: string, command: (...args: any[]) => T | Thenable, thisArgs?: any): vscode.Disposable { + return extHostCommands.registerCommand(true, id, command, thisArgs); + }, + registerTextEditorCommand(id: string, callback: (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit, ...args: any[]) => void, thisArg?: any): vscode.Disposable { + return extHostCommands.registerCommand(true, id, (...args: any[]): any => { + const activeTextEditor = extHostEditors.getActiveTextEditor(); + if (!activeTextEditor) { + console.warn('Cannot execute ' + id + ' because there is no active text editor.'); + return undefined; + } + + return activeTextEditor.edit((edit: vscode.TextEditorEdit) => { + args.unshift(activeTextEditor, edit); + callback.apply(thisArg, args); + + }).then((result) => { + if (!result) { + console.warn('Edits from command ' + id + ' were not applied.'); + } + }, (err) => { + console.warn('An error occurred while running command ' + id, err); + }); + }); + }, + registerDiffInformationCommand: proposedApiFunction(extension, (id: string, callback: (diff: vscode.LineChange[], ...args: any[]) => any, thisArg?: any): vscode.Disposable => { + return extHostCommands.registerCommand(true, id, async (...args: any[]): Promise => { + const activeTextEditor = extHostEditors.getActiveTextEditor(); + if (!activeTextEditor) { + console.warn('Cannot execute ' + id + ' because there is no active text editor.'); + return undefined; + } + + const diff = await extHostEditors.getDiffInformation(activeTextEditor.id); + callback.apply(thisArg, [diff, ...args]); + }); + }), + executeCommand(id: string, ...args: any[]): Thenable { + return extHostCommands.executeCommand(id, ...args); + }, + getCommands(filterInternal: boolean = false): Thenable { + return extHostCommands.getCommands(filterInternal); + } + }; + + // namespace: env + const env: typeof vscode.env = Object.freeze({ + get machineId() { return initData.telemetryInfo.machineId; }, + get sessionId() { return initData.telemetryInfo.sessionId; }, + get language() { return initData.environment.appLanguage; }, + get appName() { return initData.environment.appName; }, + get appRoot() { return initData.environment.appRoot!.fsPath; }, + get uriScheme() { return initData.environment.appUriScheme; }, + get logLevel() { + checkProposedApiEnabled(extension); + return typeConverters.LogLevel.to(extHostLogService.getLevel()); + }, + get onDidChangeLogLevel() { + checkProposedApiEnabled(extension); + return Event.map(extHostLogService.onDidChangeLogLevel, l => typeConverters.LogLevel.to(l)); + }, + get clipboard(): vscode.Clipboard { + return extHostClipboard; + }, + openExternal(uri: URI) { + return extHostWindow.openUri(uri); + } + }); + + // namespace: extensions + const extensions: typeof vscode.extensions = { + getExtension(extensionId: string): Extension | undefined { + const desc = extensionRegistry.getExtensionDescription(extensionId); + if (desc) { + return new Extension(extensionService, desc); + } + return undefined; + }, + get all(): Extension[] { + return extensionRegistry.getAllExtensionDescriptions().map((desc) => new Extension(extensionService, desc)); + }, + get onDidChange() { + return extensionRegistry.onDidChange; + } + }; + + // namespace: languages + const languages: typeof vscode.languages = { + createDiagnosticCollection(name?: string): vscode.DiagnosticCollection { + return extHostDiagnostics.createDiagnosticCollection(name); + }, + get onDidChangeDiagnostics() { + return extHostDiagnostics.onDidChangeDiagnostics; + }, + getDiagnostics: (resource?: vscode.Uri) => { + return extHostDiagnostics.getDiagnostics(resource); + }, + getLanguages(): Thenable { + return extHostLanguages.getLanguages(); + }, + setTextDocumentLanguage(document: vscode.TextDocument, languageId: string): Thenable { + return extHostLanguages.changeLanguage(document.uri, languageId); + }, + match(selector: vscode.DocumentSelector, document: vscode.TextDocument): number { + return score(typeConverters.LanguageSelector.from(selector), document.uri, document.languageId, true); + }, + registerCodeActionsProvider(selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider, metadata?: vscode.CodeActionProviderMetadata): vscode.Disposable { + return extHostLanguageFeatures.registerCodeActionProvider(extension, checkSelector(selector), provider, metadata); + }, + registerCodeLensProvider(selector: vscode.DocumentSelector, provider: vscode.CodeLensProvider): vscode.Disposable { + return extHostLanguageFeatures.registerCodeLensProvider(extension, checkSelector(selector), provider); + }, + registerCodeInsetProvider(selector: vscode.DocumentSelector, provider: vscode.CodeInsetProvider): vscode.Disposable { + checkProposedApiEnabled(extension); + return extHostLanguageFeatures.registerCodeInsetProvider(extension, checkSelector(selector), provider); + }, + registerDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.DefinitionProvider): vscode.Disposable { + return extHostLanguageFeatures.registerDefinitionProvider(extension, checkSelector(selector), provider); + }, + registerDeclarationProvider(selector: vscode.DocumentSelector, provider: vscode.DeclarationProvider): vscode.Disposable { + return extHostLanguageFeatures.registerDeclarationProvider(extension, checkSelector(selector), provider); + }, + registerImplementationProvider(selector: vscode.DocumentSelector, provider: vscode.ImplementationProvider): vscode.Disposable { + return extHostLanguageFeatures.registerImplementationProvider(extension, checkSelector(selector), provider); + }, + registerTypeDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.TypeDefinitionProvider): vscode.Disposable { + return extHostLanguageFeatures.registerTypeDefinitionProvider(extension, checkSelector(selector), provider); + }, + registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable { + return extHostLanguageFeatures.registerHoverProvider(extension, checkSelector(selector), provider, extension.identifier); + }, + registerDocumentHighlightProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentHighlightProvider): vscode.Disposable { + return extHostLanguageFeatures.registerDocumentHighlightProvider(extension, checkSelector(selector), provider); + }, + registerReferenceProvider(selector: vscode.DocumentSelector, provider: vscode.ReferenceProvider): vscode.Disposable { + return extHostLanguageFeatures.registerReferenceProvider(extension, checkSelector(selector), provider); + }, + registerRenameProvider(selector: vscode.DocumentSelector, provider: vscode.RenameProvider): vscode.Disposable { + return extHostLanguageFeatures.registerRenameProvider(extension, checkSelector(selector), provider); + }, + registerDocumentSymbolProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentSymbolProvider, metadata?: vscode.DocumentSymbolProviderMetadata): vscode.Disposable { + return extHostLanguageFeatures.registerDocumentSymbolProvider(extension, checkSelector(selector), provider, metadata); + }, + registerWorkspaceSymbolProvider(provider: vscode.WorkspaceSymbolProvider): vscode.Disposable { + return extHostLanguageFeatures.registerWorkspaceSymbolProvider(extension, provider); + }, + registerDocumentFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentFormattingEditProvider): vscode.Disposable { + return extHostLanguageFeatures.registerDocumentFormattingEditProvider(extension, checkSelector(selector), provider); + }, + registerDocumentRangeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentRangeFormattingEditProvider): vscode.Disposable { + return extHostLanguageFeatures.registerDocumentRangeFormattingEditProvider(extension, checkSelector(selector), provider); + }, + registerOnTypeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.OnTypeFormattingEditProvider, firstTriggerCharacter: string, ...moreTriggerCharacters: string[]): vscode.Disposable { + return extHostLanguageFeatures.registerOnTypeFormattingEditProvider(extension, checkSelector(selector), provider, [firstTriggerCharacter].concat(moreTriggerCharacters)); + }, + registerSignatureHelpProvider(selector: vscode.DocumentSelector, provider: vscode.SignatureHelpProvider, firstItem?: string | vscode.SignatureHelpProviderMetadata, ...remaining: string[]): vscode.Disposable { + if (typeof firstItem === 'object') { + return extHostLanguageFeatures.registerSignatureHelpProvider(extension, checkSelector(selector), provider, firstItem); + } + return extHostLanguageFeatures.registerSignatureHelpProvider(extension, checkSelector(selector), provider, typeof firstItem === 'undefined' ? [] : [firstItem, ...remaining]); + }, + registerCompletionItemProvider(selector: vscode.DocumentSelector, provider: vscode.CompletionItemProvider, ...triggerCharacters: string[]): vscode.Disposable { + return extHostLanguageFeatures.registerCompletionItemProvider(extension, checkSelector(selector), provider, triggerCharacters); + }, + registerDocumentLinkProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentLinkProvider): vscode.Disposable { + return extHostLanguageFeatures.registerDocumentLinkProvider(extension, checkSelector(selector), provider); + }, + registerColorProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentColorProvider): vscode.Disposable { + return extHostLanguageFeatures.registerColorProvider(extension, checkSelector(selector), provider); + }, + registerFoldingRangeProvider(selector: vscode.DocumentSelector, provider: vscode.FoldingRangeProvider): vscode.Disposable { + return extHostLanguageFeatures.registerFoldingRangeProvider(extension, checkSelector(selector), provider); + }, + registerSelectionRangeProvider(selector: vscode.DocumentSelector, provider: vscode.SelectionRangeProvider): vscode.Disposable { + return extHostLanguageFeatures.registerSelectionRangeProvider(extension, selector, provider); + }, + registerCallHierarchyProvider(selector: vscode.DocumentSelector, provider: vscode.CallHierarchyItemProvider): vscode.Disposable { + checkProposedApiEnabled(extension); + return extHostLanguageFeatures.registerCallHierarchyProvider(extension, selector, provider); + }, + setLanguageConfiguration: (language: string, configuration: vscode.LanguageConfiguration): vscode.Disposable => { + return extHostLanguageFeatures.setLanguageConfiguration(language, configuration); + } + }; + + // namespace: window + const window: typeof vscode.window = { + get activeTextEditor() { + return extHostEditors.getActiveTextEditor(); + }, + get visibleTextEditors() { + return extHostEditors.getVisibleTextEditors(); + }, + get activeTerminal(): vscode.Terminal { + throw new Error('not implemented'); + // return extHostTerminalService.activeTerminal; + }, + get terminals(): vscode.Terminal[] { + throw new Error('not implemented'); + // return extHostTerminalService.terminals; + }, + showTextDocument(documentOrUri: vscode.TextDocument | vscode.Uri, columnOrOptions?: vscode.ViewColumn | vscode.TextDocumentShowOptions, preserveFocus?: boolean): Thenable { + let documentPromise: Promise; + if (URI.isUri(documentOrUri)) { + documentPromise = Promise.resolve(workspace.openTextDocument(documentOrUri)); + } else { + documentPromise = Promise.resolve(documentOrUri); + } + return documentPromise.then(document => { + return extHostEditors.showTextDocument(document, columnOrOptions, preserveFocus); + }); + }, + createTextEditorDecorationType(options: vscode.DecorationRenderOptions): vscode.TextEditorDecorationType { + return extHostEditors.createTextEditorDecorationType(options); + }, + onDidChangeActiveTextEditor(listener, thisArg?, disposables?) { + return extHostEditors.onDidChangeActiveTextEditor(listener, thisArg, disposables); + }, + onDidChangeVisibleTextEditors(listener, thisArg, disposables) { + return extHostEditors.onDidChangeVisibleTextEditors(listener, thisArg, disposables); + }, + onDidChangeTextEditorSelection(listener: (e: vscode.TextEditorSelectionChangeEvent) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) { + return extHostEditors.onDidChangeTextEditorSelection(listener, thisArgs, disposables); + }, + onDidChangeTextEditorOptions(listener: (e: vscode.TextEditorOptionsChangeEvent) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) { + return extHostEditors.onDidChangeTextEditorOptions(listener, thisArgs, disposables); + }, + onDidChangeTextEditorVisibleRanges(listener: (e: vscode.TextEditorVisibleRangesChangeEvent) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) { + return extHostEditors.onDidChangeTextEditorVisibleRanges(listener, thisArgs, disposables); + }, + onDidChangeTextEditorViewColumn(listener, thisArg?, disposables?) { + return extHostEditors.onDidChangeTextEditorViewColumn(listener, thisArg, disposables); + }, + onDidCloseTerminal(listener, thisArg?, disposables?) { + throw new Error('not implemented'); + // return extHostTerminalService.onDidCloseTerminal(listener, thisArg, disposables); + }, + onDidOpenTerminal(listener, thisArg?, disposables?) { + throw new Error('not implemented'); + // return extHostTerminalService.onDidOpenTerminal(listener, thisArg, disposables); + }, + onDidChangeActiveTerminal(listener, thisArg?, disposables?) { + throw new Error('not implemented'); + // return extHostTerminalService.onDidChangeActiveTerminal(listener, thisArg, disposables); + }, + onDidChangeTerminalDimensions(listener, thisArg?, disposables?) { + throw new Error('not implemented'); + // return extHostTerminalService.onDidChangeTerminalDimensions(listener, thisArg, disposables); + }, + get state() { + return extHostWindow.state; + }, + onDidChangeWindowState(listener, thisArg?, disposables?) { + return extHostWindow.onDidChangeWindowState(listener, thisArg, disposables); + }, + showInformationMessage(message: string, first: vscode.MessageOptions | string | vscode.MessageItem, ...rest: Array) { + return extHostMessageService.showMessage(extension, Severity.Info, message, first, rest); + }, + showWarningMessage(message: string, first: vscode.MessageOptions | string | vscode.MessageItem, ...rest: Array) { + return extHostMessageService.showMessage(extension, Severity.Warning, message, first, rest); + }, + showErrorMessage(message: string, first: vscode.MessageOptions | string | vscode.MessageItem, ...rest: Array) { + return extHostMessageService.showMessage(extension, Severity.Error, message, first, rest); + }, + showQuickPick(items: any, options: vscode.QuickPickOptions, token?: vscode.CancellationToken): any { + return extHostQuickOpen.showQuickPick(items, !!extension.enableProposedApi, options, token); + }, + showWorkspaceFolderPick(options: vscode.WorkspaceFolderPickOptions) { + return extHostQuickOpen.showWorkspaceFolderPick(options); + }, + showInputBox(options?: vscode.InputBoxOptions, token?: vscode.CancellationToken) { + return extHostQuickOpen.showInput(options, token); + }, + showOpenDialog(options) { + return extHostDialogs.showOpenDialog(options); + }, + showSaveDialog(options) { + return extHostDialogs.showSaveDialog(options); + }, + createStatusBarItem(position?: vscode.StatusBarAlignment, priority?: number): vscode.StatusBarItem { + return extHostStatusBar.createStatusBarEntry(extension.identifier, position, priority); + }, + setStatusBarMessage(text: string, timeoutOrThenable?: number | Thenable): vscode.Disposable { + return extHostStatusBar.setStatusBarMessage(text, timeoutOrThenable); + }, + withScmProgress(task: (progress: vscode.Progress) => Thenable) { + console.warn(`[Deprecation Warning] function 'withScmProgress' is deprecated and should no longer be used. Use 'withProgress' instead.`); + return extHostProgress.withProgress(extension, { location: extHostTypes.ProgressLocation.SourceControl }, (progress, token) => task({ report(n: number) { /*noop*/ } })); + }, + withProgress(options: vscode.ProgressOptions, task: (progress: vscode.Progress<{ message?: string; worked?: number }>, token: vscode.CancellationToken) => Thenable) { + return extHostProgress.withProgress(extension, options, task); + }, + createOutputChannel(name: string): vscode.OutputChannel { + return extHostOutputService.createOutputChannel(name); + }, + createWebviewPanel(viewType: string, title: string, showOptions: vscode.ViewColumn | { viewColumn: vscode.ViewColumn, preserveFocus?: boolean }, options: vscode.WebviewPanelOptions & vscode.WebviewOptions): vscode.WebviewPanel { + return extHostWebviews.createWebviewPanel(extension, viewType, title, showOptions, options); + }, + createTerminal(nameOrOptions?: vscode.TerminalOptions | string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal { + throw new Error('not implemented'); + // if (typeof nameOrOptions === 'object') { + // return extHostTerminalService.createTerminalFromOptions(nameOrOptions); + // } + // return extHostTerminalService.createTerminal(nameOrOptions, shellPath, shellArgs); + }, + createTerminalRenderer(name: string): vscode.TerminalRenderer { + throw new Error('not implemented'); + // return extHostTerminalService.createTerminalRenderer(name); + }, + registerTreeDataProvider(viewId: string, treeDataProvider: vscode.TreeDataProvider): vscode.Disposable { + return extHostTreeViews.registerTreeDataProvider(viewId, treeDataProvider, extension); + }, + createTreeView(viewId: string, options: { treeDataProvider: vscode.TreeDataProvider }): vscode.TreeView { + return extHostTreeViews.createTreeView(viewId, options, extension); + }, + registerWebviewPanelSerializer: (viewType: string, serializer: vscode.WebviewPanelSerializer) => { + return extHostWebviews.registerWebviewPanelSerializer(viewType, serializer); + }, + registerDecorationProvider: proposedApiFunction(extension, (provider: vscode.DecorationProvider) => { + return extHostDecorations.registerDecorationProvider(provider, extension.identifier); + }), + registerUriHandler(handler: vscode.UriHandler) { + return extHostUrls.registerUriHandler(extension.identifier, handler); + }, + createQuickPick(): vscode.QuickPick { + return extHostQuickOpen.createQuickPick(extension.identifier, !!extension.enableProposedApi); + }, + createInputBox(): vscode.InputBox { + return extHostQuickOpen.createInputBox(extension.identifier); + } + }; + + // namespace: workspace + const workspace: typeof vscode.workspace = { + get rootPath() { + return extHostWorkspace.getPath(); + }, + set rootPath(value) { + throw errors.readonly(); + }, + getWorkspaceFolder(resource) { + return extHostWorkspace.getWorkspaceFolder(resource); + }, + get workspaceFolders() { + return extHostWorkspace.getWorkspaceFolders(); + }, + get name() { + return extHostWorkspace.name; + }, + set name(value) { + throw errors.readonly(); + }, + updateWorkspaceFolders: (index, deleteCount, ...workspaceFoldersToAdd) => { + return extHostWorkspace.updateWorkspaceFolders(extension, index, deleteCount || 0, ...workspaceFoldersToAdd); + }, + onDidChangeWorkspaceFolders: function (listener, thisArgs?, disposables?) { + return extHostWorkspace.onDidChangeWorkspace(listener, thisArgs, disposables); + }, + asRelativePath: (pathOrUri, includeWorkspace?) => { + return extHostWorkspace.getRelativePath(pathOrUri, includeWorkspace); + }, + findFiles: (include, exclude, maxResults?, token?) => { + return extHostWorkspace.findFiles(typeConverters.GlobPattern.from(include), typeConverters.GlobPattern.from(withNullAsUndefined(exclude)), maxResults, extension.identifier, token); + }, + findTextInFiles: (query: vscode.TextSearchQuery, optionsOrCallback: vscode.FindTextInFilesOptions | ((result: vscode.TextSearchResult) => void), callbackOrToken?: vscode.CancellationToken | ((result: vscode.TextSearchResult) => void), token?: vscode.CancellationToken) => { + let options: vscode.FindTextInFilesOptions; + let callback: (result: vscode.TextSearchResult) => void; + + if (typeof optionsOrCallback === 'object') { + options = optionsOrCallback; + callback = callbackOrToken as (result: vscode.TextSearchResult) => void; + } else { + options = {}; + callback = optionsOrCallback; + token = callbackOrToken as vscode.CancellationToken; + } + + return extHostWorkspace.findTextInFiles(query, options || {}, callback, extension.identifier, token); + }, + saveAll: (includeUntitled?) => { + return extHostWorkspace.saveAll(includeUntitled); + }, + applyEdit(edit: vscode.WorkspaceEdit): Thenable { + return extHostEditors.applyWorkspaceEdit(edit); + }, + createFileSystemWatcher: (pattern, ignoreCreate, ignoreChange, ignoreDelete): vscode.FileSystemWatcher => { + return extHostFileSystemEvent.createFileSystemWatcher(typeConverters.GlobPattern.from(pattern), ignoreCreate, ignoreChange, ignoreDelete); + }, + get textDocuments() { + return extHostDocuments.getAllDocumentData().map(data => data.document); + }, + set textDocuments(value) { + throw errors.readonly(); + }, + openTextDocument(uriOrFileNameOrOptions?: vscode.Uri | string | { language?: string; content?: string; }) { + let uriPromise: Thenable; + + const options = uriOrFileNameOrOptions as { language?: string; content?: string; }; + if (typeof uriOrFileNameOrOptions === 'string') { + uriPromise = Promise.resolve(URI.file(uriOrFileNameOrOptions)); + } else if (uriOrFileNameOrOptions instanceof URI) { + uriPromise = Promise.resolve(uriOrFileNameOrOptions); + } else if (!options || typeof options === 'object') { + uriPromise = extHostDocuments.createDocumentData(options); + } else { + throw new Error('illegal argument - uriOrFileNameOrOptions'); + } + + return uriPromise.then(uri => { + return extHostDocuments.ensureDocumentData(uri).then(() => { + return extHostDocuments.getDocument(uri); + }); + }); + }, + onDidOpenTextDocument: (listener, thisArgs?, disposables?) => { + return extHostDocuments.onDidAddDocument(listener, thisArgs, disposables); + }, + onDidCloseTextDocument: (listener, thisArgs?, disposables?) => { + return extHostDocuments.onDidRemoveDocument(listener, thisArgs, disposables); + }, + onDidChangeTextDocument: (listener, thisArgs?, disposables?) => { + return extHostDocuments.onDidChangeDocument(listener, thisArgs, disposables); + }, + onDidSaveTextDocument: (listener, thisArgs?, disposables?) => { + return extHostDocuments.onDidSaveDocument(listener, thisArgs, disposables); + }, + onWillSaveTextDocument: (listener, thisArgs?, disposables?) => { + return extHostDocumentSaveParticipant.getOnWillSaveTextDocumentEvent(extension)(listener, thisArgs, disposables); + }, + onDidChangeConfiguration: (listener: (_: any) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) => { + return configProvider.onDidChangeConfiguration(listener, thisArgs, disposables); + }, + getConfiguration(section?: string, resource?: vscode.Uri): vscode.WorkspaceConfiguration { + resource = arguments.length === 1 ? undefined : resource; + return configProvider.getConfiguration(section, resource, extension.identifier); + }, + registerTextDocumentContentProvider(scheme: string, provider: vscode.TextDocumentContentProvider) { + return extHostDocumentContentProviders.registerTextDocumentContentProvider(scheme, provider); + }, + registerTaskProvider: (type: string, provider: vscode.TaskProvider) => { + throw new Error('not implemented'); + // return extHostTask.registerTaskProvider(extension, provider); + }, + registerFileSystemProvider(scheme, provider, options) { + return extHostFileSystem.registerFileSystemProvider(scheme, provider, options); + }, + registerFileSearchProvider: proposedApiFunction(extension, (scheme: string, provider: vscode.FileSearchProvider) => { + throw new Error('not implemented'); + // return extHostSearch.registerFileSearchProvider(scheme, provider); + }), + registerTextSearchProvider: proposedApiFunction(extension, (scheme: string, provider: vscode.TextSearchProvider) => { + throw new Error('not implemented'); + // return extHostSearch.registerTextSearchProvider(scheme, provider); + }), + registerDocumentCommentProvider: proposedApiFunction(extension, (provider: vscode.DocumentCommentProvider) => { + return extHostComment.registerDocumentCommentProvider(extension.identifier, provider); + }), + registerWorkspaceCommentProvider: proposedApiFunction(extension, (provider: vscode.WorkspaceCommentProvider) => { + return extHostComment.registerWorkspaceCommentProvider(extension.identifier, provider); + }), + registerRemoteAuthorityResolver: proposedApiFunction(extension, (authorityPrefix: string, resolver: vscode.RemoteAuthorityResolver) => { + return extensionService.registerRemoteAuthorityResolver(authorityPrefix, resolver); + }), + registerResourceLabelFormatter: proposedApiFunction(extension, (formatter: vscode.ResourceLabelFormatter) => { + return extHostFileSystem.registerResourceLabelFormatter(formatter); + }), + onDidRenameFile: proposedApiFunction(extension, (listener: (e: vscode.FileRenameEvent) => any, thisArg?: any, disposables?: vscode.Disposable[]) => { + return extHostFileSystemEvent.onDidRenameFile(listener, thisArg, disposables); + }), + onWillRenameFile: proposedApiFunction(extension, (listener: (e: vscode.FileWillRenameEvent) => any, thisArg?: any, disposables?: vscode.Disposable[]) => { + return extHostFileSystemEvent.getOnWillRenameFileEvent(extension)(listener, thisArg, disposables); + }) + }; + + // namespace: scm + const scm: typeof vscode.scm = { + get inputBox() { + return extHostSCM.getLastInputBox(extension)!; // Strict null override - Deprecated api + }, + createSourceControl(id: string, label: string, rootUri?: vscode.Uri) { + return extHostSCM.createSourceControl(extension, id, label, rootUri); + } + }; + + const comment: typeof vscode.comment = { + createCommentController(id: string, label: string) { + return extHostComment.createCommentController(extension, id, label); + } + }; + + // // namespace: debug + // const debug: typeof vscode.debug = { + // get activeDebugSession() { + // return extHostDebugService.activeDebugSession; + // }, + // get activeDebugConsole() { + // return extHostDebugService.activeDebugConsole; + // }, + // get breakpoints() { + // return extHostDebugService.breakpoints; + // }, + // onDidStartDebugSession(listener, thisArg?, disposables?) { + // return extHostDebugService.onDidStartDebugSession(listener, thisArg, disposables); + // }, + // onDidTerminateDebugSession(listener, thisArg?, disposables?) { + // return extHostDebugService.onDidTerminateDebugSession(listener, thisArg, disposables); + // }, + // onDidChangeActiveDebugSession(listener, thisArg?, disposables?) { + // return extHostDebugService.onDidChangeActiveDebugSession(listener, thisArg, disposables); + // }, + // onDidReceiveDebugSessionCustomEvent(listener, thisArg?, disposables?) { + // return extHostDebugService.onDidReceiveDebugSessionCustomEvent(listener, thisArg, disposables); + // }, + // onDidChangeBreakpoints(listener, thisArgs?, disposables?) { + // return extHostDebugService.onDidChangeBreakpoints(listener, thisArgs, disposables); + // }, + // registerDebugConfigurationProvider(debugType: string, provider: vscode.DebugConfigurationProvider) { + // return extHostDebugService.registerDebugConfigurationProvider(debugType, provider); + // }, + // registerDebugAdapterDescriptorFactory(debugType: string, factory: vscode.DebugAdapterDescriptorFactory) { + // return extHostDebugService.registerDebugAdapterDescriptorFactory(extension, debugType, factory); + // }, + // registerDebugAdapterTrackerFactory(debugType: string, factory: vscode.DebugAdapterTrackerFactory) { + // return extHostDebugService.registerDebugAdapterTrackerFactory(debugType, factory); + // }, + // startDebugging(folder: vscode.WorkspaceFolder | undefined, nameOrConfig: string | vscode.DebugConfiguration, parentSession?: vscode.DebugSession) { + // return extHostDebugService.startDebugging(folder, nameOrConfig, parentSession); + // }, + // addBreakpoints(breakpoints: vscode.Breakpoint[]) { + // return extHostDebugService.addBreakpoints(breakpoints); + // }, + // removeBreakpoints(breakpoints: vscode.Breakpoint[]) { + // return extHostDebugService.removeBreakpoints(breakpoints); + // } + // }; + + // const tasks: typeof vscode.tasks = { + // registerTaskProvider: (type: string, provider: vscode.TaskProvider) => { + // return extHostTask.registerTaskProvider(extension, provider); + // }, + // fetchTasks: (filter?: vscode.TaskFilter): Thenable => { + // return extHostTask.fetchTasks(filter); + // }, + // executeTask: (task: vscode.Task): Thenable => { + // return extHostTask.executeTask(extension, task); + // }, + // get taskExecutions(): vscode.TaskExecution[] { + // return extHostTask.taskExecutions; + // }, + // onDidStartTask: (listeners, thisArgs?, disposables?) => { + // return extHostTask.onDidStartTask(listeners, thisArgs, disposables); + // }, + // onDidEndTask: (listeners, thisArgs?, disposables?) => { + // return extHostTask.onDidEndTask(listeners, thisArgs, disposables); + // }, + // onDidStartTaskProcess: (listeners, thisArgs?, disposables?) => { + // return extHostTask.onDidStartTaskProcess(listeners, thisArgs, disposables); + // }, + // onDidEndTaskProcess: (listeners, thisArgs?, disposables?) => { + // return extHostTask.onDidEndTaskProcess(listeners, thisArgs, disposables); + // } + // }; + + return { + version: initData.version, + // namespaces + commands, + get debug(): typeof vscode.debug { throw new Error('not implemented'); }, + env, + extensions, + languages, + scm, + comment, + get tasks(): typeof vscode.tasks { throw new Error('not implemented'); }, + window, + workspace, + // types + Breakpoint: extHostTypes.Breakpoint, + CancellationTokenSource: CancellationTokenSource, + CodeAction: extHostTypes.CodeAction, + CodeActionKind: extHostTypes.CodeActionKind, + CodeActionTrigger: extHostTypes.CodeActionTrigger, + CodeLens: extHostTypes.CodeLens, + CodeInset: extHostTypes.CodeInset, + Color: extHostTypes.Color, + ColorInformation: extHostTypes.ColorInformation, + ColorPresentation: extHostTypes.ColorPresentation, + CommentThreadCollapsibleState: extHostTypes.CommentThreadCollapsibleState, + CompletionItem: extHostTypes.CompletionItem, + CompletionItemKind: extHostTypes.CompletionItemKind, + CompletionList: extHostTypes.CompletionList, + CompletionTriggerKind: extHostTypes.CompletionTriggerKind, + ConfigurationTarget: extHostTypes.ConfigurationTarget, + DebugAdapterExecutable: extHostTypes.DebugAdapterExecutable, + DebugAdapterServer: extHostTypes.DebugAdapterServer, + DecorationRangeBehavior: extHostTypes.DecorationRangeBehavior, + Diagnostic: extHostTypes.Diagnostic, + DiagnosticRelatedInformation: extHostTypes.DiagnosticRelatedInformation, + DiagnosticSeverity: extHostTypes.DiagnosticSeverity, + DiagnosticTag: extHostTypes.DiagnosticTag, + Disposable: extHostTypes.Disposable, + DocumentHighlight: extHostTypes.DocumentHighlight, + DocumentHighlightKind: extHostTypes.DocumentHighlightKind, + DocumentLink: extHostTypes.DocumentLink, + DocumentSymbol: extHostTypes.DocumentSymbol, + EndOfLine: extHostTypes.EndOfLine, + EventEmitter: Emitter, + CustomExecution: extHostTypes.CustomExecution, + FileChangeType: extHostTypes.FileChangeType, + FileSystemError: extHostTypes.FileSystemError, + FileType: files.FileType, + FoldingRange: extHostTypes.FoldingRange, + FoldingRangeKind: extHostTypes.FoldingRangeKind, + FunctionBreakpoint: extHostTypes.FunctionBreakpoint, + Hover: extHostTypes.Hover, + IndentAction: languageConfiguration.IndentAction, + Location: extHostTypes.Location, + LogLevel: extHostTypes.LogLevel, + MarkdownString: extHostTypes.MarkdownString, + OverviewRulerLane: OverviewRulerLane, + ParameterInformation: extHostTypes.ParameterInformation, + Position: extHostTypes.Position, + ProcessExecution: extHostTypes.ProcessExecution, + ProgressLocation: extHostTypes.ProgressLocation, + QuickInputButtons: extHostTypes.QuickInputButtons, + Range: extHostTypes.Range, + RelativePattern: extHostTypes.RelativePattern, + ResolvedAuthority: extHostTypes.ResolvedAuthority, + Selection: extHostTypes.Selection, + SelectionRange: extHostTypes.SelectionRange, + ShellExecution: extHostTypes.ShellExecution, + ShellQuoting: extHostTypes.ShellQuoting, + SignatureHelpTriggerKind: extHostTypes.SignatureHelpTriggerKind, + SignatureHelp: extHostTypes.SignatureHelp, + SignatureInformation: extHostTypes.SignatureInformation, + SnippetString: extHostTypes.SnippetString, + SourceBreakpoint: extHostTypes.SourceBreakpoint, + SourceControlInputBoxValidationType: extHostTypes.SourceControlInputBoxValidationType, + StatusBarAlignment: extHostTypes.StatusBarAlignment, + SymbolInformation: extHostTypes.SymbolInformation, + SymbolKind: extHostTypes.SymbolKind, + Task: extHostTypes.Task, + Task2: extHostTypes.Task, + TaskGroup: extHostTypes.TaskGroup, + TaskPanelKind: extHostTypes.TaskPanelKind, + TaskRevealKind: extHostTypes.TaskRevealKind, + TaskScope: extHostTypes.TaskScope, + TextDocumentSaveReason: extHostTypes.TextDocumentSaveReason, + TextEdit: extHostTypes.TextEdit, + TextEditorCursorStyle: TextEditorCursorStyle, + TextEditorLineNumbersStyle: extHostTypes.TextEditorLineNumbersStyle, + TextEditorRevealType: extHostTypes.TextEditorRevealType, + TextEditorSelectionChangeKind: extHostTypes.TextEditorSelectionChangeKind, + ThemeColor: extHostTypes.ThemeColor, + ThemeIcon: extHostTypes.ThemeIcon, + TreeItem: extHostTypes.TreeItem, + TreeItem2: extHostTypes.TreeItem, + TreeItemCollapsibleState: extHostTypes.TreeItemCollapsibleState, + Uri: URI, + ViewColumn: extHostTypes.ViewColumn, + WorkspaceEdit: extHostTypes.WorkspaceEdit, + // proposed + CallHierarchyDirection: extHostTypes.CallHierarchyDirection, + CallHierarchyItem: extHostTypes.CallHierarchyItem + }; + }; +} + +class Extension implements vscode.Extension { + + private _extensionService: ExtHostExtensionService; + private _identifier: ExtensionIdentifier; + + public id: string; + public extensionPath: string; + public packageJSON: IExtensionDescription; + + constructor(extensionService: ExtHostExtensionService, description: IExtensionDescription) { + this._extensionService = extensionService; + this._identifier = description.identifier; + this.id = description.identifier.value; + this.extensionPath = path.normalize(originalFSPath(description.extensionLocation)); + this.packageJSON = description; + } + + get isActive(): boolean { + return this._extensionService.isActivated(this._identifier); + } + + get exports(): T { + if (this.packageJSON.api === 'none') { + return undefined!; // Strict nulloverride - Public api + } + return this._extensionService.getExtensionExports(this._identifier); + } + + activate(): Thenable { + return this._extensionService.activateByIdWithErrors(this._identifier, new ExtensionActivatedByAPI(false)).then(() => this.exports); + } +} diff --git a/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts b/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts new file mode 100644 index 00000000000..082edbd5aa2 --- /dev/null +++ b/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts @@ -0,0 +1,721 @@ +/*--------------------------------------------------------------------------------------------- + * 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 * as path from 'vs/base/common/path'; +import { originalFSPath } from 'vs/base/common/resources'; +import { Barrier } from 'vs/base/common/async'; +import { dispose, toDisposable } from 'vs/base/common/lifecycle'; +import { TernarySearchTree } from 'vs/base/common/map'; +import { URI } from 'vs/base/common/uri'; +import { ILogService } from 'vs/platform/log/common/log'; +import { createApiFactory, IExtensionApiFactory } from './extHost.api.impl'; +// import { NodeModuleRequireInterceptor, VSCodeNodeModuleFactory, KeytarNodeModuleFactory, OpenNodeModuleFactory } from 'vs/workbench/api/node/extHostRequireInterceptor'; +import { ExtHostExtensionServiceShape, IEnvironment, IInitData, IMainContext, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; +import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionModule, HostExtension } from 'vs/workbench/api/common/extHostExtensionActivator'; +import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; +import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; +import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; +import { ExtensionActivationError } from 'vs/workbench/services/extensions/common/extensions'; +import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; +import * as errors from 'vs/base/common/errors'; +import { ResolvedAuthority } from 'vs/platform/remote/common/remoteAuthorityResolver'; +import * as vscode from 'vscode'; +import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { IWorkspace } from 'vs/platform/workspace/common/workspace'; +import { Schemas } from 'vs/base/common/network'; +// import { withNullAsUndefined } from 'vs/base/common/types'; +import { VSBuffer } from 'vs/base/common/buffer'; +import { ISchemeTransformer } from 'vs/workbench/api/common/extHostLanguageFeatures'; +import { ExtensionMemento } from 'vs/workbench/api/common/extHostMemento'; +// import { ExtensionStoragePaths } from 'vs/workbench/api/node/extHostStoragePaths'; + +interface ITestRunner { + run(testsRoot: string, clb: (error: Error, failures?: number) => void): void; +} + +export interface IHostUtils { + exit(code?: number): void; + exists(path: string): Promise; + realpath(path: string): Promise; +} + +export class ExtHostExtensionService implements ExtHostExtensionServiceShape { + + private static readonly WORKSPACE_CONTAINS_TIMEOUT = 7000; + + private readonly _hostUtils: IHostUtils; + private readonly _initData: IInitData; + private readonly _extHostContext: IMainContext; + private readonly _extHostWorkspace: ExtHostWorkspace; + private readonly _extHostConfiguration: ExtHostConfiguration; + // private readonly _environment: IEnvironment; + private readonly _extHostLogService: ExtHostLogService; + + private readonly _mainThreadWorkspaceProxy: MainThreadWorkspaceShape; + private readonly _mainThreadTelemetryProxy: MainThreadTelemetryShape; + private readonly _mainThreadExtensionsProxy: MainThreadExtensionServiceShape; + + private readonly _almostReadyToRunExtensions: Barrier; + private readonly _readyToRunExtensions: Barrier; + private readonly _registry: ExtensionDescriptionRegistry; + private readonly _storage: ExtHostStorage; + // private readonly _storagePath: ExtensionStoragePaths; + private readonly _activator: ExtensionsActivator; + private _extensionPathIndex: Promise> | null; + private readonly _extensionApiFactory: IExtensionApiFactory; + + private readonly _resolvers: { [authorityPrefix: string]: vscode.RemoteAuthorityResolver; }; + + private _started: boolean; + + constructor( + hostUtils: IHostUtils, + initData: IInitData, + extHostContext: IMainContext, + extHostWorkspace: ExtHostWorkspace, + extHostConfiguration: ExtHostConfiguration, + environment: IEnvironment, + extHostLogService: ExtHostLogService, + schemeTransformer: ISchemeTransformer | null, + outputChannelName: string + ) { + this._hostUtils = hostUtils; + this._initData = initData; + this._extHostContext = extHostContext; + this._extHostWorkspace = extHostWorkspace; + this._extHostConfiguration = extHostConfiguration; + // this._environment = environment; + this._extHostLogService = extHostLogService; + + this._mainThreadWorkspaceProxy = this._extHostContext.getProxy(MainContext.MainThreadWorkspace); + this._mainThreadTelemetryProxy = this._extHostContext.getProxy(MainContext.MainThreadTelemetry); + this._mainThreadExtensionsProxy = this._extHostContext.getProxy(MainContext.MainThreadExtensionService); + + this._almostReadyToRunExtensions = new Barrier(); + this._readyToRunExtensions = new Barrier(); + this._registry = new ExtensionDescriptionRegistry(initData.extensions); + this._storage = new ExtHostStorage(this._extHostContext); + // this._storagePath = new ExtensionStoragePaths(withNullAsUndefined(initData.workspace), initData.environment); + + const hostExtensions = new Set(); + initData.hostExtensions.forEach((extensionId) => hostExtensions.add(ExtensionIdentifier.toKey(extensionId))); + + this._activator = new ExtensionsActivator(this._registry, initData.resolvedExtensions, initData.hostExtensions, { + onExtensionActivationError: (extensionId: ExtensionIdentifier, error: ExtensionActivationError): void => { + this._mainThreadExtensionsProxy.$onExtensionActivationError(extensionId, error); + }, + + actualActivateExtension: async (extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise => { + if (hostExtensions.has(ExtensionIdentifier.toKey(extensionId))) { + const activationEvent = (reason instanceof ExtensionActivatedByEvent ? reason.activationEvent : null); + await this._mainThreadExtensionsProxy.$activateExtension(extensionId, activationEvent); + return new HostExtension(); + } + const extensionDescription = this._registry.getExtensionDescription(extensionId)!; + return this._activateExtension(extensionDescription, reason); + } + }); + this._extensionPathIndex = null; + + // initialize API first (i.e. do not release barrier until the API is initialized) + this._extensionApiFactory = createApiFactory( + this._initData, + this._extHostContext, + this._extHostWorkspace, + this._extHostConfiguration, + this, + this._extHostLogService, + this._storage, + schemeTransformer, + outputChannelName + ); + + this._resolvers = Object.create(null); + + this._started = false; + + this._initialize(); + + if (this._initData.autoStart) { + this._startExtensionHost(); + } + } + + private async _initialize(): Promise { + try { + // const configProvider = await this._extHostConfiguration.getConfigProvider(); + // const extensionPaths = await this.getExtensionPathIndex(); + // NodeModuleRequireInterceptor.INSTANCE.register(new VSCodeNodeModuleFactory(this._extensionApiFactory, extensionPaths, this._registry, configProvider)); + // NodeModuleRequireInterceptor.INSTANCE.register(new KeytarNodeModuleFactory(this._extHostContext.getProxy(MainContext.MainThreadKeytar), this._environment)); + // if (this._initData.remoteAuthority) { + // NodeModuleRequireInterceptor.INSTANCE.register(new OpenNodeModuleFactory( + // this._extHostContext.getProxy(MainContext.MainThreadWindow), + // this._extHostContext.getProxy(MainContext.MainThreadTelemetry), + // extensionPaths + // )); + // } + + // // Do this when extension service exists, but extensions are not being activated yet. + // await connectProxyResolver(this._extHostWorkspace, configProvider, this, this._extHostLogService, this._mainThreadTelemetryProxy); + this._almostReadyToRunExtensions.open(); + + await this._extHostWorkspace.waitForInitializeCall(); + this._readyToRunExtensions.open(); + } catch (err) { + errors.onUnexpectedError(err); + } + } + + public async deactivateAll(): Promise { + let allPromises: Promise[] = []; + try { + const allExtensions = this._registry.getAllExtensionDescriptions(); + const allExtensionsIds = allExtensions.map(ext => ext.identifier); + const activatedExtensions = allExtensionsIds.filter(id => this.isActivated(id)); + + allPromises = activatedExtensions.map((extensionId) => { + return this._deactivate(extensionId); + }); + } catch (err) { + // TODO: write to log once we have one + } + await allPromises; + } + + public isActivated(extensionId: ExtensionIdentifier): boolean { + if (this._readyToRunExtensions.isOpen()) { + return this._activator.isActivated(extensionId); + } + return false; + } + + private _activateByEvent(activationEvent: string, startup: boolean): Promise { + const reason = new ExtensionActivatedByEvent(startup, activationEvent); + return this._activator.activateByEvent(activationEvent, reason); + } + + private _activateById(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise { + return this._activator.activateById(extensionId, reason); + } + + public activateByIdWithErrors(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise { + return this._activateById(extensionId, reason).then(() => { + const extension = this._activator.getActivatedExtension(extensionId); + if (extension.activationFailed) { + // activation failed => bubble up the error as the promise result + return Promise.reject(extension.activationFailedError); + } + return undefined; + }); + } + + public getExtensionRegistry(): Promise { + return this._readyToRunExtensions.wait().then(_ => this._registry); + } + + public getExtensionExports(extensionId: ExtensionIdentifier): IExtensionAPI | null | undefined { + if (this._readyToRunExtensions.isOpen()) { + return this._activator.getActivatedExtension(extensionId).exports; + } else { + return null; + } + } + + // create trie to enable fast 'filename -> extension id' look up + public getExtensionPathIndex(): Promise> { + if (!this._extensionPathIndex) { + const tree = TernarySearchTree.forPaths(); + const extensions = this._registry.getAllExtensionDescriptions().map(ext => { + if (!ext.main) { + return undefined; + } + return this._hostUtils.realpath(ext.extensionLocation.fsPath).then(value => tree.set(URI.file(value).fsPath, ext)); + }); + this._extensionPathIndex = Promise.all(extensions).then(() => tree); + } + return this._extensionPathIndex; + } + + private _deactivate(extensionId: ExtensionIdentifier): Promise { + let result = Promise.resolve(undefined); + + if (!this._readyToRunExtensions.isOpen()) { + return result; + } + + if (!this._activator.isActivated(extensionId)) { + return result; + } + + const extension = this._activator.getActivatedExtension(extensionId); + if (!extension) { + return result; + } + + // call deactivate if available + try { + if (typeof extension.module.deactivate === 'function') { + result = Promise.resolve(extension.module.deactivate()).then(undefined, (err) => { + // TODO: Do something with err if this is not the shutdown case + return Promise.resolve(undefined); + }); + } + } catch (err) { + // TODO: Do something with err if this is not the shutdown case + } + + // clean up subscriptions + try { + dispose(extension.subscriptions); + } catch (err) { + // TODO: Do something with err if this is not the shutdown case + } + + return result; + } + + // --- impl + + private _activateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): Promise { + this._mainThreadExtensionsProxy.$onWillActivateExtension(extensionDescription.identifier); + return this._doActivateExtension(extensionDescription, reason).then((activatedExtension) => { + const activationTimes = activatedExtension.activationTimes; + const activationEvent = (reason instanceof ExtensionActivatedByEvent ? reason.activationEvent : null); + this._mainThreadExtensionsProxy.$onDidActivateExtension(extensionDescription.identifier, activationTimes.startup, activationTimes.codeLoadingTime, activationTimes.activateCallTime, activationTimes.activateResolvedTime, activationEvent); + this._logExtensionActivationTimes(extensionDescription, reason, 'success', activationTimes); + return activatedExtension; + }, (err) => { + this._logExtensionActivationTimes(extensionDescription, reason, 'failure'); + throw err; + }); + } + + private _logExtensionActivationTimes(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason, outcome: string, activationTimes?: ExtensionActivationTimes) { + const event = getTelemetryActivationEvent(extensionDescription, reason); + /* __GDPR__ + "extensionActivationTimes" : { + "${include}": [ + "${TelemetryActivationEvent}", + "${ExtensionActivationTimes}" + ], + "outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + } + */ + this._mainThreadTelemetryProxy.$publicLog('extensionActivationTimes', { + ...event, + ...(activationTimes || {}), + outcome, + }); + } + + private _doActivateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): Promise { + const event = getTelemetryActivationEvent(extensionDescription, reason); + /* __GDPR__ + "activatePlugin" : { + "${include}": [ + "${TelemetryActivationEvent}" + ] + } + */ + this._mainThreadTelemetryProxy.$publicLog('activatePlugin', event); + if (!extensionDescription.main) { + // Treat the extension as being empty => NOT AN ERROR CASE + return Promise.resolve(new EmptyExtension(ExtensionActivationTimes.NONE)); + } + + this._extHostLogService.info(`ExtensionService#_doActivateExtension ${extensionDescription.identifier.value} ${JSON.stringify(reason)}`); + + const activationTimesBuilder = new ExtensionActivationTimesBuilder(reason.startup); + return Promise.all([ + loadCommonJSModule(this._extHostLogService, extensionDescription.main, activationTimesBuilder), + this._loadExtensionContext(extensionDescription) + ]).then(values => { + return ExtHostExtensionService._callActivate(this._extHostLogService, extensionDescription.identifier, values[0], values[1], activationTimesBuilder); + }); + } + + private _loadExtensionContext(extensionDescription: IExtensionDescription): Promise { + + const globalState = new ExtensionMemento(extensionDescription.identifier.value, true, this._storage); + const workspaceState = new ExtensionMemento(extensionDescription.identifier.value, false, this._storage); + + this._extHostLogService.trace(`ExtensionService#loadExtensionContext ${extensionDescription.identifier.value}`); + return Promise.all([ + globalState.whenReady, + workspaceState.whenReady, + // this._storagePath.whenReady + ]).then(() => { + const that = this; + return Object.freeze({ + globalState, + workspaceState, + subscriptions: [], + get extensionPath() { return extensionDescription.extensionLocation.fsPath; }, + get storagePath(): string { throw new Error('not implemented'); }, // this._storagePath.workspaceValue(extensionDescription), + get globalStoragePath(): string { throw new Error('not implemented'); }, // this._storagePath.globalValue(extensionDescription), + asAbsolutePath: (relativePath: string) => { return path.join(extensionDescription.extensionLocation.fsPath, relativePath); }, + logPath: that._extHostLogService.getLogDirectory(extensionDescription.identifier) + }); + }); + } + + private static _callActivate(logService: ILogService, extensionId: ExtensionIdentifier, extensionModule: IExtensionModule, context: IExtensionContext, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { + // Make sure the extension's surface is not undefined + extensionModule = extensionModule || { + activate: undefined, + deactivate: undefined + }; + + return this._callActivateOptional(logService, extensionId, extensionModule, context, activationTimesBuilder).then((extensionExports) => { + return new ActivatedExtension(false, null, activationTimesBuilder.build(), extensionModule, extensionExports, context.subscriptions); + }); + } + + private static _callActivateOptional(logService: ILogService, extensionId: ExtensionIdentifier, extensionModule: IExtensionModule, context: IExtensionContext, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { + if (typeof extensionModule.activate === 'function') { + try { + activationTimesBuilder.activateCallStart(); + logService.trace(`ExtensionService#_callActivateOptional ${extensionId.value}`); + const activateResult: Promise = extensionModule.activate.apply(global, [context]); + activationTimesBuilder.activateCallStop(); + + activationTimesBuilder.activateResolveStart(); + return Promise.resolve(activateResult).then((value) => { + activationTimesBuilder.activateResolveStop(); + return value; + }); + } catch (err) { + return Promise.reject(err); + } + } else { + // No activate found => the module is the extension's exports + return Promise.resolve(extensionModule); + } + } + + // -- eager activation + + // Handle "eager" activation extensions + private _handleEagerExtensions(): Promise { + this._activateByEvent('*', true).then(undefined, (err) => { + console.error(err); + }); + + return this._handleWorkspaceContainsEagerExtensions(this._extHostWorkspace.workspace); + } + + private _handleWorkspaceContainsEagerExtensions(workspace: IWorkspace | undefined): Promise { + if (!workspace || workspace.folders.length === 0) { + return Promise.resolve(undefined); + } + + return Promise.all( + this._registry.getAllExtensionDescriptions().map((desc) => { + return this._handleWorkspaceContainsEagerExtension(workspace, desc); + }) + ).then(() => { }); + } + + private _handleWorkspaceContainsEagerExtension(workspace: IWorkspace, desc: IExtensionDescription): Promise { + const activationEvents = desc.activationEvents; + if (!activationEvents) { + return Promise.resolve(undefined); + } + + const fileNames: string[] = []; + const globPatterns: string[] = []; + + for (const activationEvent of activationEvents) { + if (/^workspaceContains:/.test(activationEvent)) { + const fileNameOrGlob = activationEvent.substr('workspaceContains:'.length); + if (fileNameOrGlob.indexOf('*') >= 0 || fileNameOrGlob.indexOf('?') >= 0) { + globPatterns.push(fileNameOrGlob); + } else { + fileNames.push(fileNameOrGlob); + } + } + } + + if (fileNames.length === 0 && globPatterns.length === 0) { + return Promise.resolve(undefined); + } + + const fileNamePromise = Promise.all(fileNames.map((fileName) => this._activateIfFileName(workspace, desc.identifier, fileName))).then(() => { }); + const globPatternPromise = this._activateIfGlobPatterns(desc.identifier, globPatterns); + + return Promise.all([fileNamePromise, globPatternPromise]).then(() => { }); + } + + private async _activateIfFileName(workspace: IWorkspace, extensionId: ExtensionIdentifier, fileName: string): Promise { + + // find exact path + for (const { uri } of workspace.folders) { + if (await this._hostUtils.exists(path.join(URI.revive(uri).fsPath, fileName))) { + // the file was found + return ( + this._activateById(extensionId, new ExtensionActivatedByEvent(true, `workspaceContains:${fileName}`)) + .then(undefined, err => console.error(err)) + ); + } + } + + return undefined; + } + + private async _activateIfGlobPatterns(extensionId: ExtensionIdentifier, globPatterns: string[]): Promise { + this._extHostLogService.trace(`extensionHostMain#activateIfGlobPatterns: fileSearch, extension: ${extensionId.value}, entryPoint: workspaceContains`); + + if (globPatterns.length === 0) { + return Promise.resolve(undefined); + } + + const tokenSource = new CancellationTokenSource(); + const searchP = this._mainThreadWorkspaceProxy.$checkExists(globPatterns, tokenSource.token); + + const timer = setTimeout(async () => { + tokenSource.cancel(); + this._activateById(extensionId, new ExtensionActivatedByEvent(true, `workspaceContainsTimeout:${globPatterns.join(',')}`)) + .then(undefined, err => console.error(err)); + }, ExtHostExtensionService.WORKSPACE_CONTAINS_TIMEOUT); + + let exists: boolean = false; + try { + exists = await searchP; + } catch (err) { + if (!errors.isPromiseCanceledError(err)) { + console.error(err); + } + } + + tokenSource.dispose(); + clearTimeout(timer); + + if (exists) { + // a file was found matching one of the glob patterns + return ( + this._activateById(extensionId, new ExtensionActivatedByEvent(true, `workspaceContains:${globPatterns.join(',')}`)) + .then(undefined, err => console.error(err)) + ); + } + + return Promise.resolve(undefined); + } + + private _handleExtensionTests(): Promise { + return this._doHandleExtensionTests().then(undefined, error => { + console.error(error); // ensure any error message makes it onto the console + + return Promise.reject(error); + }); + } + + private _doHandleExtensionTests(): Promise { + const { extensionDevelopmentLocationURI: extensionDevelopmentLocationURI, extensionTestsLocationURI } = this._initData.environment; + if (!(extensionDevelopmentLocationURI && extensionTestsLocationURI && extensionTestsLocationURI.scheme === Schemas.file)) { + return Promise.resolve(undefined); + } + + const extensionTestsPath = originalFSPath(extensionTestsLocationURI); + + // Require the test runner via node require from the provided path + let testRunner: ITestRunner | undefined; + let requireError: Error | undefined; + try { + testRunner = require.__$__nodeRequire(extensionTestsPath); + } catch (error) { + requireError = error; + } + + // Execute the runner if it follows our spec + if (testRunner && typeof testRunner.run === 'function') { + return new Promise((c, e) => { + testRunner!.run(extensionTestsPath, (error, failures) => { + if (error) { + e(error.toString()); + } else { + c(undefined); + } + + // after tests have run, we shutdown the host + this._gracefulExit(error || (typeof failures === 'number' && failures > 0) ? 1 /* ERROR */ : 0 /* OK */); + }); + }); + } + + // Otherwise make sure to shutdown anyway even in case of an error + else { + this._gracefulExit(1 /* ERROR */); + } + + return Promise.reject(new Error(requireError ? requireError.toString() : nls.localize('extensionTestError', "Path {0} does not point to a valid extension test runner.", extensionTestsPath))); + } + + private _gracefulExit(code: number): void { + // to give the PH process a chance to flush any outstanding console + // messages to the main process, we delay the exit() by some time + setTimeout(() => { + // If extension tests are running, give the exit code to the renderer + if (this._initData.remoteAuthority && !!this._initData.environment.extensionTestsLocationURI) { + this._mainThreadExtensionsProxy.$onExtensionHostExit(code); + return; + } + + this._hostUtils.exit(code); + }, 500); + } + + private _startExtensionHost(): Promise { + if (this._started) { + throw new Error(`Extension host is already started!`); + } + this._started = true; + + return this._readyToRunExtensions.wait() + .then(() => this._handleEagerExtensions()) + .then(() => this._handleExtensionTests()) + .then(() => { + this._extHostLogService.info(`eager extensions activated`); + }); + } + + // -- called by extensions + + public registerRemoteAuthorityResolver(authorityPrefix: string, resolver: vscode.RemoteAuthorityResolver): vscode.Disposable { + this._resolvers[authorityPrefix] = resolver; + return toDisposable(() => { + delete this._resolvers[authorityPrefix]; + }); + } + + // -- called by main thread + + public async $resolveAuthority(remoteAuthority: string): Promise { + const authorityPlusIndex = remoteAuthority.indexOf('+'); + if (authorityPlusIndex === -1) { + throw new Error(`Not an authority that can be resolved!`); + } + const authorityPrefix = remoteAuthority.substr(0, authorityPlusIndex); + + await this._almostReadyToRunExtensions.wait(); + await this._activateByEvent(`onResolveRemoteAuthority:${authorityPrefix}`, false); + + const resolver = this._resolvers[authorityPrefix]; + if (!resolver) { + throw new Error(`No resolver available for ${authorityPrefix}`); + } + + const result = await resolver.resolve(remoteAuthority); + return { + authority: remoteAuthority, + host: result.host, + port: result.port, + }; + } + + public $startExtensionHost(enabledExtensionIds: ExtensionIdentifier[]): Promise { + this._registry.keepOnly(enabledExtensionIds); + return this._startExtensionHost(); + } + + public $activateByEvent(activationEvent: string): Promise { + return ( + this._readyToRunExtensions.wait() + .then(_ => this._activateByEvent(activationEvent, false)) + ); + } + + public async $activate(extensionId: ExtensionIdentifier, activationEvent: string): Promise { + await this._readyToRunExtensions.wait(); + if (!this._registry.getExtensionDescription(extensionId)) { + // unknown extension => ignore + return false; + } + await this._activateById(extensionId, new ExtensionActivatedByEvent(false, activationEvent)); + return true; + } + + public async $deltaExtensions(toAdd: IExtensionDescription[], toRemove: ExtensionIdentifier[]): Promise { + toAdd.forEach((extension) => (extension).extensionLocation = URI.revive(extension.extensionLocation)); + + const trie = await this.getExtensionPathIndex(); + + await Promise.all(toRemove.map(async (extensionId) => { + const extensionDescription = this._registry.getExtensionDescription(extensionId); + if (!extensionDescription) { + return; + } + const realpathValue = await this._hostUtils.realpath(extensionDescription.extensionLocation.fsPath); + trie.delete(URI.file(realpathValue).fsPath); + })); + + await Promise.all(toAdd.map(async (extensionDescription) => { + const realpathValue = await this._hostUtils.realpath(extensionDescription.extensionLocation.fsPath); + trie.set(URI.file(realpathValue).fsPath, extensionDescription); + })); + + this._registry.deltaExtensions(toAdd, toRemove); + return Promise.resolve(undefined); + } + + public async $test_latency(n: number): Promise { + return n; + } + + public async $test_up(b: VSBuffer): Promise { + return b.byteLength; + } + + public async $test_down(size: number): Promise { + return VSBuffer.wrap(Buffer.alloc(size, Math.random() % 256)); + } + +} + +function loadCommonJSModule(logService: ILogService, modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { + // let r: T | null = null; + // activationTimesBuilder.codeLoadingStart(); + // logService.info(`ExtensionService#loadCommonJSModule ${modulePath}`); + // try { + // r = require.__$__nodeRequire(modulePath); + // } catch (e) { + // return Promise.reject(e); + // } finally { + // activationTimesBuilder.codeLoadingStop(); + // } + // return Promise.resolve(r); + return Promise.reject('cannot'); +} + +function getTelemetryActivationEvent(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): any { + const reasonStr = reason instanceof ExtensionActivatedByEvent ? reason.activationEvent : + reason instanceof ExtensionActivatedByAPI ? 'api' : + ''; + + /* __GDPR__FRAGMENT__ + "TelemetryActivationEvent" : { + "id": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" }, + "name": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" }, + "extensionVersion": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" }, + "publisherDisplayName": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "activationEvents": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "isBuiltin": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "reason": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + } + */ + const event = { + id: extensionDescription.identifier.value, + name: extensionDescription.name, + extensionVersion: extensionDescription.version, + publisherDisplayName: extensionDescription.publisher, + activationEvents: extensionDescription.activationEvents ? extensionDescription.activationEvents.join(',') : null, + isBuiltin: extensionDescription.isBuiltin, + reason: reasonStr + }; + + return event; +} diff --git a/src/vs/workbench/services/extensions/worker/extensionHostMain.ts b/src/vs/workbench/services/extensions/worker/extensionHostMain.ts new file mode 100644 index 00000000000..935d6d458f4 --- /dev/null +++ b/src/vs/workbench/services/extensions/worker/extensionHostMain.ts @@ -0,0 +1,163 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { timeout } from 'vs/base/common/async'; +import * as errors from 'vs/base/common/errors'; +import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { Counter } from 'vs/base/common/numbers'; +import { URI, setUriThrowOnMissingScheme } from 'vs/base/common/uri'; +import { IURITransformer } from 'vs/base/common/uriIpc'; +import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; +import { IInitData, MainContext, MainThreadConsoleShape } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; +import { ExtHostExtensionService, IHostUtils } from './extHostExtensionService'; +import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; +import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; +import { RPCProtocol } from 'vs/workbench/services/extensions/common/rpcProtocol'; +import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { withNullAsUndefined } from 'vs/base/common/types'; +import { ILogService } from 'vs/platform/log/common/log'; +import { ISchemeTransformer } from 'vs/workbench/api/common/extHostLanguageFeatures'; + +// we don't (yet) throw when extensions parse +// uris that have no scheme +setUriThrowOnMissingScheme(false); + +export interface IExitFn { + (code?: number): any; +} + +export interface IConsolePatchFn { + (mainThreadConsole: MainThreadConsoleShape): any; +} + +export interface ILogServiceFn { + (initData: IInitData): ILogService; +} + +export class ExtensionHostMain { + + private _isTerminating: boolean; + private readonly _hostUtils: IHostUtils; + private readonly _extensionService: ExtHostExtensionService; + private readonly _extHostLogService: ExtHostLogService; + private disposables: IDisposable[] = []; + + private _searchRequestIdProvider: Counter; + + constructor( + protocol: IMessagePassingProtocol, + initData: IInitData, + hostUtils: IHostUtils, + consolePatchFn: IConsolePatchFn, + logServiceFn: ILogServiceFn, + uriTransformer: IURITransformer | null, + schemeTransformer: ISchemeTransformer | null, + outputChannelName: string, + ) { + this._isTerminating = false; + this._hostUtils = hostUtils; + const rpcProtocol = new RPCProtocol(protocol, null, uriTransformer); + + // ensure URIs are transformed and revived + initData = this.transform(initData, rpcProtocol); + + // allow to patch console + consolePatchFn(rpcProtocol.getProxy(MainContext.MainThreadConsole)); + + // services + this._extHostLogService = new ExtHostLogService(logServiceFn(initData), initData.logsLocation.fsPath); + this.disposables.push(this._extHostLogService); + + this._searchRequestIdProvider = new Counter(); + const extHostWorkspace = new ExtHostWorkspace(rpcProtocol, this._extHostLogService, this._searchRequestIdProvider, withNullAsUndefined(initData.workspace)); + + this._extHostLogService.info('extension host started'); + this._extHostLogService.trace('initData', initData); + + const extHostConfiguraiton = new ExtHostConfiguration(rpcProtocol.getProxy(MainContext.MainThreadConfiguration), extHostWorkspace); + this._extensionService = new ExtHostExtensionService( + hostUtils, + initData, + rpcProtocol, + extHostWorkspace, + extHostConfiguraiton, + initData.environment, + this._extHostLogService, + schemeTransformer, + outputChannelName + ); + + // error forwarding and stack trace scanning + Error.stackTraceLimit = 100; // increase number of stack frames (from 10, https://github.com/v8/v8/wiki/Stack-Trace-API) + const extensionErrors = new WeakMap(); + this._extensionService.getExtensionPathIndex().then(map => { + (Error).prepareStackTrace = (error: Error, stackTrace: errors.V8CallSite[]) => { + let stackTraceMessage = ''; + let extension: IExtensionDescription | undefined; + let fileName: string; + for (const call of stackTrace) { + stackTraceMessage += `\n\tat ${call.toString()}`; + fileName = call.getFileName(); + if (!extension && fileName) { + extension = map.findSubstr(fileName); + } + + } + extensionErrors.set(error, extension); + return `${error.name || 'Error'}: ${error.message || ''}${stackTraceMessage}`; + }; + }); + + const mainThreadExtensions = rpcProtocol.getProxy(MainContext.MainThreadExtensionService); + const mainThreadErrors = rpcProtocol.getProxy(MainContext.MainThreadErrors); + errors.setUnexpectedErrorHandler(err => { + const data = errors.transformErrorForSerialization(err); + const extension = extensionErrors.get(err); + if (extension) { + mainThreadExtensions.$onExtensionRuntimeError(extension.identifier, data); + } else { + mainThreadErrors.$onUnexpectedError(data); + } + }); + } + + terminate(): void { + if (this._isTerminating) { + // we are already shutting down... + return; + } + this._isTerminating = true; + + this.disposables = dispose(this.disposables); + + errors.setUnexpectedErrorHandler((err) => { + // TODO: write to log once we have one + }); + + const extensionsDeactivated = this._extensionService.deactivateAll(); + + // Give extensions 1 second to wrap up any async dispose, then exit in at most 4 seconds + setTimeout(() => { + Promise.race([timeout(4000), extensionsDeactivated]).finally(() => this._hostUtils.exit()); + }, 1000); + } + + private transform(initData: IInitData, rpcProtocol: RPCProtocol): IInitData { + initData.extensions.forEach((ext) => (ext).extensionLocation = URI.revive(rpcProtocol.transformIncomingURIs(ext.extensionLocation))); + initData.environment.appRoot = URI.revive(rpcProtocol.transformIncomingURIs(initData.environment.appRoot)); + initData.environment.appSettingsHome = URI.revive(rpcProtocol.transformIncomingURIs(initData.environment.appSettingsHome)); + const extDevLocs = initData.environment.extensionDevelopmentLocationURI; + if (extDevLocs) { + initData.environment.extensionDevelopmentLocationURI = extDevLocs.map(url => URI.revive(rpcProtocol.transformIncomingURIs(url))); + } + initData.environment.extensionTestsLocationURI = URI.revive(rpcProtocol.transformIncomingURIs(initData.environment.extensionTestsLocationURI)); + initData.environment.globalStorageHome = URI.revive(rpcProtocol.transformIncomingURIs(initData.environment.globalStorageHome)); + initData.environment.userHome = URI.revive(rpcProtocol.transformIncomingURIs(initData.environment.userHome)); + initData.logsLocation = URI.revive(rpcProtocol.transformIncomingURIs(initData.logsLocation)); + initData.workspace = rpcProtocol.transformIncomingURIs(initData.workspace); + return initData; + } +} diff --git a/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts b/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts index 0e6081d7b21..60f61307c3f 100644 --- a/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts +++ b/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts @@ -7,9 +7,11 @@ import { IRequestHandler } from 'vs/base/common/worker/simpleWorker'; import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; import { VSBuffer } from 'vs/base/common/buffer'; import { Emitter } from 'vs/base/common/event'; -import { IExitFn } from 'vs/workbench/services/extensions/node/extensionHostMain'; import { isMessageOfType, MessageType, createMessageOfType } from 'vs/workbench/services/extensions/common/extensionHostProtocol'; import { IInitData } from 'vs/workbench/api/common/extHost.protocol'; +import { IHostUtils } from 'vs/workbench/services/extensions/worker/extHostExtensionService'; +import { ExtensionHostMain } from 'vs/workbench/services/extensions/worker/extensionHostMain'; +import { ConsoleLogService } from 'vs/platform/log/common/log'; // worker-self declare namespace self { @@ -17,9 +19,21 @@ declare namespace self { } // do not allow extensions to call terminate -const nativeTerminate: IExitFn = self.close.bind(self); +const nativeClose = self.close.bind(self); self.close = () => console.trace('An extension called terminate and this was prevented'); -let onTerminate = nativeTerminate; +let onTerminate = nativeClose; + +const hostUtil = new class implements IHostUtils { + exit(code?: number | undefined): void { + nativeClose(); + } + async exists(path: string): Promise { + return true; + } + async realpath(path: string): Promise { + return path; + } +}; //todo@joh do not allow extensions to call postMessage and other globals... @@ -87,11 +101,24 @@ export function create(postMessage: (message: any, transfer?: Transferable[]) => const res = new ExtensionWorker(postMessage); connectToRenderer(res.protocol).then(data => { - console.log('INIT_DATA', data.initData); + // console.log('INIT_DATA', data.initData); - data.protocol.onMessage(msg => { - // console.log('SOME MSG', msg.toString()); - }); + // data.protocol.onMessage(msg => { + // // console.log('SOME MSG', msg.toString()); + // }); + + const extHostMain = new ExtensionHostMain( + data.protocol, + data.initData, + hostUtil, + () => { }, + () => new ConsoleLogService(), + null, + null, + 'Extension Host - WebWorker' + ); + + onTerminate = () => extHostMain.terminate(); }); return res; diff --git a/tslint.json b/tslint.json index b18e616921c..91d6bfa8f61 100644 --- a/tslint.json +++ b/tslint.json @@ -431,6 +431,19 @@ "**/vs/workbench/services/**/common/**" ] }, + { + "target": "**/vs/workbench/services/**/worker/**", + "restrictions": [ + "vs/nls", + "**/vs/base/**/common/**", + "**/vs/platform/**/common/**", + "**/vs/editor/common/**", + "**/vs/workbench/**/common/**", + "**/vs/workbench/**/worker/**", + "**/vs/workbench/services/**/common/**", + "vscode" + ] + }, { "target": "**/vs/workbench/services/**/browser/**", "restrictions": [ From a30c25f359fcf3e8f22da22f827fa681008b5028 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 11 Apr 2019 13:04:08 +0200 Subject: [PATCH 040/861] less Buffer --- src/vs/workbench/api/node/extHostExtensionService.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 643dc4899f4..c9f18be439b 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -672,7 +672,12 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { } public async $test_down(size: number): Promise { - return VSBuffer.wrap(Buffer.alloc(size, Math.random() % 256)); + let buff = VSBuffer.alloc(size); + let value = Math.random() % 256; + for (let i = 0; i < size; i++) { + buff.writeUint8(value, i); + } + return buff; } } From 0f4b4fd8efa0bb879ba74589e3d450e8b8663dd7 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 11 Apr 2019 14:24:22 +0200 Subject: [PATCH 041/861] use VSBuffer, not Buffer --- .../services/extensions/worker/extHostExtensionService.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts b/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts index 082edbd5aa2..6d6424b416e 100644 --- a/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts +++ b/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts @@ -671,7 +671,12 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { } public async $test_down(size: number): Promise { - return VSBuffer.wrap(Buffer.alloc(size, Math.random() % 256)); + let buff = VSBuffer.alloc(size); + let value = Math.random() % 256; + for (let i = 0; i < size; i++) { + buff.writeUint8(value, i); + } + return buff; } } From 79624ed7d20459de27aa296f932291fc352c1307 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 11 Apr 2019 16:11:49 +0200 Subject: [PATCH 042/861] hardcode sample to load and run --- .../electron-browser/extensionService.ts | 4 +-- .../webWorkerExtensionHostStarter.ts | 2 +- .../extensions/worker/extHost.api.impl.ts | 2 +- .../worker/extHostExtensionService.ts | 28 +++++++++---------- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index 42136f9e2c9..181983db132 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -440,14 +440,14 @@ export class ExtensionService extends Disposable implements IExtensionService { extensions = this.getExtensions(); } { - const extHostProcessWorker = this._instantiationService.createInstance(ExtensionHostProcessWorker, autoStart, extensions, this._extensionHostLogsLocation); + const extHostProcessWorker = this._instantiationService.createInstance(ExtensionHostProcessWorker, autoStart, extensions.then(value => value.filter(desc => !ExtensionIdentifier.equals(desc.identifier, 'jrieken.helloworld'))), this._extensionHostLogsLocation); const extHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, extHostProcessWorker, null, initialActivationEvents); extHostProcessManager.onDidCrash(([code, signal]) => this._onExtensionHostCrashed(code, signal)); extHostProcessManager.onDidChangeResponsiveState((responsiveState) => { this._onDidChangeResponsiveChange.fire({ target: extHostProcessManager, isResponsive: responsiveState === ResponsiveState.Responsive }); }); this._extensionHostProcessManagers.push(extHostProcessManager); } { - const extHostWebWorkerWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, /* autoStart, */ extensions, this._extensionHostLogsLocation); + const extHostWebWorkerWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, /* autoStart, */ extensions.then(value => value.filter(desc => ExtensionIdentifier.equals(desc.identifier, 'jrieken.helloworld'))), this._extensionHostLogsLocation); const extHostWebWorkerManager = this._instantiationService.createInstance(ExtensionHostProcessManager, extHostWebWorkerWorker, null, initialActivationEvents); extHostWebWorkerManager.onDidCrash(([code, signal]) => this._onExtensionHostCrashed(code, signal)); extHostWebWorkerManager.onDidChangeResponsiveState((responsiveState) => { this._onDidChangeResponsiveChange.fire({ target: extHostWebWorkerManager, isResponsive: responsiveState === ResponsiveState.Responsive }); }); diff --git a/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts b/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts index b8bec5612c8..96c40033e28 100644 --- a/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts +++ b/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts @@ -137,7 +137,7 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { }, resolvedExtensions: [], hostExtensions: [], - extensions: [], // < todo@joh extensionDescriptions, + extensions: extensionDescriptions, telemetryInfo, logLevel: this._logService.getLevel(), logsLocation: this._extensionHostLogsLocation, diff --git a/src/vs/workbench/services/extensions/worker/extHost.api.impl.ts b/src/vs/workbench/services/extensions/worker/extHost.api.impl.ts index 50c5ed11a0d..2080787d01c 100644 --- a/src/vs/workbench/services/extensions/worker/extHost.api.impl.ts +++ b/src/vs/workbench/services/extensions/worker/extHost.api.impl.ts @@ -156,7 +156,7 @@ export function createApiFactory( const extHostLanguages = new ExtHostLanguages(rpcProtocol, extHostDocuments); // Register an output channel for exthost log - extHostOutputService.createOutputChannelFromLogFile(outputChannelName, extHostLogService.logFile); + // extHostOutputService.createOutputChannelFromLogFile(outputChannelName, extHostLogService.logFile); // < todo@joh // Register API-ish commands ExtHostApiCommands.register(extHostCommands); diff --git a/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts b/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts index 6d6424b416e..b93711499c4 100644 --- a/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts +++ b/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts @@ -19,7 +19,7 @@ import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionA import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; -import { ExtensionActivationError } from 'vs/workbench/services/extensions/common/extensions'; +import { ExtensionActivationError, nullExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; import * as errors from 'vs/base/common/errors'; @@ -147,6 +147,11 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { } private async _initialize(): Promise { + + // globally define the vscode module and share that + // for all extensions + define('vscode', this._extensionApiFactory(nullExtensionDescription, this._registry, await this._extHostConfiguration.getConfigProvider())); + try { // const configProvider = await this._extHostConfiguration.getConfigProvider(); // const extensionPaths = await this.getExtensionPathIndex(); @@ -381,7 +386,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { try { activationTimesBuilder.activateCallStart(); logService.trace(`ExtensionService#_callActivateOptional ${extensionId.value}`); - const activateResult: Promise = extensionModule.activate.apply(global, [context]); + const activateResult: Promise = extensionModule.activate.apply(undefined, [context]); activationTimesBuilder.activateCallStop(); activationTimesBuilder.activateResolveStart(); @@ -681,19 +686,12 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { } -function loadCommonJSModule(logService: ILogService, modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { - // let r: T | null = null; - // activationTimesBuilder.codeLoadingStart(); - // logService.info(`ExtensionService#loadCommonJSModule ${modulePath}`); - // try { - // r = require.__$__nodeRequire(modulePath); - // } catch (e) { - // return Promise.reject(e); - // } finally { - // activationTimesBuilder.codeLoadingStop(); - // } - // return Promise.resolve(r); - return Promise.reject('cannot'); +async function loadCommonJSModule(logService: ILogService, modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { + + const exports = Object.create(null); + self['exports'] = exports; + importScripts(modulePath); + return exports; } function getTelemetryActivationEvent(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): any { From e11f4fa777621af44333532472e61b752d71d9f8 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 11 Apr 2019 16:48:54 +0200 Subject: [PATCH 043/861] more tweaks --- .../electron-browser/extensionService.ts | 8 +++++-- .../worker/extHostExtensionService.ts | 24 +++++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index 181983db132..9744ed4ddb9 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -439,15 +439,19 @@ export class ExtensionService extends Disposable implements IExtensionService { autoStart = true; extensions = this.getExtensions(); } + + const workerExtension = new Set(); + workerExtension.add(ExtensionIdentifier.toKey('jrieken.helloworld')); + { - const extHostProcessWorker = this._instantiationService.createInstance(ExtensionHostProcessWorker, autoStart, extensions.then(value => value.filter(desc => !ExtensionIdentifier.equals(desc.identifier, 'jrieken.helloworld'))), this._extensionHostLogsLocation); + const extHostProcessWorker = this._instantiationService.createInstance(ExtensionHostProcessWorker, autoStart, extensions.then(value => value.filter(desc => !workerExtension.has(desc.identifier.value))), this._extensionHostLogsLocation); const extHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, extHostProcessWorker, null, initialActivationEvents); extHostProcessManager.onDidCrash(([code, signal]) => this._onExtensionHostCrashed(code, signal)); extHostProcessManager.onDidChangeResponsiveState((responsiveState) => { this._onDidChangeResponsiveChange.fire({ target: extHostProcessManager, isResponsive: responsiveState === ResponsiveState.Responsive }); }); this._extensionHostProcessManagers.push(extHostProcessManager); } { - const extHostWebWorkerWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, /* autoStart, */ extensions.then(value => value.filter(desc => ExtensionIdentifier.equals(desc.identifier, 'jrieken.helloworld'))), this._extensionHostLogsLocation); + const extHostWebWorkerWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, /* autoStart, */ extensions.then(value => value.filter(desc => workerExtension.has(desc.identifier.value))), this._extensionHostLogsLocation); const extHostWebWorkerManager = this._instantiationService.createInstance(ExtensionHostProcessManager, extHostWebWorkerWorker, null, initialActivationEvents); extHostWebWorkerManager.onDidCrash(([code, signal]) => this._onExtensionHostCrashed(code, signal)); extHostWebWorkerManager.onDidChangeResponsiveState((responsiveState) => { this._onDidChangeResponsiveChange.fire({ target: extHostWebWorkerManager, isResponsive: responsiveState === ResponsiveState.Responsive }); }); diff --git a/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts b/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts index b93711499c4..15ae9d65804 100644 --- a/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts +++ b/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts @@ -32,6 +32,7 @@ import { Schemas } from 'vs/base/common/network'; import { VSBuffer } from 'vs/base/common/buffer'; import { ISchemeTransformer } from 'vs/workbench/api/common/extHostLanguageFeatures'; import { ExtensionMemento } from 'vs/workbench/api/common/extHostMemento'; +import { endsWith } from 'vs/base/common/strings'; // import { ExtensionStoragePaths } from 'vs/workbench/api/node/extHostStoragePaths'; interface ITestRunner { @@ -688,10 +689,25 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { async function loadCommonJSModule(logService: ILogService, modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { - const exports = Object.create(null); - self['exports'] = exports; - importScripts(modulePath); - return exports; + // fake commonjs world + const module = { exports: {} }; + self['module'] = module; + self['exports'] = module.exports; + + // that's improper but might help extensions that aren't author correctly + // @ts-ignore + self['window'] = self; + + // import the single (!) script, make sure it's a JS-file + const suffix = '.js'; + if (endsWith(modulePath, suffix)) { + importScripts(modulePath); + } else { + importScripts(modulePath + suffix); + } + + // return what it exported + return module.exports as T; } function getTelemetryActivationEvent(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): any { From a9a03796e7dab3a0a7566bcc36d34f1a434cb5f7 Mon Sep 17 00:00:00 2001 From: Jon Bockhorst Date: Thu, 11 Apr 2019 18:50:34 -0500 Subject: [PATCH 044/861] Use native scrollbar in SCM commit message box --- src/vs/base/browser/ui/inputbox/inputBox.ts | 23 ++++++++++++ .../contrib/scm/browser/scmViewlet.ts | 37 +++++++++++++++++-- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/src/vs/base/browser/ui/inputbox/inputBox.ts b/src/vs/base/browser/ui/inputbox/inputBox.ts index 16f00512cb3..84d38377688 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.ts +++ b/src/vs/base/browser/ui/inputbox/inputBox.ts @@ -95,6 +95,7 @@ export class InputBox extends Widget { private validation?: IInputValidator; private state: string | null = 'idle'; private cachedHeight: number | null; + private cachedScrollTop: number | null; private inputBackground?: Color; private inputForeground?: Color; @@ -116,6 +117,9 @@ export class InputBox extends Widget { private _onDidHeightChange = this._register(new Emitter()); public readonly onDidHeightChange: Event = this._onDidHeightChange.event; + private _onDidScrollTopChange = this._register(new Emitter()); + public readonly onDidScrollTopChange: Event = this._onDidScrollTopChange.event; + constructor(container: HTMLElement, contextViewProvider: IContextViewProvider | undefined, options?: IInputOptions) { super(); @@ -177,6 +181,7 @@ export class InputBox extends Widget { this.oninput(this.input, () => this.onValueChange()); this.onblur(this.input, () => this.onBlur()); this.onfocus(this.input, () => this.onFocus()); + this.onkeydown(this.input, () => this.checkScrollTop()); // Add placeholder shim for IE because IE decides to hide the placeholder on focus (we dont want that!) if (this.placeholder && Bal.isIE) { @@ -211,6 +216,14 @@ export class InputBox extends Widget { this._showMessage(); } + private checkScrollTop(): void { + const scrollTop = this.element.scrollTop; + if (scrollTop !== this.cachedScrollTop) { + this.cachedScrollTop = scrollTop; + this._onDidScrollTopChange.fire(this.cachedScrollTop); + } + } + public setPlaceHolder(placeHolder: string): void { if (this.input) { this.input.setAttribute('placeholder', placeHolder); @@ -301,6 +314,10 @@ export class InputBox extends Widget { } } + public get scrollTop(): number { + return this.cachedScrollTop === null ? this.element.scrollTop : this.cachedScrollTop; + } + public showMessage(message: IMessage, force?: boolean): void { this.message = message; @@ -511,6 +528,12 @@ export class InputBox extends Widget { if (previousHeight !== this.cachedHeight) { this.input.style.height = this.cachedHeight + 'px'; this._onDidHeightChange.fire(this.cachedHeight); + + if (previousHeight) { + const scrollTop = this.cachedHeight - previousHeight + this.scrollTop; + this.cachedScrollTop = scrollTop; + this._onDidScrollTopChange.fire(this.cachedScrollTop); + } } } diff --git a/src/vs/workbench/contrib/scm/browser/scmViewlet.ts b/src/vs/workbench/contrib/scm/browser/scmViewlet.ts index 7553f2ebec8..0233387e288 100644 --- a/src/vs/workbench/contrib/scm/browser/scmViewlet.ts +++ b/src/vs/workbench/contrib/scm/browser/scmViewlet.ts @@ -49,6 +49,8 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IViewsRegistry, IViewDescriptor, Extensions } from 'vs/workbench/common/views'; import { Registry } from 'vs/platform/registry/common/platform'; +import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; +import { ScrollbarVisibility } from 'vs/base/common/scrollable'; export interface ISpliceEvent { index: number; @@ -701,6 +703,7 @@ export class RepositoryPanel extends ViewletPanel { private cachedWidth: number | undefined = undefined; private inputBoxContainer: HTMLElement; private inputBox: InputBox; + private scrollableElement: ScrollableElement; private listContainer: HTMLElement; private list: List; private listLabels: ResourceLabels; @@ -794,6 +797,31 @@ export class RepositoryPanel extends ViewletPanel { this.inputBox.onDidChange(triggerValidation, null, this.disposables); + this.scrollableElement = new ScrollableElement(this.inputBox.element, { + vertical: ScrollbarVisibility.Visible + }); + + this.disposables.push(this.scrollableElement); + + this.scrollableElement.onScroll((e) => { + this.scrollInput(e.scrollTop); + }); + + append(this.inputBoxContainer, this.scrollableElement.getDomNode()); + + const updateScrollDimensions = () => { + const scrollHeight = this.inputBox.height; + const height = scrollHeight > 134 ? 134 : scrollHeight; + const scrollTop = this.inputBox.scrollTop; + + this.scrollableElement.setScrollDimensions({ scrollHeight: scrollHeight, height: height }); + this.scrollableElement.setScrollPosition({ scrollTop: scrollTop }); + }; + + this.inputBox.element.style.maxHeight = '134px'; + this.inputBox.onDidHeightChange(updateScrollDimensions, null, this.disposables); + this.inputBox.onDidScrollTopChange(updateScrollDimensions, null, this.disposables); + const onKeyUp = domEvent(this.inputBox.inputElement, 'keyup'); const onMouseUp = domEvent(this.inputBox.inputElement, 'mouseup'); Event.any(onKeyUp, onMouseUp)(triggerValidation, null, this.disposables); @@ -861,6 +889,10 @@ export class RepositoryPanel extends ViewletPanel { this.onDidChangeBodyVisibility(visible => this.inputBox.setEnabled(visible)); } + private scrollInput(scrollTop: number): void { + this.inputBox.element.scrollTop = scrollTop; + } + private onDidChangeVisibility(visible: boolean): void { if (visible) { const listSplicer = new ResourceGroupSplicer(this.repository.provider.groups, this.list); @@ -881,15 +913,12 @@ export class RepositoryPanel extends ViewletPanel { removeClass(this.inputBoxContainer, 'hidden'); this.inputBox.layout(); - const editorHeight = this.inputBox.height; + const editorHeight = this.inputBox.height > 134 ? 134 : this.inputBox.height; const listHeight = height - (editorHeight + 12 /* margin */); this.listContainer.style.height = `${listHeight}px`; this.list.layout(listHeight, width); - - toggleClass(this.inputBoxContainer, 'scroll', editorHeight >= 134); } else { addClass(this.inputBoxContainer, 'hidden'); - removeClass(this.inputBoxContainer, 'scroll'); this.listContainer.style.height = `${height}px`; this.list.layout(height, width); From 37f1fd63caa4a64c1d63428cc50679cbf5d0c10f Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 12 Apr 2019 12:19:31 +0200 Subject: [PATCH 045/861] remove unused file --- .../extensions/common/extensionHostStarter.ts | 14 -------------- .../webWorkerExtensionHostStarter.ts | 2 +- 2 files changed, 1 insertion(+), 15 deletions(-) delete mode 100644 src/vs/workbench/services/extensions/common/extensionHostStarter.ts diff --git a/src/vs/workbench/services/extensions/common/extensionHostStarter.ts b/src/vs/workbench/services/extensions/common/extensionHostStarter.ts deleted file mode 100644 index 32551aaba2d..00000000000 --- a/src/vs/workbench/services/extensions/common/extensionHostStarter.ts +++ /dev/null @@ -1,14 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Event } from 'vs/base/common/event'; -import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; - -export interface IExtensionHostStarter { - readonly onCrashed: Event<[number, string | null]>; - start(): Promise | null; - getInspectPort(): number | undefined; - dispose(): void; -} diff --git a/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts b/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts index 96c40033e28..de6f3caf590 100644 --- a/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts +++ b/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts @@ -11,7 +11,6 @@ import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; import { VSBuffer } from 'vs/base/common/buffer'; -import { IExtensionHostStarter } from 'vs/workbench/services/extensions/common/extensionHostStarter'; import { createMessageOfType, MessageType, isMessageOfType } from 'vs/workbench/services/extensions/common/extensionHostProtocol'; import { IInitData } from 'vs/workbench/api/common/extHost.protocol'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; @@ -24,6 +23,7 @@ import * as platform from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; import product from 'vs/platform/product/node/product'; import pkg from 'vs/platform/product/node/package'; +import { IExtensionHostStarter } from 'vs/workbench/services/extensions/common/extensions'; export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { From 7f4de09bf473d12bf3fe094711f359f01b0ce482 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 12 Apr 2019 16:00:18 +0200 Subject: [PATCH 046/861] fix merge issue --- .../services/extensions/electron-browser/extensionService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index 319fe22f0fb..84cc23831bf 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -445,7 +445,7 @@ export class ExtensionService extends Disposable implements IExtensionService { workerExtension.add(ExtensionIdentifier.toKey('jrieken.helloworld')); { - const extHostProcessWorker = this._instantiationService.createInstance(ExtensionHostProcessWorker, autoStart, extensions, this._extensionHostLogsLocation); + const extHostProcessWorker = this._instantiationService.createInstance(ExtensionHostProcessWorker, autoStart, extensions.then(value => value.filter(desc => !workerExtension.has(desc.identifier.value))), this._extensionHostLogsLocation); const extHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, extHostProcessWorker, null, initialActivationEvents); extHostProcessManager.onDidCrash(([code, signal]) => this._onExtensionHostCrashed(code, signal)); extHostProcessManager.onDidChangeResponsiveState((responsiveState) => { this._onDidChangeResponsiveChange.fire({ isResponsive: responsiveState === ResponsiveState.Responsive }); }); From d3ff59bf19194bda0c174dde732400a69311ea6b Mon Sep 17 00:00:00 2001 From: marmik Date: Sun, 21 Apr 2019 20:39:06 -0400 Subject: [PATCH 047/861] Disallow making commits that contain only contain whitespace to be consistent across other methods of committing to git through VS Code --- extensions/git/src/commands.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index f6e00e9abdd..71afa4941de 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1286,7 +1286,7 @@ export class CommandCenter { const message = await getCommitMessage(); - if (!message) { + if (!message || /^\s+$/.test(message)) { return false; } From 5afda64c84ead373e045f6bb1457de9f23d48330 Mon Sep 17 00:00:00 2001 From: marmik Date: Sun, 21 Apr 2019 23:19:49 -0400 Subject: [PATCH 048/861] Remove part of the regex matching expression for git commits, because previous it would think commits with empty messages were invalid when infact they are not --- extensions/git/src/git.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 3132b8cdf86..0e47d8a129c 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -584,7 +584,8 @@ export function parseGitmodules(raw: string): Submodule[] { } export function parseGitCommit(raw: string): Commit | null { - const match = /^([0-9a-f]{40})\n(.*)\n(.*)\n([^]*)$/m.exec(raw.trim()); + const match = /^([0-9a-f]{40})\n(.*)\n(.*)$/m.exec(raw.trim()); + if (!match) { return null; } From 6829b21359329ec4eb639dae9727f8686107092f Mon Sep 17 00:00:00 2001 From: marmik Date: Mon, 22 Apr 2019 19:31:55 -0400 Subject: [PATCH 049/861] Revert earlier commit that disables creating a commit with just whitespace, since this is not part of the original issue --- extensions/git/src/commands.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 71afa4941de..f6e00e9abdd 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1286,7 +1286,7 @@ export class CommandCenter { const message = await getCommitMessage(); - if (!message || /^\s+$/.test(message)) { + if (!message) { return false; } From c894647e175acae11ed4afe9d76c4bb5b34d7587 Mon Sep 17 00:00:00 2001 From: Russell Kennington Date: Sat, 11 May 2019 17:01:29 -0600 Subject: [PATCH 050/861] Fix #72587 suggestWidget no scroll on first open If the first time the suggestWidget was opened (ctrl+space) its content vertically overflowed, it would not scroll. This commit fixes suggestWidget so that it scrolls tall content even on first use. The maxHeight must be set before scanDomNode checks clientHeight. --- src/vs/editor/contrib/suggest/suggestWidget.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/suggest/suggestWidget.ts b/src/vs/editor/contrib/suggest/suggestWidget.ts index 054feaf901f..03d1327caf5 100644 --- a/src/vs/editor/contrib/suggest/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/suggestWidget.ts @@ -965,8 +965,10 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate Date: Wed, 29 May 2019 06:35:02 -0400 Subject: [PATCH 051/861] Git clone fix to use character set in regex --- extensions/git/src/git.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index ed3e432b773..f827cf8e432 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -339,6 +339,7 @@ export class Git { async clone(url: string, parentPath: string, cancellationToken?: CancellationToken): Promise { let baseFolderName = path.win32.basename(decodeURI(url), '.git') || 'repository'; + //baseFolderName = decodeURI(url).replace(/^.*[\/\\]/, '').replace(/\.git$/, '') || 'repository'; let folderName = baseFolderName; let folderPath = path.join(parentPath, folderName); let count = 1; From 0bf7825bc2de398b6423dac1a37765484e3197c4 Mon Sep 17 00:00:00 2001 From: Darrien Singleton Date: Wed, 29 May 2019 06:36:34 -0400 Subject: [PATCH 052/861] Revert "Git clone fix to use character set in regex" This reverts commit fdb1c37b06fc46dc759eb983a5133e7fb5a1666f. --- extensions/git/src/git.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index f827cf8e432..ed3e432b773 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -339,7 +339,6 @@ export class Git { async clone(url: string, parentPath: string, cancellationToken?: CancellationToken): Promise { let baseFolderName = path.win32.basename(decodeURI(url), '.git') || 'repository'; - //baseFolderName = decodeURI(url).replace(/^.*[\/\\]/, '').replace(/\.git$/, '') || 'repository'; let folderName = baseFolderName; let folderPath = path.join(parentPath, folderName); let count = 1; From 69158eb58bc791b981fa0a2b38ebb6140c35b52a Mon Sep 17 00:00:00 2001 From: Darrien Singleton Date: Wed, 29 May 2019 06:39:12 -0400 Subject: [PATCH 053/861] Git clone fix to use character set in regex --- extensions/git/src/git.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index ed3e432b773..08001470f33 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -338,7 +338,7 @@ export class Git { } async clone(url: string, parentPath: string, cancellationToken?: CancellationToken): Promise { - let baseFolderName = path.win32.basename(decodeURI(url), '.git') || 'repository'; + let baseFolderName = decodeURI(url).replace(/^.*[\/\\]/, '').replace(/\.git$/, '') || 'repository'; let folderName = baseFolderName; let folderPath = path.join(parentPath, folderName); let count = 1; From 7ef2209d13db572e3d3d0fb082ebe44ea6f37002 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 31 May 2019 15:17:26 +0200 Subject: [PATCH 054/861] adopt product service --- .../webWorkerExtensionHostStarter.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts b/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts index 8319c967813..a7d616c257c 100644 --- a/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts +++ b/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts @@ -21,9 +21,8 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import * as platform from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; -import product from 'vs/platform/product/node/product'; -import pkg from 'vs/platform/product/node/package'; import { IExtensionHostStarter } from 'vs/workbench/services/extensions/common/extensions'; +import { IProductService } from 'vs/platform/product/common/product'; export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { @@ -43,6 +42,7 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { @ILabelService private readonly _labelService: ILabelService, @ILogService private readonly _logService: ILogService, @IEnvironmentService private readonly _environmentService: IEnvironmentService, + @IProductService private readonly _productService: IProductService, ) { } @@ -115,15 +115,15 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { .then(([telemetryInfo, extensionDescriptions]) => { const workspace = this._contextService.getWorkspace(); const r: IInitData = { - commit: product.commit, - version: pkg.version, + commit: this._productService.commit, + version: this._productService.version, parentPid: process.pid, environment: { isExtensionDevelopmentDebug: false, // < todo@joh appRoot: this._environmentService.appRoot ? URI.file(this._environmentService.appRoot) : undefined, appSettingsHome: this._environmentService.appSettingsHome ? URI.file(this._environmentService.appSettingsHome) : undefined, - appName: product.nameLong, - appUriScheme: product.urlProtocol, + appName: this._productService.nameLong, + appUriScheme: this._productService.urlProtocol, appLanguage: platform.language, extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI, extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI, From cce1c18f9a1999a6c89d2525450cc88eeacec394 Mon Sep 17 00:00:00 2001 From: Micah Smith Date: Mon, 10 Jun 2019 16:12:09 -0400 Subject: [PATCH 055/861] Fix #72640 --- extensions/git/src/commands.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 336c45589ea..fbd0da16882 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -695,7 +695,13 @@ export class CommandCenter { viewColumn: ViewColumn.Active }; - const document = await workspace.openTextDocument(uri); + let document; + try { + document = await workspace.openTextDocument(uri); + } catch (error) { + await commands.executeCommand('vscode.open', uri, opts); + continue; + } // Check if active text editor has same path as other editor. we cannot compare via // URI.toString() here because the schemas can be different. Instead we just go by path. From b5b05bc105f59bed2d6cc6eda2a11c91c6203417 Mon Sep 17 00:00:00 2001 From: matthew Date: Tue, 11 Jun 2019 23:38:36 -0700 Subject: [PATCH 056/861] modifier instead of control keys --- src/vs/workbench/electron-browser/actions/developerActions.ts | 2 +- src/vs/workbench/electron-browser/main.contribution.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/electron-browser/actions/developerActions.ts b/src/vs/workbench/electron-browser/actions/developerActions.ts index 6ed0c95f8ab..5ad255d6432 100644 --- a/src/vs/workbench/electron-browser/actions/developerActions.ts +++ b/src/vs/workbench/electron-browser/actions/developerActions.ts @@ -196,7 +196,7 @@ export class ToggleScreencastModeAction extends Action { const label = keybinding.getLabel(); if (!event.ctrlKey && !event.altKey && !event.metaKey && !event.shiftKey && this.keybindingService.mightProducePrintableCharacter(event) && label) { - if (!this.configurationService.getValue('screencastMode.onlyControlKeys')) { + if (!this.configurationService.getValue('screencastMode.onlyModifierKeys')) { keyboardMarker.textContent += ' ' + label; keyboardMarker.style.display = 'block'; } diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 04038399f66..b7dca7ba280 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -699,9 +699,9 @@ import { LogStorageAction } from 'vs/platform/storage/node/storageService'; 'title': nls.localize('screencastModeConfigurationTitle', "Screencast Mode"), 'type': 'object', 'properties': { - 'screencastMode.onlyControlKeys': { + 'screencastMode.onlyModifierKeys': { 'type': 'boolean', - 'description': nls.localize('screencastMode.onlyControlKeys', "Only show control keys in Screencast Mode."), + 'description': nls.localize('screencastMode.onlyModifierKeys', "Only show character sequences with modifier keys in Screencast Mode."), 'default': false } } From c41ad1841419d7b3447b93b1b334ce93d9c0fa9d Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 12 Jun 2019 14:37:12 -0700 Subject: [PATCH 057/861] Puppeteer exploration --- package.json | 1 + test/smoke/package.json | 4 +- test/smoke/src/application.ts | 8 +- .../smoke/src/areas/terminal/terminal.test.ts | 3 +- test/smoke/src/main.ts | 16 +- test/smoke/src/vscode/code.ts | 78 +++---- test/smoke/src/vscode/puppeteer-driver.d.ts | 56 +++++ test/smoke/src/vscode/puppeteer-driver.js | 202 ++++++++++++++++++ yarn.lock | 47 +++- 9 files changed, 359 insertions(+), 56 deletions(-) create mode 100644 test/smoke/src/vscode/puppeteer-driver.d.ts create mode 100644 test/smoke/src/vscode/puppeteer-driver.js diff --git a/package.json b/package.json index 299f9cd814d..268ae97ee1f 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "native-watchdog": "1.0.0", "node-pty": "0.9.0-beta17", "onigasm-umd": "^2.2.2", + "puppeteer": "^1.17.0", "semver": "^5.5.0", "spdlog": "^0.9.0", "sudo-prompt": "8.2.0", diff --git a/test/smoke/package.json b/test/smoke/package.json index e19de8f9de2..cf0ce7cde1f 100644 --- a/test/smoke/package.json +++ b/test/smoke/package.json @@ -6,8 +6,8 @@ "postinstall": "npm run compile", "compile": "npm run copy-driver && npm run copy-driver-definition && tsc", "watch": "concurrently \"npm run watch-driver\" \"npm run watch-driver-definition\" \"tsc --watch\"", - "copy-driver": "cpx src/vscode/driver.js out/vscode", - "watch-driver": "cpx src/vscode/driver.js out/vscode -w", + "copy-driver": "cpx src/vscode/puppeteer-driver.js out/vscode", + "watch-driver": "cpx src/vscode/puppeteer-driver.js out/vscode -w", "copy-driver-definition": "node tools/copy-driver-definition.js", "watch-driver-definition": "watch \"node tools/copy-driver-definition.js\" ../../src/vs/platform/driver/node", "mocha": "mocha" diff --git a/test/smoke/src/application.ts b/test/smoke/src/application.ts index 5d764176846..4f5b7aa2e85 100644 --- a/test/smoke/src/application.ts +++ b/test/smoke/src/application.ts @@ -137,11 +137,11 @@ export class Application { } await this.code.waitForWindowIds(ids => ids.length > 0); - await this.code.waitForElement('.monaco-workbench'); + // await this.code.waitForElement('.monaco-workbench'); - if (this.remote) { - await this.code.waitForElement('.monaco-workbench .statusbar-item.statusbar-entry a[title="Editing on TestResolver"]'); - } + // if (this.remote) { + // await this.code.waitForElement('.monaco-workbench .statusbar-item.statusbar-entry a[title="Editing on TestResolver"]'); + // } // wait a bit, since focus might be stolen off widgets // as soon as they open (e.g. quick open) diff --git a/test/smoke/src/areas/terminal/terminal.test.ts b/test/smoke/src/areas/terminal/terminal.test.ts index d661b13a2dc..8dc459faf63 100644 --- a/test/smoke/src/areas/terminal/terminal.test.ts +++ b/test/smoke/src/areas/terminal/terminal.test.ts @@ -6,8 +6,9 @@ import { Application } from '../../application'; export function setup() { - describe('Terminal', () => { + describe.only('Terminal', () => { it(`opens terminal, runs 'echo' and verifies the output`, async function () { + this.timeout(60 * 5000); const app = this.app as Application; const expected = new Date().getTime().toString(); diff --git a/test/smoke/src/main.ts b/test/smoke/src/main.ts index 21a0fe252a1..81e5caa8ed2 100644 --- a/test/smoke/src/main.ts +++ b/test/smoke/src/main.ts @@ -132,13 +132,13 @@ if (testCodePath) { process.env.VSCODE_CLI = '1'; } -if (!fs.existsSync(electronPath || '')) { - fail(`Can't find Code at ${electronPath}.`); -} - -if (typeof stablePath === 'string' && !fs.existsSync(stablePath)) { - fail(`Can't find Stable Code at ${stablePath}.`); -} +// if (!fs.existsSync(electronPath || '')) { +// fail(`Can't find Code at ${electronPath}.`); +// } +console.log(stablePath); +// if (typeof stablePath === 'string' && !fs.existsSync(stablePath)) { +// fail(`Can't find Stable Code at ${stablePath}.`); +// } const userDataDir = path.join(testDataPath, 'd'); @@ -234,7 +234,7 @@ setupDataMigrationTests(stableCodePath, testDataPath); describe('Running Code', () => { before(async function () { const app = new Application(this.defaultOptions); - await app!.start(); + await app!.start(false); this.app = app; }); diff --git a/test/smoke/src/vscode/code.ts b/test/smoke/src/vscode/code.ts index 0b9c739cb69..804b38a6c7e 100644 --- a/test/smoke/src/vscode/code.ts +++ b/test/smoke/src/vscode/code.ts @@ -9,44 +9,44 @@ import * as os from 'os'; import * as fs from 'fs'; import * as mkdirp from 'mkdirp'; import { tmpName } from 'tmp'; -import { IDriver, connect as connectDriver, IDisposable, IElement, Thenable } from './driver'; +import { IDriver, connect as connectDriver, IDisposable, IElement, Thenable } from './puppeteer-driver'; import { Logger } from '../logger'; import { ncp } from 'ncp'; const repoPath = path.join(__dirname, '../../../..'); -function getDevElectronPath(): string { - const buildPath = path.join(repoPath, '.build'); - const product = require(path.join(repoPath, 'product.json')); +// function getDevElectronPath(): string { +// const buildPath = path.join(repoPath, '.build'); +// const product = require(path.join(repoPath, 'product.json')); - switch (process.platform) { - case 'darwin': - return path.join(buildPath, 'electron', `${product.nameLong}.app`, 'Contents', 'MacOS', 'Electron'); - case 'linux': - return path.join(buildPath, 'electron', `${product.applicationName}`); - case 'win32': - return path.join(buildPath, 'electron', `${product.nameShort}.exe`); - default: - throw new Error('Unsupported platform.'); - } -} +// switch (process.platform) { +// case 'darwin': +// return path.join(buildPath, 'electron', `${product.nameLong}.app`, 'Contents', 'MacOS', 'Electron'); +// case 'linux': +// return path.join(buildPath, 'electron', `${product.applicationName}`); +// case 'win32': +// return path.join(buildPath, 'electron', `${product.nameShort}.exe`); +// default: +// throw new Error('Unsupported platform.'); +// } +// } -function getBuildElectronPath(root: string): string { - switch (process.platform) { - case 'darwin': - return path.join(root, 'Contents', 'MacOS', 'Electron'); - case 'linux': { - const product = require(path.join(root, 'resources', 'app', 'product.json')); - return path.join(root, product.applicationName); - } - case 'win32': { - const product = require(path.join(root, 'resources', 'app', 'product.json')); - return path.join(root, `${product.nameShort}.exe`); - } - default: - throw new Error('Unsupported platform.'); - } -} +// function getBuildElectronPath(root: string): string { +// switch (process.platform) { +// case 'darwin': +// return path.join(root, 'Contents', 'MacOS', 'Electron'); +// case 'linux': { +// const product = require(path.join(root, 'resources', 'app', 'product.json')); +// return path.join(root, product.applicationName); +// } +// case 'win32': { +// const product = require(path.join(root, 'resources', 'app', 'product.json')); +// return path.join(root, `${product.nameShort}.exe`); +// } +// default: +// throw new Error('Unsupported platform.'); +// } +// } function getDevOutPath(): string { return path.join(repoPath, 'out'); @@ -61,7 +61,7 @@ function getBuildOutPath(root: string): string { } } -async function connect(child: cp.ChildProcess, outPath: string, handlePath: string, logger: Logger): Promise { +async function connect(child: cp.ChildProcess | undefined, outPath: string, handlePath: string, logger: Logger): Promise { let errCount = 0; while (true) { @@ -69,8 +69,9 @@ async function connect(child: cp.ChildProcess, outPath: string, handlePath: stri const { client, driver } = await connectDriver(outPath, handlePath); return new Code(client, driver, logger); } catch (err) { + console.log('err', err); if (++errCount > 50) { - child.kill(); + // child.kill(); throw err; } @@ -107,7 +108,7 @@ async function createDriverHandle(): Promise { export async function spawn(options: SpawnOptions): Promise { const codePath = options.codePath; - const electronPath = codePath ? getBuildElectronPath(codePath) : getDevElectronPath(); + // const electronPath = codePath ? getBuildElectronPath(codePath) : getDevElectronPath(); const outPath = codePath ? getBuildOutPath(codePath) : getDevOutPath(); const handle = await createDriverHandle(); @@ -163,13 +164,14 @@ export async function spawn(options: SpawnOptions): Promise { args.push(...options.extraArgs); } - const spawnOptions: cp.SpawnOptions = { env }; + // const spawnOptions: cp.SpawnOptions = { env }; - const child = cp.spawn(electronPath, args, spawnOptions); + // const child = cp.spawn(electronPath, args, spawnOptions); - instances.add(child); - child.once('exit', () => instances.delete(child)); + // instances.add(child); + // child.once('exit', () => instances.delete(child)); + const child = undefined; return connect(child, outPath, handle, options.logger); } diff --git a/test/smoke/src/vscode/puppeteer-driver.d.ts b/test/smoke/src/vscode/puppeteer-driver.d.ts new file mode 100644 index 00000000000..ee385f2b3f3 --- /dev/null +++ b/test/smoke/src/vscode/puppeteer-driver.d.ts @@ -0,0 +1,56 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +/** + * Thenable is a common denominator between ES6 promises, Q, jquery.Deferred, WinJS.Promise, + * and others. This API makes no assumption about what promise library is being used which + * enables reusing existing code without migrating to a specific promise implementation. Still, + * we recommend the use of native promises which are available in this editor. + */ +interface Thenable { + /** + * Attaches callbacks for the resolution and/or rejection of the Promise. + * @param onfulfilled The callback to execute when the Promise is resolved. + * @param onrejected The callback to execute when the Promise is rejected. + * @returns A Promise for the completion of which ever callback is executed. + */ + then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => TResult | Thenable): Thenable; + then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => void): Thenable; +} + +export interface IElement { + tagName: string; + className: string; + textContent: string; + attributes: { [name: string]: string; }; + children: IElement[]; + top: number; + left: number; +} + +export interface IDriver { + _serviceBrand: any; + + getWindowIds(): Promise; + capturePage(windowId: number): Promise; + reloadWindow(windowId: number): Promise; + exitApplication(): Promise; + dispatchKeybinding(windowId: number, keybinding: string): Promise; + click(windowId: number, selector: string, xoffset?: number | undefined, yoffset?: number | undefined): Promise; + doubleClick(windowId: number, selector: string): Promise; + setValue(windowId: number, selector: string, text: string): Promise; + getTitle(windowId: number): Promise; + isActiveElement(windowId: number, selector: string): Promise; + getElements(windowId: number, selector: string, recursive?: boolean): Promise; + typeInEditor(windowId: number, selector: string, text: string): Promise; + getTerminalBuffer(windowId: number, selector: string): Promise; + writeInTerminal(windowId: number, selector: string, text: string): Promise; +} + +export interface IDisposable { + dispose(): void; +} + +export function connect(outPath: string, handle: string): Promise<{ client: IDisposable, driver: IDriver }>; diff --git a/test/smoke/src/vscode/puppeteer-driver.js b/test/smoke/src/vscode/puppeteer-driver.js new file mode 100644 index 00000000000..78aebc45974 --- /dev/null +++ b/test/smoke/src/vscode/puppeteer-driver.js @@ -0,0 +1,202 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +const puppeteer = require('puppeteer'); + +// export function connect(outPath: string, handle: string): Promise<{ client: IDisposable, driver: IDriver }> + +const width = 800; +const height = 600; + +function buildDriver(browser, page) { + return { + _serviceBrand: undefined, + getWindowIds: () => { + return Promise.resolve([1]); + }, + capturePage: () => Promise.result(''), + reloadWindow: (windowId) => Promise.resolve(), + exitApplication: () => browser.close(), + dispatchKeybinding: async (windowId, keybinding) => { + console.log('ctrl+p'); + await page.keyboard.down('Control'); + await page.keyboard.press('p'); + await page.keyboard.up('Control'); + await page.waitForSelector('.jkasndknjadsf'); + }, + click: (windowId, selector, xoffset, yoffset) => Promise.resolve(), + doubleClick: (windowId, selector) => Promise.resolve(), + setValue: (windowId, selector, text) => Promise.resolve(), + getTitle: (windowId) => page.title(), + isActiveElement: (windowId, selector) => { + page.evaluate(`document.querySelector('${selector}') === document.activeElement`); + }, + getElements: async (windowId, selector, recursive) => { + return await page.evaluate(` + (function() { + function convertToPixels(element, value) { + return parseFloat(value) || 0; + } + function getDimension(element, cssPropertyName, jsPropertyName) { + let computedStyle = getComputedStyle(element); + let value = '0'; + if (computedStyle) { + if (computedStyle.getPropertyValue) { + value = computedStyle.getPropertyValue(cssPropertyName); + } else { + // IE8 + value = (computedStyle).getAttribute(jsPropertyName); + } + } + return convertToPixels(element, value); + } + function getBorderLeftWidth(element) { + return getDimension(element, 'border-left-width', 'borderLeftWidth'); + } + function getBorderRightWidth(element) { + return getDimension(element, 'border-right-width', 'borderRightWidth'); + } + function getBorderTopWidth(element) { + return getDimension(element, 'border-top-width', 'borderTopWidth'); + } + function getBorderBottomWidth(element) { + return getDimension(element, 'border-bottom-width', 'borderBottomWidth'); + } + function getTopLeftOffset(element) { + // Adapted from WinJS.Utilities.getPosition + // and added borders to the mix + + let offsetParent = element.offsetParent, top = element.offsetTop, left = element.offsetLeft; + + while ((element = element.parentNode) !== null && element !== document.body && element !== document.documentElement) { + top -= element.scrollTop; + let c = getComputedStyle(element); + if (c) { + left -= c.direction !== 'rtl' ? element.scrollLeft : -element.scrollLeft; + } + + if (element === offsetParent) { + left += getBorderLeftWidth(element); + top += getBorderTopWidth(element); + top += element.offsetTop; + left += element.offsetLeft; + offsetParent = element.offsetParent; + } + } + + return { + left: left, + top: top + }; + } + function serializeElement(element, recursive) { + const attributes = Object.create(null); + + for (let j = 0; j < element.attributes.length; j++) { + const attr = element.attributes.item(j); + if (attr) { + attributes[attr.name] = attr.value; + } + } + + const children = []; + + if (recursive) { + for (let i = 0; i < element.children.length; i++) { + const child = element.children.item(i); + if (child) { + children.push(serializeElement(child, true)); + } + } + } + + const { left, top } = getTopLeftOffset(element); + + return { + tagName: element.tagName, + className: element.className, + textContent: element.textContent || '', + attributes, + children, + left, + top + }; + } + + const query = document.querySelectorAll('${selector}'); + const result = []; + + for (let i = 0; i < query.length; i++) { + const element = query.item(i); + result.push(serializeElement(element, ${recursive})); + } + + return result; + })(); + `); + }, + typeInEditor: (windowId, selector, text) => Promise.resolve(), + getTerminalBuffer: async (windowId, selector) => { + return await page.evaluate(` + (function () { + const element = document.querySelector(selector); + + if (!element) { + throw new Error('Terminal not found: ${selector}''); + } + + const xterm: Terminal = element.xterm; + + if (!xterm) { + throw new Error('Xterm not found: ${selector}'); + } + + const lines: string[] = []; + + for (let i = 0; i < xterm.buffer.length; i++) { + lines.push(xterm.buffer.getLine(i).translateToString(true)); + } + + return lines; + })(); + `); + }, + writeInTerminal: async (windowId, selector, text) => { + page.evaluate(` + const element = document.querySelector(selector); + + if (!element) { + throw new Error('Element not found: ${selector}'); + } + + const xterm: Terminal = element.xterm; + + if (!xterm) { + throw new Error('Xterm not found: ${selector}'); + } + + xterm._core.handler(text); + `); + } + } +} + +exports.connect = function (outPath, handle) { + return new Promise(async (c) => { + const browser = await puppeteer.launch({ + headless: false, + slowMo: 80, + args: [`--window-size=${width},${height}`] + }); + const page = (await browser.pages())[0]; + await page.setViewport({ width, height }); + await page.goto('http://127.0.0.1:8000'); + const result = { + client: { dispose: () => {} }, + driver: buildDriver(browser, page) + } + c(result); + }); +}; diff --git a/yarn.lock b/yarn.lock index d2629586c09..0e22653e4dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1729,7 +1729,7 @@ concat-stream@1.6.0, concat-stream@^1.5.2: readable-stream "^2.2.2" typedarray "^0.0.6" -concat-stream@^1.5.0, concat-stream@^1.6.0: +concat-stream@1.6.2, concat-stream@^1.5.0, concat-stream@^1.6.0: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== @@ -2104,7 +2104,7 @@ debug@^3.2.6: dependencies: ms "^2.1.1" -debug@^4.0.1: +debug@^4.0.1, debug@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== @@ -3109,6 +3109,16 @@ extract-zip@^1.6.5: mkdirp "0.5.0" yauzl "2.4.1" +extract-zip@^1.6.6: + version "1.6.7" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.7.tgz#a840b4b8af6403264c8db57f4f1a74333ef81fe9" + integrity sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k= + dependencies: + concat-stream "1.6.2" + debug "2.6.9" + mkdirp "0.5.1" + yauzl "2.4.1" + extsprintf@1.3.0, extsprintf@^1.2.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" @@ -5772,6 +5782,11 @@ mime@^1.4.1, mime@^1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mime@^2.0.3: + version "2.4.4" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" + integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== + mimic-fn@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" @@ -7201,7 +7216,7 @@ progress@^1.1.8: resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" integrity sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74= -progress@^2.0.0: +progress@^2.0.0, progress@^2.0.1: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== @@ -7224,6 +7239,11 @@ proxy-addr@~2.0.2: forwarded "~0.1.2" ipaddr.js "1.5.2" +proxy-from-env@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" + integrity sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4= + prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" @@ -7298,6 +7318,20 @@ punycode@^2.1.0: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +puppeteer@^1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-1.17.0.tgz#371957d227a2f450fa74b78e78a2dadb2be7f14f" + integrity sha512-3EXZSximCzxuVKpIHtyec8Wm2dWZn1fc5tQi34qWfiUgubEVYHjUvr0GOJojqf3mifI6oyKnCdrGxaOI+lWReA== + dependencies: + debug "^4.1.0" + extract-zip "^1.6.6" + https-proxy-agent "^2.2.1" + mime "^2.0.3" + progress "^2.0.1" + proxy-from-env "^1.0.0" + rimraf "^2.6.1" + ws "^6.1.0" + q@^1.0.1, q@^1.1.2: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" @@ -9842,6 +9876,13 @@ ws@^3.3.3: safe-buffer "~5.1.0" ultron "~1.1.0" +ws@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== + dependencies: + async-limiter "~1.0.0" + xml-name-validator@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-1.0.0.tgz#dcf82ee092322951ef8cc1ba596c9cbfd14a83f1" From f0614b0e242b2b04af517d4926fa6b3d622b817a Mon Sep 17 00:00:00 2001 From: Patrick Burke Date: Tue, 11 Jun 2019 21:31:32 +0200 Subject: [PATCH 058/861] Show head label in placeholder of commit message --- extensions/git/src/repository.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 6018648f468..90a56a6a806 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -658,7 +658,19 @@ export class Repository implements Disposable { const root = Uri.file(repository.root); this._sourceControl = scm.createSourceControl('git', 'Git', root); - this._sourceControl.inputBox.placeholder = localize('commitMessage', "Message (press {0} to commit)"); + this.onDidRunGitStatus(() => { + const headLabel = this.headLabel; + let placeholder: string; + + if (headLabel !== '') { + // '{0}' will be replaced by the corresponding key-command later in the process, which is why it needs to stay. + placeholder = localize('commitMessageWithHeadLabel', "Message ({0} to commit to {1})", "{0}", this.headLabel); + } else { + placeholder = localize('commitMessage', "Message ({0} to commit)"); + } + + this._sourceControl.inputBox.placeholder = placeholder; + }); this._sourceControl.acceptInputCommand = { command: 'git.commitWithInput', title: localize('commit', "Commit"), arguments: [this._sourceControl] }; this._sourceControl.quickDiffProvider = this; this._sourceControl.inputBox.validateInput = this.validateInput.bind(this); From 328dd156db44fcf874ead77cd96fd302de9353b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4hn?= Date: Wed, 3 Jul 2019 00:43:23 +0200 Subject: [PATCH 059/861] Fix middle mouse button opening broken release notes link in browser --- src/vs/workbench/contrib/webview/browser/pre/main.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/webview/browser/pre/main.js b/src/vs/workbench/contrib/webview/browser/pre/main.js index 1dc234fe681..1708578ee9b 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/main.js +++ b/src/vs/workbench/contrib/webview/browser/pre/main.js @@ -188,6 +188,11 @@ return; } + // Prevent middle clicks opening a broken link in the browser + if (event.button == 1) { + event.preventDefault(); + } + let baseElement = event.view.document.getElementsByTagName('base')[0]; /** @type {any} */ let node = event.target; @@ -443,7 +448,7 @@ }); // Bubble out link clicks - newFrame.contentWindow.addEventListener('click', handleInnerClick); + newFrame.contentWindow.addEventListener('mousedown', handleInnerClick); if (host.onIframeLoaded) { host.onIframeLoaded(newFrame); From 756b305e395944374883455bf9d75b1b8f5690f7 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 10 Jul 2019 13:51:48 +0200 Subject: [PATCH 060/861] dialog box add aria-label fixes #70981 --- src/vs/base/browser/ui/dialog/dialog.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/base/browser/ui/dialog/dialog.ts b/src/vs/base/browser/ui/dialog/dialog.ts index 6dc7d9ee067..513233f4b28 100644 --- a/src/vs/base/browser/ui/dialog/dialog.ts +++ b/src/vs/base/browser/ui/dialog/dialog.ts @@ -189,6 +189,7 @@ export class Dialog extends Disposable { this.applyStyles(); + this.element.setAttribute('aria-label', this.message); show(this.element); // Focus first element From fc9bb947809b5a7fce5c79172d0d2154be4fb3e7 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 10 Jul 2019 14:34:11 +0200 Subject: [PATCH 061/861] do not auto assign to me while I am on vacation --- .github/classifier.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/classifier.yml b/.github/classifier.yml index 9581f82f716..330cc3d0aa1 100644 --- a/.github/classifier.yml +++ b/.github/classifier.yml @@ -63,7 +63,7 @@ assignLabel: false }, file-explorer: { - assignees: [ isidorn ], + assignees: [ ], assignLabel: false }, file-glob: [], From 7dd109c2dfdb8cc8b0748d4858da08403c4cc3f3 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Wed, 10 Jul 2019 15:49:06 -0700 Subject: [PATCH 062/861] feat(markdown): add render command (fixes #75612) This adds a command which renders the provided document, or the active editor if one is provided. Following the pattern of some of the preview commands, it returned `undefined` if there's no document provided and no active text editor. Otherwise, seems to work... ```ts const html = await vscode.commands.executeCommand('markdown.render'); ``` A way to render arbitrary strings in addition to documents may be useful at some point in the future. However, I didn't implement that here as that'd require some refactoring of the markdown engine. If we're interested though I could certainly give that a shot. --- .../markdown-language-features/package.json | 3 +- .../src/commands/index.ts | 1 + .../src/commands/renderDocument.ts | 30 +++++++++++++++++++ .../src/extension.ts | 1 + 4 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 extensions/markdown-language-features/src/commands/renderDocument.ts diff --git a/extensions/markdown-language-features/package.json b/extensions/markdown-language-features/package.json index 8e841a982aa..8a53e3fa331 100644 --- a/extensions/markdown-language-features/package.json +++ b/extensions/markdown-language-features/package.json @@ -24,6 +24,7 @@ "onCommand:markdown.showLockedPreviewToSide", "onCommand:markdown.showSource", "onCommand:markdown.showPreviewSecuritySelector", + "onCommand:markdown.render", "onWebviewPanel:markdown.preview" ], "contributes": { @@ -325,4 +326,4 @@ "webpack": "^4.1.0", "webpack-cli": "^2.0.10" } -} \ No newline at end of file +} diff --git a/extensions/markdown-language-features/src/commands/index.ts b/extensions/markdown-language-features/src/commands/index.ts index e8c9651ee0c..68aff7ffcf5 100644 --- a/extensions/markdown-language-features/src/commands/index.ts +++ b/extensions/markdown-language-features/src/commands/index.ts @@ -10,3 +10,4 @@ export { RefreshPreviewCommand } from './refreshPreview'; export { ShowPreviewSecuritySelectorCommand } from './showPreviewSecuritySelector'; export { MoveCursorToPositionCommand } from './moveCursorToPosition'; export { ToggleLockCommand } from './toggleLock'; +export { RenderDocument } from './renderDocument'; diff --git a/extensions/markdown-language-features/src/commands/renderDocument.ts b/extensions/markdown-language-features/src/commands/renderDocument.ts new file mode 100644 index 00000000000..f041c1c4adf --- /dev/null +++ b/extensions/markdown-language-features/src/commands/renderDocument.ts @@ -0,0 +1,30 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; + +import { Command } from '../commandManager'; +import { MarkdownEngine } from '../markdownEngine'; +import { SkinnyTextDocument } from '../tableOfContentsProvider'; + +export class RenderDocument implements Command { + public readonly id = 'markdown.render'; + + public constructor( + private readonly engine: MarkdownEngine + ) { } + + public async execute(document?: SkinnyTextDocument): Promise { + if (!document) { + if (!vscode.window.activeTextEditor) { + return; + } + + document = vscode.window.activeTextEditor.document; + } + + return this.engine.render(document); + } +} diff --git a/extensions/markdown-language-features/src/extension.ts b/extensions/markdown-language-features/src/extension.ts index 3fe2c9d4cd3..44e8873b16d 100644 --- a/extensions/markdown-language-features/src/extension.ts +++ b/extensions/markdown-language-features/src/extension.ts @@ -83,6 +83,7 @@ function registerMarkdownCommands( commandManager.register(new commands.ShowPreviewSecuritySelectorCommand(previewSecuritySelector, previewManager)); commandManager.register(new commands.OpenDocumentLinkCommand(engine)); commandManager.register(new commands.ToggleLockCommand(previewManager)); + commandManager.register(new commands.RenderDocument(engine)); return commandManager; } From b41712ecafdd570c997efec2661aabede3a73750 Mon Sep 17 00:00:00 2001 From: matthew Date: Wed, 10 Jul 2019 22:43:55 -0700 Subject: [PATCH 063/861] move to new file --- src/vs/workbench/browser/actions/developerActions.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/actions/developerActions.ts b/src/vs/workbench/browser/actions/developerActions.ts index 5fd57fadf7b..e04954eba02 100644 --- a/src/vs/workbench/browser/actions/developerActions.ts +++ b/src/vs/workbench/browser/actions/developerActions.ts @@ -11,6 +11,8 @@ import { domEvent } from 'vs/base/browser/event'; import { Event } from 'vs/base/common/event'; import { IDisposable, toDisposable, dispose, Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { getDomNodePagePosition, createStyleSheet, createCSSRule, append, $ } from 'vs/base/browser/dom'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { ConfigurationService } from 'vs/platform/configuration/node/configurationService'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { Context } from 'vs/platform/contextkey/browser/contextKeyService'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; @@ -96,7 +98,8 @@ export class ToggleScreencastModeAction extends Action { id: string, label: string, @IKeybindingService private readonly keybindingService: IKeybindingService, - @IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService + @IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService, + @IConfigurationService private readonly configurationService: ConfigurationService ) { super(id, label); } @@ -169,9 +172,13 @@ export class ToggleScreencastModeAction extends Action { const label = keybinding.getLabel(); if (!event.ctrlKey && !event.altKey && !event.metaKey && !event.shiftKey && this.keybindingService.mightProducePrintableCharacter(event) && label) { - keyboardMarker.textContent += ' ' + label; + if (!this.configurationService.getValue('screencastMode.onlyModifierKeys')) { + keyboardMarker.textContent += ' ' + label; + keyboardMarker.style.display = 'block'; + } } else { keyboardMarker.textContent = label; + keyboardMarker.style.display = 'block'; } keyboardMarker.style.display = 'block'; From 6ca238fcb6290bb2eea9cfc8167db4b1e5e4b475 Mon Sep 17 00:00:00 2001 From: matthew Date: Wed, 10 Jul 2019 23:28:02 -0700 Subject: [PATCH 064/861] only keyboard shortcuts --- .../browser/actions/developerActions.ts | 22 ++++++++++--------- .../electron-browser/main.contribution.ts | 4 ++-- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/browser/actions/developerActions.ts b/src/vs/workbench/browser/actions/developerActions.ts index e04954eba02..1903872e487 100644 --- a/src/vs/workbench/browser/actions/developerActions.ts +++ b/src/vs/workbench/browser/actions/developerActions.ts @@ -12,7 +12,6 @@ import { Event } from 'vs/base/common/event'; import { IDisposable, toDisposable, dispose, Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { getDomNodePagePosition, createStyleSheet, createCSSRule, append, $ } from 'vs/base/browser/dom'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { ConfigurationService } from 'vs/platform/configuration/node/configurationService'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { Context } from 'vs/platform/contextkey/browser/contextKeyService'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; @@ -99,7 +98,7 @@ export class ToggleScreencastModeAction extends Action { label: string, @IKeybindingService private readonly keybindingService: IKeybindingService, @IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService, - @IConfigurationService private readonly configurationService: ConfigurationService + @IConfigurationService private readonly configurationService: IConfigurationService ) { super(id, label); } @@ -168,21 +167,24 @@ export class ToggleScreencastModeAction extends Action { keyboardTimeout.dispose(); const event = new StandardKeyboardEvent(e); + const shortcut = this.keybindingService.softDispatch(event, event.target); + console.log(event.target); const keybinding = this.keybindingService.resolveKeyboardEvent(event); const label = keybinding.getLabel(); - if (!event.ctrlKey && !event.altKey && !event.metaKey && !event.shiftKey && this.keybindingService.mightProducePrintableCharacter(event) && label) { - if (!this.configurationService.getValue('screencastMode.onlyModifierKeys')) { - keyboardMarker.textContent += ' ' + label; - keyboardMarker.style.display = 'block'; - } - } else { + if (shortcut) { keyboardMarker.textContent = label; keyboardMarker.style.display = 'block'; + } else if (!this.configurationService.getValue('screencastMode.onlyKeyboardShortcuts')) { + if (this.keybindingService.mightProducePrintableCharacter(event) && label) { + keyboardMarker.textContent += ' ' + label; + keyboardMarker.style.display = 'block'; + } else if (!event.shiftKey) { + keyboardMarker.textContent = label; + keyboardMarker.style.display = 'block'; + } } - keyboardMarker.style.display = 'block'; - const promise = timeout(800); keyboardTimeout = toDisposable(() => promise.cancel()); diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 4c0b47b7e86..79a7309ca3f 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -540,9 +540,9 @@ import product from 'vs/platform/product/node/product'; 'title': nls.localize('screencastModeConfigurationTitle', "Screencast Mode"), 'type': 'object', 'properties': { - 'screencastMode.onlyModifierKeys': { + 'screencastMode.onlyKeyboardShortcuts': { 'type': 'boolean', - 'description': nls.localize('screencastMode.onlyModifierKeys', "Only show character sequences with modifier keys in Screencast Mode."), + 'description': nls.localize('screencastMode.onlyKeyboardShortcuts', "Only show keyboard shortcuts in Screencast Mode."), 'default': false } } From bb98a8a3cac225bdc78182112275d1b74ed698cf Mon Sep 17 00:00:00 2001 From: matthew Date: Thu, 11 Jul 2019 00:07:32 -0700 Subject: [PATCH 065/861] add support for chords --- src/vs/workbench/browser/actions/developerActions.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/actions/developerActions.ts b/src/vs/workbench/browser/actions/developerActions.ts index 1903872e487..9b5efecb624 100644 --- a/src/vs/workbench/browser/actions/developerActions.ts +++ b/src/vs/workbench/browser/actions/developerActions.ts @@ -163,18 +163,24 @@ export class ToggleScreencastModeAction extends Action { const onKeyDown = domEvent(container, 'keydown', true); let keyboardTimeout: IDisposable = Disposable.None; + let enterChord = false; + const keyboardListener = onKeyDown(e => { keyboardTimeout.dispose(); const event = new StandardKeyboardEvent(e); const shortcut = this.keybindingService.softDispatch(event, event.target); - console.log(event.target); const keybinding = this.keybindingService.resolveKeyboardEvent(event); const label = keybinding.getLabel(); if (shortcut) { - keyboardMarker.textContent = label; + if (enterChord) { + keyboardMarker.textContent += ' ' + label; + } else { + keyboardMarker.textContent = label; + } keyboardMarker.style.display = 'block'; + enterChord = shortcut.enterChord; } else if (!this.configurationService.getValue('screencastMode.onlyKeyboardShortcuts')) { if (this.keybindingService.mightProducePrintableCharacter(event) && label) { keyboardMarker.textContent += ' ' + label; @@ -183,6 +189,7 @@ export class ToggleScreencastModeAction extends Action { keyboardMarker.textContent = label; keyboardMarker.style.display = 'block'; } + enterChord = false; } const promise = timeout(800); From ac683ad110d8d23b019cf55b31936786e3886b46 Mon Sep 17 00:00:00 2001 From: Leonardo Rochael Almeida Date: Thu, 11 Jul 2019 15:32:08 +0200 Subject: [PATCH 066/861] Toggle for disabling autofocus on debugger stop Add boolean config to control whether the workbench window should be focused when the debugger stops. Fixes #23117 Co-authored-by: Joao Moreno --- src/vs/workbench/contrib/debug/browser/debug.contribution.ts | 5 +++++ src/vs/workbench/contrib/debug/browser/debugSession.ts | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts index 84afaa1d2f1..de7a22bad75 100644 --- a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts +++ b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts @@ -259,6 +259,11 @@ configurationRegistry.registerConfiguration({ description: nls.localize({ comment: ['This is the description for a setting'], key: 'launch' }, "Global debug launch configuration. Should be used as an alternative to 'launch.json' that is shared across workspaces."), default: { configurations: [], compounds: [] }, $ref: launchSchemaId + }, + 'debug.autoFocusEditor': { + type: 'boolean', + description: nls.localize('debug.autoFocusEditor', "Controls whether the workbench window should be focused when the debugger stops."), + default: true } } }); diff --git a/src/vs/workbench/contrib/debug/browser/debugSession.ts b/src/vs/workbench/contrib/debug/browser/debugSession.ts index ca53f26dbf5..2bea76a9b8e 100644 --- a/src/vs/workbench/contrib/debug/browser/debugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/debugSession.ts @@ -676,7 +676,10 @@ export class DebugSession implements IDebugSession { if (this.configurationService.getValue('debug').openDebug === 'openOnDebugBreak') { this.viewletService.openViewlet(VIEWLET_ID); } - this.windowService.focusWindow(); + + if (this.configurationService.getValue('debug.autoFocusEditor')) { + this.windowService.focusWindow(); + } } } }; From 3c42f56552ade4960c968705f424619ba05f2493 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Thu, 11 Jul 2019 11:24:28 -0700 Subject: [PATCH 067/861] fixup! render a string as well --- .../src/commands/renderDocument.ts | 2 +- .../src/markdownEngine.ts | 23 ++++++++----- .../src/test/engine.test.ts | 32 +++++++++++++++++++ 3 files changed, 48 insertions(+), 9 deletions(-) create mode 100644 extensions/markdown-language-features/src/test/engine.test.ts diff --git a/extensions/markdown-language-features/src/commands/renderDocument.ts b/extensions/markdown-language-features/src/commands/renderDocument.ts index f041c1c4adf..3d7a0bc29a0 100644 --- a/extensions/markdown-language-features/src/commands/renderDocument.ts +++ b/extensions/markdown-language-features/src/commands/renderDocument.ts @@ -16,7 +16,7 @@ export class RenderDocument implements Command { private readonly engine: MarkdownEngine ) { } - public async execute(document?: SkinnyTextDocument): Promise { + public async execute(document?: SkinnyTextDocument | string): Promise { if (!document) { if (!vscode.window.activeTextEditor) { return; diff --git a/extensions/markdown-language-features/src/markdownEngine.ts b/extensions/markdown-language-features/src/markdownEngine.ts index 0cc75bfe823..0a2286e35d6 100644 --- a/extensions/markdown-language-features/src/markdownEngine.ts +++ b/extensions/markdown-language-features/src/markdownEngine.ts @@ -118,7 +118,7 @@ export class MarkdownEngine { return md; } - private tokenize( + private tokenizeDocument( document: SkinnyTextDocument, config: MarkdownItConfig, engine: MarkdownIt @@ -131,16 +131,23 @@ export class MarkdownEngine { this.currentDocument = document.uri; this._slugCount = new Map(); - const text = document.getText(); - const tokens = engine.parse(text.replace(UNICODE_NEWLINE_REGEX, ''), {}); + const tokens = this.tokenizeString(document.getText(), engine); this._tokenCache.update(document, config, tokens); return tokens; } - public async render(document: SkinnyTextDocument): Promise { - const config = this.getConfig(document.uri); + private tokenizeString(text: string, engine: MarkdownIt) { + return engine.parse(text.replace(UNICODE_NEWLINE_REGEX, ''), {}); + } + + public async render(document: SkinnyTextDocument | string): Promise { + const config = this.getConfig(typeof document === 'string' ? undefined : document.uri); const engine = await this.getEngine(config); - return engine.renderer.render(this.tokenize(document, config, engine), { + const tokens = typeof document === 'string' + ? this.tokenizeString(document, engine) + : this.tokenizeDocument(document, config, engine); + + return engine.renderer.render(tokens, { ...(engine as any).options, ...config }, {}); @@ -149,14 +156,14 @@ export class MarkdownEngine { public async parse(document: SkinnyTextDocument): Promise { const config = this.getConfig(document.uri); const engine = await this.getEngine(config); - return this.tokenize(document, config, engine); + return this.tokenizeDocument(document, config, engine); } public cleanCache(): void { this._tokenCache.clean(); } - private getConfig(resource: vscode.Uri): MarkdownItConfig { + private getConfig(resource?: vscode.Uri): MarkdownItConfig { const config = vscode.workspace.getConfiguration('markdown', resource); return { breaks: config.get('preview.breaks', false), diff --git a/extensions/markdown-language-features/src/test/engine.test.ts b/extensions/markdown-language-features/src/test/engine.test.ts new file mode 100644 index 00000000000..3cd4f86693e --- /dev/null +++ b/extensions/markdown-language-features/src/test/engine.test.ts @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------------------------- + * 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 * as vscode from 'vscode'; +import 'mocha'; + +import { InMemoryDocument } from './inMemoryDocument'; +import { createNewMarkdownEngine } from './engine'; + +const testFileName = vscode.Uri.file('test.md'); + +suite('markdown.engine', () => { + suite('rendering', () => { + const input = '# hello\n\nworld!'; + const output = '

hello

\n' + + '

world!

\n'; + + test('Renders a document', async () => { + const doc = new InMemoryDocument(testFileName, input); + const engine = createNewMarkdownEngine(); + assert.strictEqual(await engine.render(doc), output); + }); + + test('Renders a string', async () => { + const engine = createNewMarkdownEngine(); + assert.strictEqual(await engine.render(input), output); + }); + }); +}); From 76641f06d34e9d5f06ecda5b91ff08140028ab7e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 12 Jul 2019 12:39:53 -0700 Subject: [PATCH 068/861] Get terminal smoke tests working under puppeteer --- src/typings/xterm.d.ts | 4 +- .../driver/electron-browser/driver.ts | 2 +- test/smoke/src/application.ts | 3 +- test/smoke/src/main.ts | 24 +-- test/smoke/src/vscode/puppeteer-driver.js | 196 +++++++++++++++--- 5 files changed, 184 insertions(+), 45 deletions(-) diff --git a/src/typings/xterm.d.ts b/src/typings/xterm.d.ts index b41d12219a9..47c626a2fe5 100644 --- a/src/typings/xterm.d.ts +++ b/src/typings/xterm.d.ts @@ -931,7 +931,9 @@ declare module 'xterm' { interface TerminalCore { debug: boolean; - handler(text: string): void; + _coreService: { + triggerDataEvent(text: string): void; + }; _onScroll: IEventEmitter; _onKey: IEventEmitter<{ key: string }>; diff --git a/src/vs/platform/driver/electron-browser/driver.ts b/src/vs/platform/driver/electron-browser/driver.ts index d6dc3f659bc..a956739bed7 100644 --- a/src/vs/platform/driver/electron-browser/driver.ts +++ b/src/vs/platform/driver/electron-browser/driver.ts @@ -206,7 +206,7 @@ class WindowDriver implements IWindowDriver { throw new Error(`Xterm not found: ${selector}`); } - xterm._core.handler(text); + xterm._core._coreService.triggerDataEvent(text); } async openDevTools(): Promise { diff --git a/test/smoke/src/application.ts b/test/smoke/src/application.ts index 40fc3097639..904cb7e8232 100644 --- a/test/smoke/src/application.ts +++ b/test/smoke/src/application.ts @@ -66,7 +66,8 @@ export class Application { async start(expectWalkthroughPart = true): Promise { await this._start(); - await this.code.waitForElement('.explorer-folders-view'); + // web doesn't show explorer? + // await this.code.waitForElement('.explorer-folders-view'); if (expectWalkthroughPart) { await this.code.waitForActiveElement(`.editor-instance[id="workbench.editor.walkThroughPart"] > div > div[tabIndex="0"]`); diff --git a/test/smoke/src/main.ts b/test/smoke/src/main.ts index 81e5caa8ed2..c0cf9f5d15b 100644 --- a/test/smoke/src/main.ts +++ b/test/smoke/src/main.ts @@ -263,19 +263,19 @@ describe('Running Code', () => { }); } - setupDataLossTests(); - setupDataExplorerTests(); - setupDataPreferencesTests(); - setupDataSearchTests(); - setupDataCSSTests(); - setupDataEditorTests(); - setupDataDebugTests(); - setupDataGitTests(); - setupDataStatusbarTests(); - setupDataExtensionTests(); + // setupDataLossTests(); + // setupDataExplorerTests(); + // setupDataPreferencesTests(); + // setupDataSearchTests(); + // setupDataCSSTests(); + // setupDataEditorTests(); + // setupDataDebugTests(); + // setupDataGitTests(); + // setupDataStatusbarTests(); + // setupDataExtensionTests(); setupTerminalTests(); - setupDataMultirootTests(); - setupDataLocalizationTests(); + // setupDataMultirootTests(); + // setupDataLocalizationTests(); }); setupLaunchTests(); \ No newline at end of file diff --git a/test/smoke/src/vscode/puppeteer-driver.js b/test/smoke/src/vscode/puppeteer-driver.js index 78aebc45974..80127b29b69 100644 --- a/test/smoke/src/vscode/puppeteer-driver.js +++ b/test/smoke/src/vscode/puppeteer-driver.js @@ -7,8 +7,14 @@ const puppeteer = require('puppeteer'); // export function connect(outPath: string, handle: string): Promise<{ client: IDisposable, driver: IDriver }> -const width = 800; -const height = 600; +const width = 1200; +const height = 800; + +const vscodeToPuppeteerKey = { + cmd: 'Meta', + ctrl: 'Control', + enter: 'Enter' +}; function buildDriver(browser, page) { return { @@ -20,21 +26,147 @@ function buildDriver(browser, page) { reloadWindow: (windowId) => Promise.resolve(), exitApplication: () => browser.close(), dispatchKeybinding: async (windowId, keybinding) => { - console.log('ctrl+p'); - await page.keyboard.down('Control'); - await page.keyboard.press('p'); - await page.keyboard.up('Control'); - await page.waitForSelector('.jkasndknjadsf'); + const keys = keybinding.split('+'); + const keysDown = []; + for (let i = 0; i < keys.length; i++) { + if (keys[i] in vscodeToPuppeteerKey) { + keys[i] = vscodeToPuppeteerKey[keys[i]]; + } + await page.keyboard.down(keys[i]); + keysDown.push(keys[i]); + } + while (keysDown.length > 0) { + await page.keyboard.up(keysDown.pop()); + } + }, + click: async (windowId, selector, xoffset, yoffset) => { + console.log('click'); + const { x, y } = await page.evaluate(` + (function() { + function convertToPixels(element, value) { + return parseFloat(value) || 0; + } + function getDimension(element, cssPropertyName, jsPropertyName) { + let computedStyle = getComputedStyle(element); + let value = '0'; + if (computedStyle) { + if (computedStyle.getPropertyValue) { + value = computedStyle.getPropertyValue(cssPropertyName); + } else { + // IE8 + value = (computedStyle).getAttribute(jsPropertyName); + } + } + return convertToPixels(element, value); + } + function getBorderLeftWidth(element) { + return getDimension(element, 'border-left-width', 'borderLeftWidth'); + } + function getBorderRightWidth(element) { + return getDimension(element, 'border-right-width', 'borderRightWidth'); + } + function getBorderTopWidth(element) { + return getDimension(element, 'border-top-width', 'borderTopWidth'); + } + function getBorderBottomWidth(element) { + return getDimension(element, 'border-bottom-width', 'borderBottomWidth'); + } + function getClientArea(element) { + // Try with DOM clientWidth / clientHeight + if (element !== document.body) { + return { width: element.clientWidth, height: element.clientHeight }; + } + + // Try innerWidth / innerHeight + if (window.innerWidth && window.innerHeight) { + return { width: window.innerWidth, height: window.innerHeight }; + } + + // Try with document.body.clientWidth / document.body.clientHeight + if (document.body && document.body.clientWidth && document.body.clientHeight) { + return { width: document.body.clientWidth, height: document.body.clientHeight }; + } + + // Try with document.documentElement.clientWidth / document.documentElement.clientHeight + if (document.documentElement && document.documentElement.clientWidth && document.documentElement.clientHeight) { + return { width: document.documentElement.clientWidth, height: document.documentElement.clientHeight }; + } + + throw new Error('Unable to figure out browser width and height'); + } + function getTopLeftOffset(element) { + // Adapted from WinJS.Utilities.getPosition + // and added borders to the mix + + let offsetParent = element.offsetParent, top = element.offsetTop, left = element.offsetLeft; + + while ((element = element.parentNode) !== null && element !== document.body && element !== document.documentElement) { + top -= element.scrollTop; + let c = getComputedStyle(element); + if (c) { + left -= c.direction !== 'rtl' ? element.scrollLeft : -element.scrollLeft; + } + + if (element === offsetParent) { + left += getBorderLeftWidth(element); + top += getBorderTopWidth(element); + top += element.offsetTop; + left += element.offsetLeft; + offsetParent = element.offsetParent; + } + } + + return { + left: left, + top: top + }; + } + const element = document.querySelector('${selector}'); + + if (!element) { + throw new Error('Element not found: ${selector}'); + } + + const { left, top } = getTopLeftOffset(element); + const { width, height } = getClientArea(element); + let x, y; + + x = left + (width / 2); + y = top + (height / 2); + + x = Math.round(x); + y = Math.round(y); + + return { x, y }; + })(); + `); + await page.mouse.click(x + (xoffset ? xoffset : 0), y + (yoffset ? yoffset : 0)); }, - click: (windowId, selector, xoffset, yoffset) => Promise.resolve(), doubleClick: (windowId, selector) => Promise.resolve(), - setValue: (windowId, selector, text) => Promise.resolve(), + setValue: async (windowId, selector, text) => { + return page.evaluate(` + (function() { + const element = document.querySelector('${selector}'); + + if (!element) { + throw new Error('Element not found: ${selector}'); + } + + const inputElement = element; + inputElement.value = '${text}'; + + const event = new Event('input', { bubbles: true, cancelable: true }); + inputElement.dispatchEvent(event); + return true; + })(); + `); + }, getTitle: (windowId) => page.title(), isActiveElement: (windowId, selector) => { - page.evaluate(`document.querySelector('${selector}') === document.activeElement`); + return page.evaluate(`document.querySelector('${selector}') === document.activeElement`); }, - getElements: async (windowId, selector, recursive) => { - return await page.evaluate(` + getElements: (windowId, selector, recursive) => { + return page.evaluate(` (function() { function convertToPixels(element, value) { return parseFloat(value) || 0; @@ -138,22 +270,22 @@ function buildDriver(browser, page) { `); }, typeInEditor: (windowId, selector, text) => Promise.resolve(), - getTerminalBuffer: async (windowId, selector) => { - return await page.evaluate(` + getTerminalBuffer: (windowId, selector) => { + return page.evaluate(` (function () { - const element = document.querySelector(selector); + const element = document.querySelector('${selector}'); if (!element) { - throw new Error('Terminal not found: ${selector}''); + throw new Error('Terminal not found: ${selector}'); } - const xterm: Terminal = element.xterm; + const xterm = element.xterm; if (!xterm) { throw new Error('Xterm not found: ${selector}'); } - const lines: string[] = []; + const lines = []; for (let i = 0; i < xterm.buffer.length; i++) { lines.push(xterm.buffer.getLine(i).translateToString(true)); @@ -163,21 +295,23 @@ function buildDriver(browser, page) { })(); `); }, - writeInTerminal: async (windowId, selector, text) => { - page.evaluate(` - const element = document.querySelector(selector); + writeInTerminal: (windowId, selector, text) => { + return page.evaluate(` + (function () { + const element = document.querySelector('${selector}'); - if (!element) { - throw new Error('Element not found: ${selector}'); - } + if (!element) { + throw new Error('Element not found: ${selector}'); + } - const xterm: Terminal = element.xterm; + const xterm = element.xterm; - if (!xterm) { - throw new Error('Xterm not found: ${selector}'); - } + if (!xterm) { + throw new Error('Xterm not found: ${selector}'); + } - xterm._core.handler(text); + xterm._core._coreService.triggerDataEvent('${text}'); + })(); `); } } @@ -186,13 +320,15 @@ function buildDriver(browser, page) { exports.connect = function (outPath, handle) { return new Promise(async (c) => { const browser = await puppeteer.launch({ + // Run in Edge dev on macOS + // executablePath: '/Applications/Microsoft\ Edge\ Dev.app/Contents/MacOS/Microsoft\ Edge\ Dev', headless: false, slowMo: 80, args: [`--window-size=${width},${height}`] }); const page = (await browser.pages())[0]; await page.setViewport({ width, height }); - await page.goto('http://127.0.0.1:8000'); + await page.goto('http://127.0.0.1:9888'); const result = { client: { dispose: () => {} }, driver: buildDriver(browser, page) From 61c463b5202e44b8a0c21f3bffa1f747b882fbb8 Mon Sep 17 00:00:00 2001 From: matthew Date: Sat, 13 Jul 2019 11:42:35 -0700 Subject: [PATCH 069/861] only display keybindings that can be dispatched --- .../browser/actions/developerActions.ts | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/browser/actions/developerActions.ts b/src/vs/workbench/browser/actions/developerActions.ts index 9b5efecb624..b2883b38f3d 100644 --- a/src/vs/workbench/browser/actions/developerActions.ts +++ b/src/vs/workbench/browser/actions/developerActions.ts @@ -169,27 +169,31 @@ export class ToggleScreencastModeAction extends Action { keyboardTimeout.dispose(); const event = new StandardKeyboardEvent(e); - const shortcut = this.keybindingService.softDispatch(event, event.target); const keybinding = this.keybindingService.resolveKeyboardEvent(event); - const label = keybinding.getLabel(); + const [firstPart,] = keybinding.getDispatchParts(); - if (shortcut) { - if (enterChord) { - keyboardMarker.textContent += ' ' + label; - } else { - keyboardMarker.textContent = label; - } - keyboardMarker.style.display = 'block'; - enterChord = shortcut.enterChord; - } else if (!this.configurationService.getValue('screencastMode.onlyKeyboardShortcuts')) { - if (this.keybindingService.mightProducePrintableCharacter(event) && label) { - keyboardMarker.textContent += ' ' + label; - keyboardMarker.style.display = 'block'; - } else if (!event.shiftKey) { - keyboardMarker.textContent = label; + if (firstPart !== null) { + const shortcut = this.keybindingService.softDispatch(event, event.target); + const label = keybinding.getLabel(); + + if (shortcut) { + if (enterChord) { + keyboardMarker.textContent += ' ' + label; + } else { + keyboardMarker.textContent = label; + } keyboardMarker.style.display = 'block'; + enterChord = shortcut.enterChord; + } else if (!this.configurationService.getValue('screencastMode.onlyKeyboardShortcuts')) { + if (this.keybindingService.mightProducePrintableCharacter(event) && label) { + keyboardMarker.textContent += ' ' + label; + keyboardMarker.style.display = 'block'; + } else { + keyboardMarker.textContent = label; + keyboardMarker.style.display = 'block'; + } + enterChord = false; } - enterChord = false; } const promise = timeout(800); From f7b8079f218bf3b08f614be2a073c341256750a1 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 15 Jul 2019 11:50:15 -0700 Subject: [PATCH 070/861] Add puppeteer types and use TS in driver --- package.json | 3 +- test/smoke/src/main.ts | 24 +++---- test/smoke/src/vscode/puppeteer-driver.d.ts | 56 ---------------- ...uppeteer-driver.js => puppeteer-driver.ts} | 64 +++++++++++++++++-- yarn.lock | 7 ++ 5 files changed, 78 insertions(+), 76 deletions(-) delete mode 100644 test/smoke/src/vscode/puppeteer-driver.d.ts rename test/smoke/src/vscode/{puppeteer-driver.js => puppeteer-driver.ts} (80%) diff --git a/package.json b/package.json index 30a031ec455..dd5a11c2434 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "@types/minimist": "^1.2.0", "@types/mocha": "2.2.39", "@types/node": "^10.12.12", + "@types/puppeteer": "^1.12.4", "@types/semver": "^5.5.0", "@types/sinon": "^1.16.36", "@types/webpack": "^4.4.10", @@ -156,4 +157,4 @@ "windows-mutex": "0.2.1", "windows-process-tree": "0.2.4" } -} \ No newline at end of file +} diff --git a/test/smoke/src/main.ts b/test/smoke/src/main.ts index 945f109449f..c51b6817e9d 100644 --- a/test/smoke/src/main.ts +++ b/test/smoke/src/main.ts @@ -14,19 +14,19 @@ import { ncp } from 'ncp'; import { Application, Quality, ApplicationOptions } from './application'; import { setup as setupDataMigrationTests } from './areas/workbench/data-migration.test'; -import { setup as setupDataLossTests } from './areas/workbench/data-loss.test'; -import { setup as setupDataExplorerTests } from './areas/explorer/explorer.test'; -import { setup as setupDataPreferencesTests } from './areas/preferences/preferences.test'; -import { setup as setupDataSearchTests } from './areas/search/search.test'; -import { setup as setupDataCSSTests } from './areas/css/css.test'; -import { setup as setupDataEditorTests } from './areas/editor/editor.test'; -import { setup as setupDataDebugTests } from './areas/debug/debug.test'; -import { setup as setupDataGitTests } from './areas/git/git.test'; -import { setup as setupDataStatusbarTests } from './areas/statusbar/statusbar.test'; -import { setup as setupDataExtensionTests } from './areas/extensions/extensions.test'; +// import { setup as setupDataLossTests } from './areas/workbench/data-loss.test'; +// import { setup as setupDataExplorerTests } from './areas/explorer/explorer.test'; +// import { setup as setupDataPreferencesTests } from './areas/preferences/preferences.test'; +// import { setup as setupDataSearchTests } from './areas/search/search.test'; +// import { setup as setupDataCSSTests } from './areas/css/css.test'; +// import { setup as setupDataEditorTests } from './areas/editor/editor.test'; +// import { setup as setupDataDebugTests } from './areas/debug/debug.test'; +// import { setup as setupDataGitTests } from './areas/git/git.test'; +// import { setup as setupDataStatusbarTests } from './areas/statusbar/statusbar.test'; +// import { setup as setupDataExtensionTests } from './areas/extensions/extensions.test'; import { setup as setupTerminalTests } from './areas/terminal/terminal.test'; -import { setup as setupDataMultirootTests } from './areas/multiroot/multiroot.test'; -import { setup as setupDataLocalizationTests } from './areas/workbench/localization.test'; +// import { setup as setupDataMultirootTests } from './areas/multiroot/multiroot.test'; +// import { setup as setupDataLocalizationTests } from './areas/workbench/localization.test'; import { setup as setupLaunchTests } from './areas/workbench/launch.test'; import { MultiLogger, Logger, ConsoleLogger, FileLogger } from './logger'; diff --git a/test/smoke/src/vscode/puppeteer-driver.d.ts b/test/smoke/src/vscode/puppeteer-driver.d.ts deleted file mode 100644 index ee385f2b3f3..00000000000 --- a/test/smoke/src/vscode/puppeteer-driver.d.ts +++ /dev/null @@ -1,56 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -/** - * Thenable is a common denominator between ES6 promises, Q, jquery.Deferred, WinJS.Promise, - * and others. This API makes no assumption about what promise library is being used which - * enables reusing existing code without migrating to a specific promise implementation. Still, - * we recommend the use of native promises which are available in this editor. - */ -interface Thenable { - /** - * Attaches callbacks for the resolution and/or rejection of the Promise. - * @param onfulfilled The callback to execute when the Promise is resolved. - * @param onrejected The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of which ever callback is executed. - */ - then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => TResult | Thenable): Thenable; - then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => void): Thenable; -} - -export interface IElement { - tagName: string; - className: string; - textContent: string; - attributes: { [name: string]: string; }; - children: IElement[]; - top: number; - left: number; -} - -export interface IDriver { - _serviceBrand: any; - - getWindowIds(): Promise; - capturePage(windowId: number): Promise; - reloadWindow(windowId: number): Promise; - exitApplication(): Promise; - dispatchKeybinding(windowId: number, keybinding: string): Promise; - click(windowId: number, selector: string, xoffset?: number | undefined, yoffset?: number | undefined): Promise; - doubleClick(windowId: number, selector: string): Promise; - setValue(windowId: number, selector: string, text: string): Promise; - getTitle(windowId: number): Promise; - isActiveElement(windowId: number, selector: string): Promise; - getElements(windowId: number, selector: string, recursive?: boolean): Promise; - typeInEditor(windowId: number, selector: string, text: string): Promise; - getTerminalBuffer(windowId: number, selector: string): Promise; - writeInTerminal(windowId: number, selector: string, text: string): Promise; -} - -export interface IDisposable { - dispose(): void; -} - -export function connect(outPath: string, handle: string): Promise<{ client: IDisposable, driver: IDriver }>; diff --git a/test/smoke/src/vscode/puppeteer-driver.js b/test/smoke/src/vscode/puppeteer-driver.ts similarity index 80% rename from test/smoke/src/vscode/puppeteer-driver.js rename to test/smoke/src/vscode/puppeteer-driver.ts index 80127b29b69..927af49964b 100644 --- a/test/smoke/src/vscode/puppeteer-driver.js +++ b/test/smoke/src/vscode/puppeteer-driver.ts @@ -22,12 +22,12 @@ function buildDriver(browser, page) { getWindowIds: () => { return Promise.resolve([1]); }, - capturePage: () => Promise.result(''), + capturePage: () => Promise.resolve(''), reloadWindow: (windowId) => Promise.resolve(), exitApplication: () => browser.close(), dispatchKeybinding: async (windowId, keybinding) => { const keys = keybinding.split('+'); - const keysDown = []; + const keysDown: string[] = []; for (let i = 0; i < keys.length; i++) { if (keys[i] in vscodeToPuppeteerKey) { keys[i] = vscodeToPuppeteerKey[keys[i]]; @@ -314,10 +314,10 @@ function buildDriver(browser, page) { })(); `); } - } + }; } -exports.connect = function (outPath, handle) { +export function connect(outPath: string, handle: string): Promise<{ client: IDisposable, driver: IDriver }> { return new Promise(async (c) => { const browser = await puppeteer.launch({ // Run in Edge dev on macOS @@ -330,9 +330,59 @@ exports.connect = function (outPath, handle) { await page.setViewport({ width, height }); await page.goto('http://127.0.0.1:9888'); const result = { - client: { dispose: () => {} }, + client: { dispose: () => { } }, driver: buildDriver(browser, page) - } + }; c(result); }); -}; +} + +/** + * Thenable is a common denominator between ES6 promises, Q, jquery.Deferred, WinJS.Promise, + * and others. This API makes no assumption about what promise library is being used which + * enables reusing existing code without migrating to a specific promise implementation. Still, + * we recommend the use of native promises which are available in this editor. + */ +export interface Thenable { + /** + * Attaches callbacks for the resolution and/or rejection of the Promise. + * @param onfulfilled The callback to execute when the Promise is resolved. + * @param onrejected The callback to execute when the Promise is rejected. + * @returns A Promise for the completion of which ever callback is executed. + */ + then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => TResult | Thenable): Thenable; + then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => void): Thenable; +} + +export interface IElement { + tagName: string; + className: string; + textContent: string; + attributes: { [name: string]: string; }; + children: IElement[]; + top: number; + left: number; +} + +export interface IDriver { + _serviceBrand: any; + + getWindowIds(): Promise; + capturePage(windowId: number): Promise; + reloadWindow(windowId: number): Promise; + exitApplication(): Promise; + dispatchKeybinding(windowId: number, keybinding: string): Promise; + click(windowId: number, selector: string, xoffset?: number | undefined, yoffset?: number | undefined): Promise; + doubleClick(windowId: number, selector: string): Promise; + setValue(windowId: number, selector: string, text: string): Promise; + getTitle(windowId: number): Promise; + isActiveElement(windowId: number, selector: string): Promise; + getElements(windowId: number, selector: string, recursive?: boolean): Promise; + typeInEditor(windowId: number, selector: string, text: string): Promise; + getTerminalBuffer(windowId: number, selector: string): Promise; + writeInTerminal(windowId: number, selector: string, text: string): Promise; +} + +export interface IDisposable { + dispose(): void; +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 4c46dae4c82..efa24d5eb3a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -65,6 +65,13 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.12.tgz#e15a9d034d9210f00320ef718a50c4a799417c47" integrity sha512-Pr+6JRiKkfsFvmU/LK68oBRCQeEg36TyAbPhc2xpez24OOZZCuoIhWGTd39VZy6nGafSbxzGouFPTFD/rR1A0A== +"@types/puppeteer@^1.12.4": + version "1.12.4" + resolved "https://registry.yarnpkg.com/@types/puppeteer/-/puppeteer-1.12.4.tgz#8388efdb0b30a54a7e7c4831ca0d709191d77ff1" + integrity sha512-aaGbJaJ9TuF9vZfTeoh876sBa+rYJWPwtsmHmYr28pGr42ewJnkDTq2aeSKEmS39SqUdkwLj73y/d7rBSp7mDQ== + dependencies: + "@types/node" "*" + "@types/semver@^5.4.0", "@types/semver@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.5.0.tgz#146c2a29ee7d3bae4bf2fcb274636e264c813c45" From 2eb4b1aebdcc9d1c1c19d9bcc6e8deb0292fdb13 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 16 Jul 2019 14:09:12 -0700 Subject: [PATCH 071/861] Improve types --- test/smoke/src/vscode/puppeteer-driver.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/test/smoke/src/vscode/puppeteer-driver.ts b/test/smoke/src/vscode/puppeteer-driver.ts index 927af49964b..f864aede94b 100644 --- a/test/smoke/src/vscode/puppeteer-driver.ts +++ b/test/smoke/src/vscode/puppeteer-driver.ts @@ -3,9 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -const puppeteer = require('puppeteer'); - -// export function connect(outPath: string, handle: string): Promise<{ client: IDisposable, driver: IDriver }> +import * as puppeteer from 'puppeteer'; const width = 1200; const height = 800; @@ -16,7 +14,7 @@ const vscodeToPuppeteerKey = { enter: 'Enter' }; -function buildDriver(browser, page) { +function buildDriver(browser: puppeteer.Browser, page: puppeteer.Page): IDriver { return { _serviceBrand: undefined, getWindowIds: () => { @@ -36,11 +34,10 @@ function buildDriver(browser, page) { keysDown.push(keys[i]); } while (keysDown.length > 0) { - await page.keyboard.up(keysDown.pop()); + await page.keyboard.up(keysDown.pop()!); } }, click: async (windowId, selector, xoffset, yoffset) => { - console.log('click'); const { x, y } = await page.evaluate(` (function() { function convertToPixels(element, value) { From 8d20c171fce04be00a26a880643106160e015355 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 19 Jul 2019 17:12:11 -0700 Subject: [PATCH 072/861] Bring back non-web smoke tests --- test/smoke/package.json | 4 +- .../smoke/src/areas/terminal/terminal.test.ts | 2 +- test/smoke/src/main.ts | 72 +++++++------- test/smoke/src/vscode/code.ts | 96 +++++++++++-------- test/smoke/src/vscode/puppeteer-driver.ts | 10 +- 5 files changed, 105 insertions(+), 79 deletions(-) diff --git a/test/smoke/package.json b/test/smoke/package.json index 188a2e08253..2d92a7a8846 100644 --- a/test/smoke/package.json +++ b/test/smoke/package.json @@ -6,8 +6,8 @@ "postinstall": "npm run compile", "compile": "npm run copy-driver && npm run copy-driver-definition && tsc", "watch": "concurrently \"npm run watch-driver\" \"npm run watch-driver-definition\" \"tsc --watch\"", - "copy-driver": "cpx src/vscode/puppeteer-driver.js out/vscode", - "watch-driver": "cpx src/vscode/puppeteer-driver.js out/vscode -w", + "copy-driver": "cpx src/vscode/driver.js out/vscode", + "watch-driver": "cpx src/vscode/driver.js out/vscode -w", "copy-driver-definition": "node tools/copy-driver-definition.js", "watch-driver-definition": "watch \"node tools/copy-driver-definition.js\" ../../src/vs/platform/driver/node", "mocha": "mocha" diff --git a/test/smoke/src/areas/terminal/terminal.test.ts b/test/smoke/src/areas/terminal/terminal.test.ts index 8dc459faf63..46bd8d997b3 100644 --- a/test/smoke/src/areas/terminal/terminal.test.ts +++ b/test/smoke/src/areas/terminal/terminal.test.ts @@ -6,7 +6,7 @@ import { Application } from '../../application'; export function setup() { - describe.only('Terminal', () => { + describe('Terminal', () => { it(`opens terminal, runs 'echo' and verifies the output`, async function () { this.timeout(60 * 5000); const app = this.app as Application; diff --git a/test/smoke/src/main.ts b/test/smoke/src/main.ts index c51b6817e9d..85695d96dcc 100644 --- a/test/smoke/src/main.ts +++ b/test/smoke/src/main.ts @@ -14,19 +14,19 @@ import { ncp } from 'ncp'; import { Application, Quality, ApplicationOptions } from './application'; import { setup as setupDataMigrationTests } from './areas/workbench/data-migration.test'; -// import { setup as setupDataLossTests } from './areas/workbench/data-loss.test'; -// import { setup as setupDataExplorerTests } from './areas/explorer/explorer.test'; -// import { setup as setupDataPreferencesTests } from './areas/preferences/preferences.test'; -// import { setup as setupDataSearchTests } from './areas/search/search.test'; -// import { setup as setupDataCSSTests } from './areas/css/css.test'; -// import { setup as setupDataEditorTests } from './areas/editor/editor.test'; -// import { setup as setupDataDebugTests } from './areas/debug/debug.test'; -// import { setup as setupDataGitTests } from './areas/git/git.test'; -// import { setup as setupDataStatusbarTests } from './areas/statusbar/statusbar.test'; -// import { setup as setupDataExtensionTests } from './areas/extensions/extensions.test'; +import { setup as setupDataLossTests } from './areas/workbench/data-loss.test'; +import { setup as setupDataExplorerTests } from './areas/explorer/explorer.test'; +import { setup as setupDataPreferencesTests } from './areas/preferences/preferences.test'; +import { setup as setupDataSearchTests } from './areas/search/search.test'; +import { setup as setupDataCSSTests } from './areas/css/css.test'; +import { setup as setupDataEditorTests } from './areas/editor/editor.test'; +import { setup as setupDataDebugTests } from './areas/debug/debug.test'; +import { setup as setupDataGitTests } from './areas/git/git.test'; +import { setup as setupDataStatusbarTests } from './areas/statusbar/statusbar.test'; +import { setup as setupDataExtensionTests } from './areas/extensions/extensions.test'; import { setup as setupTerminalTests } from './areas/terminal/terminal.test'; -// import { setup as setupDataMultirootTests } from './areas/multiroot/multiroot.test'; -// import { setup as setupDataLocalizationTests } from './areas/workbench/localization.test'; +import { setup as setupDataMultirootTests } from './areas/multiroot/multiroot.test'; +import { setup as setupDataLocalizationTests } from './areas/workbench/localization.test'; import { setup as setupLaunchTests } from './areas/workbench/launch.test'; import { MultiLogger, Logger, ConsoleLogger, FileLogger } from './logger'; @@ -51,7 +51,8 @@ const opts = minimist(args, { ], boolean: [ 'verbose', - 'remote' + 'remote', + 'web' ], default: { verbose: false @@ -132,13 +133,13 @@ if (testCodePath) { process.env.VSCODE_CLI = '1'; } -// if (!fs.existsSync(electronPath || '')) { -// fail(`Can't find Code at ${electronPath}.`); -// } -console.log(stablePath); -// if (typeof stablePath === 'string' && !fs.existsSync(stablePath)) { -// fail(`Can't find Stable Code at ${stablePath}.`); -// } +if (!fs.existsSync(electronPath || '')) { + fail(`Can't find Code at ${electronPath}.`); +} + +if (typeof stablePath === 'string' && !fs.existsSync(stablePath)) { + fail(`Can't find Stable Code at ${stablePath}.`); +} const userDataDir = path.join(testDataPath, 'd'); @@ -239,7 +240,7 @@ setupDataMigrationTests(stableCodePath, testDataPath); describe('Running Code', () => { before(async function () { const app = new Application(this.defaultOptions); - await app!.start(false); + await app!.start(opts.web ? false : undefined); this.app = app; }); @@ -268,19 +269,24 @@ describe('Running Code', () => { }); } - // setupDataLossTests(); - // setupDataExplorerTests(); - // setupDataPreferencesTests(); - // setupDataSearchTests(); - // setupDataCSSTests(); - // setupDataEditorTests(); - // setupDataDebugTests(); - // setupDataGitTests(); - // setupDataStatusbarTests(); - // setupDataExtensionTests(); + if (opts.web) { + setupTerminalTests(); + return; + } + + setupDataLossTests(); + setupDataExplorerTests(); + setupDataPreferencesTests(); + setupDataSearchTests(); + setupDataCSSTests(); + setupDataEditorTests(); + setupDataDebugTests(); + setupDataGitTests(); + setupDataStatusbarTests(); + setupDataExtensionTests(); setupTerminalTests(); - // setupDataMultirootTests(); - // setupDataLocalizationTests(); + setupDataMultirootTests(); + setupDataLocalizationTests(); }); setupLaunchTests(); \ No newline at end of file diff --git a/test/smoke/src/vscode/code.ts b/test/smoke/src/vscode/code.ts index 4ccf2307d32..0c493ec65f1 100644 --- a/test/smoke/src/vscode/code.ts +++ b/test/smoke/src/vscode/code.ts @@ -9,45 +9,46 @@ import * as os from 'os'; import * as fs from 'fs'; import * as mkdirp from 'mkdirp'; import { tmpName } from 'tmp'; -import { IDriver, connect as connectDriver, IDisposable, IElement, Thenable } from './puppeteer-driver'; +import { IDriver, connect as connectElectronDriver, IDisposable, IElement, Thenable } from './driver'; +import { connect as connectPuppeteerDriver, launch } from './puppeteer-driver'; import { Logger } from '../logger'; import { ncp } from 'ncp'; import { URI } from 'vscode-uri'; const repoPath = path.join(__dirname, '../../../..'); -// function getDevElectronPath(): string { -// const buildPath = path.join(repoPath, '.build'); -// const product = require(path.join(repoPath, 'product.json')); +function getDevElectronPath(): string { + const buildPath = path.join(repoPath, '.build'); + const product = require(path.join(repoPath, 'product.json')); -// switch (process.platform) { -// case 'darwin': -// return path.join(buildPath, 'electron', `${product.nameLong}.app`, 'Contents', 'MacOS', 'Electron'); -// case 'linux': -// return path.join(buildPath, 'electron', `${product.applicationName}`); -// case 'win32': -// return path.join(buildPath, 'electron', `${product.nameShort}.exe`); -// default: -// throw new Error('Unsupported platform.'); -// } -// } + switch (process.platform) { + case 'darwin': + return path.join(buildPath, 'electron', `${product.nameLong}.app`, 'Contents', 'MacOS', 'Electron'); + case 'linux': + return path.join(buildPath, 'electron', `${product.applicationName}`); + case 'win32': + return path.join(buildPath, 'electron', `${product.nameShort}.exe`); + default: + throw new Error('Unsupported platform.'); + } +} -// function getBuildElectronPath(root: string): string { -// switch (process.platform) { -// case 'darwin': -// return path.join(root, 'Contents', 'MacOS', 'Electron'); -// case 'linux': { -// const product = require(path.join(root, 'resources', 'app', 'product.json')); -// return path.join(root, product.applicationName); -// } -// case 'win32': { -// const product = require(path.join(root, 'resources', 'app', 'product.json')); -// return path.join(root, `${product.nameShort}.exe`); -// } -// default: -// throw new Error('Unsupported platform.'); -// } -// } +function getBuildElectronPath(root: string): string { + switch (process.platform) { + case 'darwin': + return path.join(root, 'Contents', 'MacOS', 'Electron'); + case 'linux': { + const product = require(path.join(root, 'resources', 'app', 'product.json')); + return path.join(root, product.applicationName); + } + case 'win32': { + const product = require(path.join(root, 'resources', 'app', 'product.json')); + return path.join(root, `${product.nameShort}.exe`); + } + default: + throw new Error('Unsupported platform.'); + } +} function getDevOutPath(): string { return path.join(repoPath, 'out'); @@ -62,7 +63,7 @@ function getBuildOutPath(root: string): string { } } -async function connect(child: cp.ChildProcess | undefined, outPath: string, handlePath: string, logger: Logger): Promise { +async function connect(connectDriver: typeof connectElectronDriver, child: cp.ChildProcess | undefined, outPath: string, handlePath: string, logger: Logger): Promise { let errCount = 0; while (true) { @@ -95,7 +96,10 @@ export interface SpawnOptions { verbose?: boolean; extraArgs?: string[]; log?: string; + /** Run in the test resolver */ remote?: boolean; + /** Run in the web */ + web?: boolean; } async function createDriverHandle(): Promise { @@ -109,7 +113,7 @@ async function createDriverHandle(): Promise { export async function spawn(options: SpawnOptions): Promise { const codePath = options.codePath; - // const electronPath = codePath ? getBuildElectronPath(codePath) : getDevElectronPath(); + const electronPath = codePath ? getBuildElectronPath(codePath) : getDevElectronPath(); const outPath = codePath ? getBuildOutPath(codePath) : getDevOutPath(); const handle = await createDriverHandle(); @@ -162,15 +166,21 @@ export async function spawn(options: SpawnOptions): Promise { args.push(...options.extraArgs); } - // const spawnOptions: cp.SpawnOptions = { env }; + let child: cp.ChildProcess | undefined; + let connectDriver: typeof connectElectronDriver; - // const child = cp.spawn(electronPath, args, spawnOptions); + if (options.web) { + launch(args); + connectDriver = connectPuppeteerDriver; + } else { + const spawnOptions: cp.SpawnOptions = { env }; + child = cp.spawn(electronPath, args, spawnOptions); + instances.add(child); + child.once('exit', () => instances.delete(child!)); + connectDriver = connectElectronDriver; + } - // instances.add(child); - // child.once('exit', () => instances.delete(child)); - - const child = undefined; - return connect(child, outPath, handle, options.logger); + return connect(connectDriver, child, outPath, handle, options.logger); } async function poll( @@ -215,7 +225,7 @@ export class Code { private driver: IDriver; constructor( - private client: IDisposable, + private client: IDisposable | undefined, driver: IDriver, readonly logger: Logger ) { @@ -331,7 +341,9 @@ export class Code { } dispose(): void { - this.client.dispose(); + if (this.client) { + this.client.dispose(); + } } } diff --git a/test/smoke/src/vscode/puppeteer-driver.ts b/test/smoke/src/vscode/puppeteer-driver.ts index f864aede94b..7e1ca48ab30 100644 --- a/test/smoke/src/vscode/puppeteer-driver.ts +++ b/test/smoke/src/vscode/puppeteer-driver.ts @@ -314,6 +314,14 @@ function buildDriver(browser: puppeteer.Browser, page: puppeteer.Page): IDriver }; } +let args; + +export function launch(_args): void { + args = _args; + // TODO: Move puppeteer launch here + console.log(args); +} + export function connect(outPath: string, handle: string): Promise<{ client: IDisposable, driver: IDriver }> { return new Promise(async (c) => { const browser = await puppeteer.launch({ @@ -325,7 +333,7 @@ export function connect(outPath: string, handle: string): Promise<{ client: IDis }); const page = (await browser.pages())[0]; await page.setViewport({ width, height }); - await page.goto('http://127.0.0.1:9888'); + await page.goto(`http://127.0.0.1:9888?folder=${args[1]}`); const result = { client: { dispose: () => { } }, driver: buildDriver(browser, page) From 88c8745851393fbd99e0956c9e9aed7108c7c887 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 19 Jul 2019 17:16:04 -0700 Subject: [PATCH 073/861] Bring more non-web smoke test code back --- test/smoke/src/application.ts | 13 +++++++------ test/smoke/src/areas/terminal/terminal.test.ts | 1 - test/smoke/src/vscode/code.ts | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/test/smoke/src/application.ts b/test/smoke/src/application.ts index 904cb7e8232..7a5b364b16c 100644 --- a/test/smoke/src/application.ts +++ b/test/smoke/src/application.ts @@ -66,8 +66,8 @@ export class Application { async start(expectWalkthroughPart = true): Promise { await this._start(); - // web doesn't show explorer? - // await this.code.waitForElement('.explorer-folders-view'); + // TODO: web doesn't show explorer? + await this.code.waitForElement('.explorer-folders-view'); if (expectWalkthroughPart) { await this.code.waitForActiveElement(`.editor-instance[id="workbench.editor.walkThroughPart"] > div > div[tabIndex="0"]`); @@ -138,11 +138,12 @@ export class Application { } await this.code.waitForWindowIds(ids => ids.length > 0); - // await this.code.waitForElement('.monaco-workbench'); + // TODO: Remove on web? + await this.code.waitForElement('.monaco-workbench'); - // if (this.remote) { - // await this.code.waitForElement('.monaco-workbench .statusbar-item[title="Editing on TestResolver"]'); - // } + if (this.remote) { + await this.code.waitForElement('.monaco-workbench .statusbar-item[title="Editing on TestResolver"]'); + } // wait a bit, since focus might be stolen off widgets // as soon as they open (e.g. quick open) diff --git a/test/smoke/src/areas/terminal/terminal.test.ts b/test/smoke/src/areas/terminal/terminal.test.ts index 46bd8d997b3..d661b13a2dc 100644 --- a/test/smoke/src/areas/terminal/terminal.test.ts +++ b/test/smoke/src/areas/terminal/terminal.test.ts @@ -8,7 +8,6 @@ import { Application } from '../../application'; export function setup() { describe('Terminal', () => { it(`opens terminal, runs 'echo' and verifies the output`, async function () { - this.timeout(60 * 5000); const app = this.app as Application; const expected = new Date().getTime().toString(); diff --git a/test/smoke/src/vscode/code.ts b/test/smoke/src/vscode/code.ts index 0c493ec65f1..da5326e929c 100644 --- a/test/smoke/src/vscode/code.ts +++ b/test/smoke/src/vscode/code.ts @@ -71,9 +71,10 @@ async function connect(connectDriver: typeof connectElectronDriver, child: cp.Ch const { client, driver } = await connectDriver(outPath, handlePath); return new Code(client, driver, logger); } catch (err) { - console.log('err', err); if (++errCount > 50) { - // child.kill(); + if (child) { + child.kill(); + } throw err; } From e0d2e537f0555bb6e27eba6bfcb95d836088b728 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 19 Jul 2019 17:21:11 -0700 Subject: [PATCH 074/861] Pass web opt through --- test/smoke/src/application.ts | 3 ++- test/smoke/src/main.ts | 3 ++- test/smoke/src/vscode/puppeteer-driver.ts | 1 - 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/test/smoke/src/application.ts b/test/smoke/src/application.ts index 7a5b364b16c..52fe19dd834 100644 --- a/test/smoke/src/application.ts +++ b/test/smoke/src/application.ts @@ -125,7 +125,8 @@ export class Application { verbose: this.options.verbose, log: this.options.log, extraArgs, - remote: this.options.remote + remote: this.options.remote, + web: this.options.web }); this._workbench = new Workbench(this._code, this.userDataPath); diff --git a/test/smoke/src/main.ts b/test/smoke/src/main.ts index 85695d96dcc..3060b27d93c 100644 --- a/test/smoke/src/main.ts +++ b/test/smoke/src/main.ts @@ -212,7 +212,8 @@ function createOptions(): ApplicationOptions { verbose: opts.verbose, log, screenshotsPath, - remote: opts.remote + remote: opts.remote, + web: opts.web }; } diff --git a/test/smoke/src/vscode/puppeteer-driver.ts b/test/smoke/src/vscode/puppeteer-driver.ts index 7e1ca48ab30..42f0c652487 100644 --- a/test/smoke/src/vscode/puppeteer-driver.ts +++ b/test/smoke/src/vscode/puppeteer-driver.ts @@ -319,7 +319,6 @@ let args; export function launch(_args): void { args = _args; // TODO: Move puppeteer launch here - console.log(args); } export function connect(outPath: string, handle: string): Promise<{ client: IDisposable, driver: IDriver }> { From a23f859aa9f4e4b51dbbbd7fd34d80613c2a4e98 Mon Sep 17 00:00:00 2001 From: jeanp413 Date: Mon, 22 Jul 2019 03:53:24 -0500 Subject: [PATCH 075/861] Make centerEditorLayout do not call layout. Fixes #76494 --- src/vs/workbench/browser/workbench.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/workbench.ts b/src/vs/workbench/browser/workbench.ts index 634655ffa84..489d07550ef 100644 --- a/src/vs/workbench/browser/workbench.ts +++ b/src/vs/workbench/browser/workbench.ts @@ -414,7 +414,7 @@ export class Workbench extends Layout { // Restore Editor Center Mode if (this.state.editor.restoreCentered) { - this.centerEditorLayout(true); + this.centerEditorLayout(true, true); } // Emit a warning after 10s if restore does not complete From 793fc0295c0f94ffedace68d63c14c8d19c4e2a8 Mon Sep 17 00:00:00 2001 From: Gabriel DeBacker Date: Mon, 22 Jul 2019 06:58:16 -0700 Subject: [PATCH 076/861] Use correct resolved TDO and task for custom execution --- src/vs/workbench/api/node/extHostTask.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index 4d97792f198..55160a13a8c 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -744,11 +744,11 @@ export class ExtHostTask implements ExtHostTaskShape { } if (CustomExecutionDTO.is(resolvedTaskDTO.execution)) { - await this.addCustomExecution(taskDTO, task); + await this.addCustomExecution(resolvedTaskDTO, resolvedTask); } if (CustomExecution2DTO.is(resolvedTaskDTO.execution)) { - await this.addCustomExecution2(taskDTO, task); + await this.addCustomExecution2(resolvedTaskDTO, resolvedTask); } return resolvedTaskDTO; From c23b8fd5e103f91072047a2eb084cecc1e05ec27 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 23 Jul 2019 08:37:13 -0700 Subject: [PATCH 077/861] Fix remote EH environment after reconnection For microsoft/vscode-remote-release#16 --- .../workbench/api/common/extHost.protocol.ts | 1 + .../api/node/extHostExtensionService.ts | 14 +++++++++++++ .../electron-browser/remote.contribution.ts | 21 +++++++++++++++++++ .../extensions/browser/extensionService.ts | 1 - .../common/abstractExtensionService.ts | 5 +++++ .../common/extensionHostProcessManager.ts | 9 ++++++++ .../services/extensions/common/extensions.ts | 7 +++++++ 7 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 8fb612d3a7c..39d2dd19f50 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -872,6 +872,7 @@ export interface ExtHostExtensionServiceShape { $startExtensionHost(enabledExtensionIds: ExtensionIdentifier[]): Promise; $activateByEvent(activationEvent: string): Promise; $activate(extensionId: ExtensionIdentifier, activationEvent: string): Promise; + $setRemoteEnvironment(env: { [key: string]: string | null }): Promise; $deltaExtensions(toAdd: IExtensionDescription[], toRemove: ExtensionIdentifier[]): Promise; diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 781cb8998ab..f1a8d786a20 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -758,6 +758,20 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { return buff; } + public async $setRemoteEnvironment(env: { [key: string]: string | null }): Promise { + if (!this._initData.remote.isRemote) { + return; + } + + for (const key in env) { + const value = env[key]; + if (value === null) { + delete process.env[key]; + } else { + process.env[key] = value; + } + } + } } function loadCommonJSModule(logService: ILogService, modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { diff --git a/src/vs/workbench/contrib/remote/electron-browser/remote.contribution.ts b/src/vs/workbench/contrib/remote/electron-browser/remote.contribution.ts index 4fd4e7e56ad..a659919e73c 100644 --- a/src/vs/workbench/contrib/remote/electron-browser/remote.contribution.ts +++ b/src/vs/workbench/contrib/remote/electron-browser/remote.contribution.ts @@ -279,6 +279,26 @@ class ProgressReporter { } } +class RemoteExtensionHostEnvironmentUpdater implements IWorkbenchContribution { + constructor( + @IRemoteAgentService remoteAgentService: IRemoteAgentService, + @IRemoteAuthorityResolverService remoteResolverService: IRemoteAuthorityResolverService, + @IExtensionService extensionService: IExtensionService + ) { + const connection = remoteAgentService.getConnection(); + if (connection) { + connection.onDidStateChange(async e => { + if (e.type === PersistentConnectionEventType.ConnectionGain) { + const resolveResult = await remoteResolverService.resolveAuthority(connection.remoteAuthority); + if (resolveResult.options && resolveResult.options.extensionHostEnv) { + await extensionService.setRemoteEnvironment(resolveResult.options.extensionHostEnv); + } + } + }); + } + } +} + class RemoteAgentConnectionStatusListener implements IWorkbenchContribution { constructor( @IRemoteAgentService remoteAgentService: IRemoteAgentService, @@ -435,6 +455,7 @@ const workbenchContributionsRegistry = Registry.as { + await this._extensionHostProcessManagers + .map(manager => manager.setRemoteEnvironment(env)); + } + //#endregion // --- impl diff --git a/src/vs/workbench/services/extensions/common/extensionHostProcessManager.ts b/src/vs/workbench/services/extensions/common/extensionHostProcessManager.ts index 21cddb13749..68c824b46c3 100644 --- a/src/vs/workbench/services/extensions/common/extensionHostProcessManager.ts +++ b/src/vs/workbench/services/extensions/common/extensionHostProcessManager.ts @@ -288,6 +288,15 @@ export class ExtensionHostProcessManager extends Disposable { } return proxy.$deltaExtensions(toAdd, toRemove); } + + public async setRemoteEnvironment(env: { [key: string]: string | null }): Promise { + const proxy = await this._getExtensionHostProcessProxy(); + if (!proxy) { + return; + } + + return proxy.$setRemoteEnvironment(env); + } } const colorTables = [ diff --git a/src/vs/workbench/services/extensions/common/extensions.ts b/src/vs/workbench/services/extensions/common/extensions.ts index 1bd329231b6..0a56702ac0b 100644 --- a/src/vs/workbench/services/extensions/common/extensions.ts +++ b/src/vs/workbench/services/extensions/common/extensions.ts @@ -229,6 +229,12 @@ export interface IExtensionService { */ stopExtensionHost(): void; + /** + * Modify the environment of the remote extension host + * @param env New properties for the remote extension host + */ + setRemoteEnvironment(env: { [key: string]: string | null }): Promise; + _logOrShowMessage(severity: Severity, msg: string): void; _activateById(extensionId: ExtensionIdentifier, activationEvent: string): Promise; _onWillActivateExtension(extensionId: ExtensionIdentifier): void; @@ -278,6 +284,7 @@ export class NullExtensionService implements IExtensionService { restartExtensionHost(): void { } startExtensionHost(): void { } stopExtensionHost(): void { } + async setRemoteEnvironment(_env: { [key: string]: string | null }): Promise { } canAddExtension(): boolean { return false; } canRemoveExtension(): boolean { return false; } _logOrShowMessage(_severity: Severity, _msg: string): void { } From 1c1e82f9ea9cc8576dee73d5dd02325646f7b13f Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 23 Jul 2019 10:05:21 -0700 Subject: [PATCH 078/861] Revert unmodified file --- src/vs/workbench/services/extensions/browser/extensionService.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/services/extensions/browser/extensionService.ts b/src/vs/workbench/services/extensions/browser/extensionService.ts index 1ba9c27dc96..14d0da31fad 100644 --- a/src/vs/workbench/services/extensions/browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/browser/extensionService.ts @@ -21,6 +21,7 @@ import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEn import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; export class ExtensionService extends AbstractExtensionService implements IExtensionService { + private _remoteExtensionsEnvironmentData: IRemoteAgentEnvironment | null; constructor( From 9800baa7e916aee8f012a7ee6a8be9ce47ff7448 Mon Sep 17 00:00:00 2001 From: DiamondYuan Date: Wed, 24 Jul 2019 14:00:00 +0800 Subject: [PATCH 079/861] feat: support list.focusParent command --- .../workbench/browser/actions/listCommands.ts | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/vs/workbench/browser/actions/listCommands.ts b/src/vs/workbench/browser/actions/listCommands.ts index 634dcd69599..e3982aa2160 100644 --- a/src/vs/workbench/browser/actions/listCommands.ts +++ b/src/vs/workbench/browser/actions/listCommands.ts @@ -817,3 +817,33 @@ CommandsRegistry.registerCommand({ } } }); + +KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: 'list.focusParent', + weight: KeybindingWeight.WorkbenchContrib, + when: WorkbenchListFocusContextKey, + primary: KeyCode.Shift | KeyCode.LeftArrow, + handler: (accessor) => { + const focused = accessor.get(IListService).lastFocusedList; + // Tree only + if (focused && !(focused instanceof List || focused instanceof PagedList)) { + if (focused instanceof ObjectTree || focused instanceof DataTree || focused instanceof AsyncDataTree) { + const tree = focused; + const focusedElements = tree.getFocus(); + if (focusedElements.length === 0) { + return; + } + const focus = focusedElements[0]; + const parent = tree.getParentElement(focus); + if (parent) { + const fakeKeyboardEvent = new KeyboardEvent('keydown'); + tree.setFocus([parent], fakeKeyboardEvent); + tree.reveal(parent); + } + } else { + const tree = focused; + tree.focusParent({ origin: 'keyboard' }); + } + } + } +}); \ No newline at end of file From b0b2a0cf160a07c7fa95f39d3465b987ee4ca064 Mon Sep 17 00:00:00 2001 From: jeanp413 Date: Wed, 24 Jul 2019 01:32:59 -0500 Subject: [PATCH 080/861] Use active indent guide when active tree item is folder. Fixes #76276 --- src/vs/base/browser/ui/tree/abstractTree.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 7624d5b1fbe..c3094ca36f2 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -244,7 +244,7 @@ class TreeRenderer implements IListRenderer, HTMLDivElement>(); - private activeParentNodes = new Set>(); + private activeIndentNodes = new Set>(); private indentGuidesDisposable: IDisposable = Disposable.None; private disposables: IDisposable[] = []; @@ -353,6 +353,7 @@ class TreeRenderer implements IListRenderer implements IListRenderer('.indent-guide', { style: `width: ${this.indent}px` }); - if (this.activeParentNodes.has(parent)) { + if (this.activeIndentNodes.has(parent)) { addClass(guide, 'active'); } @@ -413,24 +414,26 @@ class TreeRenderer implements IListRenderer>(); nodes.forEach(node => { - if (node.parent) { + if (node.collapsible && node.children.length > 0 && !node.collapsed) { + set.add(node); + } else if (node.parent) { set.add(node.parent); } }); - this.activeParentNodes.forEach(node => { + this.activeIndentNodes.forEach(node => { if (!set.has(node)) { this.renderedIndentGuides.forEach(node, line => removeClass(line, 'active')); } }); set.forEach(node => { - if (!this.activeParentNodes.has(node)) { + if (!this.activeIndentNodes.has(node)) { this.renderedIndentGuides.forEach(node, line => addClass(line, 'active')); } }); - this.activeParentNodes = set; + this.activeIndentNodes = set; } dispose(): void { From 96d1767464491e63300aabf886b9e65f6739118f Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 24 Jul 2019 18:15:07 -0700 Subject: [PATCH 081/861] Start of browser driver and driver lib sharing --- src/vs/platform/driver/browser/driver.ts | 233 +++++++++++++++++++++++ src/vs/platform/driver/common/driver.ts | 51 +++++ src/vs/workbench/workbench.web.main.ts | 3 + 3 files changed, 287 insertions(+) create mode 100644 src/vs/platform/driver/browser/driver.ts create mode 100644 src/vs/platform/driver/common/driver.ts diff --git a/src/vs/platform/driver/browser/driver.ts b/src/vs/platform/driver/browser/driver.ts new file mode 100644 index 00000000000..83b37dc1e21 --- /dev/null +++ b/src/vs/platform/driver/browser/driver.ts @@ -0,0 +1,233 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { getTopLeftOffset } from 'vs/base/browser/dom'; +// TODO: Allow this +// tslint:disable-next-line: import-patterns +import { Terminal } from 'xterm'; +import { coalesce } from 'vs/base/common/arrays'; +import { IElement, IWindowDriver } from 'vs/platform/driver/common/driver'; + +function serializeElement(element: Element, recursive: boolean): IElement { + const attributes = Object.create(null); + + for (let j = 0; j < element.attributes.length; j++) { + const attr = element.attributes.item(j); + if (attr) { + attributes[attr.name] = attr.value; + } + } + + const children: IElement[] = []; + + if (recursive) { + for (let i = 0; i < element.children.length; i++) { + const child = element.children.item(i); + if (child) { + children.push(serializeElement(child, true)); + } + } + } + + const { left, top } = getTopLeftOffset(element as HTMLElement); + + return { + tagName: element.tagName, + className: element.className, + textContent: element.textContent || '', + attributes, + children, + left, + top + }; +} + +class BrowserWindowDriver implements IWindowDriver { + + constructor() { } + + click(selector: string, xoffset?: number, yoffset?: number): Promise { + const offset = typeof xoffset === 'number' && typeof yoffset === 'number' ? { x: xoffset, y: yoffset } : undefined; + return this._click(selector, 1, offset); + } + + doubleClick(selector: string): Promise { + return this._click(selector, 2); + } + + // private async _getElementXY(selector: string, offset?: { x: number, y: number }): Promise<{ x: number; y: number; }> { + // const element = document.querySelector(selector); + + // if (!element) { + // return Promise.reject(new Error(`Element not found: ${selector}`)); + // } + + // const { left, top } = getTopLeftOffset(element as HTMLElement); + // const { width, height } = getClientArea(element as HTMLElement); + // let x: number, y: number; + + // if (offset) { + // x = left + offset.x; + // y = top + offset.y; + // } else { + // x = left + (width / 2); + // y = top + (height / 2); + // } + + // x = Math.round(x); + // y = Math.round(y); + + // return { x, y }; + // } + + private async _click(selector: string, clickCount: number, offset?: { x: number, y: number }): Promise { + console.log('NYI'); + // const { x, y } = await this._getElementXY(selector, offset); + + // const webContents: electron.WebContents = (electron as any).remote.getCurrentWebContents(); + // webContents.sendInputEvent({ type: 'mouseDown', x, y, button: 'left', clickCount } as any); + // await timeout(10); + + // webContents.sendInputEvent({ type: 'mouseUp', x, y, button: 'left', clickCount } as any); + // await timeout(100); + } + + async setValue(selector: string, text: string): Promise { + const element = document.querySelector(selector); + + if (!element) { + return Promise.reject(new Error(`Element not found: ${selector}`)); + } + + const inputElement = element as HTMLInputElement; + inputElement.value = text; + + const event = new Event('input', { bubbles: true, cancelable: true }); + inputElement.dispatchEvent(event); + } + + async getTitle(): Promise { + return document.title; + } + + async isActiveElement(selector: string): Promise { + const element = document.querySelector(selector); + + if (element !== document.activeElement) { + const chain: string[] = []; + let el = document.activeElement; + + while (el) { + const tagName = el.tagName; + const id = el.id ? `#${el.id}` : ''; + const classes = coalesce(el.className.split(/\s+/g).map(c => c.trim())).map(c => `.${c}`).join(''); + chain.unshift(`${tagName}${id}${classes}`); + + el = el.parentElement; + } + + throw new Error(`Active element not found. Current active element is '${chain.join(' > ')}'. Looking for ${selector}`); + } + + return true; + } + + async getElements(selector: string, recursive: boolean): Promise { + const query = document.querySelectorAll(selector); + const result: IElement[] = []; + + for (let i = 0; i < query.length; i++) { + const element = query.item(i); + result.push(serializeElement(element, recursive)); + } + + return result; + } + + async typeInEditor(selector: string, text: string): Promise { + const element = document.querySelector(selector); + + if (!element) { + throw new Error(`Editor not found: ${selector}`); + } + + const textarea = element as HTMLTextAreaElement; + const start = textarea.selectionStart; + const newStart = start + text.length; + const value = textarea.value; + const newValue = value.substr(0, start) + text + value.substr(start); + + textarea.value = newValue; + textarea.setSelectionRange(newStart, newStart); + + const event = new Event('input', { 'bubbles': true, 'cancelable': true }); + textarea.dispatchEvent(event); + } + + async getTerminalBuffer(selector: string): Promise { + const element = document.querySelector(selector); + + if (!element) { + throw new Error(`Terminal not found: ${selector}`); + } + + const xterm: Terminal = (element as any).xterm; + + if (!xterm) { + throw new Error(`Xterm not found: ${selector}`); + } + + const lines: string[] = []; + + for (let i = 0; i < xterm.buffer.length; i++) { + lines.push(xterm.buffer.getLine(i)!.translateToString(true)); + } + + return lines; + } + + async writeInTerminal(selector: string, text: string): Promise { + const element = document.querySelector(selector); + + if (!element) { + throw new Error(`Element not found: ${selector}`); + } + + const xterm: Terminal = (element as any).xterm; + + if (!xterm) { + throw new Error(`Xterm not found: ${selector}`); + } + + xterm._core._coreService.triggerDataEvent(text); + } + + async openDevTools(): Promise { + // await this.windowService.openDevTools({ mode: 'detach' }); + } +} + +export async function registerWindowDriver(): Promise { + console.log('registerWindowDriver'); + (window).driver = new BrowserWindowDriver(); + // const windowDriverChannel = new WindowDriverChannel(windowDriver); + // mainProcessService.registerChannel('windowDriver', windowDriverChannel); + + // const windowDriverRegistryChannel = mainProcessService.getChannel('windowDriverRegistry'); + // const windowDriverRegistry = new WindowDriverRegistryChannelClient(windowDriverRegistryChannel); + + // await windowDriverRegistry.registerWindowDriver(windowService.windowId); + // const options = await windowDriverRegistry.registerWindowDriver(windowId); + + // if (options.verbose) { + // windowDriver.openDevTools(); + // } + + // return toDisposable(() => windowDriverRegistry.reloadWindowDriver(windowService.windowId)); + return toDisposable(() => { + return { dispose: () => { } }; + }); +} diff --git a/src/vs/platform/driver/common/driver.ts b/src/vs/platform/driver/common/driver.ts new file mode 100644 index 00000000000..299628846a4 --- /dev/null +++ b/src/vs/platform/driver/common/driver.ts @@ -0,0 +1,51 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +// TODO: Change smoketest build to read off common instead + +// !! Do not remove the following START and END markers, they are parsed by the smoketest build + +//*START +export interface IElement { + tagName: string; + className: string; + textContent: string; + attributes: { [name: string]: string; }; + children: IElement[]; + top: number; + left: number; +} + +export interface IDriver { + _serviceBrand: any; + + getWindowIds(): Promise; + capturePage(windowId: number): Promise; + reloadWindow(windowId: number): Promise; + exitApplication(): Promise; + dispatchKeybinding(windowId: number, keybinding: string): Promise; + click(windowId: number, selector: string, xoffset?: number | undefined, yoffset?: number | undefined): Promise; + doubleClick(windowId: number, selector: string): Promise; + setValue(windowId: number, selector: string, text: string): Promise; + getTitle(windowId: number): Promise; + isActiveElement(windowId: number, selector: string): Promise; + getElements(windowId: number, selector: string, recursive?: boolean): Promise; + typeInEditor(windowId: number, selector: string, text: string): Promise; + getTerminalBuffer(windowId: number, selector: string): Promise; + writeInTerminal(windowId: number, selector: string, text: string): Promise; +} +//*END + +export interface IWindowDriver { + click(selector: string, xoffset?: number | undefined, yoffset?: number | undefined): Promise; + doubleClick(selector: string): Promise; + setValue(selector: string, text: string): Promise; + getTitle(): Promise; + isActiveElement(selector: string): Promise; + getElements(selector: string, recursive: boolean): Promise; + typeInEditor(selector: string, text: string): Promise; + getTerminalBuffer(selector: string): Promise; + writeInTerminal(selector: string, text: string): Promise; +} diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 4d5cf7bfbf9..4e00191bd99 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -349,6 +349,7 @@ import 'vs/workbench/contrib/callHierarchy/browser/callHierarchy.contribution'; // Outline import 'vs/workbench/contrib/outline/browser/outline.contribution'; +import { registerWindowDriver } from 'vs/platform/driver/browser/driver'; // Experiments // import 'vs/workbench/contrib/experiments/electron-browser/experiments.contribution'; @@ -357,3 +358,5 @@ import 'vs/workbench/contrib/outline/browser/outline.contribution'; // import 'vs/workbench/contrib/issue/electron-browser/issue.contribution'; //#endregion + +registerWindowDriver(); From 65cd41503b525757d347fc1fd1bcce45e14feb10 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 27 Jul 2019 13:39:35 -0700 Subject: [PATCH 082/861] Share code between electron and browser drivers --- package.json | 1 - src/vs/platform/driver/browser/baseDriver.ts | 166 ++++++++++++++ src/vs/platform/driver/browser/driver.ts | 206 +----------------- .../driver/electron-browser/driver.ts | 155 +------------ test/smoke/package.json | 1 + test/smoke/src/main.ts | 9 +- test/smoke/src/vscode/puppeteer-driver.ts | 191 ++-------------- test/smoke/yarn.lock | 7 + yarn.lock | 7 - 9 files changed, 213 insertions(+), 530 deletions(-) create mode 100644 src/vs/platform/driver/browser/baseDriver.ts diff --git a/package.json b/package.json index ca74e4fb961..0da0569d843 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,6 @@ "@types/minimist": "^1.2.0", "@types/mocha": "2.2.39", "@types/node": "^10.12.12", - "@types/puppeteer": "^1.12.4", "@types/semver": "^5.5.0", "@types/sinon": "^1.16.36", "@types/webpack": "^4.4.10", diff --git a/src/vs/platform/driver/browser/baseDriver.ts b/src/vs/platform/driver/browser/baseDriver.ts new file mode 100644 index 00000000000..7b7d3057db6 --- /dev/null +++ b/src/vs/platform/driver/browser/baseDriver.ts @@ -0,0 +1,166 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { getTopLeftOffset } from 'vs/base/browser/dom'; +// TODO: Allow this +// tslint:disable-next-line: import-patterns +import { Terminal } from 'xterm'; +import { coalesce } from 'vs/base/common/arrays'; +import { IElement, IWindowDriver } from 'vs/platform/driver/common/driver'; + +function serializeElement(element: Element, recursive: boolean): IElement { + const attributes = Object.create(null); + + for (let j = 0; j < element.attributes.length; j++) { + const attr = element.attributes.item(j); + if (attr) { + attributes[attr.name] = attr.value; + } + } + + const children: IElement[] = []; + + if (recursive) { + for (let i = 0; i < element.children.length; i++) { + const child = element.children.item(i); + if (child) { + children.push(serializeElement(child, true)); + } + } + } + + const { left, top } = getTopLeftOffset(element as HTMLElement); + + return { + tagName: element.tagName, + className: element.className, + textContent: element.textContent || '', + attributes, + children, + left, + top + }; +} + +export abstract class BaseWindowDriver implements IWindowDriver { + + constructor() { } + + // TODO: This doesn't work in browser driver + abstract click(selector: string, xoffset?: number, yoffset?: number): Promise; + abstract doubleClick(selector: string): Promise; + + async setValue(selector: string, text: string): Promise { + const element = document.querySelector(selector); + + if (!element) { + return Promise.reject(new Error(`Element not found: ${selector}`)); + } + + const inputElement = element as HTMLInputElement; + inputElement.value = text; + + const event = new Event('input', { bubbles: true, cancelable: true }); + inputElement.dispatchEvent(event); + } + + async getTitle(): Promise { + return document.title; + } + + async isActiveElement(selector: string): Promise { + const element = document.querySelector(selector); + + if (element !== document.activeElement) { + const chain: string[] = []; + let el = document.activeElement; + + while (el) { + const tagName = el.tagName; + const id = el.id ? `#${el.id}` : ''; + const classes = coalesce(el.className.split(/\s+/g).map(c => c.trim())).map(c => `.${c}`).join(''); + chain.unshift(`${tagName}${id}${classes}`); + + el = el.parentElement; + } + + throw new Error(`Active element not found. Current active element is '${chain.join(' > ')}'. Looking for ${selector}`); + } + + return true; + } + + async getElements(selector: string, recursive: boolean): Promise { + const query = document.querySelectorAll(selector); + const result: IElement[] = []; + + for (let i = 0; i < query.length; i++) { + const element = query.item(i); + result.push(serializeElement(element, recursive)); + } + + return result; + } + + async typeInEditor(selector: string, text: string): Promise { + const element = document.querySelector(selector); + + if (!element) { + throw new Error(`Editor not found: ${selector}`); + } + + const textarea = element as HTMLTextAreaElement; + const start = textarea.selectionStart; + const newStart = start + text.length; + const value = textarea.value; + const newValue = value.substr(0, start) + text + value.substr(start); + + textarea.value = newValue; + textarea.setSelectionRange(newStart, newStart); + + const event = new Event('input', { 'bubbles': true, 'cancelable': true }); + textarea.dispatchEvent(event); + } + + async getTerminalBuffer(selector: string): Promise { + const element = document.querySelector(selector); + + if (!element) { + throw new Error(`Terminal not found: ${selector}`); + } + + const xterm: Terminal = (element as any).xterm; + + if (!xterm) { + throw new Error(`Xterm not found: ${selector}`); + } + + const lines: string[] = []; + + for (let i = 0; i < xterm.buffer.length; i++) { + lines.push(xterm.buffer.getLine(i)!.translateToString(true)); + } + + return lines; + } + + async writeInTerminal(selector: string, text: string): Promise { + const element = document.querySelector(selector); + + if (!element) { + throw new Error(`Element not found: ${selector}`); + } + + const xterm: Terminal = (element as any).xterm; + + if (!xterm) { + throw new Error(`Xterm not found: ${selector}`); + } + + xterm._core._coreService.triggerDataEvent(text); + } + + abstract async openDevTools(): Promise; +} diff --git a/src/vs/platform/driver/browser/driver.ts b/src/vs/platform/driver/browser/driver.ts index 83b37dc1e21..e22460f228f 100644 --- a/src/vs/platform/driver/browser/driver.ts +++ b/src/vs/platform/driver/browser/driver.ts @@ -4,209 +4,17 @@ *--------------------------------------------------------------------------------------------*/ import { IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { getTopLeftOffset } from 'vs/base/browser/dom'; -// TODO: Allow this -// tslint:disable-next-line: import-patterns -import { Terminal } from 'xterm'; -import { coalesce } from 'vs/base/common/arrays'; -import { IElement, IWindowDriver } from 'vs/platform/driver/common/driver'; +import { BaseWindowDriver } from 'vs/platform/driver/browser/baseDriver'; -function serializeElement(element: Element, recursive: boolean): IElement { - const attributes = Object.create(null); - - for (let j = 0; j < element.attributes.length; j++) { - const attr = element.attributes.item(j); - if (attr) { - attributes[attr.name] = attr.value; - } +class BrowserWindowDriver extends BaseWindowDriver { + click(selector: string, xoffset?: number | undefined, yoffset?: number | undefined): Promise { + throw new Error('Method not implemented.'); } - - const children: IElement[] = []; - - if (recursive) { - for (let i = 0; i < element.children.length; i++) { - const child = element.children.item(i); - if (child) { - children.push(serializeElement(child, true)); - } - } - } - - const { left, top } = getTopLeftOffset(element as HTMLElement); - - return { - tagName: element.tagName, - className: element.className, - textContent: element.textContent || '', - attributes, - children, - left, - top - }; -} - -class BrowserWindowDriver implements IWindowDriver { - - constructor() { } - - click(selector: string, xoffset?: number, yoffset?: number): Promise { - const offset = typeof xoffset === 'number' && typeof yoffset === 'number' ? { x: xoffset, y: yoffset } : undefined; - return this._click(selector, 1, offset); - } - doubleClick(selector: string): Promise { - return this._click(selector, 2); + throw new Error('Method not implemented.'); } - - // private async _getElementXY(selector: string, offset?: { x: number, y: number }): Promise<{ x: number; y: number; }> { - // const element = document.querySelector(selector); - - // if (!element) { - // return Promise.reject(new Error(`Element not found: ${selector}`)); - // } - - // const { left, top } = getTopLeftOffset(element as HTMLElement); - // const { width, height } = getClientArea(element as HTMLElement); - // let x: number, y: number; - - // if (offset) { - // x = left + offset.x; - // y = top + offset.y; - // } else { - // x = left + (width / 2); - // y = top + (height / 2); - // } - - // x = Math.round(x); - // y = Math.round(y); - - // return { x, y }; - // } - - private async _click(selector: string, clickCount: number, offset?: { x: number, y: number }): Promise { - console.log('NYI'); - // const { x, y } = await this._getElementXY(selector, offset); - - // const webContents: electron.WebContents = (electron as any).remote.getCurrentWebContents(); - // webContents.sendInputEvent({ type: 'mouseDown', x, y, button: 'left', clickCount } as any); - // await timeout(10); - - // webContents.sendInputEvent({ type: 'mouseUp', x, y, button: 'left', clickCount } as any); - // await timeout(100); - } - - async setValue(selector: string, text: string): Promise { - const element = document.querySelector(selector); - - if (!element) { - return Promise.reject(new Error(`Element not found: ${selector}`)); - } - - const inputElement = element as HTMLInputElement; - inputElement.value = text; - - const event = new Event('input', { bubbles: true, cancelable: true }); - inputElement.dispatchEvent(event); - } - - async getTitle(): Promise { - return document.title; - } - - async isActiveElement(selector: string): Promise { - const element = document.querySelector(selector); - - if (element !== document.activeElement) { - const chain: string[] = []; - let el = document.activeElement; - - while (el) { - const tagName = el.tagName; - const id = el.id ? `#${el.id}` : ''; - const classes = coalesce(el.className.split(/\s+/g).map(c => c.trim())).map(c => `.${c}`).join(''); - chain.unshift(`${tagName}${id}${classes}`); - - el = el.parentElement; - } - - throw new Error(`Active element not found. Current active element is '${chain.join(' > ')}'. Looking for ${selector}`); - } - - return true; - } - - async getElements(selector: string, recursive: boolean): Promise { - const query = document.querySelectorAll(selector); - const result: IElement[] = []; - - for (let i = 0; i < query.length; i++) { - const element = query.item(i); - result.push(serializeElement(element, recursive)); - } - - return result; - } - - async typeInEditor(selector: string, text: string): Promise { - const element = document.querySelector(selector); - - if (!element) { - throw new Error(`Editor not found: ${selector}`); - } - - const textarea = element as HTMLTextAreaElement; - const start = textarea.selectionStart; - const newStart = start + text.length; - const value = textarea.value; - const newValue = value.substr(0, start) + text + value.substr(start); - - textarea.value = newValue; - textarea.setSelectionRange(newStart, newStart); - - const event = new Event('input', { 'bubbles': true, 'cancelable': true }); - textarea.dispatchEvent(event); - } - - async getTerminalBuffer(selector: string): Promise { - const element = document.querySelector(selector); - - if (!element) { - throw new Error(`Terminal not found: ${selector}`); - } - - const xterm: Terminal = (element as any).xterm; - - if (!xterm) { - throw new Error(`Xterm not found: ${selector}`); - } - - const lines: string[] = []; - - for (let i = 0; i < xterm.buffer.length; i++) { - lines.push(xterm.buffer.getLine(i)!.translateToString(true)); - } - - return lines; - } - - async writeInTerminal(selector: string, text: string): Promise { - const element = document.querySelector(selector); - - if (!element) { - throw new Error(`Element not found: ${selector}`); - } - - const xterm: Terminal = (element as any).xterm; - - if (!xterm) { - throw new Error(`Xterm not found: ${selector}`); - } - - xterm._core._coreService.triggerDataEvent(text); - } - - async openDevTools(): Promise { - // await this.windowService.openDevTools({ mode: 'detach' }); + openDevTools(): Promise { + throw new Error('Method not implemented.'); } } diff --git a/src/vs/platform/driver/electron-browser/driver.ts b/src/vs/platform/driver/electron-browser/driver.ts index a956739bed7..931b898d55f 100644 --- a/src/vs/platform/driver/electron-browser/driver.ts +++ b/src/vs/platform/driver/electron-browser/driver.ts @@ -4,55 +4,22 @@ *--------------------------------------------------------------------------------------------*/ import { IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { IWindowDriver, IElement, WindowDriverChannel, WindowDriverRegistryChannelClient } from 'vs/platform/driver/node/driver'; +import { WindowDriverChannel, WindowDriverRegistryChannelClient } from 'vs/platform/driver/node/driver'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService'; import { getTopLeftOffset, getClientArea } from 'vs/base/browser/dom'; import * as electron from 'electron'; import { IWindowService } from 'vs/platform/windows/common/windows'; -import { Terminal } from 'xterm'; import { timeout } from 'vs/base/common/async'; -import { coalesce } from 'vs/base/common/arrays'; +import { BaseWindowDriver } from 'vs/platform/driver/browser/baseDriver'; -function serializeElement(element: Element, recursive: boolean): IElement { - const attributes = Object.create(null); - - for (let j = 0; j < element.attributes.length; j++) { - const attr = element.attributes.item(j); - if (attr) { - attributes[attr.name] = attr.value; - } - } - - const children: IElement[] = []; - - if (recursive) { - for (let i = 0; i < element.children.length; i++) { - const child = element.children.item(i); - if (child) { - children.push(serializeElement(child, true)); - } - } - } - - const { left, top } = getTopLeftOffset(element as HTMLElement); - - return { - tagName: element.tagName, - className: element.className, - textContent: element.textContent || '', - attributes, - children, - left, - top - }; -} - -class WindowDriver implements IWindowDriver { +class WindowDriver extends BaseWindowDriver { constructor( @IWindowService private readonly windowService: IWindowService - ) { } + ) { + super(); + } click(selector: string, xoffset?: number, yoffset?: number): Promise { const offset = typeof xoffset === 'number' && typeof yoffset === 'number' ? { x: xoffset, y: yoffset } : undefined; @@ -99,116 +66,6 @@ class WindowDriver implements IWindowDriver { await timeout(100); } - async setValue(selector: string, text: string): Promise { - const element = document.querySelector(selector); - - if (!element) { - return Promise.reject(new Error(`Element not found: ${selector}`)); - } - - const inputElement = element as HTMLInputElement; - inputElement.value = text; - - const event = new Event('input', { bubbles: true, cancelable: true }); - inputElement.dispatchEvent(event); - } - - async getTitle(): Promise { - return document.title; - } - - async isActiveElement(selector: string): Promise { - const element = document.querySelector(selector); - - if (element !== document.activeElement) { - const chain: string[] = []; - let el = document.activeElement; - - while (el) { - const tagName = el.tagName; - const id = el.id ? `#${el.id}` : ''; - const classes = coalesce(el.className.split(/\s+/g).map(c => c.trim())).map(c => `.${c}`).join(''); - chain.unshift(`${tagName}${id}${classes}`); - - el = el.parentElement; - } - - throw new Error(`Active element not found. Current active element is '${chain.join(' > ')}'. Looking for ${selector}`); - } - - return true; - } - - async getElements(selector: string, recursive: boolean): Promise { - const query = document.querySelectorAll(selector); - const result: IElement[] = []; - - for (let i = 0; i < query.length; i++) { - const element = query.item(i); - result.push(serializeElement(element, recursive)); - } - - return result; - } - - async typeInEditor(selector: string, text: string): Promise { - const element = document.querySelector(selector); - - if (!element) { - throw new Error(`Editor not found: ${selector}`); - } - - const textarea = element as HTMLTextAreaElement; - const start = textarea.selectionStart; - const newStart = start + text.length; - const value = textarea.value; - const newValue = value.substr(0, start) + text + value.substr(start); - - textarea.value = newValue; - textarea.setSelectionRange(newStart, newStart); - - const event = new Event('input', { 'bubbles': true, 'cancelable': true }); - textarea.dispatchEvent(event); - } - - async getTerminalBuffer(selector: string): Promise { - const element = document.querySelector(selector); - - if (!element) { - throw new Error(`Terminal not found: ${selector}`); - } - - const xterm: Terminal = (element as any).xterm; - - if (!xterm) { - throw new Error(`Xterm not found: ${selector}`); - } - - const lines: string[] = []; - - for (let i = 0; i < xterm.buffer.length; i++) { - lines.push(xterm.buffer.getLine(i)!.translateToString(true)); - } - - return lines; - } - - async writeInTerminal(selector: string, text: string): Promise { - const element = document.querySelector(selector); - - if (!element) { - throw new Error(`Element not found: ${selector}`); - } - - const xterm: Terminal = (element as any).xterm; - - if (!xterm) { - throw new Error(`Xterm not found: ${selector}`); - } - - xterm._core._coreService.triggerDataEvent(text); - } - async openDevTools(): Promise { await this.windowService.openDevTools({ mode: 'detach' }); } diff --git a/test/smoke/package.json b/test/smoke/package.json index 11b5662b207..24d4cc743ae 100644 --- a/test/smoke/package.json +++ b/test/smoke/package.json @@ -18,6 +18,7 @@ "@types/mocha": "2.2.41", "@types/ncp": "2.0.1", "@types/node": "^10.14.8", + "@types/puppeteer": "^1.19.0", "@types/rimraf": "2.0.2", "@types/webdriverio": "4.6.1", "concurrently": "^3.5.1", diff --git a/test/smoke/src/main.ts b/test/smoke/src/main.ts index 3060b27d93c..935b16fb46c 100644 --- a/test/smoke/src/main.ts +++ b/test/smoke/src/main.ts @@ -236,7 +236,9 @@ after(async function () { await new Promise((c, e) => rimraf(testDataPath, { maxBusyTries: 10 }, err => err ? e(err) : c())); }); -setupDataMigrationTests(stableCodePath, testDataPath); +if (!opts.web) { + setupDataMigrationTests(stableCodePath, testDataPath); +} describe('Running Code', () => { before(async function () { @@ -271,6 +273,7 @@ describe('Running Code', () => { } if (opts.web) { + console.log('setup term tests only'); setupTerminalTests(); return; } @@ -290,4 +293,6 @@ describe('Running Code', () => { setupDataLocalizationTests(); }); -setupLaunchTests(); \ No newline at end of file +if (!opts.web) { + setupLaunchTests(); +} diff --git a/test/smoke/src/vscode/puppeteer-driver.ts b/test/smoke/src/vscode/puppeteer-driver.ts index 42f0c652487..12b56ebd202 100644 --- a/test/smoke/src/vscode/puppeteer-driver.ts +++ b/test/smoke/src/vscode/puppeteer-driver.ts @@ -139,181 +139,28 @@ function buildDriver(browser: puppeteer.Browser, page: puppeteer.Page): IDriver `); await page.mouse.click(x + (xoffset ? xoffset : 0), y + (yoffset ? yoffset : 0)); }, - doubleClick: (windowId, selector) => Promise.resolve(), - setValue: async (windowId, selector, text) => { - return page.evaluate(` - (function() { - const element = document.querySelector('${selector}'); - - if (!element) { - throw new Error('Element not found: ${selector}'); - } - - const inputElement = element; - inputElement.value = '${text}'; - - const event = new Event('input', { bubbles: true, cancelable: true }); - inputElement.dispatchEvent(event); - return true; - })(); - `); + doubleClick: async (windowId, selector) => { + await this.click(windowId, selector, 0, 0); + await timeout(60); + await this.click(windowId, selector, 0, 0); + await timeout(100); }, - getTitle: (windowId) => page.title(), - isActiveElement: (windowId, selector) => { - return page.evaluate(`document.querySelector('${selector}') === document.activeElement`); - }, - getElements: (windowId, selector, recursive) => { - return page.evaluate(` - (function() { - function convertToPixels(element, value) { - return parseFloat(value) || 0; - } - function getDimension(element, cssPropertyName, jsPropertyName) { - let computedStyle = getComputedStyle(element); - let value = '0'; - if (computedStyle) { - if (computedStyle.getPropertyValue) { - value = computedStyle.getPropertyValue(cssPropertyName); - } else { - // IE8 - value = (computedStyle).getAttribute(jsPropertyName); - } - } - return convertToPixels(element, value); - } - function getBorderLeftWidth(element) { - return getDimension(element, 'border-left-width', 'borderLeftWidth'); - } - function getBorderRightWidth(element) { - return getDimension(element, 'border-right-width', 'borderRightWidth'); - } - function getBorderTopWidth(element) { - return getDimension(element, 'border-top-width', 'borderTopWidth'); - } - function getBorderBottomWidth(element) { - return getDimension(element, 'border-bottom-width', 'borderBottomWidth'); - } - function getTopLeftOffset(element) { - // Adapted from WinJS.Utilities.getPosition - // and added borders to the mix - - let offsetParent = element.offsetParent, top = element.offsetTop, left = element.offsetLeft; - - while ((element = element.parentNode) !== null && element !== document.body && element !== document.documentElement) { - top -= element.scrollTop; - let c = getComputedStyle(element); - if (c) { - left -= c.direction !== 'rtl' ? element.scrollLeft : -element.scrollLeft; - } - - if (element === offsetParent) { - left += getBorderLeftWidth(element); - top += getBorderTopWidth(element); - top += element.offsetTop; - left += element.offsetLeft; - offsetParent = element.offsetParent; - } - } - - return { - left: left, - top: top - }; - } - function serializeElement(element, recursive) { - const attributes = Object.create(null); - - for (let j = 0; j < element.attributes.length; j++) { - const attr = element.attributes.item(j); - if (attr) { - attributes[attr.name] = attr.value; - } - } - - const children = []; - - if (recursive) { - for (let i = 0; i < element.children.length; i++) { - const child = element.children.item(i); - if (child) { - children.push(serializeElement(child, true)); - } - } - } - - const { left, top } = getTopLeftOffset(element); - - return { - tagName: element.tagName, - className: element.className, - textContent: element.textContent || '', - attributes, - children, - left, - top - }; - } - - const query = document.querySelectorAll('${selector}'); - const result = []; - - for (let i = 0; i < query.length; i++) { - const element = query.item(i); - result.push(serializeElement(element, ${recursive})); - } - - return result; - })(); - `); - }, - typeInEditor: (windowId, selector, text) => Promise.resolve(), - getTerminalBuffer: (windowId, selector) => { - return page.evaluate(` - (function () { - const element = document.querySelector('${selector}'); - - if (!element) { - throw new Error('Terminal not found: ${selector}'); - } - - const xterm = element.xterm; - - if (!xterm) { - throw new Error('Xterm not found: ${selector}'); - } - - const lines = []; - - for (let i = 0; i < xterm.buffer.length; i++) { - lines.push(xterm.buffer.getLine(i).translateToString(true)); - } - - return lines; - })(); - `); - }, - writeInTerminal: (windowId, selector, text) => { - return page.evaluate(` - (function () { - const element = document.querySelector('${selector}'); - - if (!element) { - throw new Error('Element not found: ${selector}'); - } - - const xterm = element.xterm; - - if (!xterm) { - throw new Error('Xterm not found: ${selector}'); - } - - xterm._core._coreService.triggerDataEvent('${text}'); - })(); - `); - } + setValue: async (windowId, selector, text) => page.evaluate(`window.driver.setValue('${selector}', '${text}')`), + getTitle: (windowId) => page.evaluate(`window.driver.getTitle()`), + isActiveElement: (windowId, selector) => page.evaluate(`window.driver.isActiveElement('${selector}')`), + getElements: (windowId, selector, recursive) => page.evaluate(`window.driver.getElements('${selector}', ${recursive})`), + typeInEditor: (windowId, selector, text) => page.evaluate(`window.driver.typeInEditor('${selector}', '${text}')`), + getTerminalBuffer: (windowId, selector) => page.evaluate(`window.driver.getTerminalBuffer('${selector}')`), + writeInTerminal: (windowId, selector, text) => page.evaluate(`window.driver.writeInTerminal('${selector}', '${text}')`) }; } +function timeout(ms: number): Promise { + return new Promise(r => setTimeout(r, ms)); +} + +// function runInDriver(call: string, args: (string | boolean)[]): Promise {} + let args; export function launch(_args): void { @@ -389,4 +236,4 @@ export interface IDriver { export interface IDisposable { dispose(): void; -} \ No newline at end of file +} diff --git a/test/smoke/yarn.lock b/test/smoke/yarn.lock index b86356d3ac3..7ae63926a20 100644 --- a/test/smoke/yarn.lock +++ b/test/smoke/yarn.lock @@ -54,6 +54,13 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.8.tgz#fe444203ecef1162348cd6deb76c62477b2cc6e9" integrity sha512-I4+DbJEhLEg4/vIy/2gkWDvXBOOtPKV9EnLhYjMoqxcRW+TTZtUftkHktz/a8suoD5mUL7m6ReLrkPvSsCQQmw== +"@types/puppeteer@^1.19.0": + version "1.19.0" + resolved "https://registry.yarnpkg.com/@types/puppeteer/-/puppeteer-1.19.0.tgz#59f0050bae019cee7c3af2bb840a25892a3078b6" + integrity sha512-Db9LWOuTm2bR/qgPE7PQCmnsCQ6flHdULuIDWTks8YdQ/SGHKg5WGWG54gl0734NDKCTF5MbqAp2qWuvBiyQ3Q== + dependencies: + "@types/node" "*" + "@types/rimraf@2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-2.0.2.tgz#7f0fc3cf0ff0ad2a99bb723ae1764f30acaf8b6e" diff --git a/yarn.lock b/yarn.lock index 8c907deb523..46df292dba6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -137,13 +137,6 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.12.tgz#e15a9d034d9210f00320ef718a50c4a799417c47" integrity sha512-Pr+6JRiKkfsFvmU/LK68oBRCQeEg36TyAbPhc2xpez24OOZZCuoIhWGTd39VZy6nGafSbxzGouFPTFD/rR1A0A== -"@types/puppeteer@^1.12.4": - version "1.12.4" - resolved "https://registry.yarnpkg.com/@types/puppeteer/-/puppeteer-1.12.4.tgz#8388efdb0b30a54a7e7c4831ca0d709191d77ff1" - integrity sha512-aaGbJaJ9TuF9vZfTeoh876sBa+rYJWPwtsmHmYr28pGr42ewJnkDTq2aeSKEmS39SqUdkwLj73y/d7rBSp7mDQ== - dependencies: - "@types/node" "*" - "@types/semver@^5.4.0", "@types/semver@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.5.0.tgz#146c2a29ee7d3bae4bf2fcb274636e264c813c45" From 60684fbad3739a18eaa866cfdc2f0ccab1ecf13f Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 30 Jul 2019 15:57:51 +0200 Subject: [PATCH 083/861] Fix horizontal scrolling in custom tree view by fixing the tree width, which was not being set Fixes #78177 --- .../browser/parts/views/customView.ts | 24 ++++++++++--------- src/vs/workbench/common/views.ts | 2 +- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/browser/parts/views/customView.ts b/src/vs/workbench/browser/parts/views/customView.ts index 9dedb437fcf..d6557daf7a1 100644 --- a/src/vs/workbench/browser/parts/views/customView.ts +++ b/src/vs/workbench/browser/parts/views/customView.ts @@ -76,8 +76,8 @@ export class CustomTreeViewPanel extends ViewletPanel { this.treeView.show(container); } - layoutBody(size: number): void { - this.treeView.layout(size); + layoutBody(height: number, width: number): void { + this.treeView.layout(height, width); } getActions(): IAction[] { @@ -481,14 +481,14 @@ export class CustomTreeView extends Disposable implements ITreeView { this.markdownResult = this.markdownRenderer.render(this._messageValue); DOM.append(this.messageElement, this.markdownResult.element); } - this.layout(this._size); + this.layout(this._height, this._width); } } private hideMessage(): void { this.resetMessageElement(); DOM.addClass(this.messageElement, 'hide'); - this.layout(this._size); + this.layout(this._height, this._width); } private resetMessageElement(): void { @@ -499,14 +499,16 @@ export class CustomTreeView extends Disposable implements ITreeView { DOM.clearNode(this.messageElement); } - private _size: number; - layout(size: number) { - if (size) { - this._size = size; - const treeSize = size - DOM.getTotalHeight(this.messageElement); - this.treeContainer.style.height = treeSize + 'px'; + private _height: number; + private _width: number; + layout(height: number, width: number) { + if (height && width) { + this._height = height; + this._width = width; + const treeHeight = height - DOM.getTotalHeight(this.messageElement); + this.treeContainer.style.height = treeHeight + 'px'; if (this.tree) { - this.tree.layout(treeSize); + this.tree.layout(treeHeight, width); } } } diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index 6f5386ee4a8..ed734711561 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -325,7 +325,7 @@ export interface ITreeView extends IDisposable { focus(): void; - layout(height: number): void; + layout(height: number, width: number): void; show(container: HTMLElement): void; From 8db973db62993c25a9e0e1d78153172b620c7798 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Tue, 30 Jul 2019 15:40:19 +0200 Subject: [PATCH 084/861] Adopt latest loader (throws Error objects) --- src/vs/loader.js | 53 +++++++++++++++------------ src/vs/workbench/browser/workbench.ts | 18 ++++++++- 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/src/vs/loader.js b/src/vs/loader.js index e3bebe82544..be131c2a443 100644 --- a/src/vs/loader.js +++ b/src/vs/loader.js @@ -235,6 +235,17 @@ var AMDLoader; *--------------------------------------------------------------------------------------------*/ var AMDLoader; (function (AMDLoader) { + function ensureError(err) { + if (err instanceof Error) { + return err; + } + var result = new Error(err.message || String(err) || 'Unknown Error'); + if (err.stack) { + result.stack = err.stack; + } + return result; + } + AMDLoader.ensureError = ensureError; ; var ConfigurationOptionsUtil = /** @class */ (function () { function ConfigurationOptionsUtil() { @@ -244,22 +255,16 @@ var AMDLoader; */ ConfigurationOptionsUtil.validateConfigurationOptions = function (options) { function defaultOnError(err) { - if (err.errorCode === 'load') { + if (err.phase === 'loading') { console.error('Loading "' + err.moduleId + '" failed'); - console.error('Detail: ', err.detail); - if (err.detail && err.detail.stack) { - console.error(err.detail.stack); - } + console.error(err); console.error('Here are the modules that depend on it:'); console.error(err.neededBy); return; } - if (err.errorCode === 'factory') { + if (err.phase === 'factory') { console.error('The factory method of "' + err.moduleId + '" has thrown an exception'); - console.error(err.detail); - if (err.detail && err.detail.stack) { - console.error(err.detail.stack); - } + console.error(err); return; } } @@ -302,7 +307,7 @@ var AMDLoader; if (!Array.isArray(options.nodeModules)) { options.nodeModules = []; } - if (typeof options.nodeCachedData === 'object') { + if (options.nodeCachedData && typeof options.nodeCachedData === 'object') { if (typeof options.nodeCachedData.seed !== 'string') { options.nodeCachedData.seed = 'seed'; } @@ -310,7 +315,9 @@ var AMDLoader; options.nodeCachedData.writeDelay = 1000 * 7; } if (!options.nodeCachedData.path || typeof options.nodeCachedData.path !== 'string') { - options.onError('INVALID cached data configuration, \'path\' MUST be set'); + var err = ensureError(new Error('INVALID cached data configuration, \'path\' MUST be set')); + err.phase = 'configuration'; + options.onError(err); options.nodeCachedData = undefined; } } @@ -1007,11 +1014,10 @@ var AMDLoader; } } if (producedError) { - config.onError({ - errorCode: 'factory', - moduleId: this.strId, - detail: producedError - }); + var err = AMDLoader.ensureError(producedError); + err.phase = 'factory'; + err.moduleId = this.strId; + config.onError(err); } this.dependencies = null; this._callback = null; @@ -1301,16 +1307,15 @@ var AMDLoader; this.defineModule(this._moduleIdProvider.getStrModuleId(moduleId), defineCall.dependencies, defineCall.callback, null, defineCall.stack); } }; - ModuleManager.prototype._createLoadError = function (moduleId, err) { + ModuleManager.prototype._createLoadError = function (moduleId, _err) { var _this = this; var strModuleId = this._moduleIdProvider.getStrModuleId(moduleId); var neededBy = (this._inverseDependencies2[moduleId] || []).map(function (intModuleId) { return _this._moduleIdProvider.getStrModuleId(intModuleId); }); - return { - errorCode: 'load', - moduleId: strModuleId, - neededBy: neededBy, - detail: err - }; + var err = AMDLoader.ensureError(_err); + err.phase = 'loading'; + err.moduleId = strModuleId; + err.neededBy = neededBy; + return err; }; /** * Callback from the scriptLoader when a module hasn't been loaded. diff --git a/src/vs/workbench/browser/workbench.ts b/src/vs/workbench/browser/workbench.ts index 634655ffa84..aa5a918fc23 100644 --- a/src/vs/workbench/browser/workbench.ts +++ b/src/vs/workbench/browser/workbench.ts @@ -79,11 +79,25 @@ export class Workbench extends Layout { setUnexpectedErrorHandler(error => this.handleUnexpectedError(error, logService)); // Inform user about loading issues from the loader + interface AnnotatedLoadingError extends Error { + phase: 'loading'; + moduleId: string; + neededBy: string[]; + } + interface AnnotatedFactoryError extends Error { + phase: 'factory'; + moduleId: string; + } + interface AnnotatedValidationError extends Error { + phase: 'configuration'; + } + type AnnotatedError = AnnotatedLoadingError | AnnotatedFactoryError | AnnotatedValidationError; (window).require.config({ - onError: (err: { errorCode: string; }) => { - if (err.errorCode === 'load') { + onError: (err: AnnotatedError) => { + if (err.phase === 'loading') { onUnexpectedError(new Error(localize('loaderErrorNative', "Failed to load a required file. Please restart the application to try again. Details: {0}", JSON.stringify(err)))); } + console.error(err); } }); } From d04d9d17c86640f45c528ec43443e67e5e981a10 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Tue, 30 Jul 2019 16:08:19 +0200 Subject: [PATCH 085/861] Update to latest loader --- src/vs/loader.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/vs/loader.js b/src/vs/loader.js index be131c2a443..8445bbeff3f 100644 --- a/src/vs/loader.js +++ b/src/vs/loader.js @@ -963,6 +963,7 @@ var AMDLoader; this._errorback = errorback; this.moduleIdResolver = moduleIdResolver; this.exports = {}; + this.error = null; this.exportsPassedIn = false; this.unresolvedDependenciesCount = this.dependencies.length; this._isComplete = false; @@ -1017,6 +1018,7 @@ var AMDLoader; var err = AMDLoader.ensureError(producedError); err.phase = 'factory'; err.moduleId = this.strId; + this.error = err; config.onError(err); } this.dependencies = null; @@ -1028,6 +1030,8 @@ var AMDLoader; * One of the direct dependencies or a transitive dependency has failed to load. */ Module.prototype.onDependencyError = function (err) { + this._isComplete = true; + this.error = err; if (this._errorback) { this._errorback(err); return true; @@ -1278,6 +1282,9 @@ var AMDLoader; if (!m.isComplete()) { throw new Error('Check dependency list! Synchronous require cannot resolve module \'' + _strModuleId + '\'. This module has not been resolved completely yet.'); } + if (m.error) { + throw m.error; + } return m.exports; }; ModuleManager.prototype.configure = function (params, shouldOverwrite) { @@ -1323,6 +1330,9 @@ var AMDLoader; */ ModuleManager.prototype._onLoadError = function (moduleId, err) { var error = this._createLoadError(moduleId, err); + if (!this._modules2[moduleId]) { + this._modules2[moduleId] = new Module(moduleId, this._moduleIdProvider.getStrModuleId(moduleId), [], function () { }, function () { }, null); + } // Find any 'local' error handlers, walk the entire chain of inverse dependencies if necessary. var seenModuleId = []; for (var i = 0, len = this._moduleIdProvider.getMaxModuleId(); i < len; i++) { @@ -1530,6 +1540,10 @@ var AMDLoader; } var dependencyModule = this._modules2[dependency.id]; if (dependencyModule && dependencyModule.isComplete()) { + if (dependencyModule.error) { + module.onDependencyError(dependencyModule.error); + return; + } module.unresolvedDependenciesCount--; continue; } From 327832422c19a2118992dcc5dd4acd42a69c37cc Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Tue, 30 Jul 2019 16:37:15 +0200 Subject: [PATCH 086/861] scripts/code.sh: remove -x --- scripts/code.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/code.sh b/scripts/code.sh index 830271adff6..542efab5237 100755 --- a/scripts/code.sh +++ b/scripts/code.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -set -ex +set -e if [[ "$OSTYPE" == "darwin"* ]]; then realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; } From 716788a90445c75d07f0ea7e5971d454770ccbb6 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Tue, 30 Jul 2019 10:40:48 -0400 Subject: [PATCH 087/861] Renames ${qs} to ${query} --- .../services/label/common/labelService.ts | 6 +++--- .../workbench/services/label/test/label.test.ts | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/services/label/common/labelService.ts b/src/vs/workbench/services/label/common/labelService.ts index 7042c156bfc..a8e2290be22 100644 --- a/src/vs/workbench/services/label/common/labelService.ts +++ b/src/vs/workbench/services/label/common/labelService.ts @@ -68,7 +68,7 @@ const resourceLabelFormattersExtPoint = ExtensionsRegistry.registerExtensionPoin }); const sepRegexp = /\//g; -const labelMatchingRegexp = /\$\{(scheme|authority|path|(qs)\.(.+?))\}/g; +const labelMatchingRegexp = /\$\{(scheme|authority|path|(query)\.(.+?))\}/g; function hasDriveLetter(path: string): boolean { return !!(isWindows && path && path[2] === ':'); @@ -228,7 +228,7 @@ export class LabelService implements ILabelService { case 'authority': return resource.authority; case 'path': return resource.path; default: { - if (qsToken === 'qs') { + if (qsToken === 'query') { const { query } = resource; if (query && query[0] === '{' && query[query.length - 1] === '}') { try { @@ -276,4 +276,4 @@ export class LabelService implements ILabelService { } } -registerSingleton(ILabelService, LabelService, true); \ No newline at end of file +registerSingleton(ILabelService, LabelService, true); diff --git a/src/vs/workbench/services/label/test/label.test.ts b/src/vs/workbench/services/label/test/label.test.ts index 891c928fc34..ee4650f4d2b 100644 --- a/src/vs/workbench/services/label/test/label.test.ts +++ b/src/vs/workbench/services/label/test/label.test.ts @@ -98,11 +98,11 @@ suite('URI Label', () => { assert.equal(labelService.getUriLabel(uri1, { relative: false }), 'second'); }); - test('custom qs', function () { + test('custom query', function () { labelService.registerFormatter({ scheme: 'vscode', formatting: { - label: 'LABEL${qs.prefix}: ${qs.path}/END', + label: 'LABEL${query.prefix}: ${query.path}/END', separator: '/', tildify: true, normalizeDriveLetter: true @@ -113,11 +113,11 @@ suite('URI Label', () => { assert.equal(labelService.getUriLabel(uri1, { relative: false }), 'LABELprefix: path/END'); }); - test('custom qs without value', function () { + test('custom query without value', function () { labelService.registerFormatter({ scheme: 'vscode', formatting: { - label: 'LABEL${qs.prefix}: ${qs.path}/END', + label: 'LABEL${query.prefix}: ${query.path}/END', separator: '/', tildify: true, normalizeDriveLetter: true @@ -128,11 +128,11 @@ suite('URI Label', () => { assert.equal(labelService.getUriLabel(uri1, { relative: false }), 'LABEL: path/END'); }); - test('custom qs without query json', function () { + test('custom query without query json', function () { labelService.registerFormatter({ scheme: 'vscode', formatting: { - label: 'LABEL${qs.prefix}: ${qs.path}/END', + label: 'LABEL${query.prefix}: ${query.path}/END', separator: '/', tildify: true, normalizeDriveLetter: true @@ -143,11 +143,11 @@ suite('URI Label', () => { assert.equal(labelService.getUriLabel(uri1, { relative: false }), 'LABEL: /END'); }); - test('custom qs without query', function () { + test('custom query without query', function () { labelService.registerFormatter({ scheme: 'vscode', formatting: { - label: 'LABEL${qs.prefix}: ${qs.path}/END', + label: 'LABEL${query.prefix}: ${query.path}/END', separator: '/', tildify: true, normalizeDriveLetter: true From f2f21da86fda600c6fbc6609799b956b1eea6265 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 30 Jul 2019 16:58:56 +0200 Subject: [PATCH 088/861] fixes #74103 --- src/vs/code/electron-main/main.ts | 18 +++++++++++++----- .../environment/node/environmentService.ts | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index 71891c9bafd..c6301eb4a33 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -23,7 +23,7 @@ import { ILogService, ConsoleLogMainService, MultiplexLogService, getLogLevel } import { StateService } from 'vs/platform/state/node/stateService'; import { IStateService } from 'vs/platform/state/common/state'; import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment'; -import { EnvironmentService } from 'vs/platform/environment/node/environmentService'; +import { EnvironmentService, xdgRuntimeDir } from 'vs/platform/environment/node/environmentService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ConfigurationService } from 'vs/platform/configuration/node/configurationService'; import { IRequestService } from 'vs/platform/request/common/request'; @@ -330,11 +330,19 @@ class CodeMain { private handleStartupDataDirError(environmentService: IEnvironmentService, error: NodeJS.ErrnoException): void { if (error.code === 'EACCES' || error.code === 'EPERM') { + const directories = [environmentService.userDataPath]; + + if (environmentService.extensionsPath) { + directories.push(environmentService.extensionsPath); + } + + if (xdgRuntimeDir) { + directories.push(xdgRuntimeDir); + } + this.showStartupWarningDialog( localize('startupDataDirError', "Unable to write program user data."), - environmentService.extensionsPath - ? localize('startupUserDataAndExtensionsDirErrorDetail', "Please make sure the directories {0} and {1} are writeable.", environmentService.userDataPath, environmentService.extensionsPath) - : localize('startupUserDataDirErrorDetail', "Please make sure the directory {0} is writeable.", environmentService.userDataPath) + localize('startupUserDataAndExtensionsDirErrorDetail', "Please make sure the following directories are writeable:\n\n{0}", directories.join('\n')) ); } } @@ -392,4 +400,4 @@ class CodeMain { // Main Startup const code = new CodeMain(); -code.main(); \ No newline at end of file +code.main(); diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index e4635b7fc32..9373b22383b 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -19,7 +19,7 @@ import { URI } from 'vs/base/common/uri'; // Read this before there's any chance it is overwritten // Related to https://github.com/Microsoft/vscode/issues/30624 -const xdgRuntimeDir = process.env['XDG_RUNTIME_DIR']; +export const xdgRuntimeDir = process.env['XDG_RUNTIME_DIR']; function getNixIPCHandle(userDataPath: string, type: string): string { const vscodePortable = process.env['VSCODE_PORTABLE']; From 9bbf3f25d50ba79b5c40b4ed79adf482b2356925 Mon Sep 17 00:00:00 2001 From: Gabriel DeBacker Date: Tue, 30 Jul 2019 08:20:29 -0700 Subject: [PATCH 089/861] Make sure that task definition is not changed in resolved task --- src/vs/workbench/api/node/extHostTask.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index e71fb134985..57105c22813 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -741,6 +741,10 @@ export class ExtHostTask implements ExtHostTaskShape { throw new Error('Unexpected: Task cannot be resolved.'); } + if (resolvedTask.definition !== task.definition) { + throw new Error('Unexpected: A task definition cannot be modified when resolving a task.'); + } + if (CustomExecutionDTO.is(resolvedTaskDTO.execution)) { await this.addCustomExecution(resolvedTaskDTO, resolvedTask); } From f2b65a9601b57778cc15bfd240905132bc25e436 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 30 Jul 2019 17:21:15 +0200 Subject: [PATCH 090/861] Fix opening of tree items with keyboard (#78187) Up until very recently, the custom tree used a TreeResourceNavigator2 with openOnSelection: true. This caused command to be executed twice on clicks though. Once on the selection and once on the click. Setting that to false caused the enter key to stop causing commands to run though. This was because the enter key was only causing the selection to trigger, not the open. The Open event was getting swallowed before it made it out of the tree because it was missing a UIEvent. Adding the UIEvent in here fixes that Fixes #78174 --- src/vs/base/browser/ui/tree/asyncDataTree.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/tree/asyncDataTree.ts b/src/vs/base/browser/ui/tree/asyncDataTree.ts index 4421bce8de1..86eaeb31618 100644 --- a/src/vs/base/browser/ui/tree/asyncDataTree.ts +++ b/src/vs/base/browser/ui/tree/asyncDataTree.ts @@ -602,9 +602,9 @@ export class AsyncDataTree implements IDisposable return nodes.map(n => n!.element as T); } - open(elements: T[]): void { + open(elements: T[], browserEvent?: UIEvent): void { const nodes = elements.map(e => this.getDataNode(e)); - this.tree.open(nodes); + this.tree.open(nodes, browserEvent); } reveal(element: T, relativeTop?: number): void { From 5e135c4cafc7df9fd117f1398afdc958645cf426 Mon Sep 17 00:00:00 2001 From: Gabriel DeBacker Date: Tue, 30 Jul 2019 08:35:06 -0700 Subject: [PATCH 091/861] Make exception error more accurate --- src/vs/workbench/api/node/extHostTask.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index 57105c22813..5c6a6a2c2f3 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -742,7 +742,7 @@ export class ExtHostTask implements ExtHostTaskShape { } if (resolvedTask.definition !== task.definition) { - throw new Error('Unexpected: A task definition cannot be modified when resolving a task.'); + throw new Error('Unexpected: The resolved task definition must be the same object as the original task definition. The task definition cannot be changed.'); } if (CustomExecutionDTO.is(resolvedTaskDTO.execution)) { From b54d77256281a58ff49627db4ee716b6e877ae49 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Tue, 30 Jul 2019 09:06:23 -0700 Subject: [PATCH 092/861] List possible categories (#78198) * List possible categories * TODO comment * Message if category is invalid --- src/vs/code/node/cliProcessMain.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index 032287a3b5d..d9ed94ff68e 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -112,7 +112,13 @@ export class Main { private async listExtensions(showVersions: boolean, category?: string): Promise { let extensions = await this.extensionManagementService.getInstalled(ExtensionType.User); - if (category) { + // TODO: we should save this array in a common place so that the command and extensionQuery can use it that way changing it is easier + const categories = ['"programming languages"', 'snippets', 'linters', 'themes', 'debuggers', 'formatters', 'keymaps', '"scm providers"', 'other', '"extension packs"', '"language packs"']; + if (category && category !== '') { + if (categories.indexOf(category.toLowerCase()) < 0) { + console.log('Invalid category please enter a valid category. To list valid categories run --category without a category specified'); + return; + } extensions = extensions.filter(e => { if (e.manifest.categories) { const lowerCaseCategories: string[] = e.manifest.categories.map(c => c.toLowerCase()); @@ -120,6 +126,12 @@ export class Main { } return false; }); + } else if (category === '') { + console.log('Possible Categories: '); + categories.forEach(category => { + console.log(category); + }); + return; } extensions.forEach(e => console.log(getId(e.manifest, showVersions))); } @@ -369,4 +381,4 @@ export async function main(argv: ParsedArgs): Promise { disposables.dispose(); } }); -} \ No newline at end of file +} From 148f67d786ebfdc918998ad128c7eda2b0c49015 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 30 Jul 2019 18:16:19 +0200 Subject: [PATCH 093/861] when running integration tests, use memfs instead of fs --- extensions/vscode-api-tests/src/memfs.ts | 229 ++++++++++++++++++ .../src/singlefolder-tests/languages.test.ts | 4 +- .../src/singlefolder-tests/workspace.test.ts | 12 +- extensions/vscode-api-tests/src/utils.ts | 57 ++--- 4 files changed, 260 insertions(+), 42 deletions(-) create mode 100644 extensions/vscode-api-tests/src/memfs.ts diff --git a/extensions/vscode-api-tests/src/memfs.ts b/extensions/vscode-api-tests/src/memfs.ts new file mode 100644 index 00000000000..2b4a5f751ab --- /dev/null +++ b/extensions/vscode-api-tests/src/memfs.ts @@ -0,0 +1,229 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + + +import * as path from 'path'; +import * as vscode from 'vscode'; + +class File implements vscode.FileStat { + + type: vscode.FileType; + ctime: number; + mtime: number; + size: number; + + name: string; + data?: Uint8Array; + + constructor(name: string) { + this.type = vscode.FileType.File; + this.ctime = Date.now(); + this.mtime = Date.now(); + this.size = 0; + this.name = name; + } +} + +class Directory implements vscode.FileStat { + + type: vscode.FileType; + ctime: number; + mtime: number; + size: number; + + name: string; + entries: Map; + + constructor(name: string) { + this.type = vscode.FileType.Directory; + this.ctime = Date.now(); + this.mtime = Date.now(); + this.size = 0; + this.name = name; + this.entries = new Map(); + } +} + +export type Entry = File | Directory; + +export class MemFS implements vscode.FileSystemProvider { + + readonly scheme = 'fake-fs'; + + readonly root = new Directory(''); + + // --- manage file metadata + + stat(uri: vscode.Uri): vscode.FileStat { + return this._lookup(uri, false); + } + + readDirectory(uri: vscode.Uri): [string, vscode.FileType][] { + const entry = this._lookupAsDirectory(uri, false); + let result: [string, vscode.FileType][] = []; + for (const [name, child] of entry.entries) { + result.push([name, child.type]); + } + return result; + } + + // --- manage file contents + + readFile(uri: vscode.Uri): Uint8Array { + const data = this._lookupAsFile(uri, false).data; + if (data) { + return data; + } + throw vscode.FileSystemError.FileNotFound(); + } + + writeFile(uri: vscode.Uri, content: Uint8Array, options: { create: boolean, overwrite: boolean }): void { + let basename = path.posix.basename(uri.path); + let parent = this._lookupParentDirectory(uri); + let entry = parent.entries.get(basename); + if (entry instanceof Directory) { + throw vscode.FileSystemError.FileIsADirectory(uri); + } + if (!entry && !options.create) { + throw vscode.FileSystemError.FileNotFound(uri); + } + if (entry && options.create && !options.overwrite) { + throw vscode.FileSystemError.FileExists(uri); + } + if (!entry) { + entry = new File(basename); + parent.entries.set(basename, entry); + this._fireSoon({ type: vscode.FileChangeType.Created, uri }); + } + entry.mtime = Date.now(); + entry.size = content.byteLength; + entry.data = content; + + this._fireSoon({ type: vscode.FileChangeType.Changed, uri }); + } + + // --- manage files/folders + + rename(oldUri: vscode.Uri, newUri: vscode.Uri, options: { overwrite: boolean }): void { + + if (!options.overwrite && this._lookup(newUri, true)) { + throw vscode.FileSystemError.FileExists(newUri); + } + + let entry = this._lookup(oldUri, false); + let oldParent = this._lookupParentDirectory(oldUri); + + let newParent = this._lookupParentDirectory(newUri); + let newName = path.posix.basename(newUri.path); + + oldParent.entries.delete(entry.name); + entry.name = newName; + newParent.entries.set(newName, entry); + + this._fireSoon( + { type: vscode.FileChangeType.Deleted, uri: oldUri }, + { type: vscode.FileChangeType.Created, uri: newUri } + ); + } + + delete(uri: vscode.Uri): void { + let dirname = uri.with({ path: path.posix.dirname(uri.path) }); + let basename = path.posix.basename(uri.path); + let parent = this._lookupAsDirectory(dirname, false); + if (!parent.entries.has(basename)) { + throw vscode.FileSystemError.FileNotFound(uri); + } + parent.entries.delete(basename); + parent.mtime = Date.now(); + parent.size -= 1; + this._fireSoon({ type: vscode.FileChangeType.Changed, uri: dirname }, { uri, type: vscode.FileChangeType.Deleted }); + } + + createDirectory(uri: vscode.Uri): void { + let basename = path.posix.basename(uri.path); + let dirname = uri.with({ path: path.posix.dirname(uri.path) }); + let parent = this._lookupAsDirectory(dirname, false); + + let entry = new Directory(basename); + parent.entries.set(entry.name, entry); + parent.mtime = Date.now(); + parent.size += 1; + this._fireSoon({ type: vscode.FileChangeType.Changed, uri: dirname }, { type: vscode.FileChangeType.Created, uri }); + } + + // --- lookup + + private _lookup(uri: vscode.Uri, silent: false): Entry; + private _lookup(uri: vscode.Uri, silent: boolean): Entry | undefined; + private _lookup(uri: vscode.Uri, silent: boolean): Entry | undefined { + let parts = uri.path.split('/'); + let entry: Entry = this.root; + for (const part of parts) { + if (!part) { + continue; + } + let child: Entry | undefined; + if (entry instanceof Directory) { + child = entry.entries.get(part); + } + if (!child) { + if (!silent) { + throw vscode.FileSystemError.FileNotFound(uri); + } else { + return undefined; + } + } + entry = child; + } + return entry; + } + + private _lookupAsDirectory(uri: vscode.Uri, silent: boolean): Directory { + let entry = this._lookup(uri, silent); + if (entry instanceof Directory) { + return entry; + } + throw vscode.FileSystemError.FileNotADirectory(uri); + } + + private _lookupAsFile(uri: vscode.Uri, silent: boolean): File { + let entry = this._lookup(uri, silent); + if (entry instanceof File) { + return entry; + } + throw vscode.FileSystemError.FileIsADirectory(uri); + } + + private _lookupParentDirectory(uri: vscode.Uri): Directory { + const dirname = uri.with({ path: path.posix.dirname(uri.path) }); + return this._lookupAsDirectory(dirname, false); + } + + // --- manage file events + + private _emitter = new vscode.EventEmitter(); + private _bufferedEvents: vscode.FileChangeEvent[] = []; + private _fireSoonHandle?: NodeJS.Timer; + + readonly onDidChangeFile: vscode.Event = this._emitter.event; + + watch(_resource: vscode.Uri): vscode.Disposable { + // ignore, fires for all changes... + return new vscode.Disposable(() => { }); + } + + private _fireSoon(...events: vscode.FileChangeEvent[]): void { + this._bufferedEvents.push(...events); + + if (this._fireSoonHandle) { + clearTimeout(this._fireSoonHandle); + } + + this._fireSoonHandle = setTimeout(() => { + this._emitter.fire(this._bufferedEvents); + this._bufferedEvents.length = 0; + }, 5); + } +} diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/languages.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/languages.test.ts index 81c9c2eeadf..0a828ad8d73 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/languages.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/languages.test.ts @@ -6,7 +6,7 @@ import * as assert from 'assert'; import { join } from 'path'; import * as vscode from 'vscode'; -import { createRandomFile } from '../utils'; +import { createRandomFile, testFs } from '../utils'; suite('languages namespace tests', () => { @@ -103,7 +103,7 @@ suite('languages namespace tests', () => { return [new vscode.DocumentLink(range, target)]; } }; - vscode.languages.registerDocumentLinkProvider({ language: 'java', scheme: 'file' }, linkProvider); + vscode.languages.registerDocumentLinkProvider({ language: 'java', scheme: testFs.scheme }, linkProvider); const links = await vscode.commands.executeCommand('vscode.executeLinkProvider', doc.uri); assert.equal(2, links && links.length); diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts index 898a41247c3..3617b55f41c 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts @@ -5,10 +5,9 @@ import * as assert from 'assert'; import * as vscode from 'vscode'; -import { createRandomFile, deleteFile, closeAllEditors, pathEquals, rndName, disposeAll } from '../utils'; +import { createRandomFile, deleteFile, closeAllEditors, pathEquals, rndName, disposeAll, testFs } from '../utils'; import { join, posix, basename } from 'path'; import * as fs from 'fs'; -import * as os from 'os'; suite('workspace-namespace', () => { @@ -131,8 +130,7 @@ suite('workspace-namespace', () => { assert.ok(fs.existsSync(path)); d0.dispose(); - - return deleteFile(vscode.Uri.file(join(vscode.workspace.rootPath || '', './newfile.txt'))); + fs.unlinkSync(join(vscode.workspace.rootPath || '', './newfile.txt')); }); }); @@ -702,10 +700,8 @@ suite('workspace-namespace', () => { test('WorkspaceEdit: edit and rename parent folder duplicates resource #42641', async function () { - let dir = join(os.tmpdir(), 'before-' + rndName()); - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir); - } + let dir = vscode.Uri.parse(`${testFs.scheme}:/before-${rndName()}`); + await testFs.createDirectory(dir); let docUri = await createRandomFile('', dir); let docParent = docUri.with({ path: posix.dirname(docUri.path) }); diff --git a/extensions/vscode-api-tests/src/utils.ts b/extensions/vscode-api-tests/src/utils.ts index d9fda3bb76d..38ede848840 100644 --- a/extensions/vscode-api-tests/src/utils.ts +++ b/extensions/vscode-api-tests/src/utils.ts @@ -4,25 +4,35 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import * as fs from 'fs'; -import * as os from 'os'; -import { join } from 'path'; +import { MemFS } from './memfs'; +import * as assert from 'assert'; export function rndName() { return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 10); } -export function createRandomFile(contents = '', dir: string = os.tmpdir(), ext = ''): Thenable { - return new Promise((resolve, reject) => { - const tmpFile = join(dir, rndName() + ext); - fs.writeFile(tmpFile, contents, (error) => { - if (error) { - return reject(error); - } +export const testFs = new MemFS(); +vscode.workspace.registerFileSystemProvider(testFs.scheme, testFs); - resolve(vscode.Uri.file(tmpFile)); - }); - }); +export async function createRandomFile(contents = '', dir: vscode.Uri | undefined = undefined, ext = ''): Promise { + let fakeFile: vscode.Uri; + if (dir) { + assert.equal(dir.scheme, testFs.scheme); + fakeFile = dir.with({ path: dir.path + '/' + rndName() + ext }); + } else { + fakeFile = vscode.Uri.parse(`${testFs.scheme}:/${rndName() + ext}`); + } + await testFs.writeFile(fakeFile, Buffer.from(contents), { create: true, overwrite: true }); + return fakeFile; +} + +export async function deleteFile(file: vscode.Uri): Promise { + try { + await testFs.delete(file); + return true; + } catch { + return false; + } } export function pathEquals(path1: string, path2: string): boolean { @@ -34,30 +44,13 @@ export function pathEquals(path1: string, path2: string): boolean { return path1 === path2; } -export function deleteFile(file: vscode.Uri): Thenable { - return new Promise((resolve, reject) => { - fs.unlink(file.fsPath, (err) => { - if (err) { - reject(err); - } else { - resolve(true); - } - }); - }); -} - export function closeAllEditors(): Thenable { return vscode.commands.executeCommand('workbench.action.closeAllEditors'); } export function disposeAll(disposables: vscode.Disposable[]) { - while (disposables.length) { - let item = disposables.pop(); - if (item) { - item.dispose(); - } - } + vscode.Disposable.from(...disposables).dispose(); } export function conditionalTest(name: string, testCallback: (done: MochaDone) => void | Thenable) { @@ -73,4 +66,4 @@ export function conditionalTest(name: string, testCallback: (done: MochaDone) => function isTestTypeActive(): boolean { return !!vscode.extensions.getExtension('vscode-resolver-test'); -} \ No newline at end of file +} From e39677fd3a4b6dc9c4680a7dc4ddaf1449df8547 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 30 Jul 2019 18:20:07 +0200 Subject: [PATCH 094/861] run int-test on linux --- build/azure-pipelines/linux/continuous-build-linux.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build/azure-pipelines/linux/continuous-build-linux.yml b/build/azure-pipelines/linux/continuous-build-linux.yml index 6f3008f73d2..23656fe9d1a 100644 --- a/build/azure-pipelines/linux/continuous-build-linux.yml +++ b/build/azure-pipelines/linux/continuous-build-linux.yml @@ -46,9 +46,12 @@ steps: - script: | DISPLAY=:10 ./scripts/test.sh --tfs "Unit Tests" displayName: Run Unit Tests +- script: | + ./scripts/test-integration.sh --tfs "Integration Tests" + displayName: Run Integration Tests - task: PublishTestResults@2 displayName: Publish Tests Results inputs: testResultsFiles: '*-results.xml' searchFolder: '$(Build.ArtifactStagingDirectory)/test-results' - condition: succeededOrFailed() \ No newline at end of file + condition: succeededOrFailed() From f0058ed0d43dc58620abc65570719d06e1e67c76 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 30 Jul 2019 18:30:43 +0200 Subject: [PATCH 095/861] also update linux prod build --- .../azure-pipelines/linux/product-build-linux.yml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index e97f5cfdeff..dee07a95d78 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -93,16 +93,23 @@ steps: - script: | set -e - yarn gulp "electron-x64" - - # xvfb seems to be crashing often, let's make sure it's always up service xvfb start + displayName: Start xvfb + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) +- script: | + set -e DISPLAY=:10 ./scripts/test.sh --build --tfs "Unit Tests" - # yarn smoketest -- --build "$(agent.builddirectory)/VSCode-linux-x64" displayName: Run unit tests condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) +- script: | + set -e + DISPLAY=:10 ./scripts/test-integration.sh --build --tfs "Integration Tests" + # yarn smoketest -- --build "$(agent.builddirectory)/VSCode-linux-x64" + displayName: Run integration tests + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) + - script: | set -e AZURE_DOCUMENTDB_MASTERKEY="$(builds-docdb-key-readwrite)" \ From 4df80a5be3026374f83dbb9ecda1ea145971e082 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 30 Jul 2019 22:10:06 +0530 Subject: [PATCH 096/861] Fix #78171 --- .../{node => common}/media/defaultIcon.png | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename src/vs/platform/extensionManagement/{node => common}/media/defaultIcon.png (100%) diff --git a/src/vs/platform/extensionManagement/node/media/defaultIcon.png b/src/vs/platform/extensionManagement/common/media/defaultIcon.png similarity index 100% rename from src/vs/platform/extensionManagement/node/media/defaultIcon.png rename to src/vs/platform/extensionManagement/common/media/defaultIcon.png From 425040ef8faebc352818c39cbdd68d15f119e5ea Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 30 Jul 2019 22:18:06 +0530 Subject: [PATCH 097/861] Fix microsoft/vscode-remote-release/issues/1064 --- .../contrib/extensions/browser/extensionsActions.ts | 8 ++++---- .../contrib/extensions/browser/extensionsViewlet.ts | 4 ++-- .../extensions/browser/remoteExtensionsInstaller.ts | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index fdb0056d228..52410ff3f2e 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -346,7 +346,7 @@ export class RemoteInstallAction extends InstallInOtherServerAction { } protected getInstallLabel(): string { - return this.extensionManagementServerService.remoteExtensionManagementServer ? localize('Install on Server', "Install on {0}", this.extensionManagementServerService.remoteExtensionManagementServer.label) : InstallInOtherServerAction.INSTALL_LABEL; + return this.extensionManagementServerService.remoteExtensionManagementServer ? localize('Install on Server', "Install in {0}", this.extensionManagementServerService.remoteExtensionManagementServer.label) : InstallInOtherServerAction.INSTALL_LABEL; } } @@ -3014,7 +3014,7 @@ interface IExtensionPickItem extends IQuickPickItem { extension?: IExtension; } -export class InstallLocalExtensionsOnRemoteAction extends Action { +export class InstallLocalExtensionsInRemoteAction extends Action { constructor( @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService, @@ -3026,14 +3026,14 @@ export class InstallLocalExtensionsOnRemoteAction extends Action { @IProgressService private readonly progressService: IProgressService, @IInstantiationService private readonly instantiationService: IInstantiationService ) { - super('workbench.extensions.actions.installLocalExtensionsOnRemote'); + super('workbench.extensions.actions.installLocalExtensionsInRemote'); this.update(); this._register(this.extensionsWorkbenchService.onChange(() => this.update())); } get label(): string { return this.extensionManagementServerService.remoteExtensionManagementServer ? - localize('install local extensions', "Install Local Extensions on {0}", this.extensionManagementServerService.remoteExtensionManagementServer.label) : ''; + localize('install local extensions', "Install Local Extensions in {0}...", this.extensionManagementServerService.remoteExtensionManagementServer.label) : ''; } private update(): void { diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts index 9bed184ac05..51d47e81958 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts @@ -22,7 +22,7 @@ import { IExtensionsWorkbenchService, IExtensionsViewlet, VIEWLET_ID, AutoUpdate import { ShowEnabledExtensionsAction, ShowInstalledExtensionsAction, ShowRecommendedExtensionsAction, ShowPopularExtensionsAction, ShowDisabledExtensionsAction, ShowOutdatedExtensionsAction, ClearExtensionsInputAction, ChangeSortAction, UpdateAllAction, CheckForUpdatesAction, DisableAllAction, EnableAllAction, - EnableAutoUpdateAction, DisableAutoUpdateAction, ShowBuiltInExtensionsAction, InstallVSIXAction, InstallLocalExtensionsOnRemoteAction + EnableAutoUpdateAction, DisableAutoUpdateAction, ShowBuiltInExtensionsAction, InstallVSIXAction, InstallLocalExtensionsInRemoteAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IExtensionEnablementService, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; @@ -478,7 +478,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio this.instantiationService.createInstance(CheckForUpdatesAction, CheckForUpdatesAction.ID, CheckForUpdatesAction.LABEL), ...(this.configurationService.getValue(AutoUpdateConfigurationKey) ? [this.instantiationService.createInstance(DisableAutoUpdateAction, DisableAutoUpdateAction.ID, DisableAutoUpdateAction.LABEL)] : [this.instantiationService.createInstance(UpdateAllAction, UpdateAllAction.ID, UpdateAllAction.LABEL), this.instantiationService.createInstance(EnableAutoUpdateAction, EnableAutoUpdateAction.ID, EnableAutoUpdateAction.LABEL)]), this.instantiationService.createInstance(InstallVSIXAction, InstallVSIXAction.ID, InstallVSIXAction.LABEL), - ...(this.extensionManagementServerService.localExtensionManagementServer && this.extensionManagementServerService.remoteExtensionManagementServer ? [this.instantiationService.createInstance(InstallLocalExtensionsOnRemoteAction)] : []), + ...(this.extensionManagementServerService.localExtensionManagementServer && this.extensionManagementServerService.remoteExtensionManagementServer ? [this.instantiationService.createInstance(InstallLocalExtensionsInRemoteAction)] : []), new Separator(), this.instantiationService.createInstance(DisableAllAction, DisableAllAction.ID, DisableAllAction.LABEL), this.instantiationService.createInstance(EnableAllAction, EnableAllAction.ID, EnableAllAction.LABEL) diff --git a/src/vs/workbench/contrib/extensions/browser/remoteExtensionsInstaller.ts b/src/vs/workbench/contrib/extensions/browser/remoteExtensionsInstaller.ts index 19e4a47c99c..a61c79d5575 100644 --- a/src/vs/workbench/contrib/extensions/browser/remoteExtensionsInstaller.ts +++ b/src/vs/workbench/contrib/extensions/browser/remoteExtensionsInstaller.ts @@ -11,7 +11,7 @@ import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { ILabelService } from 'vs/platform/label/common/label'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { InstallLocalExtensionsOnRemoteAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; +import { InstallLocalExtensionsInRemoteAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; export class RemoteExtensionsInstaller extends Disposable implements IWorkbenchContribution { @@ -22,8 +22,8 @@ export class RemoteExtensionsInstaller extends Disposable implements IWorkbenchC ) { super(); if (this.extensionManagementServerService.localExtensionManagementServer && this.extensionManagementServerService.remoteExtensionManagementServer) { - const installLocalExtensionsOnRemoteAction = instantiationService.createInstance(InstallLocalExtensionsOnRemoteAction); - CommandsRegistry.registerCommand('workbench.extensions.installLocalExtensions', () => installLocalExtensionsOnRemoteAction.run()); + const installLocalExtensionsInRemoteAction = instantiationService.createInstance(InstallLocalExtensionsInRemoteAction); + CommandsRegistry.registerCommand('workbench.extensions.installLocalExtensions', () => installLocalExtensionsInRemoteAction.run()); let disposable = Disposable.None; const appendMenuItem = () => { disposable.dispose(); @@ -31,7 +31,7 @@ export class RemoteExtensionsInstaller extends Disposable implements IWorkbenchC command: { id: 'workbench.extensions.installLocalExtensions', category: localize('extensions', "Extensions"), - title: installLocalExtensionsOnRemoteAction.label + title: installLocalExtensionsInRemoteAction.label } }); }; @@ -41,4 +41,4 @@ export class RemoteExtensionsInstaller extends Disposable implements IWorkbenchC } } -} \ No newline at end of file +} From 4738cb2ff517ae58ded1f3e6e2a78a96449b1a4a Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Tue, 30 Jul 2019 09:51:02 -0700 Subject: [PATCH 098/861] Fix #78160 --- src/vs/workbench/contrib/preferences/browser/settingsTree.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts index 4c48aa744d3..2008a6edb14 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts @@ -703,7 +703,7 @@ export class SettingArrayRenderer extends AbstractSettingRenderer implements ITr : [...template.context.value]; // Delete value - if (e.removeIndex) { + if (e.removeIndex !== undefined) { if (!e.value && e.originalValue && e.removeIndex > -1) { newValue.splice(e.removeIndex, 1); } From 07a172406b629975e5dfbd9d103103b09289bc47 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 30 Jul 2019 22:21:52 +0530 Subject: [PATCH 099/861] Fix microsoft/vscode-remote-release/issues/1065 --- src/vs/workbench/contrib/extensions/browser/extensionsActions.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index 52410ff3f2e..975f4b74113 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -3066,6 +3066,7 @@ export class InstallLocalExtensionsInRemoteAction extends Action { const localExtensionsToInstall = this.getLocalExtensionsToInstall(); quickPick.busy = false; if (localExtensionsToInstall.length) { + quickPick.title = localize('install local extensions title', "Install Local Extensions in {0}", this.extensionManagementServerService.remoteExtensionManagementServer!.label); quickPick.placeholder = localize('select extensions to install', "Select extensions to install"); quickPick.canSelectMany = true; localExtensionsToInstall.sort((e1, e2) => e1.displayName.localeCompare(e2.displayName)); From cf415de20fa5feb811c43ad7b8de23da578ca7b8 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 30 Jul 2019 22:32:39 +0530 Subject: [PATCH 100/861] #78062 Fix sorting --- .../workbench/contrib/extensions/browser/extensionsViewlet.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts index 51d47e81958..50e67a2a888 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts @@ -405,7 +405,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio triggerCharacters: ['@'], sortKey: (item: string) => { if (item.indexOf(':') === -1) { return 'a'; } - else if (/ext:/.test(item) || /tag:/.test(item)) { return 'b'; } + else if (/ext:/.test(item) || /id:/.test(item) || /tag:/.test(item)) { return 'b'; } else if (/sort:/.test(item)) { return 'c'; } else { return 'd'; } }, From f3cc59274917faed13be4e2670aa5dcf9fafe341 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 30 Jul 2019 22:44:01 +0530 Subject: [PATCH 101/861] fix tests --- .../electron-browser/extensionsActions.test.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts index 2334ecebeec..bce6e57e287 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts @@ -1518,7 +1518,7 @@ suite('ExtensionsActions Test', () => { await workbenchService.queryGallery(CancellationToken.None); testObject.extension = extensions[0]; assert.ok(testObject.enabled); - assert.equal('Install on remote', testObject.label); + assert.equal('Install in remote', testObject.label); assert.equal('extension-action prominent install', testObject.class); }); @@ -1544,7 +1544,7 @@ suite('ExtensionsActions Test', () => { await workbenchService.queryGallery(CancellationToken.None); testObject.extension = extensions[0]; assert.ok(testObject.enabled); - assert.equal('Install on remote', testObject.label); + assert.equal('Install in remote', testObject.label); assert.equal('extension-action prominent install', testObject.class); onInstallExtension.fire({ identifier: localWorkspaceExtension.identifier, gallery }); @@ -1577,7 +1577,7 @@ suite('ExtensionsActions Test', () => { await workbenchService.queryGallery(CancellationToken.None); testObject.extension = extensions[0]; assert.ok(testObject.enabled); - assert.equal('Install on remote', testObject.label); + assert.equal('Install in remote', testObject.label); assert.equal('extension-action prominent install', testObject.class); onInstallExtension.fire({ identifier: localWorkspaceExtension.identifier, gallery }); @@ -1608,7 +1608,7 @@ suite('ExtensionsActions Test', () => { await workbenchService.queryGallery(CancellationToken.None); testObject.extension = extensions[0]; assert.ok(testObject.enabled); - assert.equal('Install on remote', testObject.label); + assert.equal('Install in remote', testObject.label); assert.equal('extension-action prominent install', testObject.class); }); @@ -1704,7 +1704,7 @@ suite('ExtensionsActions Test', () => { await workbenchService.queryGallery(CancellationToken.None); testObject.extension = extensions[0]; assert.ok(testObject.enabled); - assert.equal('Install on remote', testObject.label); + assert.equal('Install in remote', testObject.label); uninstallEvent.fire(localWorkspaceExtension.identifier); assert.ok(!testObject.enabled); @@ -1825,7 +1825,7 @@ suite('ExtensionsActions Test', () => { await workbenchService.queryGallery(CancellationToken.None); testObject.extension = extensions[0]; assert.ok(testObject.enabled); - assert.equal('Install on remote', testObject.label); + assert.equal('Install in remote', testObject.label); assert.equal('extension-action prominent install', testObject.class); }); @@ -1848,7 +1848,7 @@ suite('ExtensionsActions Test', () => { await workbenchService.queryGallery(CancellationToken.None); testObject.extension = extensions[0]; assert.ok(testObject.enabled); - assert.equal('Install on remote', testObject.label); + assert.equal('Install in remote', testObject.label); uninstallEvent.fire(languagePackExtension.identifier); assert.ok(!testObject.enabled); From 99d5ff9c0f5a66a9e1cd7d49f9af6892e13f96a4 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Tue, 30 Jul 2019 11:10:12 -0700 Subject: [PATCH 102/861] Redo emmet change --- extensions/emmet/.vscode/launch.json | 50 ++++++++++------- extensions/emmet/package.json | 7 ++- extensions/emmet/src/abbreviationActions.ts | 2 +- .../emmet/src/defaultCompletionProvider.ts | 56 ++++++++++++++++--- .../emmet/src/test/abbreviationAction.test.ts | 10 ---- extensions/emmet/src/util.ts | 15 +++++ extensions/emmet/yarn.lock | 24 ++++++++ 7 files changed, 121 insertions(+), 43 deletions(-) diff --git a/extensions/emmet/.vscode/launch.json b/extensions/emmet/.vscode/launch.json index 8a89122dafb..0b693f921ee 100644 --- a/extensions/emmet/.vscode/launch.json +++ b/extensions/emmet/.vscode/launch.json @@ -1,21 +1,31 @@ { - // Use IntelliSense to learn about possible Node.js debug attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "extensionHost", - "request": "launch", - "name": "Launch Extension", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" - ], - "sourceMaps": true, - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ] - } - ] -} \ No newline at end of file + // Use IntelliSense to learn about possible Node.js debug attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "extensionHost", + "request": "launch", + "name": "Launch Extension", + "runtimeExecutable": "${execPath}", + "args": ["--extensionDevelopmentPath=${workspaceFolder}"], + "sourceMaps": true, + "outFiles": ["${workspaceFolder}/out/**/*.js"] + }, + { + "type": "extensionHost", + "request": "launch", + "name": "Launch Tests", + "runtimeExecutable": "${execPath}", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}", + "--extensionTestsPath=${workspaceFolder}/out/test", + "--disable-extensions", + "--skip-getting-started", + ], + "sourceMaps": true, + "outFiles": ["${workspaceFolder}/out/**/*.js"] + } + ] +} diff --git a/extensions/emmet/package.json b/extensions/emmet/package.json index fd347852231..d88c3717ab3 100644 --- a/extensions/emmet/package.json +++ b/extensions/emmet/package.json @@ -3,8 +3,8 @@ "displayName": "Emmet", "description": "%description%", "version": "1.0.0", - "publisher": "vscode", - "license": "MIT", + "publisher": "vscode", + "license": "MIT", "engines": { "vscode": "^1.13.0" }, @@ -450,6 +450,7 @@ "@emmetio/html-matcher": "^0.3.3", "@emmetio/math-expression": "^0.1.1", "image-size": "^0.5.2", - "vscode-emmet-helper": "^1.2.15" + "vscode-emmet-helper": "^1.2.15", + "vscode-html-languageservice": "^3.0.3" } } diff --git a/extensions/emmet/src/abbreviationActions.ts b/extensions/emmet/src/abbreviationActions.ts index 26510e803cb..9508d3a6a0b 100644 --- a/extensions/emmet/src/abbreviationActions.ts +++ b/extensions/emmet/src/abbreviationActions.ts @@ -635,7 +635,7 @@ function expandAbbr(input: ExpandAbbreviationInput): string { return expandedText; } -function getSyntaxFromArgs(args: { [x: string]: string }): string | undefined { +export function getSyntaxFromArgs(args: { [x: string]: string }): string | undefined { const mappedModes = getMappingForIncludedLanguages(); const language: string = args['language']; const parentMode: string = args['parentMode']; diff --git a/extensions/emmet/src/defaultCompletionProvider.ts b/extensions/emmet/src/defaultCompletionProvider.ts index cb9f433f6ba..509ca805a98 100644 --- a/extensions/emmet/src/defaultCompletionProvider.ts +++ b/extensions/emmet/src/defaultCompletionProvider.ts @@ -5,13 +5,16 @@ import * as vscode from 'vscode'; import { Node, Stylesheet } from 'EmmetNode'; -import { isValidLocationForEmmetAbbreviation } from './abbreviationActions'; -import { getEmmetHelper, getMappingForIncludedLanguages, parsePartialStylesheet, getEmmetConfiguration, getEmmetMode, isStyleSheet, parseDocument, getEmbeddedCssNodeIfAny, isStyleAttribute, getNode } from './util'; +import { isValidLocationForEmmetAbbreviation, getSyntaxFromArgs } from './abbreviationActions'; +import { getEmmetHelper, getMappingForIncludedLanguages, parsePartialStylesheet, getEmmetConfiguration, getEmmetMode, isStyleSheet, parseDocument, getNode, allowedMimeTypesInScriptTag, trimQuotes } from './util'; +import { getLanguageService, TextDocument, TokenType } from 'vscode-html-languageservice'; export class DefaultCompletionItemProvider implements vscode.CompletionItemProvider { private lastCompletionType: string | undefined; + private htmlLS = getLanguageService(); + public provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, _: vscode.CancellationToken, context: vscode.CompletionContext): Thenable | undefined { const completionResult = this.provideCompletionItemsInternal(document, position, context); if (!completionResult) { @@ -76,20 +79,55 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi } if (validateLocation) { - rootNode = parseDocument(document, false); - currentNode = getNode(rootNode, position, true); - if (isStyleAttribute(currentNode, position)) { + const lsDoc = TextDocument.create(document.uri.toString(), 'html', 0, document.getText()); + const parsedLsDoc = this.htmlLS.parseHTMLDocument(lsDoc); + const positionOffset = document.offsetAt(position); + const node = parsedLsDoc.findNodeAt(positionOffset); + + if (node.tag === 'script') { + if (node.attributes && 'type' in node.attributes) { + const rawTypeAttrValue = node.attributes['type']; + if (rawTypeAttrValue) { + const typeAttrValue = trimQuotes(rawTypeAttrValue); + if (typeAttrValue === 'application/javascript' || typeAttrValue === 'text/javascript') { + if (!getSyntaxFromArgs({ language: 'javascript' })) { + return; + } else { + validateLocation = false; + } + } + + else if (allowedMimeTypesInScriptTag.indexOf(trimQuotes(rawTypeAttrValue)) > -1) { + validateLocation = false; + } + } + } else { + return; + } + } + else if (node.tag === 'style') { syntax = 'css'; validateLocation = false; } else { - const embeddedCssNode = getEmbeddedCssNodeIfAny(document, currentNode, position); - if (embeddedCssNode) { - currentNode = getNode(embeddedCssNode, position, true); - syntax = 'css'; + if (node.attributes && node.attributes['style']) { + const scanner = this.htmlLS.createScanner(document.getText(), node.start); + let tokenType = scanner.scan(); + let prevAttr = undefined; + while (tokenType !== TokenType.EOS && (scanner.getTokenEnd() <= positionOffset)) { + tokenType = scanner.scan(); + if (tokenType === TokenType.AttributeName) { + prevAttr = scanner.getTokenText(); + } + } + if (prevAttr === 'style') { + syntax = 'css'; + validateLocation = false; + } } } } + } const extractAbbreviationResults = helper.extractAbbreviation(document, position, !isStyleSheet(syntax)); diff --git a/extensions/emmet/src/test/abbreviationAction.test.ts b/extensions/emmet/src/test/abbreviationAction.test.ts index 0a99bae1862..31f46891965 100644 --- a/extensions/emmet/src/test/abbreviationAction.test.ts +++ b/extensions/emmet/src/test/abbreviationAction.test.ts @@ -264,16 +264,6 @@ suite('Tests for Expand Abbreviations (HTML)', () => { }); }); - test('No expanding text in completion list inside style tag if position is not for property name (HTML)', () => { - return withRandomFileEditor(htmlContents, 'html', (editor, _doc) => { - editor.selection = new Selection(13, 14, 13, 14); - const cancelSrc = new CancellationTokenSource(); - const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, { triggerKind: CompletionTriggerKind.Invoke }); - assert.equal(!completionPromise, true, `Got unexpected comapletion promise instead of undefined`); - return Promise.resolve(); - }); - }); - test('Expand css when inside style attribute (HTML)', () => { const styleAttributeContent = '
'; return withRandomFileEditor(styleAttributeContent, 'html', async (editor, _doc) => { diff --git a/extensions/emmet/src/util.ts b/extensions/emmet/src/util.ts index 8ce65ca04b3..b6281272851 100644 --- a/extensions/emmet/src/util.ts +++ b/extensions/emmet/src/util.ts @@ -608,3 +608,18 @@ export function isStyleAttribute(currentNode: Node | null, position: vscode.Posi } +export function trimQuotes(s: string) { + if (s.length <= 1) { + return s.replace(/['"]/, ''); + } + + if (s[0] === `'` || s[0] === `"`) { + s = s.slice(1); + } + + if (s[s.length - 1] === `'` || s[s.length - 1] === `"`) { + s = s.slice(0, -1); + } + + return s; +} \ No newline at end of file diff --git a/extensions/emmet/yarn.lock b/extensions/emmet/yarn.lock index a417831756a..7b22c533426 100644 --- a/extensions/emmet/yarn.lock +++ b/extensions/emmet/yarn.lock @@ -2478,11 +2478,35 @@ vscode-emmet-helper@^1.2.15: jsonc-parser "^1.0.0" vscode-languageserver-types "^3.6.0-next.1" +vscode-html-languageservice@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-3.0.3.tgz#0aeae18a59000e317447ea34965f72680a2140ef" + integrity sha512-U+upM3gHp3HaF3wXAnUduA6IDKcz6frWS/dTAju3cZVIyZwOLBBFElQVlLH0ycHyMzqUFrjvdv+kEyPAEWfQ/g== + dependencies: + vscode-languageserver-types "^3.15.0-next.2" + vscode-nls "^4.1.1" + vscode-uri "^2.0.3" + +vscode-languageserver-types@^3.15.0-next.2: + version "3.15.0-next.2" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.2.tgz#a0601332cdaafac21931f497bb080cfb8d73f254" + integrity sha512-2JkrMWWUi2rlVLSo9OFR2PIGUzdiowEM8NgNYiwLKnXTjpwpjjIrJbNNxDik7Rv4oo9KtikcFQZKXbrKilL/MQ== + vscode-languageserver-types@^3.6.0-next.1: version "3.6.0-next.1" resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.6.0-next.1.tgz#98e488d3f87b666b4ee1a3d89f0023e246d358f3" integrity sha512-n4G+hCgZwAhtcJSCkwJP153TLdcEBWwrIrb3Su/SpOkhmU7KjDgxaQBLA45hf+QbhB8uKQb+TVStPvbuYFHSMA== +vscode-nls@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.1.tgz#f9916b64e4947b20322defb1e676a495861f133c" + integrity sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A== + +vscode-uri@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.0.3.tgz#25e5f37f552fbee3cec7e5f80cef8469cefc6543" + integrity sha512-4D3DI3F4uRy09WNtDGD93H9q034OHImxiIcSq664Hq1Y1AScehlP3qqZyTkX/RWxeu0MRMHGkrxYqm2qlDF/aw== + vscode@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.0.1.tgz#3d161200615fe2af1d92ddc650751159411a513b" From 45aea4e0a0128a32764c7a29922e9fce979f39df Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 30 Jul 2019 11:11:44 -0700 Subject: [PATCH 103/861] Fix issues with Pseudoterminal API docs Fixes #78157 --- src/vs/vscode.proposed.d.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 3c56766657d..0aa9138cf0f 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -990,12 +990,12 @@ declare module 'vscode' { * * **Example:** Override the dimensions of a terminal to 20 columns and 10 rows * ```typescript - * const dimensionsEmitter = new vscode.EventEmitter(); + * const dimensionsEmitter = new vscode.EventEmitter(); * const pty: vscode.Pseudoterminal = { * onDidWrite: writeEmitter.event, * onDidOverrideDimensions: dimensionsEmitter.event, * open: () => { - * dimensionsEmitter.fire({ + * dimensionsEmitter.fire({ * columns: 20, * rows: 10 * }); @@ -1013,17 +1013,17 @@ declare module 'vscode' { * **Example:** Exit the terminal when "y" is pressed, otherwise show a notification. * ```typescript * const writeEmitter = new vscode.EventEmitter(); - * const closeEmitter = new vscode.EventEmitter(); + * const closeEmitter = new vscode.EventEmitter(); * const pty: vscode.Pseudoterminal = { * onDidWrite: writeEmitter.event, * onDidClose: closeEmitter.event, * open: () => writeEmitter.fire('Press y to exit successfully'), * close: () => {} - * handleInput: { + * handleInput: data => { * if (data !== 'y') { * vscode.window.showInformationMessage('Something went wrong'); * } - * data => closeEmitter.fire(); + * closeEmitter.fire(); * } * }; * vscode.window.createTerminal({ name: 'Exit example', pty }); From 183deef5f43d77dc0c13e8accc41f5dff492a434 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 30 Jul 2019 11:27:41 -0700 Subject: [PATCH 104/861] Support links in terminal for IAR compiler errors --- .../contrib/terminal/browser/terminalLinkHandler.ts | 1 + .../test/electron-browser/terminalLinkHandler.test.ts | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts b/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts index a89f5bf7cdc..1313dabefa6 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts @@ -38,6 +38,7 @@ const winLocalLinkClause = '((' + winPathPrefix + '|(' + winExcludedPathCharacte replacing space with nonBreakningSpace or space ASCII code - 32. */ const lineAndColumnClause = [ '((\\S*)", line ((\\d+)( column (\\d+))?))', // "(file path)", line 45 [see #40468] + '((\\S*)",((\\d+)(:(\\d+))?))', // "(file path)",45 [see #78205] '((\\S*) on line ((\\d+)(, column (\\d+))?))', // (file path) on line 8, column 13 '((\\S*):line ((\\d+)(, column (\\d+))?))', // (file path):line 8, column 13 '(([^\\s\\(\\)]*)(\\s?[\\(\\[](\\d+)(,\\s?(\\d+))?)[\\)\\]])', // (file path)(45), (file path) (45), (file path)(45,18), (file path) (45,18), (file path)(45, 18), (file path) (45, 18), also with [] diff --git a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts index 96daea4ad44..5cbeb9a7ba0 100644 --- a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts +++ b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts @@ -121,7 +121,8 @@ suite('Workbench - TerminalLinkHandler', () => { { urlFormat: '{0}[{1},{2}]', line: '5', column: '3' }, { urlFormat: '{0} [{1},{2}]', line: '5', column: '3' }, { urlFormat: '{0}[{1}, {2}]', line: '5', column: '3' }, - { urlFormat: '{0} [{1}, {2}]', line: '5', column: '3' } + { urlFormat: '{0} [{1}, {2}]', line: '5', column: '3' }, + { urlFormat: '"{0}",{1}', line: '5' } ]; linkUrls.forEach(linkUrl => { @@ -185,7 +186,8 @@ suite('Workbench - TerminalLinkHandler', () => { { 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},{2}]', line: '5', column: '3' }, + { urlFormat: '"{0}",{1}', line: '5' } ]; linkUrls.forEach(linkUrl => { From da0ea79e2fcad1e7b1799c50c94d174865b976ab Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 30 Jul 2019 11:46:24 -0700 Subject: [PATCH 105/861] Set resolved cwd as customCwd This way it goes through the absolute and relative checks Fixes #78206 --- .../workbench/contrib/terminal/common/terminalEnvironment.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index a240585b4dc..6b8255d444e 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -138,14 +138,14 @@ export function getCwd( if (!shell.ignoreConfigurationCwd && customCwd) { if (configurationResolverService) { try { - cwd = configurationResolverService.resolve(lastActiveWorkspace, customCwd); + customCwd = configurationResolverService.resolve(lastActiveWorkspace, customCwd); } catch (e) { // There was an issue resolving a variable, just use the unresolved customCwd which // which will fail, and log the error in the console. - cwd = customCwd; if (logService) { logService.error('Resolving terminal.integrated.cwd', e); } + return customCwd; } } if (path.isAbsolute(customCwd) && !cwd) { From 4f8538ac8e5b77d713e644b5b6cc547fe88a7022 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Tue, 30 Jul 2019 13:50:26 -0700 Subject: [PATCH 106/861] Clean up if statements (#78218) --- .../workbench/contrib/terminal/common/terminalEnvironment.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index 6b8255d444e..820506f8fe9 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -148,9 +148,9 @@ export function getCwd( return customCwd; } } - if (path.isAbsolute(customCwd) && !cwd) { + if (path.isAbsolute(customCwd)) { cwd = customCwd; - } else if (root && !cwd) { + } else if (root) { cwd = path.join(root.fsPath, customCwd); } } From ce15ecb0d50cab9f0ca6ef443b145a144f428634 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Tue, 30 Jul 2019 15:52:32 -0700 Subject: [PATCH 107/861] Fix #78162 --- .../contrib/preferences/browser/settingsEditor2.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts index 0d080e7d577..b3567495097 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts @@ -970,8 +970,15 @@ export class SettingsEditor2 extends BaseEditor { // If a single setting is being refreshed, it's ok to refresh now if that is not the focused setting if (key) { const focusedKey = focusedSetting.getAttribute(AbstractSettingRenderer.SETTING_KEY_ATTR); - if (focusedKey === key && - !DOM.hasClass(focusedSetting, 'setting-item-list')) { // update `list`s live, as they have a separate "submit edit" step built in before this + /** + * Update `list`s live if focused item is whole list or list item, + * as they have a separate "submit edit" step built in before this + */ + if ( + focusedKey === key && + !DOM.hasClass(focusedSetting, 'setting-item-list') && + !DOM.hasClass(focusedSetting, 'setting-item-contents') + ) { this.updateModifiedLabelForKey(key); this.scheduleRefresh(focusedSetting, key); From 1cee9f7dfbd1c09e1717328ddc1d36a105b2b0e5 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Tue, 30 Jul 2019 16:18:42 -0700 Subject: [PATCH 108/861] fixes #71580 --- src/vs/editor/contrib/codeAction/lightBulbWidget.ts | 2 +- src/vs/platform/contextview/browser/contextMenuHandler.ts | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/codeAction/lightBulbWidget.ts b/src/vs/editor/contrib/codeAction/lightBulbWidget.ts index 455798e4a9d..8575f354d5c 100644 --- a/src/vs/editor/contrib/codeAction/lightBulbWidget.ts +++ b/src/vs/editor/contrib/codeAction/lightBulbWidget.ts @@ -74,7 +74,7 @@ export class LightBulbWidget extends Disposable implements IContentWidget { // Make sure that focus / cursor location is not lost when clicking widget icon this._editor.focus(); - dom.EventHelper.stop(e, true); + e.preventDefault(); // a bit of extra work to make sure the menu // doesn't cover the line-text const { top, height } = dom.getDomNodePagePosition(this._domNode); diff --git a/src/vs/platform/contextview/browser/contextMenuHandler.ts b/src/vs/platform/contextview/browser/contextMenuHandler.ts index 4d3479aae8b..8ab9ccc2d82 100644 --- a/src/vs/platform/contextview/browser/contextMenuHandler.ts +++ b/src/vs/platform/contextview/browser/contextMenuHandler.ts @@ -85,6 +85,10 @@ export class ContextMenuHandler { menu.onDidBlur(() => this.contextViewService.hideContextView(true), null, menuDisposables); domEvent(window, EventType.BLUR)(() => { this.contextViewService.hideContextView(true); }, null, menuDisposables); domEvent(window, EventType.MOUSE_DOWN)((e: MouseEvent) => { + if (e.defaultPrevented) { + return; + } + let event = new StandardMouseEvent(e); let element: HTMLElement | null = event.target; From 2d9214c3fe29dc35ef75b400a226a88ef4251eaf Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 30 Jul 2019 17:17:35 -0700 Subject: [PATCH 109/861] Run OSS tool --- ThirdPartyNotices.txt | 8 ++++---- cglicenses.json | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index 1d854430864..64f72e53be0 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -7,7 +7,7 @@ This project incorporates components from the projects listed below. The origina 1. atom/language-clojure version 0.22.7 (https://github.com/atom/language-clojure) 2. atom/language-coffee-script version 0.49.3 (https://github.com/atom/language-coffee-script) -3. atom/language-java version 0.31.2 (https://github.com/atom/language-java) +3. atom/language-java version 0.31.3 (https://github.com/atom/language-java) 4. atom/language-sass version 0.61.4 (https://github.com/atom/language-sass) 5. atom/language-shellscript version 0.26.0 (https://github.com/atom/language-shellscript) 6. atom/language-xml version 0.35.2 (https://github.com/atom/language-xml) @@ -25,8 +25,8 @@ This project incorporates components from the projects listed below. The origina 18. Ikuyadeu/vscode-R version 0.5.5 (https://github.com/Ikuyadeu/vscode-R) 19. Ionic documentation version 1.2.4 (https://github.com/ionic-team/ionic-site) 20. ionide/ionide-fsgrammar (https://github.com/ionide/ionide-fsgrammar) -21. jeff-hykin/cpp-textmate-grammar version 1.11.0 (https://github.com/jeff-hykin/cpp-textmate-grammar) -22. jeff-hykin/cpp-textmate-grammar version 1.11.7 (https://github.com/jeff-hykin/cpp-textmate-grammar) +21. jeff-hykin/cpp-textmate-grammar version 1.12.11 (https://github.com/jeff-hykin/cpp-textmate-grammar) +22. jeff-hykin/cpp-textmate-grammar version 1.12.18 (https://github.com/jeff-hykin/cpp-textmate-grammar) 23. js-beautify version 1.6.8 (https://github.com/beautify-web/js-beautify) 24. Jxck/assert version 1.0.0 (https://github.com/Jxck/assert) 25. language-docker (https://github.com/moby/moby) @@ -39,7 +39,7 @@ This project incorporates components from the projects listed below. The origina 32. mdn-data version 1.1.12 (https://github.com/mdn/data) 33. Microsoft/TypeScript-TmLanguage version 0.0.1 (https://github.com/Microsoft/TypeScript-TmLanguage) 34. Microsoft/vscode-JSON.tmLanguage (https://github.com/Microsoft/vscode-JSON.tmLanguage) -35. Microsoft/vscode-mssql version 1.4.0 (https://github.com/Microsoft/vscode-mssql) +35. Microsoft/vscode-mssql version 1.6.0 (https://github.com/Microsoft/vscode-mssql) 36. mmims/language-batchfile version 0.7.5 (https://github.com/mmims/language-batchfile) 37. octicons version 8.3.0 (https://github.com/primer/octicons) 38. octref/language-css version 0.42.11 (https://github.com/octref/language-css) diff --git a/cglicenses.json b/cglicenses.json index 469cdedc9ad..b7f408109bf 100644 --- a/cglicenses.json +++ b/cglicenses.json @@ -743,5 +743,31 @@ "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN", "THE SOFTWARE." ] + }, + { + "name": "atob", + "licenseDetail": [ + "The MIT License (MIT)", + "", + "Copyright (c) 2015 AJ ONeal", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and associated documentation files (the \"Software\"), to deal", + "in the Software without restriction, including without limitation the rights", + "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell", + "copies of the Software, and to permit persons to whom the Software is", + "furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in all", + "copies or substantial portions of the Software.", + "", + "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." + ] } ] From a3587cab6120072cb316a1926c450edad991b114 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 30 Jul 2019 17:12:22 -0700 Subject: [PATCH 110/861] Fix #72588. --- .../contrib/extensions/browser/extensionsActions.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index 975f4b74113..32a97b64099 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -692,7 +692,13 @@ export class ManageExtensionAction extends ExtensionDropDownAction { ]); groups.push([this.instantiationService.createInstance(UninstallAction)]); groups.push([this.instantiationService.createInstance(InstallAnotherVersionAction)]); - groups.push([this.instantiationService.createInstance(ExtensionInfoAction), this.instantiationService.createInstance(ExtensionSettingsAction)]); + + const extensionActions: ExtensionAction[] = [this.instantiationService.createInstance(ExtensionInfoAction)]; + if (this.extension.local && this.extension.local.manifest.contributes && this.extension.local.manifest.contributes.configuration) { + extensionActions.push(this.instantiationService.createInstance(ExtensionSettingsAction)); + } + + groups.push(extensionActions); groups.forEach(group => group.forEach(extensionAction => extensionAction.extension = this.extension)); From 7a05099b0e00048a458b57f4c924ea774fb569f0 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 30 Jul 2019 17:24:54 -0700 Subject: [PATCH 111/861] Fix #75279. --- src/vs/editor/common/viewModel/viewModelImpl.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/common/viewModel/viewModelImpl.ts b/src/vs/editor/common/viewModel/viewModelImpl.ts index 5161636aa45..65284147a64 100644 --- a/src/vs/editor/common/viewModel/viewModelImpl.ts +++ b/src/vs/editor/common/viewModel/viewModelImpl.ts @@ -6,7 +6,7 @@ import { Color } from 'vs/base/common/color'; import { IDisposable } from 'vs/base/common/lifecycle'; import * as strings from 'vs/base/common/strings'; -import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions'; +import { IConfigurationChangedEvent, EDITOR_FONT_DEFAULTS } from 'vs/editor/common/config/editorOptions'; import { IPosition, Position } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; import * as editorCommon from 'vs/editor/common/editorCommon'; @@ -668,12 +668,13 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel const fontInfo = this.configuration.editor.fontInfo; const colorMap = this._getColorMap(); + const fontFamily = fontInfo.fontFamily === EDITOR_FONT_DEFAULTS.fontFamily ? fontInfo.fontFamily : `'${fontInfo.fontFamily}', ${EDITOR_FONT_DEFAULTS.fontFamily}`; return ( `
Date: Wed, 31 Jul 2019 11:10:21 +0200 Subject: [PATCH 115/861] fix #78261 --- extensions/theme-seti/icons/vs-seti-icon-theme.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/theme-seti/icons/vs-seti-icon-theme.json b/extensions/theme-seti/icons/vs-seti-icon-theme.json index 2b5d276a515..52a81da4596 100644 --- a/extensions/theme-seti/icons/vs-seti-icon-theme.json +++ b/extensions/theme-seti/icons/vs-seti-icon-theme.json @@ -1608,7 +1608,7 @@ "bat": "_windows", "clojure": "_clojure", "coffeescript": "_coffee", - "jsonc": "_tsconfig", + "jsonc": "_json", "c": "_c", "cpp": "_cpp", "csharp": "_c-sharp", @@ -1871,7 +1871,7 @@ "bat": "_windows_light", "clojure": "_clojure_light", "coffeescript": "_coffee_light", - "jsonc": "_tsconfig_light", + "jsonc": "_json_light", "c": "_c_light", "cpp": "_cpp_light", "csharp": "_c-sharp_light", @@ -1981,4 +1981,4 @@ } }, "version": "https://github.com/jesseweed/seti-ui/commit/904c16acced1134a81b31d71d60293288c31334b" -} \ No newline at end of file +} From 7c5e0803df31f485243eb5e6629862d873e9540f Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 31 Jul 2019 12:19:16 +0200 Subject: [PATCH 116/861] fixes #78251 --- src/vs/workbench/contrib/debug/browser/debugCommands.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugCommands.ts b/src/vs/workbench/contrib/debug/browser/debugCommands.ts index 95cd771b7f3..67bcdb80de9 100644 --- a/src/vs/workbench/contrib/debug/browser/debugCommands.ts +++ b/src/vs/workbench/contrib/debug/browser/debugCommands.ts @@ -184,7 +184,7 @@ export function registerCommands(): void { id: STEP_INTO_ID, weight: KeybindingWeight.WorkbenchContrib + 10, // Have a stronger weight to have priority over full screen when debugging primary: KeyCode.F11, - when: CONTEXT_DEBUG_STATE.isEqualTo('stopped'), + when: CONTEXT_IN_DEBUG_MODE, handler: (accessor: ServicesAccessor, _: string, thread: IThread | undefined) => { getThreadAndRun(accessor, thread, thread => thread.stepIn()); } From 06701f533d4d883d5cb545d851985b7f78bc44df Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 31 Jul 2019 12:30:30 +0200 Subject: [PATCH 117/861] add a bunch of strict field initializations --- .../ui/breadcrumbs/breadcrumbsWidget.ts | 4 ++-- src/vs/base/common/event.ts | 2 +- .../editor/contrib/codelens/codelensWidget.ts | 6 +++--- .../contrib/documentSymbols/outlineTree.ts | 19 +++++++++++-------- .../goToDefinition/goToDefinitionMouse.ts | 8 +++----- .../referenceSearch/referencesModel.ts | 2 +- .../editor/contrib/snippet/snippetParser.ts | 8 ++------ .../contrib/suggest/suggestAlternatives.ts | 2 +- .../editor/contrib/suggest/wordContextKey.ts | 2 +- .../api/browser/mainThreadCodeInsets.ts | 4 ++-- .../browser/mainThreadDocumentsAndEditors.ts | 4 ++-- .../workbench/api/common/extHostCodeInsets.ts | 2 +- .../api/common/extHostDocumentData.ts | 2 +- .../api/common/extHostDocumentsAndEditors.ts | 2 +- .../workbench/api/common/extHostFileSystem.ts | 2 +- src/vs/workbench/api/common/extHostMemento.ts | 8 ++++---- src/vs/workbench/api/common/extHostOutput.ts | 3 ++- .../browser/parts/editor/breadcrumbs.ts | 6 +++--- .../extensionProfileService.ts | 6 +++--- .../electron-browser/extensionsSlowActions.ts | 6 +++--- .../markers/browser/markersFileDecorations.ts | 4 ++-- .../electron-browser/perfviewEditor.ts | 10 +++++----- .../browser/snippetCompletionProvider.ts | 2 +- .../contrib/snippets/browser/tabCompletion.ts | 4 ++-- .../partsSplash.contribution.ts | 4 ++-- .../bulkEdit/browser/bulkEditService.ts | 12 ++++++------ .../timer/electron-browser/timerService.ts | 2 +- 27 files changed, 67 insertions(+), 69 deletions(-) diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts index 13e4b9c34be..2e72938f986 100644 --- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts +++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts @@ -77,8 +77,8 @@ export class BreadcrumbsWidget { private _focusedItemIdx: number = -1; private _selectedItemIdx: number = -1; - private _pendingLayout: IDisposable; - private _dimension: dom.Dimension; + private _pendingLayout: IDisposable | undefined; + private _dimension: dom.Dimension | undefined; constructor( container: HTMLElement diff --git a/src/vs/base/common/event.ts b/src/vs/base/common/event.ts index 2a423637149..4d43bd8c132 100644 --- a/src/vs/base/common/event.ts +++ b/src/vs/base/common/event.ts @@ -645,7 +645,7 @@ export interface IWaitUntil { export class AsyncEmitter extends Emitter { - private _asyncDeliveryQueue: [Listener, T, Promise[]][]; + private _asyncDeliveryQueue?: [Listener, T, Promise[]][]; async fireAsync(eventFn: (thenables: Promise[], listener: Function) => T): Promise { if (!this._listeners) { diff --git a/src/vs/editor/contrib/codelens/codelensWidget.ts b/src/vs/editor/contrib/codelens/codelensWidget.ts index 24ed75a4405..2f34263e0fd 100644 --- a/src/vs/editor/contrib/codelens/codelensWidget.ts +++ b/src/vs/editor/contrib/codelens/codelensWidget.ts @@ -60,7 +60,7 @@ class CodeLensContentWidget implements editorBrowser.IContentWidget { private readonly _editor: editorBrowser.ICodeEditor; private readonly _commands = new Map(); - private _widgetPosition: editorBrowser.IContentWidgetPosition; + private _widgetPosition?: editorBrowser.IContentWidgetPosition; constructor( editor: editorBrowser.ICodeEditor, @@ -147,8 +147,8 @@ class CodeLensContentWidget implements editorBrowser.IContentWidget { }; } - getPosition(): editorBrowser.IContentWidgetPosition { - return this._widgetPosition; + getPosition(): editorBrowser.IContentWidgetPosition | null { + return this._widgetPosition || null; } isVisible(): boolean { diff --git a/src/vs/editor/contrib/documentSymbols/outlineTree.ts b/src/vs/editor/contrib/documentSymbols/outlineTree.ts index a77c8d1bd2e..365b3e45c13 100644 --- a/src/vs/editor/contrib/documentSymbols/outlineTree.ts +++ b/src/vs/editor/contrib/documentSymbols/outlineTree.ts @@ -45,16 +45,19 @@ export class OutlineIdentityProvider implements IIdentityProvider { export class OutlineGroupTemplate { static id = 'OutlineGroupTemplate'; - - labelContainer: HTMLElement; - label: HighlightedLabel; + constructor( + readonly labelContainer: HTMLElement, + readonly label: HighlightedLabel, + ) { } } export class OutlineElementTemplate { static id = 'OutlineElementTemplate'; - container: HTMLElement; - iconLabel: IconLabel; - decoration: HTMLElement; + constructor( + readonly container: HTMLElement, + readonly iconLabel: IconLabel, + readonly decoration: HTMLElement, + ) { } } export class OutlineVirtualDelegate implements IListVirtualDelegate { @@ -80,7 +83,7 @@ export class OutlineGroupRenderer implements ITreeRenderer, index: number, template: OutlineGroupTemplate): void { @@ -109,7 +112,7 @@ export class OutlineElementRenderer implements ITreeRenderer, index: number, template: OutlineElementTemplate): void { diff --git a/src/vs/editor/contrib/goToDefinition/goToDefinitionMouse.ts b/src/vs/editor/contrib/goToDefinition/goToDefinitionMouse.ts index 717c7ba4d13..7d0dd7ce4e1 100644 --- a/src/vs/editor/contrib/goToDefinition/goToDefinitionMouse.ts +++ b/src/vs/editor/contrib/goToDefinition/goToDefinitionMouse.ts @@ -34,18 +34,16 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC private readonly editor: ICodeEditor; private readonly toUnhook = new DisposableStore(); - private decorations: string[]; - private currentWordUnderMouse: IWordAtPosition | null; - private previousPromise: CancelablePromise | null; + private decorations: string[] = []; + private currentWordUnderMouse: IWordAtPosition | null = null; + private previousPromise: CancelablePromise | null = null; constructor( editor: ICodeEditor, @ITextModelService private readonly textModelResolverService: ITextModelService, @IModeService private readonly modeService: IModeService ) { - this.decorations = []; this.editor = editor; - this.previousPromise = null; let linkGesture = new ClickLinkGesture(editor); this.toUnhook.add(linkGesture); diff --git a/src/vs/editor/contrib/referenceSearch/referencesModel.ts b/src/vs/editor/contrib/referenceSearch/referencesModel.ts index 591092048d2..35af7095f8b 100644 --- a/src/vs/editor/contrib/referenceSearch/referencesModel.ts +++ b/src/vs/editor/contrib/referenceSearch/referencesModel.ts @@ -89,7 +89,7 @@ export class FileReferences implements IDisposable { private _children: OneReference[]; private _preview?: FilePreview; - private _resolved: boolean; + private _resolved?: boolean; private _loadFailure: any; constructor(private readonly _parent: ReferencesModel, private readonly _uri: URI) { diff --git a/src/vs/editor/contrib/snippet/snippetParser.ts b/src/vs/editor/contrib/snippet/snippetParser.ts index 46d069cddbc..69b0f621302 100644 --- a/src/vs/editor/contrib/snippet/snippetParser.ts +++ b/src/vs/editor/contrib/snippet/snippetParser.ts @@ -56,12 +56,8 @@ export class Scanner { || (ch >= CharCode.A && ch <= CharCode.Z); } - value: string; - pos: number; - - constructor() { - this.text(''); - } + value: string = ''; + pos: number = 0; text(value: string) { this.value = value; diff --git a/src/vs/editor/contrib/suggest/suggestAlternatives.ts b/src/vs/editor/contrib/suggest/suggestAlternatives.ts index 4d480fa8f4f..e8a6ea1a338 100644 --- a/src/vs/editor/contrib/suggest/suggestAlternatives.ts +++ b/src/vs/editor/contrib/suggest/suggestAlternatives.ts @@ -15,7 +15,7 @@ export class SuggestAlternatives { private readonly _ckOtherSuggestions: IContextKey; - private _index: number; + private _index: number = 0; private _model: CompletionModel | undefined; private _acceptNext: ((selected: ISelectedSuggestion) => any) | undefined; private _listener: IDisposable | undefined; diff --git a/src/vs/editor/contrib/suggest/wordContextKey.ts b/src/vs/editor/contrib/suggest/wordContextKey.ts index 9461b86d339..7ec28a4cbef 100644 --- a/src/vs/editor/contrib/suggest/wordContextKey.ts +++ b/src/vs/editor/contrib/suggest/wordContextKey.ts @@ -13,7 +13,7 @@ export class WordContextKey extends Disposable { private readonly _ckAtEnd: IContextKey; - private _enabled: boolean; + private _enabled: boolean = false; private _selectionListener?: IDisposable; constructor( diff --git a/src/vs/workbench/api/browser/mainThreadCodeInsets.ts b/src/vs/workbench/api/browser/mainThreadCodeInsets.ts index 48938ad1f5b..1e23e14ce69 100644 --- a/src/vs/workbench/api/browser/mainThreadCodeInsets.ts +++ b/src/vs/workbench/api/browser/mainThreadCodeInsets.ts @@ -21,7 +21,7 @@ class EditorWebviewZone implements IViewZone { readonly afterColumn: number; readonly heightInLines: number; - private _id: number; + private _id?: number; // suppressMouseDown?: boolean | undefined; // heightInPx?: number | undefined; // minWidthInPx?: number | undefined; @@ -46,7 +46,7 @@ class EditorWebviewZone implements IViewZone { } dispose(): void { - this.editor.changeViewZones(accessor => accessor.removeZone(this._id)); + this.editor.changeViewZones(accessor => this._id && accessor.removeZone(this._id)); } } diff --git a/src/vs/workbench/api/browser/mainThreadDocumentsAndEditors.ts b/src/vs/workbench/api/browser/mainThreadDocumentsAndEditors.ts index 804349ee484..10037f6c21a 100644 --- a/src/vs/workbench/api/browser/mainThreadDocumentsAndEditors.ts +++ b/src/vs/workbench/api/browser/mainThreadDocumentsAndEditors.ts @@ -109,7 +109,7 @@ class DocumentAndEditorStateDelta { class DocumentAndEditorState { - static compute(before: DocumentAndEditorState, after: DocumentAndEditorState): DocumentAndEditorStateDelta { + static compute(before: DocumentAndEditorState | undefined, after: DocumentAndEditorState): DocumentAndEditorStateDelta { if (!before) { return new DocumentAndEditorStateDelta( [], values(after.documents), @@ -146,7 +146,7 @@ class MainThreadDocumentAndEditorStateComputer { private readonly _toDispose = new DisposableStore(); private _toDisposeOnEditorRemove = new Map(); - private _currentState: DocumentAndEditorState; + private _currentState?: DocumentAndEditorState; private _activeEditorOrder: ActiveEditorOrder = ActiveEditorOrder.Editor; constructor( diff --git a/src/vs/workbench/api/common/extHostCodeInsets.ts b/src/vs/workbench/api/common/extHostCodeInsets.ts index cf7f22b692a..066b25f2b02 100644 --- a/src/vs/workbench/api/common/extHostCodeInsets.ts +++ b/src/vs/workbench/api/common/extHostCodeInsets.ts @@ -63,7 +63,7 @@ export class ExtHostEditorInsets implements ExtHostEditorInsetsShape { private readonly _uuid = generateUuid(); private _html: string = ''; - private _options: vscode.WebviewOptions; + private _options: vscode.WebviewOptions = Object.create(null); toWebviewResource(resource: vscode.Uri): vscode.Uri { return toWebviewResource(that._initData, this._uuid, resource); diff --git a/src/vs/workbench/api/common/extHostDocumentData.ts b/src/vs/workbench/api/common/extHostDocumentData.ts index 96f70218b48..b44527a2b51 100644 --- a/src/vs/workbench/api/common/extHostDocumentData.ts +++ b/src/vs/workbench/api/common/extHostDocumentData.ts @@ -26,7 +26,7 @@ export class ExtHostDocumentData extends MirrorTextModel { private _proxy: MainThreadDocumentsShape; private _languageId: string; private _isDirty: boolean; - private _document: vscode.TextDocument; + private _document?: vscode.TextDocument; private _textLines: vscode.TextLine[] = []; private _isDisposed: boolean = false; diff --git a/src/vs/workbench/api/common/extHostDocumentsAndEditors.ts b/src/vs/workbench/api/common/extHostDocumentsAndEditors.ts index 5157bb71267..98002f78c71 100644 --- a/src/vs/workbench/api/common/extHostDocumentsAndEditors.ts +++ b/src/vs/workbench/api/common/extHostDocumentsAndEditors.ts @@ -17,7 +17,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha private _disposables: Disposable[] = []; - private _activeEditorId: string | null; + private _activeEditorId: string | null = null; private readonly _editors = new Map(); private readonly _documents = new Map(); diff --git a/src/vs/workbench/api/common/extHostFileSystem.ts b/src/vs/workbench/api/common/extHostFileSystem.ts index 9f0519b636f..4b82d98426b 100644 --- a/src/vs/workbench/api/common/extHostFileSystem.ts +++ b/src/vs/workbench/api/common/extHostFileSystem.ts @@ -155,7 +155,7 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { private readonly _usedSchemes = new Set(); private readonly _watches = new Map(); - private _linkProviderRegistration: IDisposable; + private _linkProviderRegistration?: IDisposable; private _handlePool: number = 0; readonly fileSystem: vscode.FileSystem; diff --git a/src/vs/workbench/api/common/extHostMemento.ts b/src/vs/workbench/api/common/extHostMemento.ts index 4502bacd671..d0e68010a17 100644 --- a/src/vs/workbench/api/common/extHostMemento.ts +++ b/src/vs/workbench/api/common/extHostMemento.ts @@ -14,7 +14,7 @@ export class ExtensionMemento implements IExtensionMemento { private readonly _storage: ExtHostStorage; private readonly _init: Promise; - private _value: { [n: string]: any; }; + private _value?: { [n: string]: any; }; private readonly _storageListener: IDisposable; constructor(id: string, global: boolean, storage: ExtHostStorage) { @@ -41,7 +41,7 @@ export class ExtensionMemento implements IExtensionMemento { get(key: string): T | undefined; get(key: string, defaultValue: T): T; get(key: string, defaultValue?: T): T { - let value = this._value[key]; + let value = this._value![key]; if (typeof value === 'undefined') { value = defaultValue; } @@ -49,8 +49,8 @@ export class ExtensionMemento implements IExtensionMemento { } update(key: string, value: any): Promise { - this._value[key] = value; - return this._storage.setValue(this._shared, this._id, this._value); + this._value![key] = value; + return this._storage.setValue(this._shared, this._id, this._value!); } dispose(): void { diff --git a/src/vs/workbench/api/common/extHostOutput.ts b/src/vs/workbench/api/common/extHostOutput.ts index 09ae3c549fc..3580d0e6679 100644 --- a/src/vs/workbench/api/common/extHostOutput.ts +++ b/src/vs/workbench/api/common/extHostOutput.ts @@ -27,6 +27,7 @@ export abstract class AbstractExtHostOutputChannel extends Disposable implements this._name = name; this._proxy = proxy; this._id = proxy.$register(this.name, log, file); + this._disposed = false; this._offset = 0; } @@ -121,7 +122,7 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape { private readonly _logsLocation: URI; private readonly _proxy: MainThreadOutputServiceShape; private readonly _channels: Map = new Map(); - private _visibleChannelDisposable: IDisposable; + private _visibleChannelDisposable?: IDisposable; constructor(factory: IOutputChannelFactory, logsLocation: URI, mainContext: IMainContext) { this._factory = factory; diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts index ca8fb69dd8c..85aed7a9bf4 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts @@ -29,7 +29,7 @@ export interface IBreadcrumbsService { export class BreadcrumbsService implements IBreadcrumbsService { - _serviceBrand: ServiceIdentifier; + _serviceBrand: any; private readonly _map = new Map(); @@ -55,8 +55,8 @@ registerSingleton(IBreadcrumbsService, BreadcrumbsService, true); export abstract class BreadcrumbsConfig { - name: string; - onDidChange: Event; + abstract get name(): string; + abstract get onDidChange(): Event; abstract getValue(overrides?: IConfigurationOverrides): T; abstract updateValue(value: T, overrides?: IConfigurationOverrides): Promise; diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionProfileService.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionProfileService.ts index 283c3406d8f..af073fb2c6f 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionProfileService.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionProfileService.ts @@ -5,7 +5,7 @@ import * as nls from 'vs/nls'; import { Event, Emitter } from 'vs/base/common/event'; -import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IExtensionHostProfile, ProfileSession, IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { Disposable, toDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { onUnexpectedError } from 'vs/base/common/errors'; @@ -23,7 +23,7 @@ import { CommandsRegistry } from 'vs/platform/commands/common/commands'; export class ExtensionHostProfileService extends Disposable implements IExtensionHostProfileService { - _serviceBrand: ServiceIdentifier; + _serviceBrand: any; private readonly _onDidChangeState: Emitter = this._register(new Emitter()); public readonly onDidChangeState: Event = this._onDidChangeState.event; @@ -34,7 +34,7 @@ export class ExtensionHostProfileService extends Disposable implements IExtensio private readonly _unresponsiveProfiles = new Map(); private _profile: IExtensionHostProfile | null; private _profileSession: ProfileSession | null; - private _state: ProfileSessionState; + private _state: ProfileSessionState = ProfileSessionState.None; private profilingStatusBarIndicator: IStatusbarEntryAccessor | undefined; private readonly profilingStatusBarIndicatorLabelUpdater = this._register(new MutableDisposable()); diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsSlowActions.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionsSlowActions.ts index 3b81b03291c..11aacd06955 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionsSlowActions.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionsSlowActions.ts @@ -19,9 +19,9 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import Severity from 'vs/base/common/severity'; abstract class RepoInfo { - readonly base: string; - readonly owner: string; - readonly repo: string; + abstract get base(): string; + abstract get owner(): string; + abstract get repo(): string; static fromExtension(desc: IExtensionDescription): RepoInfo | undefined { diff --git a/src/vs/workbench/contrib/markers/browser/markersFileDecorations.ts b/src/vs/workbench/contrib/markers/browser/markersFileDecorations.ts index ce1755e1f09..7c13cb5575e 100644 --- a/src/vs/workbench/contrib/markers/browser/markersFileDecorations.ts +++ b/src/vs/workbench/contrib/markers/browser/markersFileDecorations.ts @@ -56,8 +56,8 @@ class MarkersDecorationsProvider implements IDecorationsProvider { class MarkersFileDecorations implements IWorkbenchContribution { private readonly _disposables: IDisposable[]; - private _provider: IDisposable; - private _enabled: boolean; + private _provider?: IDisposable; + private _enabled?: boolean; constructor( @IMarkerService private readonly _markerService: IMarkerService, diff --git a/src/vs/workbench/contrib/performance/electron-browser/perfviewEditor.ts b/src/vs/workbench/contrib/performance/electron-browser/perfviewEditor.ts index 052e4bd2f5c..f0f73e07083 100644 --- a/src/vs/workbench/contrib/performance/electron-browser/perfviewEditor.ts +++ b/src/vs/workbench/contrib/performance/electron-browser/perfviewEditor.ts @@ -262,11 +262,11 @@ class PerfModelContentProvider implements ITextModelContentProvider { } abstract class LoaderStats { - readonly amdLoad: (string | number)[][]; - readonly amdInvoke: (string | number)[][]; - readonly nodeRequire: (string | number)[][]; - readonly nodeEval: (string | number)[][]; - readonly nodeRequireTotal: number; + abstract get amdLoad(): (string | number)[][]; + abstract get amdInvoke(): (string | number)[][]; + abstract get nodeRequire(): (string | number)[][]; + abstract get nodeEval(): (string | number)[][]; + abstract get nodeRequireTotal(): number; static get(): LoaderStats { diff --git a/src/vs/workbench/contrib/snippets/browser/snippetCompletionProvider.ts b/src/vs/workbench/contrib/snippets/browser/snippetCompletionProvider.ts index ec5d1ce087b..54888ea75b7 100644 --- a/src/vs/workbench/contrib/snippets/browser/snippetCompletionProvider.ts +++ b/src/vs/workbench/contrib/snippets/browser/snippetCompletionProvider.ts @@ -21,7 +21,7 @@ export class SnippetCompletion implements CompletionItem { label: string; detail: string; insertText: string; - documentation: MarkdownString; + documentation?: MarkdownString; range: IRange; sortText: string; kind: CompletionItemKind; diff --git a/src/vs/workbench/contrib/snippets/browser/tabCompletion.ts b/src/vs/workbench/contrib/snippets/browser/tabCompletion.ts index 8154a9da364..569598138e8 100644 --- a/src/vs/workbench/contrib/snippets/browser/tabCompletion.ts +++ b/src/vs/workbench/contrib/snippets/browser/tabCompletion.ts @@ -31,8 +31,8 @@ export class TabCompletionController implements editorCommon.IEditorContribution private _hasSnippets: IContextKey; private _activeSnippets: Snippet[] = []; - private _enabled: boolean; - private _selectionListener: IDisposable; + private _enabled?: boolean; + private _selectionListener?: IDisposable; private readonly _configListener: IDisposable; constructor( diff --git a/src/vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts b/src/vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts index 179c565335d..011b14816fb 100644 --- a/src/vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts +++ b/src/vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts @@ -32,8 +32,8 @@ class PartsSplash { private readonly _disposables = new DisposableStore(); - private _didChangeTitleBarStyle: boolean; - private _lastBaseTheme: string; + private _didChangeTitleBarStyle?: boolean; + private _lastBaseTheme?: string; private _lastBackground?: string; constructor( diff --git a/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts b/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts index f698782a600..fff264d6463 100644 --- a/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts +++ b/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts @@ -51,7 +51,7 @@ class ModelEditTask implements IDisposable { protected _edits: IIdentifiedSingleEditOperation[]; private _expectedModelVersionId: number | undefined; - protected _newEol: EndOfLineSequence; + protected _newEol: EndOfLineSequence | undefined; constructor(private readonly _modelReference: IReference) { this._model = this._modelReference.object.textEditorModel; @@ -142,7 +142,7 @@ class BulkEditModel implements IDisposable { private _textModelResolverService: ITextModelService; private _edits = new Map(); private _editor: ICodeEditor | undefined; - private _tasks: ModelEditTask[]; + private _tasks: ModelEditTask[] | undefined; private _progress: IProgress; constructor( @@ -159,7 +159,7 @@ class BulkEditModel implements IDisposable { } dispose(): void { - this._tasks = dispose(this._tasks); + this._tasks = dispose(this._tasks!); } addEdit(edit: ResourceTextEdit): void { @@ -196,7 +196,7 @@ class BulkEditModel implements IDisposable { } value.forEach(edit => task.addEdit(edit)); - this._tasks.push(task); + this._tasks!.push(task); this._progress.report(undefined); }); promises.push(promise); @@ -208,7 +208,7 @@ class BulkEditModel implements IDisposable { } validate(): ValidationResult { - for (const task of this._tasks) { + for (const task of this._tasks!) { const result = task.validate(); if (!result.canApply) { return result; @@ -218,7 +218,7 @@ class BulkEditModel implements IDisposable { } apply(): void { - for (const task of this._tasks) { + for (const task of this._tasks!) { task.apply(); this._progress.report(undefined); } diff --git a/src/vs/workbench/services/timer/electron-browser/timerService.ts b/src/vs/workbench/services/timer/electron-browser/timerService.ts index ffc0854905f..45d1e342b76 100644 --- a/src/vs/workbench/services/timer/electron-browser/timerService.ts +++ b/src/vs/workbench/services/timer/electron-browser/timerService.ts @@ -305,7 +305,7 @@ class TimerService implements ITimerService { _serviceBrand: any; - private _startupMetrics: Promise; + private _startupMetrics?: Promise; constructor( @IWindowsService private readonly _windowsService: IWindowsService, From 1e27e717479af478e43653aa87bc989cbf1539bf Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 31 Jul 2019 12:47:37 +0200 Subject: [PATCH 118/861] Fix gulp and jake resolve task Fixes #78269 --- extensions/gulp/src/main.ts | 7 ++----- extensions/jake/src/main.ts | 7 ++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/extensions/gulp/src/main.ts b/extensions/gulp/src/main.ts index ddc07a2f5c5..6f9a9e49334 100644 --- a/extensions/gulp/src/main.ts +++ b/extensions/gulp/src/main.ts @@ -130,10 +130,7 @@ class FolderDetector { public async getTask(_task: vscode.Task): Promise { const gulpTask = (_task.definition).task; if (gulpTask) { - let kind: GulpTaskDefinition = { - type: 'gulp', - task: gulpTask - }; + let kind: GulpTaskDefinition = (_task.definition); let options: vscode.ShellExecutionOptions = { cwd: this.workspaceFolder.uri.fsPath }; let task = new vscode.Task(kind, this.workspaceFolder, gulpTask, 'gulp', new vscode.ShellExecution(await this._gulpCommand, [gulpTask], options)); return task; @@ -342,4 +339,4 @@ export function activate(_context: vscode.ExtensionContext): void { export function deactivate(): void { detector.dispose(); -} \ No newline at end of file +} diff --git a/extensions/jake/src/main.ts b/extensions/jake/src/main.ts index 5a68447f94b..b8c6d5e7344 100644 --- a/extensions/jake/src/main.ts +++ b/extensions/jake/src/main.ts @@ -124,10 +124,7 @@ class FolderDetector { public async getTask(_task: vscode.Task): Promise { const jakeTask = (_task.definition).task; if (jakeTask) { - let kind: JakeTaskDefinition = { - type: 'jake', - task: jakeTask - }; + let kind: JakeTaskDefinition = (_task.definition); let options: vscode.ShellExecutionOptions = { cwd: this.workspaceFolder.uri.fsPath }; let task = new vscode.Task(kind, this.workspaceFolder, jakeTask, 'jake', new vscode.ShellExecution(await this._jakeCommand, [jakeTask], options)); return task; @@ -341,4 +338,4 @@ export function activate(_context: vscode.ExtensionContext): void { export function deactivate(): void { detector.dispose(); -} \ No newline at end of file +} From bcc8fb61cca9b1fed803cb6988a166730fe28be9 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 31 Jul 2019 12:53:47 +0200 Subject: [PATCH 119/861] Add powershell members to default themes Fixes #78212 --- extensions/theme-defaults/themes/dark_plus.json | 5 +++-- extensions/theme-defaults/themes/hc_black.json | 5 +++-- extensions/theme-defaults/themes/light_plus.json | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/extensions/theme-defaults/themes/dark_plus.json b/extensions/theme-defaults/themes/dark_plus.json index 1898153ba89..f12d3d7633e 100644 --- a/extensions/theme-defaults/themes/dark_plus.json +++ b/extensions/theme-defaults/themes/dark_plus.json @@ -8,7 +8,8 @@ "scope": [ "entity.name.function", "support.function", - "support.constant.handlebars" + "support.constant.handlebars", + "source.powershell variable.other.member" ], "settings": { "foreground": "#DCDCAA" @@ -171,4 +172,4 @@ } } ] -} \ No newline at end of file +} diff --git a/extensions/theme-defaults/themes/hc_black.json b/extensions/theme-defaults/themes/hc_black.json index 8119256d5f2..f76d7bb960f 100644 --- a/extensions/theme-defaults/themes/hc_black.json +++ b/extensions/theme-defaults/themes/hc_black.json @@ -13,7 +13,8 @@ "scope": [ "entity.name.function", "support.function", - "support.constant.handlebars" + "support.constant.handlebars", + "source.powershell variable.other.member" ], "settings": { "foreground": "#DCDCAA" @@ -115,4 +116,4 @@ } } ] -} \ No newline at end of file +} diff --git a/extensions/theme-defaults/themes/light_plus.json b/extensions/theme-defaults/themes/light_plus.json index 7138f045d58..3d30c5d17fb 100644 --- a/extensions/theme-defaults/themes/light_plus.json +++ b/extensions/theme-defaults/themes/light_plus.json @@ -8,7 +8,8 @@ "scope": [ "entity.name.function", "support.function", - "support.constant.handlebars" + "support.constant.handlebars", + "source.powershell variable.other.member" ], "settings": { "foreground": "#795E26" @@ -172,4 +173,4 @@ } ] -} \ No newline at end of file +} From b4d736b67b3a4b9ed87b8c45022ce97bce1cf3bc Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 31 Jul 2019 17:15:20 +0530 Subject: [PATCH 120/861] Fix microsoft/vscode-remote-release/issues/273 --- .../standalone/browser/simpleServices.ts | 2 +- .../configuration/common/configuration.ts | 4 ++-- .../common/configurationModels.ts | 8 +++---- .../api/common/extHostConfiguration.ts | 4 ++-- .../api/extHostConfiguration.test.ts | 24 +++++++++---------- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/vs/editor/standalone/browser/simpleServices.ts b/src/vs/editor/standalone/browser/simpleServices.ts index d333ce03746..423b8497be7 100644 --- a/src/vs/editor/standalone/browser/simpleServices.ts +++ b/src/vs/editor/standalone/browser/simpleServices.ts @@ -468,7 +468,7 @@ export class SimpleConfigurationService implements IConfigurationService { defaults: emptyModel, user: emptyModel, workspace: emptyModel, - folders: {} + folders: [] }; } } diff --git a/src/vs/platform/configuration/common/configuration.ts b/src/vs/platform/configuration/common/configuration.ts index 22a97c872cd..7249d295d87 100644 --- a/src/vs/platform/configuration/common/configuration.ts +++ b/src/vs/platform/configuration/common/configuration.ts @@ -5,7 +5,7 @@ import * as objects from 'vs/base/common/objects'; import * as types from 'vs/base/common/types'; -import { URI } from 'vs/base/common/uri'; +import { URI, UriComponents } from 'vs/base/common/uri'; import { Event } from 'vs/base/common/event'; import { Registry } from 'vs/platform/registry/common/platform'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; @@ -124,7 +124,7 @@ export interface IConfigurationData { defaults: IConfigurationModel; user: IConfigurationModel; workspace: IConfigurationModel; - folders: { [folder: string]: IConfigurationModel }; + folders: [UriComponents, IConfigurationModel][]; } export function compare(from: IConfigurationModel, to: IConfigurationModel): { added: string[], removed: string[], updated: string[] } { diff --git a/src/vs/platform/configuration/common/configurationModels.ts b/src/vs/platform/configuration/common/configurationModels.ts index 1765a06822f..373a2e1b086 100644 --- a/src/vs/platform/configuration/common/configurationModels.ts +++ b/src/vs/platform/configuration/common/configurationModels.ts @@ -8,7 +8,7 @@ import { ResourceMap } from 'vs/base/common/map'; import * as arrays from 'vs/base/common/arrays'; import * as types from 'vs/base/common/types'; import * as objects from 'vs/base/common/objects'; -import { URI } from 'vs/base/common/uri'; +import { URI, UriComponents } from 'vs/base/common/uri'; import { OVERRIDE_PROPERTY_PATTERN, ConfigurationScope, IConfigurationRegistry, Extensions, IConfigurationPropertySchema } from 'vs/platform/configuration/common/configurationRegistry'; import { IOverrides, overrideIdentifierFromKey, addToValueTree, toValuesTree, IConfigurationModel, getConfigurationValue, IConfigurationOverrides, IConfigurationData, getDefaultValues, getConfigurationKeys, IConfigurationChangeEvent, ConfigurationTarget, removeFromValueTree, toOverrides } from 'vs/platform/configuration/common/configuration'; import { Workspace } from 'vs/platform/workspace/common/workspace'; @@ -545,11 +545,11 @@ export class Configuration { overrides: this._workspaceConfiguration.overrides, keys: this._workspaceConfiguration.keys }, - folders: this._folderConfigurations.keys().reduce((result, folder) => { + folders: this._folderConfigurations.keys().reduce<[UriComponents, IConfigurationModel][]>((result, folder) => { const { contents, overrides, keys } = this._folderConfigurations.get(folder)!; - result[folder.toString()] = { contents, overrides, keys }; + result.push([folder, { contents, overrides, keys }]); return result; - }, Object.create({})) + }, []) }; } diff --git a/src/vs/workbench/api/common/extHostConfiguration.ts b/src/vs/workbench/api/common/extHostConfiguration.ts index 4c8515502df..4f19d1f59e4 100644 --- a/src/vs/workbench/api/common/extHostConfiguration.ts +++ b/src/vs/workbench/api/common/extHostConfiguration.ts @@ -263,8 +263,8 @@ export class ExtHostConfigProvider { const defaultConfiguration = ExtHostConfigProvider.parseConfigurationModel(data.defaults); const userConfiguration = ExtHostConfigProvider.parseConfigurationModel(data.user); const workspaceConfiguration = ExtHostConfigProvider.parseConfigurationModel(data.workspace); - const folders: ResourceMap = Object.keys(data.folders).reduce((result, key) => { - result.set(URI.parse(key), ExtHostConfigProvider.parseConfigurationModel(data.folders[key])); + const folders: ResourceMap = data.folders.reduce((result, value) => { + result.set(URI.revive(value[0]), ExtHostConfigProvider.parseConfigurationModel(value[1])); return result; }, new ResourceMap()); return new Configuration(defaultConfiguration, userConfiguration, new ConfigurationModel(), workspaceConfiguration, folders, new ConfigurationModel(), new ResourceMap(), false); diff --git a/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts b/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts index db499917207..02f4cf4cd98 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { URI } from 'vs/base/common/uri'; +import { URI, UriComponents } from 'vs/base/common/uri'; import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import { ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration'; import { MainThreadConfigurationShape, IConfigurationInitData } from 'vs/workbench/api/common/extHost.protocol'; @@ -12,7 +12,7 @@ import { ConfigurationModel } from 'vs/platform/configuration/common/configurati import { TestRPCProtocol } from './testRPCProtocol'; import { mock } from 'vs/workbench/test/electron-browser/api/mock'; import { IWorkspaceFolder, WorkspaceFolder } from 'vs/platform/workspace/common/workspace'; -import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; +import { ConfigurationTarget, IConfigurationModel } from 'vs/platform/configuration/common/configuration'; import { NullLogService } from 'vs/platform/log/common/log'; import { assign } from 'vs/base/common/objects'; import { Counter } from 'vs/base/common/numbers'; @@ -39,7 +39,7 @@ suite('ExtHostConfiguration', function () { defaults: new ConfigurationModel(contents), user: new ConfigurationModel(contents), workspace: new ConfigurationModel(), - folders: Object.create(null), + folders: [], configurationScopes: [] }; } @@ -277,7 +277,7 @@ suite('ExtHostConfiguration', function () { } }, ['editor.wordWrap']), workspace: new ConfigurationModel({}, []), - folders: Object.create(null), + folders: [], configurationScopes: [] } ); @@ -297,13 +297,13 @@ suite('ExtHostConfiguration', function () { test('inspect in single root context', function () { const workspaceUri = URI.file('foo'); - const folders = Object.create(null); + const folders: [UriComponents, IConfigurationModel][] = []; const workspace = new ConfigurationModel({ 'editor': { 'wordWrap': 'bounded' } }, ['editor.wordWrap']); - folders[workspaceUri.toString()] = workspace; + folders.push([workspaceUri, workspace]); const extHostWorkspace = new ExtHostWorkspace(new TestRPCProtocol(), new NullLogService(), new Counter()); extHostWorkspace.$initializeWorkspace({ 'id': 'foo', @@ -365,19 +365,19 @@ suite('ExtHostConfiguration', function () { const firstRoot = URI.file('foo1'); const secondRoot = URI.file('foo2'); const thirdRoot = URI.file('foo3'); - const folders = Object.create(null); - folders[firstRoot.toString()] = new ConfigurationModel({ + const folders: [UriComponents, IConfigurationModel][] = []; + folders.push([firstRoot, new ConfigurationModel({ 'editor': { 'wordWrap': 'off', 'lineNumbers': 'relative' } - }, ['editor.wordWrap']); - folders[secondRoot.toString()] = new ConfigurationModel({ + }, ['editor.wordWrap'])]); + folders.push([secondRoot, new ConfigurationModel({ 'editor': { 'wordWrap': 'on' } - }, ['editor.wordWrap']); - folders[thirdRoot.toString()] = new ConfigurationModel({}, []); + }, ['editor.wordWrap'])]); + folders.push([thirdRoot, new ConfigurationModel({}, [])]); const extHostWorkspace = new ExtHostWorkspace(new TestRPCProtocol(), new NullLogService(), new Counter()); extHostWorkspace.$initializeWorkspace({ From 9cbe1a17b0e69f0165c1a42f1c7ace6c0a91c798 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 31 Jul 2019 12:52:35 +0200 Subject: [PATCH 121/861] fixes #77575 --- src/vs/base/browser/ui/list/listWidget.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index 6b920ee1e7a..a3bd2958421 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -647,12 +647,15 @@ export class MouseController implements IDisposable { } const newSelection = disjunction(rangeSelection, relativeComplement(selection, contiguousRange)); + this.list.setFocus([focus]); this.list.setSelection(newSelection, e.browserEvent); } else if (this.isSelectionSingleChangeEvent(e)) { const selection = this.list.getSelection(); const newSelection = selection.filter(i => i !== focus); + this.list.setFocus([focus]); + if (selection.length === newSelection.length) { this.list.setSelection([...newSelection, focus], e.browserEvent); } else { From 38568cede0ebe0d071fc65ae618ee22a450802aa Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 31 Jul 2019 14:38:17 +0200 Subject: [PATCH 122/861] fixes #75817 --- build/azure-pipelines/win32/product-build-win32.yml | 1 + build/gulpfile.vscode.win32.js | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 66583616c6d..7a72dcfb09b 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -99,6 +99,7 @@ steps: exec { yarn gulp "vscode-win32-$env:VSCODE_ARCH-min-ci" } exec { yarn gulp "vscode-reh-win32-$env:VSCODE_ARCH-min-ci" } exec { yarn gulp "vscode-reh-web-win32-$env:VSCODE_ARCH-min-ci" } + exec { yarn gulp "vscode-win32-$env:VSCODE_ARCH-code-helper" } exec { yarn gulp "vscode-win32-$env:VSCODE_ARCH-inno-updater" } displayName: Build diff --git a/build/gulpfile.vscode.win32.js b/build/gulpfile.vscode.win32.js index b20efebdb62..497fc553c03 100644 --- a/build/gulpfile.vscode.win32.js +++ b/build/gulpfile.vscode.win32.js @@ -135,12 +135,17 @@ function copyInnoUpdater(arch) { }; } -function patchInnoUpdater(arch) { +function updateIcon(executablePath) { return cb => { const icon = path.join(repoPath, 'resources', 'win32', 'code.ico'); - rcedit(path.join(buildPath(arch), 'tools', 'inno_updater.exe'), { icon }, cb); + rcedit(executablePath, { icon }, cb); }; } -gulp.task(task.define('vscode-win32-ia32-inno-updater', task.series(copyInnoUpdater('ia32'), patchInnoUpdater('ia32')))); -gulp.task(task.define('vscode-win32-x64-inno-updater', task.series(copyInnoUpdater('x64'), patchInnoUpdater('x64')))); \ No newline at end of file +gulp.task(task.define('vscode-win32-ia32-inno-updater', task.series(copyInnoUpdater('ia32'), updateIcon(path.join(buildPath('ia32'), 'tools', 'inno_updater.exe'))))); +gulp.task(task.define('vscode-win32-x64-inno-updater', task.series(copyInnoUpdater('x64'), updateIcon(path.join(buildPath('x64'), 'tools', 'inno_updater.exe'))))); + +// CodeHelper.exe icon + +gulp.task(task.define('vscode-win32-ia32-code-helper', task.series(updateIcon(path.join(buildPath('ia32'), 'resources', 'app', 'out', 'vs', 'platform', 'files', 'node', 'watcher', 'win32', 'CodeHelper.exe'))))); +gulp.task(task.define('vscode-win32-x64-code-helper', task.series(updateIcon(path.join(buildPath('x64'), 'resources', 'app', 'out', 'vs', 'platform', 'files', 'node', 'watcher', 'win32', 'CodeHelper.exe'))))); From bd387921da722d14b9ac9e7cc15f7e17d574538a Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 31 Jul 2019 15:15:07 +0200 Subject: [PATCH 123/861] fixes #73101 --- .../extensions/common/inactiveExtensionUrlHandler.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/services/extensions/common/inactiveExtensionUrlHandler.ts b/src/vs/workbench/services/extensions/common/inactiveExtensionUrlHandler.ts index 7330ceedefb..2b8c9a72c57 100644 --- a/src/vs/workbench/services/extensions/common/inactiveExtensionUrlHandler.ts +++ b/src/vs/workbench/services/extensions/common/inactiveExtensionUrlHandler.ts @@ -19,7 +19,9 @@ import { IURLHandler, IURLService } from 'vs/platform/url/common/url'; import { IWindowService } from 'vs/platform/windows/common/windows'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; -import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { IWorkbenchContribution, Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; +import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; const FIVE_MINUTES = 5 * 60 * 1000; const THIRTY_SECONDS = 30 * 1000; @@ -34,7 +36,6 @@ function isExtensionId(value: string): boolean { export const IExtensionUrlHandler = createDecorator('inactiveExtensionUrlHandler'); export interface IExtensionUrlHandler { - readonly _serviceBrand: any; registerExtensionHandler(extensionId: ExtensionIdentifier, handler: IURLHandler): void; unregisterExtensionHandler(extensionId: ExtensionIdentifier): void; } @@ -48,9 +49,7 @@ export interface IExtensionUrlHandler { * * It also makes sure the user confirms opening URLs directed towards extensions. */ -export class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler { - - readonly _serviceBrand: any; +export class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler, IWorkbenchContribution { private extensionHandlers = new Map(); private uriBuffer = new Map(); @@ -332,4 +331,5 @@ export class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler { } } -registerSingleton(IExtensionUrlHandler, ExtensionUrlHandler); +const workbenchRegistry = Registry.as(WorkbenchExtensions.Workbench); +workbenchRegistry.registerWorkbenchContribution(ExtensionUrlHandler, LifecyclePhase.Ready); From 42cdcbb1bd14b9b65cfad38ecc35369200b4a77c Mon Sep 17 00:00:00 2001 From: Christian Oliff Date: Wed, 31 Jul 2019 22:16:42 +0900 Subject: [PATCH 124/861] Fix 'Untitled' typo --- test/smoke/src/areas/workbench/data-loss.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/smoke/src/areas/workbench/data-loss.test.ts b/test/smoke/src/areas/workbench/data-loss.test.ts index 6d0506144f9..85e593745d2 100644 --- a/test/smoke/src/areas/workbench/data-loss.test.ts +++ b/test/smoke/src/areas/workbench/data-loss.test.ts @@ -12,7 +12,7 @@ export function setup() { await app.workbench.editors.newUntitledFile(); const untitled = 'Untitled-1'; - const textToTypeInUntitled = 'Hello, Unitled Code'; + const textToTypeInUntitled = 'Hello, Untitled Code'; await app.workbench.editor.waitForTypeInEditor(untitled, textToTypeInUntitled); const readmeMd = 'readme.md'; @@ -30,4 +30,4 @@ export function setup() { await app.workbench.editor.waitForEditorContents(untitled, c => c.indexOf(textToTypeInUntitled) > -1); }); }); -} \ No newline at end of file +} From d0e7dabc6f78e537a6c5506049ef6864b79023fc Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 31 Jul 2019 15:19:14 +0200 Subject: [PATCH 125/861] Revert "fixes #73101" This reverts commit bd387921da722d14b9ac9e7cc15f7e17d574538a. --- .../extensions/common/inactiveExtensionUrlHandler.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/services/extensions/common/inactiveExtensionUrlHandler.ts b/src/vs/workbench/services/extensions/common/inactiveExtensionUrlHandler.ts index 2b8c9a72c57..7330ceedefb 100644 --- a/src/vs/workbench/services/extensions/common/inactiveExtensionUrlHandler.ts +++ b/src/vs/workbench/services/extensions/common/inactiveExtensionUrlHandler.ts @@ -19,9 +19,7 @@ import { IURLHandler, IURLService } from 'vs/platform/url/common/url'; import { IWindowService } from 'vs/platform/windows/common/windows'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; -import { Registry } from 'vs/platform/registry/common/platform'; -import { IWorkbenchContribution, Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; -import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; const FIVE_MINUTES = 5 * 60 * 1000; const THIRTY_SECONDS = 30 * 1000; @@ -36,6 +34,7 @@ function isExtensionId(value: string): boolean { export const IExtensionUrlHandler = createDecorator('inactiveExtensionUrlHandler'); export interface IExtensionUrlHandler { + readonly _serviceBrand: any; registerExtensionHandler(extensionId: ExtensionIdentifier, handler: IURLHandler): void; unregisterExtensionHandler(extensionId: ExtensionIdentifier): void; } @@ -49,7 +48,9 @@ export interface IExtensionUrlHandler { * * It also makes sure the user confirms opening URLs directed towards extensions. */ -export class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler, IWorkbenchContribution { +export class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler { + + readonly _serviceBrand: any; private extensionHandlers = new Map(); private uriBuffer = new Map(); @@ -331,5 +332,4 @@ export class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler, I } } -const workbenchRegistry = Registry.as(WorkbenchExtensions.Workbench); -workbenchRegistry.registerWorkbenchContribution(ExtensionUrlHandler, LifecyclePhase.Ready); +registerSingleton(IExtensionUrlHandler, ExtensionUrlHandler); From 227f661bd9ddf1831219c2de3b7e6dc1f1a1e1ea Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 31 Jul 2019 15:33:42 +0200 Subject: [PATCH 126/861] opsy --- .github/classifier.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/classifier.yml b/.github/classifier.yml index 29f9fa41f52..8acb0002347 100644 --- a/.github/classifier.yml +++ b/.github/classifier.yml @@ -150,7 +150,7 @@ assignLabel: false }, file-explorer: { - assignees: [ ], + assignees: [ isidorn ], assignLabel: false }, file-glob: [], From 350a1979752adb6f4416e013e45795591afc6309 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 31 Jul 2019 16:03:33 +0200 Subject: [PATCH 127/861] fix #78274 --- src/vs/workbench/api/common/extHostCommands.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/api/common/extHostCommands.ts b/src/vs/workbench/api/common/extHostCommands.ts index 19e4d5655f1..2f429539b4c 100644 --- a/src/vs/workbench/api/common/extHostCommands.ts +++ b/src/vs/workbench/api/common/extHostCommands.ts @@ -128,7 +128,9 @@ export class ExtHostCommands implements ExtHostCommandsShape { if (this._commands.has(id)) { // we stay inside the extension host and support // to pass any kind of parameters around - return this._executeContributedCommand(id, args); + const res = this._executeContributedCommand(id, args); + this._onDidExecuteCommand.fire({ command: id, arguments: args }); + return res; } else { // automagically convert some argument types @@ -170,7 +172,6 @@ export class ExtHostCommands implements ExtHostCommandsShape { try { const result = callback.apply(thisArg, args); - this._onDidExecuteCommand.fire({ command: id, arguments: args }); return Promise.resolve(result); } catch (err) { this._logService.error(err, id); From 678decdae18bfe27e45544faa8443a826aa7eb5e Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 31 Jul 2019 17:17:39 +0200 Subject: [PATCH 128/861] fixes #72531 --- src/vs/base/parts/ipc/common/ipc.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/base/parts/ipc/common/ipc.ts b/src/vs/base/parts/ipc/common/ipc.ts index 9715105baa3..e0205092202 100644 --- a/src/vs/base/parts/ipc/common/ipc.ts +++ b/src/vs/base/parts/ipc/common/ipc.ts @@ -268,7 +268,9 @@ export class ChannelServer implements IChannelServer): void { this.channels.set(channelName, channel); - this.flushPendingRequests(channelName); + + // https://github.com/microsoft/vscode/issues/72531 + setTimeout(() => this.flushPendingRequests(channelName), 0); } private sendResponse(response: IRawResponse): void { From 5f55c1b8801ec88c3a55093c061297bf794e466b Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Wed, 31 Jul 2019 09:39:53 -0700 Subject: [PATCH 129/861] Fix #78240 --- .../contrib/preferences/browser/settingsWidgets.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts index 6f38e066dd4..06d1532bec5 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts @@ -20,6 +20,7 @@ import { foreground, inputBackground, inputBorder, inputForeground, listActiveSe import { attachButtonStyler, attachInputBoxStyler } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { disposableTimeout } from 'vs/base/common/async'; +import { isUndefinedOrNull } from 'vs/base/common/types'; const $ = DOM.$; export const settingsHeaderForeground = registerColor('settings.headerForeground', { light: '#444444', dark: '#e7e7e7', hc: '#ffffff' }, localize('headerForeground', "(For settings editor preview) The foreground color for a section header or active title.")); @@ -365,7 +366,7 @@ export class ListSettingWidget extends Disposable { private renderItem(item: IListViewItem, idx: number, listFocused: boolean): HTMLElement { return item.editing ? - this.renderEditItem(item) : + this.renderEditItem(item, idx) : this.renderDataItem(item, idx, listFocused); } @@ -419,17 +420,18 @@ export class ListSettingWidget extends Disposable { return rowElement; } - private renderEditItem(item: IListViewItem): HTMLElement { + private renderEditItem(item: IListViewItem, idx: number): HTMLElement { const rowElement = $('.setting-list-edit-row'); const onSubmit = (edited: boolean) => { this.model.setEditKey(null); const value = valueInput.value.trim(); - if (edited && value) { + if (edited && !isUndefinedOrNull(value)) { this._onDidChangeList.fire({ originalValue: item.value, value: value, - sibling: siblingInput && siblingInput.value.trim() + sibling: siblingInput && siblingInput.value.trim(), + removeIndex: value === '' ? idx : undefined }); } this.renderList(); From e723f810ecba9738b9c98eb2b8f18c2b14ec0058 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 31 Jul 2019 10:24:42 -0700 Subject: [PATCH 130/861] Add more tests --- .../src/areas/preferences/preferences.test.ts | 2 +- test/smoke/src/areas/preferences/settings.ts | 4 +- test/smoke/src/main.ts | 11 +++++- test/smoke/src/vscode/puppeteer-driver.ts | 38 +++++++++++++------ 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/test/smoke/src/areas/preferences/preferences.test.ts b/test/smoke/src/areas/preferences/preferences.test.ts index f1eb589b118..c7a1ce51475 100644 --- a/test/smoke/src/areas/preferences/preferences.test.ts +++ b/test/smoke/src/areas/preferences/preferences.test.ts @@ -34,4 +34,4 @@ export function setup() { await app.workbench.settingsEditor.clearUserSettings(); }); }); -} \ No newline at end of file +} diff --git a/test/smoke/src/areas/preferences/settings.ts b/test/smoke/src/areas/preferences/settings.ts index cebd2f51497..de7bd1ffb43 100644 --- a/test/smoke/src/areas/preferences/settings.ts +++ b/test/smoke/src/areas/preferences/settings.ts @@ -30,7 +30,7 @@ export class SettingsEditor { async clearUserSettings(): Promise { const settingsPath = path.join(this.userDataPath, 'User', 'settings.json'); - await new Promise((c, e) => fs.writeFile(settingsPath, '{}', 'utf8', err => err ? e(err) : c())); + await new Promise((c, e) => fs.writeFile(settingsPath, '{\n}', 'utf8', err => err ? e(err) : c())); await this.openSettings(); await this.editor.waitForEditorContents('settings.json', c => c === '{}'); @@ -39,4 +39,4 @@ export class SettingsEditor { private async openSettings(): Promise { await this.quickopen.runCommand('Preferences: Open Settings (JSON)'); } -} \ No newline at end of file +} diff --git a/test/smoke/src/main.ts b/test/smoke/src/main.ts index 935b16fb46c..4972be890f1 100644 --- a/test/smoke/src/main.ts +++ b/test/smoke/src/main.ts @@ -141,7 +141,8 @@ if (typeof stablePath === 'string' && !fs.existsSync(stablePath)) { fail(`Can't find Stable Code at ${stablePath}.`); } -const userDataDir = path.join(testDataPath, 'd'); +// TODO: Server should be launched from smoke tests +const userDataDir = opts.web ? path.join(process.env.HOME!, '.vscode-remote/data') : path.join(testDataPath, 'd'); let quality: Quality; if (process.env.VSCODE_DEV === '1') { @@ -245,6 +246,11 @@ describe('Running Code', () => { const app = new Application(this.defaultOptions); await app!.start(opts.web ? false : undefined); this.app = app; + + // TODO: User data dir is not cleared for web yet + if (opts.web) { + await app.workbench.settingsEditor.clearUserSettings(); + } }); after(async function () { @@ -273,7 +279,8 @@ describe('Running Code', () => { } if (opts.web) { - console.log('setup term tests only'); + setupDataExplorerTests(); + setupDataPreferencesTests(); setupTerminalTests(); return; } diff --git a/test/smoke/src/vscode/puppeteer-driver.ts b/test/smoke/src/vscode/puppeteer-driver.ts index 12b56ebd202..fbe7b26db47 100644 --- a/test/smoke/src/vscode/puppeteer-driver.ts +++ b/test/smoke/src/vscode/puppeteer-driver.ts @@ -11,7 +11,13 @@ const height = 800; const vscodeToPuppeteerKey = { cmd: 'Meta', ctrl: 'Control', - enter: 'Enter' + enter: 'Enter', + escape: 'Escape', + right: 'ArrowRight', + up: 'ArrowUp', + down: 'ArrowDown', + left: 'ArrowLeft', + home: 'Home' }; function buildDriver(browser: puppeteer.Browser, page: puppeteer.Page): IDriver { @@ -24,18 +30,26 @@ function buildDriver(browser: puppeteer.Browser, page: puppeteer.Page): IDriver reloadWindow: (windowId) => Promise.resolve(), exitApplication: () => browser.close(), dispatchKeybinding: async (windowId, keybinding) => { - const keys = keybinding.split('+'); - const keysDown: string[] = []; - for (let i = 0; i < keys.length; i++) { - if (keys[i] in vscodeToPuppeteerKey) { - keys[i] = vscodeToPuppeteerKey[keys[i]]; + const chords = keybinding.split(' '); + chords.forEach(async (chord, index) => { + if (index > 0) { + await timeout(100); } - await page.keyboard.down(keys[i]); - keysDown.push(keys[i]); - } - while (keysDown.length > 0) { - await page.keyboard.up(keysDown.pop()!); - } + const keys = chord.split('+'); + const keysDown: string[] = []; + for (let i = 0; i < keys.length; i++) { + if (keys[i] in vscodeToPuppeteerKey) { + keys[i] = vscodeToPuppeteerKey[keys[i]]; + } + await page.keyboard.down(keys[i]); + keysDown.push(keys[i]); + } + while (keysDown.length > 0) { + await page.keyboard.up(keysDown.pop()!); + } + }); + + await timeout(100); }, click: async (windowId, selector, xoffset, yoffset) => { const { x, y } = await page.evaluate(` From 479577f46489f85a00c9658271ebb4e0d8f806af Mon Sep 17 00:00:00 2001 From: kaoru <679719+0x6b@users.noreply.github.com> Date: Thu, 1 Aug 2019 02:45:44 +0900 Subject: [PATCH 131/861] Lowercase 'For' in 'Checking For Updates...' menu item (#77972) Fixed remaining upper case 'For' in similar menu item which is reported and fixed at #27532. --- src/vs/platform/menubar/electron-main/menubar.ts | 2 +- src/vs/workbench/browser/parts/titlebar/menubarControl.ts | 2 +- src/vs/workbench/contrib/update/electron-browser/update.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/platform/menubar/electron-main/menubar.ts b/src/vs/platform/menubar/electron-main/menubar.ts index 76185f93da8..01f781dd944 100644 --- a/src/vs/platform/menubar/electron-main/menubar.ts +++ b/src/vs/platform/menubar/electron-main/menubar.ts @@ -550,7 +550,7 @@ export class Menubar { })]; case StateType.CheckingForUpdates: - return [new MenuItem({ label: nls.localize('miCheckingForUpdates', "Checking For Updates..."), enabled: false })]; + return [new MenuItem({ label: nls.localize('miCheckingForUpdates', "Checking for Updates..."), enabled: false })]; case StateType.AvailableForDownload: return [new MenuItem({ diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index 7b7ca5972b1..bb5dda0c50f 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -586,7 +586,7 @@ export class CustomMenubarControl extends MenubarControl { this.updateService.checkForUpdates({ windowId })); case StateType.CheckingForUpdates: - return new Action('update.checking', nls.localize('checkingForUpdates', "Checking For Updates..."), undefined, false); + return new Action('update.checking', nls.localize('checkingForUpdates', "Checking for Updates..."), undefined, false); case StateType.AvailableForDownload: return new Action('update.downloadNow', nls.localize({ key: 'download now', comment: ['&& denotes a mnemonic'] }, "D&&ownload Now"), undefined, true, () => diff --git a/src/vs/workbench/contrib/update/electron-browser/update.ts b/src/vs/workbench/contrib/update/electron-browser/update.ts index ae89e3f4719..0d2d53003b7 100644 --- a/src/vs/workbench/contrib/update/electron-browser/update.ts +++ b/src/vs/workbench/contrib/update/electron-browser/update.ts @@ -484,7 +484,7 @@ export class UpdateContribution extends Disposable implements IWorkbenchContribu group: '5_update', command: { id: 'update.checking', - title: nls.localize('checkingForUpdates', "Checking For Updates..."), + title: nls.localize('checkingForUpdates', "Checking for Updates..."), precondition: FalseContext }, when: CONTEXT_UPDATE_STATE.isEqualTo(StateType.CheckingForUpdates) From f067a979d878ce0256521c3cfc5331f9dbb1989a Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Wed, 31 Jul 2019 11:05:58 -0700 Subject: [PATCH 132/861] Fix #77452 --- .../contrib/preferences/browser/settingsWidgets.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts index 06d1532bec5..1a94dfde46e 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts @@ -229,13 +229,19 @@ export class ListSettingWidget extends Disposable { this._register(DOM.addStandardDisposableListener(this.listElement, 'keydown', (e: KeyboardEvent) => { if (e.keyCode === KeyCode.UpArrow) { + const selectedIndex = this.model.getSelected(); this.model.selectPrevious(); - this.renderList(); + if (this.model.getSelected() !== selectedIndex) { + this.renderList(); + } e.preventDefault(); e.stopPropagation(); } else if (e.keyCode === KeyCode.DownArrow) { + const selectedIndex = this.model.getSelected(); this.model.selectNext(); - this.renderList(); + if (this.model.getSelected() !== selectedIndex) { + this.renderList(); + } e.preventDefault(); e.stopPropagation(); } From a1d910fea4617f637e25f1bc624df2b3a9d25c88 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 31 Jul 2019 11:11:06 -0700 Subject: [PATCH 133/861] xterm@3.15.0-beta90 Diff: https://github.com/xtermjs/xterm.js/compare/689fb6b...d20068c Changes: - Make dispose idempotent Fixes #78184 --- package.json | 2 +- remote/package.json | 2 +- remote/yarn.lock | 8 ++++---- yarn.lock | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index e24f6bfec46..67058f1777e 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "vscode-ripgrep": "^1.5.5", "vscode-sqlite3": "4.0.8", "vscode-textmate": "^4.2.2", - "xterm": "3.15.0-beta89", + "xterm": "3.15.0-beta90", "xterm-addon-search": "0.2.0-beta3", "xterm-addon-web-links": "0.1.0-beta10", "yauzl": "^2.9.2", diff --git a/remote/package.json b/remote/package.json index 34ffee1a4be..5f851213c9d 100644 --- a/remote/package.json +++ b/remote/package.json @@ -20,7 +20,7 @@ "vscode-proxy-agent": "0.4.0", "vscode-ripgrep": "^1.5.5", "vscode-textmate": "^4.2.2", - "xterm": "3.15.0-beta89", + "xterm": "3.15.0-beta90", "xterm-addon-search": "0.2.0-beta3", "xterm-addon-web-links": "0.1.0-beta10", "yauzl": "^2.9.2", diff --git a/remote/yarn.lock b/remote/yarn.lock index 1c4e700f495..019b237911f 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -1159,10 +1159,10 @@ xterm-addon-web-links@0.1.0-beta10: resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23" integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg== -xterm@3.15.0-beta89: - version "3.15.0-beta89" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta89.tgz#255962e2595deefb42b8c0043001256526163a3f" - integrity sha512-rNaoUamacPRg+ejbKDGRDNqR3SZ3Uf/pUW0mO+FF25/lIgdLq8x7RgZVBgFweCZ/dijPjxoyMcgfNDTH9h8LOg== +xterm@3.15.0-beta90: + version "3.15.0-beta90" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta90.tgz#e1732c2914584c86cffa797ba762c482f21ce182" + integrity sha512-eixIA5brfoez+Y8bJPCcIw8Q7LgOvxRX3cPBaGmo7ozUASx9IEGOmvIRQX1ozTUmxEiXPnAxOfl/isQ+yNlaww== yauzl@^2.9.2: version "2.10.0" diff --git a/yarn.lock b/yarn.lock index f1c162556e3..6697594e961 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9895,10 +9895,10 @@ xterm-addon-web-links@0.1.0-beta10: resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23" integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg== -xterm@3.15.0-beta89: - version "3.15.0-beta89" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta89.tgz#255962e2595deefb42b8c0043001256526163a3f" - integrity sha512-rNaoUamacPRg+ejbKDGRDNqR3SZ3Uf/pUW0mO+FF25/lIgdLq8x7RgZVBgFweCZ/dijPjxoyMcgfNDTH9h8LOg== +xterm@3.15.0-beta90: + version "3.15.0-beta90" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta90.tgz#e1732c2914584c86cffa797ba762c482f21ce182" + integrity sha512-eixIA5brfoez+Y8bJPCcIw8Q7LgOvxRX3cPBaGmo7ozUASx9IEGOmvIRQX1ozTUmxEiXPnAxOfl/isQ+yNlaww== y18n@^3.2.1: version "3.2.1" From c6ff21a30e68ce50ddce969531ee7d59f56634b7 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 31 Jul 2019 11:13:58 -0700 Subject: [PATCH 134/861] Update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 67058f1777e..d7994dbe4d5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.37.0", - "distro": "11ab6b1c5be090591adc26a81f72a16908697165", + "distro": "ea88b4ff40235904907278b141fe4bd3e4a035f7", "author": { "name": "Microsoft Corporation" }, From 8db441df8713e775e0716b89d2fe3a58f5919589 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 31 Jul 2019 11:19:06 -0700 Subject: [PATCH 135/861] Disable cygwin shell detection Related #75945 --- src/vs/workbench/contrib/terminal/node/terminal.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/node/terminal.ts b/src/vs/workbench/contrib/terminal/node/terminal.ts index f686213d1cb..e7fc03e6bcd 100644 --- a/src/vs/workbench/contrib/terminal/node/terminal.ts +++ b/src/vs/workbench/contrib/terminal/node/terminal.ts @@ -120,10 +120,11 @@ async function detectAvailableWindowsShells(): Promise { `${process.env['ProgramFiles']}\\Git\\usr\\bin\\bash.exe`, `${process.env['LocalAppData']}\\Programs\\Git\\bin\\bash.exe`, ], - Cygwin: [ - `${process.env['HOMEDRIVE']}\\cygwin64\\bin\\bash.exe`, - `${process.env['HOMEDRIVE']}\\cygwin\\bin\\bash.exe` - ] + // See #75945 + // Cygwin: [ + // `${process.env['HOMEDRIVE']}\\cygwin64\\bin\\bash.exe`, + // `${process.env['HOMEDRIVE']}\\cygwin\\bin\\bash.exe` + // ] }; const promises: PromiseLike[] = []; Object.keys(expectedLocations).forEach(key => promises.push(validateShellPaths(key, expectedLocations[key]))); @@ -170,4 +171,4 @@ async function getShellPathFromRegistry(shellName: string): Promise { } catch (error) { return ''; } -} \ No newline at end of file +} From 9db05a8451d35b0bd9a4cf6139ad543928fc6125 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Wed, 31 Jul 2019 11:16:54 -0700 Subject: [PATCH 136/861] Fix #77451 --- .../contrib/preferences/browser/media/settingsWidgets.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/preferences/browser/media/settingsWidgets.css b/src/vs/workbench/contrib/preferences/browser/media/settingsWidgets.css index fe32e55ab66..1ddeedc5e16 100644 --- a/src/vs/workbench/contrib/preferences/browser/media/settingsWidgets.css +++ b/src/vs/workbench/contrib/preferences/browser/media/settingsWidgets.css @@ -104,4 +104,5 @@ .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-widget { margin-bottom: 1px; + padding: 1px; } From ec78f9eed2a0a05fa2ab56ba6b2308dee2237776 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Wed, 31 Jul 2019 11:50:51 -0700 Subject: [PATCH 137/861] Fix #77449 --- .../contrib/preferences/browser/settingsTree.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts index 2008a6edb14..ac895cbccb2 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts @@ -698,7 +698,7 @@ export class SettingArrayRenderer extends AbstractSettingRenderer implements ITr private onDidChangeList(template: ISettingListItemTemplate, e: IListChangeEvent): void { if (template.context) { - const newValue: any[] | undefined = isArray(template.context.scopeValue) + const newValue: any[] = isArray(template.context.scopeValue) ? [...template.context.scopeValue] : [...template.context.value]; @@ -725,6 +725,19 @@ export class SettingArrayRenderer extends AbstractSettingRenderer implements ITr } } + if ( + template.context.defaultValue && + isArray(template.context.defaultValue) && + template.context.defaultValue.length === newValue.length && + template.context.defaultValue.join() === newValue.join() + ) { + return this._onDidChangeSetting.fire({ + key: template.context.setting.key, + value: undefined, // reset setting + type: template.context.valueType + }); + } + this._onDidChangeSetting.fire({ key: template.context.setting.key, value: newValue, From fc727b7bc7f37e97d376d97e2f3ad4c968e4e146 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 31 Jul 2019 21:42:28 +0200 Subject: [PATCH 138/861] Do not send isBuilt --- src/vs/code/electron-main/app.ts | 3 --- src/vs/platform/remote/common/remoteAgentConnection.ts | 7 +------ .../extensions/common/remoteExtensionHostClient.ts | 1 - .../services/remote/browser/remoteAgentServiceImpl.ts | 2 +- .../services/remote/common/abstractRemoteAgentService.ts | 2 -- .../remote/electron-browser/remoteAgentServiceImpl.ts | 2 +- src/vs/workbench/services/remote/node/tunnelService.ts | 1 - 7 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 785a214c7a3..d71ddf83ea1 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -697,8 +697,6 @@ export class CodeApplication extends Disposable { private handleRemoteAuthorities(): void { const connectionPool: Map = new Map(); - const isBuilt = this.environmentService.isBuilt; - class ActiveConnection { private readonly _authority: string; private readonly _connection: Promise; @@ -708,7 +706,6 @@ export class CodeApplication extends Disposable { this._authority = authority; const options: IConnectionOptions = { - isBuilt, commit: product.commit, socketFactory: nodeSocketFactory, addressProvider: { diff --git a/src/vs/platform/remote/common/remoteAgentConnection.ts b/src/vs/platform/remote/common/remoteAgentConnection.ts index ad95b6751a7..5653a6912b2 100644 --- a/src/vs/platform/remote/common/remoteAgentConnection.ts +++ b/src/vs/platform/remote/common/remoteAgentConnection.ts @@ -35,7 +35,6 @@ export interface ConnectionTypeRequest { signedData?: string; desiredConnectionType?: ConnectionType; args?: any; - isBuilt: boolean; } export interface ErrorMessage { @@ -51,7 +50,6 @@ export type HandshakeMessage = AuthRequest | SignRequest | ConnectionTypeRequest interface ISimpleConnectionOptions { - isBuilt: boolean; commit: string | undefined; host: string; port: number; @@ -110,8 +108,7 @@ async function connectToRemoteExtensionHostAgent(options: ISimpleConnectionOptio type: 'connectionType', commit: options.commit, signedData: signed, - desiredConnectionType: connectionType, - isBuilt: options.isBuilt + desiredConnectionType: connectionType }; if (args) { connTypeRequest.args = args; @@ -200,7 +197,6 @@ async function doConnectRemoteAgentTunnel(options: ISimpleConnectionOptions, sta } export interface IConnectionOptions { - isBuilt: boolean; commit: string | undefined; socketFactory: ISocketFactory; addressProvider: IAddressProvider; @@ -210,7 +206,6 @@ export interface IConnectionOptions { async function resolveConnectionOptions(options: IConnectionOptions, reconnectionToken: string, reconnectionProtocol: PersistentProtocol | null): Promise { const { host, port } = await options.addressProvider.getAddress(); return { - isBuilt: options.isBuilt, commit: options.commit, host: host, port: port, diff --git a/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts b/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts index 037a2534d92..47aaf4a22bb 100644 --- a/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts +++ b/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts @@ -71,7 +71,6 @@ export class RemoteExtensionHostClient extends Disposable implements IExtensionH public start(): Promise { const options: IConnectionOptions = { - isBuilt: this._environmentService.isBuilt, commit: this._productService.commit, socketFactory: this._socketFactory, addressProvider: { diff --git a/src/vs/workbench/services/remote/browser/remoteAgentServiceImpl.ts b/src/vs/workbench/services/remote/browser/remoteAgentServiceImpl.ts index 4219ca53901..fd979ca094c 100644 --- a/src/vs/workbench/services/remote/browser/remoteAgentServiceImpl.ts +++ b/src/vs/workbench/services/remote/browser/remoteAgentServiceImpl.ts @@ -28,7 +28,7 @@ export class RemoteAgentService extends AbstractRemoteAgentService implements IR super(environmentService); this.socketFactory = new BrowserSocketFactory(webSocketFactory); - this._connection = this._register(new RemoteAgentConnection(environmentService.configuration.remoteAuthority!, productService.commit, this.socketFactory, environmentService, remoteAuthorityResolverService, signService)); + this._connection = this._register(new RemoteAgentConnection(environmentService.configuration.remoteAuthority!, productService.commit, this.socketFactory, remoteAuthorityResolverService, signService)); } getConnection(): IRemoteAgentConnection | null { diff --git a/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts b/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts index e48834a6a6b..5168e7f16c3 100644 --- a/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts +++ b/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts @@ -84,7 +84,6 @@ export class RemoteAgentConnection extends Disposable implements IRemoteAgentCon remoteAuthority: string, private readonly _commit: string | undefined, private readonly _socketFactory: ISocketFactory, - private readonly _environmentService: IEnvironmentService, private readonly _remoteAuthorityResolverService: IRemoteAuthorityResolverService, private readonly _signService: ISignService ) { @@ -111,7 +110,6 @@ export class RemoteAgentConnection extends Disposable implements IRemoteAgentCon private async _createConnection(): Promise> { let firstCall = true; const options: IConnectionOptions = { - isBuilt: this._environmentService.isBuilt, commit: this._commit, socketFactory: this._socketFactory, addressProvider: { diff --git a/src/vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl.ts b/src/vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl.ts index 538fb1be860..82d039a6c54 100644 --- a/src/vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl.ts +++ b/src/vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl.ts @@ -27,7 +27,7 @@ export class RemoteAgentService extends AbstractRemoteAgentService implements IR super(environmentService); this.socketFactory = nodeSocketFactory; if (remoteAuthority) { - this._connection = this._register(new RemoteAgentConnection(remoteAuthority, product.commit, nodeSocketFactory, environmentService, remoteAuthorityResolverService, signService)); + this._connection = this._register(new RemoteAgentConnection(remoteAuthority, product.commit, nodeSocketFactory, remoteAuthorityResolverService, signService)); } } diff --git a/src/vs/workbench/services/remote/node/tunnelService.ts b/src/vs/workbench/services/remote/node/tunnelService.ts index 9a359e44c28..87b657be6a5 100644 --- a/src/vs/workbench/services/remote/node/tunnelService.ts +++ b/src/vs/workbench/services/remote/node/tunnelService.ts @@ -100,7 +100,6 @@ export class TunnelService implements ITunnelService { } const options: IConnectionOptions = { - isBuilt: this.environmentService.isBuilt, commit: product.commit, socketFactory: nodeSocketFactory, addressProvider: { From 299f04763e892cd4004cfe6227e11d3a42589fcb Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 31 Jul 2019 21:49:50 +0200 Subject: [PATCH 139/861] Update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d7994dbe4d5..0681d59750a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.37.0", - "distro": "ea88b4ff40235904907278b141fe4bd3e4a035f7", + "distro": "7565d95cd71597eda6885d2c4e8f5a6dd72bf62b", "author": { "name": "Microsoft Corporation" }, From e81b51de5356054df9f02e8c23c721ba226d4564 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Wed, 31 Jul 2019 14:45:45 -0700 Subject: [PATCH 140/861] Fix #78149, make icons the same pixel width --- .../extensions/browser/media/profile-start-dark.svg | 10 ++-------- .../extensions/browser/media/profile-start-light.svg | 10 ++-------- .../contrib/extensions/browser/media/start-dark.svg | 2 +- .../contrib/extensions/browser/media/start-light.svg | 2 +- 4 files changed, 6 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/media/profile-start-dark.svg b/src/vs/workbench/contrib/extensions/browser/media/profile-start-dark.svg index c67e550c15f..a60d77cd37a 100644 --- a/src/vs/workbench/contrib/extensions/browser/media/profile-start-dark.svg +++ b/src/vs/workbench/contrib/extensions/browser/media/profile-start-dark.svg @@ -1,10 +1,4 @@ - - - - - - - - + + diff --git a/src/vs/workbench/contrib/extensions/browser/media/profile-start-light.svg b/src/vs/workbench/contrib/extensions/browser/media/profile-start-light.svg index c67e550c15f..f541ed4d519 100644 --- a/src/vs/workbench/contrib/extensions/browser/media/profile-start-light.svg +++ b/src/vs/workbench/contrib/extensions/browser/media/profile-start-light.svg @@ -1,10 +1,4 @@ - - - - - - - - + + diff --git a/src/vs/workbench/contrib/extensions/browser/media/start-dark.svg b/src/vs/workbench/contrib/extensions/browser/media/start-dark.svg index 9debdf8c625..8b0a58eca9b 100644 --- a/src/vs/workbench/contrib/extensions/browser/media/start-dark.svg +++ b/src/vs/workbench/contrib/extensions/browser/media/start-dark.svg @@ -1,3 +1,3 @@ - + diff --git a/src/vs/workbench/contrib/extensions/browser/media/start-light.svg b/src/vs/workbench/contrib/extensions/browser/media/start-light.svg index dac8bdae31f..2563bfa114b 100644 --- a/src/vs/workbench/contrib/extensions/browser/media/start-light.svg +++ b/src/vs/workbench/contrib/extensions/browser/media/start-light.svg @@ -1,3 +1,3 @@ - + From 8162c25be59d6adec1aabd6c4567bd0adfaf6eb7 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Wed, 31 Jul 2019 15:02:11 -0700 Subject: [PATCH 141/861] Fix #78241 --- .../preferences/browser/settingsTree.ts | 32 +++++++++---------- .../preferences/browser/settingsWidgets.ts | 32 ++++++++++--------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts index ac895cbccb2..9b366bbc780 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts @@ -702,29 +702,27 @@ export class SettingArrayRenderer extends AbstractSettingRenderer implements ITr ? [...template.context.scopeValue] : [...template.context.value]; - // Delete value - if (e.removeIndex !== undefined) { - if (!e.value && e.originalValue && e.removeIndex > -1) { - newValue.splice(e.removeIndex, 1); + if (e.targetIndex !== undefined) { + // Delete value + if (!e.value && e.originalValue && e.targetIndex > -1) { + newValue.splice(e.targetIndex, 1); + } + // Update value + else if (e.value && e.originalValue) { + if (e.targetIndex > -1) { + newValue[e.targetIndex] = e.value; + } + // For some reason, we are updating and cannot find original value + // Just append the value in this case + else { + newValue.push(e.value); + } } } // Add value else if (e.value && !e.originalValue) { newValue.push(e.value); } - // Update value - else if (e.value && e.originalValue) { - const valueIndex = newValue.indexOf(e.originalValue); - if (valueIndex > -1) { - newValue[valueIndex] = e.value; - } - // For some reason, we are updating and cannot find original value - // Just append the value in this case - else { - newValue.push(e.value); - } - } - if ( template.context.defaultValue && isArray(template.context.defaultValue) && diff --git a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts index 1a94dfde46e..35fa5c372f8 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts @@ -132,14 +132,16 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { } }); +type EditKey = 'none' | 'create' | number; + export class ListSettingListModel { private _dataItems: IListDataItem[] = []; - private _editKey: string | null; + private _editKey: EditKey; private _selectedIdx: number | null; get items(): IListViewItem[] { const items = this._dataItems.map((item, i) => { - const editing = item.value === this._editKey; + const editing = typeof this._editKey === 'number' && this._editKey === i; return { ...item, editing, @@ -147,7 +149,7 @@ export class ListSettingListModel { }; }); - if (this._editKey === '') { + if (this._editKey === 'create') { items.push({ editing: true, selected: true, @@ -159,7 +161,7 @@ export class ListSettingListModel { return items; } - setEditKey(key: string | null): void { + setEditKey(key: EditKey): void { this._editKey = key; } @@ -196,7 +198,7 @@ export interface IListChangeEvent { originalValue: string; value?: string; sibling?: string; - removeIndex?: number; + targetIndex?: number; } export class ListSettingWidget extends Disposable { @@ -295,7 +297,7 @@ export class ListSettingWidget extends Disposable { const item = this.model.items[targetIdx]; if (item) { - this.editSetting(item.value); + this.editSetting(targetIdx); e.preventDefault(); e.stopPropagation(); } @@ -349,24 +351,24 @@ export class ListSettingWidget extends Disposable { enabled: true, id: 'workbench.action.removeListItem', tooltip: this.getLocalizedStrings().deleteActionTooltip, - run: () => this._onDidChangeList.fire({ originalValue: key, value: undefined, removeIndex: idx }) + run: () => this._onDidChangeList.fire({ originalValue: key, value: undefined, targetIndex: idx }) }; } - private createEditAction(key: string): IAction { + private createEditAction(idx: number): IAction { return { class: 'setting-listAction-edit', enabled: true, id: 'workbench.action.editListItem', tooltip: this.getLocalizedStrings().editActionTooltip, run: () => { - this.editSetting(key); + this.editSetting(idx); } }; } - private editSetting(key: string): void { - this.model.setEditKey(key); + private editSetting(idx: number): void { + this.model.setEditKey(idx); this.renderList(); } @@ -391,7 +393,7 @@ export class ListSettingWidget extends Disposable { siblingElement.textContent = item.sibling ? ('when: ' + item.sibling) : null; actionBar.push([ - this.createEditAction(item.value), + this.createEditAction(idx), this.createDeleteAction(item.value, idx) ], { icon: true, label: false }); @@ -419,7 +421,7 @@ export class ListSettingWidget extends Disposable { this._register(attachButtonStyler(startAddButton, this.themeService)); this._register(startAddButton.onDidClick(() => { - this.model.setEditKey(''); + this.model.setEditKey('create'); this.renderList(); })); @@ -430,14 +432,14 @@ export class ListSettingWidget extends Disposable { const rowElement = $('.setting-list-edit-row'); const onSubmit = (edited: boolean) => { - this.model.setEditKey(null); + this.model.setEditKey('none'); const value = valueInput.value.trim(); if (edited && !isUndefinedOrNull(value)) { this._onDidChangeList.fire({ originalValue: item.value, value: value, sibling: siblingInput && siblingInput.value.trim(), - removeIndex: value === '' ? idx : undefined + targetIndex: idx }); } this.renderList(); From a85b2645eebab99451ea70910ec694512d054adc Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Wed, 31 Jul 2019 15:12:22 -0700 Subject: [PATCH 142/861] Fix typo --- src/vs/workbench/contrib/webview/common/themeing.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/webview/common/themeing.ts b/src/vs/workbench/contrib/webview/common/themeing.ts index 5f0649247a8..7c39b7a4bdd 100644 --- a/src/vs/workbench/contrib/webview/common/themeing.ts +++ b/src/vs/workbench/contrib/webview/common/themeing.ts @@ -31,7 +31,7 @@ export function getWebviewThemeData( }, {} as { [key: string]: string }); const styles = { - 'vscode-font-family': '-apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", ans-serif', + 'vscode-font-family': '-apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif', 'vscode-font-weight': 'normal', 'vscode-font-size': '13px', 'vscode-editor-font-family': editorFontFamily, @@ -60,4 +60,4 @@ namespace ApiThemeClassName { return ApiThemeClassName.highContrast; } } -} \ No newline at end of file +} From 0bf2bc05f9b6c6d9db329b78d2df94fc8ffcaba3 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Wed, 31 Jul 2019 15:25:43 -0700 Subject: [PATCH 143/861] One more fix for #78241 --- .../workbench/contrib/preferences/browser/settingsTree.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts index 9b366bbc780..424c8736ed2 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts @@ -718,10 +718,10 @@ export class SettingArrayRenderer extends AbstractSettingRenderer implements ITr newValue.push(e.value); } } - } - // Add value - else if (e.value && !e.originalValue) { - newValue.push(e.value); + // Add value + else if (e.value && !e.originalValue && e.targetIndex >= newValue.length) { + newValue.push(e.value); + } } if ( template.context.defaultValue && From 51ca91d87e8f7d8e45a6047c84e0433aa8c84668 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Wed, 31 Jul 2019 15:30:30 -0700 Subject: [PATCH 144/861] Fix #78239 --- .../preferences/browser/media/settingsWidgets.css | 5 +++++ .../contrib/preferences/browser/settingsWidgets.ts | 11 ++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/preferences/browser/media/settingsWidgets.css b/src/vs/workbench/contrib/preferences/browser/media/settingsWidgets.css index 1ddeedc5e16..2d483db0b0e 100644 --- a/src/vs/workbench/contrib/preferences/browser/media/settingsWidgets.css +++ b/src/vs/workbench/contrib/preferences/browser/media/settingsWidgets.css @@ -16,6 +16,11 @@ .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-sibling { display: inline-block; line-height: 22px; +} + +/* Use monospace to display glob patterns in exclude widget */ +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-exclude-widget .setting-list-value, +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-exclude-widget .setting-list-sibling { font-family: var(--monaco-monospace-font); } diff --git a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts index 35fa5c372f8..03da415821f 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts @@ -221,7 +221,8 @@ export class ListSettingWidget extends Disposable { ) { super(); - this.listElement = DOM.append(container, $('.setting-list-widget')); + this.listElement = DOM.append(container, $('div')); + this.getContainerClasses().forEach(c => this.listElement.classList.add(c)); this.listElement.setAttribute('tabindex', '0'); DOM.append(container, this.renderAddButton()); this.renderList(); @@ -268,6 +269,10 @@ export class ListSettingWidget extends Disposable { }; } + protected getContainerClasses() { + return ['setting-list-widget']; + } + setValue(listData: IListDataItem[]): void { this.model.setValue(listData); this.renderList(); @@ -524,6 +529,10 @@ export class ExcludeSettingWidget extends ListSettingWidget { settingListRowSiblingHintLabel: localize('excludeSiblingHintLabel', "Exclude files matching `{0}`, only when a file matching `{1}` is present", pattern, sibling) }; } + + protected getContainerClasses() { + return ['setting-list-widget', 'setting-list-exclude-widget']; + } } export interface IListDataItem { From cc5de3329c6028fd0d4d45bef0a5b81a87590b94 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 31 Jul 2019 16:06:21 -0700 Subject: [PATCH 145/861] Re #78128. Hide comment widget when editor is an embed editor. --- .../comments/browser/commentsEditorContribution.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts b/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts index 89dd182ebe2..d5cfcfb4f19 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts @@ -36,6 +36,7 @@ import { ICommentInfo, ICommentService } from 'vs/workbench/contrib/comments/bro import { COMMENTEDITOR_DECORATION_KEY, ReviewZoneWidget } from 'vs/workbench/contrib/comments/browser/commentThreadWidget'; import { ctxCommentEditorFocused, SimpleCommentEditor } from 'vs/workbench/contrib/comments/browser/simpleCommentEditor'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { EmbeddedCodeEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget'; export const ID = 'editor.contrib.review'; @@ -173,7 +174,6 @@ export class ReviewController implements IEditorContribution { @IContextMenuService readonly contextMenuService: IContextMenuService, @IQuickInputService private readonly quickInputService: IQuickInputService ) { - this.editor = editor; this.globalToDispose = []; this.localToDispose = []; this._commentInfos = []; @@ -181,6 +181,12 @@ export class ReviewController implements IEditorContribution { this._pendingCommentCache = {}; this._computePromise = null; + if (editor instanceof EmbeddedCodeEditorWidget) { + return; + } + + this.editor = editor; + this._commentingRangeDecorator = new CommentingRangeDecorator(); this.globalToDispose.push(this.commentService.onDidDeleteDataProvider(ownerId => { From 7d6e7ac373aeaa2347838de4df546e3cf231ff79 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 31 Jul 2019 16:12:37 -0700 Subject: [PATCH 146/861] Fix #78128. --- src/vs/workbench/contrib/comments/browser/media/review.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/contrib/comments/browser/media/review.css b/src/vs/workbench/contrib/comments/browser/media/review.css index 47f8feb5fc9..fb8c2b0d6ca 100644 --- a/src/vs/workbench/contrib/comments/browser/media/review.css +++ b/src/vs/workbench/contrib/comments/browser/media/review.css @@ -433,6 +433,10 @@ z-index: 10; } +div.preview.inline .monaco-editor .comment-range-glyph { + display: none !important; +} + .monaco-editor .comment-range-glyph:before { position: absolute; content: ""; From cc4373565be8862569068cf5ea09cdbfeafbb8cd Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Wed, 31 Jul 2019 16:13:21 -0700 Subject: [PATCH 147/861] Fix #78235 --- .../browser/media/settingsWidgets.css | 18 +++++++++++++++++- .../preferences/browser/settingsWidgets.ts | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/media/settingsWidgets.css b/src/vs/workbench/contrib/preferences/browser/media/settingsWidgets.css index 2d483db0b0e..060fc54921c 100644 --- a/src/vs/workbench/contrib/preferences/browser/media/settingsWidgets.css +++ b/src/vs/workbench/contrib/preferences/browser/media/settingsWidgets.css @@ -12,6 +12,20 @@ margin-left: 2px; } +/* Deal with overflow */ +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-widget .setting-list-value, +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-widget .setting-list-sibling { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-widget .setting-list-value { + max-width: 90%; +} +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-widget .setting-list-sibling { + max-width: 10%; +} + .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-value, .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-sibling { display: inline-block; @@ -40,6 +54,7 @@ .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row { position: relative; + max-height: 22px; } .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row:focus { @@ -107,7 +122,8 @@ margin-right: 10px; } -.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-widget { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-widget, +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-exclude-widget { margin-bottom: 1px; padding: 1px; } diff --git a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts index 03da415821f..ad1b781ae28 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts @@ -531,7 +531,7 @@ export class ExcludeSettingWidget extends ListSettingWidget { } protected getContainerClasses() { - return ['setting-list-widget', 'setting-list-exclude-widget']; + return ['setting-list-exclude-widget']; } } From 92da68a71cfb60bd3b9b0d7fbfb2a7e1fff9dbaf Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 31 Jul 2019 17:22:48 -0700 Subject: [PATCH 148/861] Revert "Remove duplicate registration of FocusTerminalFindWidgetAction" This reverts commit 6b88a5364546109b6bec8b56873aa8a51b4005b6. Fixes #78301 --- .../contrib/terminal/browser/terminal.contribution.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts index 08fc487af2f..4dc89120557 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts @@ -378,6 +378,9 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(RenameTerminalAc actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusTerminalFindWidgetAction, FocusTerminalFindWidgetAction.ID, FocusTerminalFindWidgetAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_F }, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Focus Find Widget', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusTerminalFindWidgetAction, FocusTerminalFindWidgetAction.ID, FocusTerminalFindWidgetAction.LABEL, { + primary: KeyMod.CtrlCmd | KeyCode.KEY_F +}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Focus Find Widget', category); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(HideTerminalFindWidgetAction, HideTerminalFindWidgetAction.ID, HideTerminalFindWidgetAction.LABEL, { primary: KeyCode.Escape, secondary: [KeyMod.Shift | KeyCode.Escape] From 1735b2b2dcc9161862a7d007eed3e6dabb4216e5 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 1 Aug 2019 10:18:43 +0530 Subject: [PATCH 149/861] chnage category to remote --- .../contrib/extensions/browser/remoteExtensionsInstaller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/extensions/browser/remoteExtensionsInstaller.ts b/src/vs/workbench/contrib/extensions/browser/remoteExtensionsInstaller.ts index a61c79d5575..84c47be3064 100644 --- a/src/vs/workbench/contrib/extensions/browser/remoteExtensionsInstaller.ts +++ b/src/vs/workbench/contrib/extensions/browser/remoteExtensionsInstaller.ts @@ -30,7 +30,7 @@ export class RemoteExtensionsInstaller extends Disposable implements IWorkbenchC disposable = MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: 'workbench.extensions.installLocalExtensions', - category: localize('extensions', "Extensions"), + category: localize('remote', "Remote"), title: installLocalExtensionsInRemoteAction.label } }); From e35ef3baffd513ce62c38d57473129a13d896760 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 1 Aug 2019 13:41:46 +0530 Subject: [PATCH 150/861] Fix #77882 --- .../markers/browser/markersTreeViewer.ts | 31 +++++++++---------- .../contrib/markers/browser/media/markers.css | 18 +++++------ 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/vs/workbench/contrib/markers/browser/markersTreeViewer.ts b/src/vs/workbench/contrib/markers/browser/markersTreeViewer.ts index ed087ccf8c0..06148b3c5ff 100644 --- a/src/vs/workbench/contrib/markers/browser/markersTreeViewer.ts +++ b/src/vs/workbench/contrib/markers/browser/markersTreeViewer.ts @@ -258,7 +258,7 @@ class MarkerWidget extends Disposable { })); this.icon = dom.append(parent, dom.$('')); this.multilineActionbar = this._register(new ActionBar(dom.append(parent, dom.$('.multiline-actions')))); - this.messageAndDetailsContainer = dom.append(parent, dom.$('.marker-message-details')); + this.messageAndDetailsContainer = dom.append(parent, dom.$('.marker-message-details-container')); } render(element: Marker, filterData: MarkerFilterData | undefined): void { @@ -312,33 +312,32 @@ class MarkerWidget extends Disposable { const viewState = this.markersViewModel.getViewModel(element); const multiline = !viewState || viewState.multiline; const lineMatches = filterData && filterData.lineMatches || []; - const messageContainer = dom.append(this.messageAndDetailsContainer, dom.$('.marker-message')); - dom.toggleClass(messageContainer, 'multiline', multiline); - let lastLineElement = messageContainer; + let lastLineElement: HTMLElement | undefined = undefined; for (let index = 0; index < (multiline ? lines.length : 1); index++) { - lastLineElement = dom.append(messageContainer, dom.$('.marker-message-line')); - const highlightedLabel = new HighlightedLabel(lastLineElement, false); - highlightedLabel.set(lines[index], lineMatches[index]); + lastLineElement = dom.append(this.messageAndDetailsContainer, dom.$('.marker-message-line')); + const messageElement = dom.append(lastLineElement, dom.$('.marker-message')); + const highlightedLabel = new HighlightedLabel(messageElement, false); + highlightedLabel.set(lines[index].length > 1000 ? `${lines[index].substring(0, 1000)}...` : lines[index], lineMatches[index]); if (lines[index] === '') { lastLineElement.style.height = `${VirtualDelegate.LINE_HEIGHT}px`; } } - this.renderDetails(marker, filterData, multiline ? lastLineElement : this.messageAndDetailsContainer); + this.renderDetails(marker, filterData, lastLineElement || dom.append(this.messageAndDetailsContainer, dom.$('.marker-message-line'))); } private renderDetails(marker: IMarker, filterData: MarkerFilterData | undefined, parent: HTMLElement): void { dom.addClass(parent, 'details-container'); - const sourceMatches = filterData && filterData.sourceMatches || []; - const codeMatches = filterData && filterData.codeMatches || []; - const source = new HighlightedLabel(dom.append(parent, dom.$('')), false); - source.set(marker.source, sourceMatches); - dom.toggleClass(source.element, 'marker-source', !!marker.source); + if (marker.source || marker.code) { + const source = new HighlightedLabel(dom.append(parent, dom.$('.marker-source')), false); + const sourceMatches = filterData && filterData.sourceMatches || []; + source.set(marker.source, sourceMatches); - const code = new HighlightedLabel(dom.append(parent, dom.$('')), false); - code.set(marker.code, codeMatches); - dom.toggleClass(code.element, 'marker-code', !!marker.code); + const code = new HighlightedLabel(dom.append(parent, dom.$('.marker-code')), false); + const codeMatches = filterData && filterData.codeMatches || []; + code.set(marker.code, codeMatches); + } const lnCol = dom.append(parent, dom.$('span.marker-line')); lnCol.textContent = Messages.MARKERS_PANEL_AT_LINE_COL_NUMBER(marker.startLineNumber, marker.startColumn); diff --git a/src/vs/workbench/contrib/markers/browser/media/markers.css b/src/vs/workbench/contrib/markers/browser/media/markers.css index 7cbfe050394..42321b8dba4 100644 --- a/src/vs/workbench/contrib/markers/browser/media/markers.css +++ b/src/vs/workbench/contrib/markers/browser/media/markers.css @@ -97,6 +97,7 @@ .markers-panel .markers-panel-container .tree-container .monaco-tl-contents { display: flex; line-height: 22px; + padding-right: 10px; } .hc-black .markers-panel .markers-panel-container .tree-container .monaco-tl-contents { @@ -112,23 +113,22 @@ margin-left: 10px; } -.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message-details, -.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message:not(.multiline) { - display: flex; +.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message-details-container { + flex: 1; overflow: hidden; } -.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message.multiline { - white-space: pre; - flex: 1; +.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message-details-container > .marker-message-line { + overflow: hidden; } -.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message:not(.multiline) .marker-message-line { +.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message-details-container > .marker-message-line > .marker-message { overflow: hidden; text-overflow: ellipsis; + white-space: nowrap; } -.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message .details-container { +.markers-panel .markers-panel-container .tree-container .monaco-tl-contents .marker-message-details-container > .marker-message-line.details-container { display: flex; } @@ -222,4 +222,4 @@ .markers-panel .monaco-tl-contents .multiline-actions .action-item.disabled, .markers-panel .monaco-tl-contents .actions .action-item.disabled { display: none; -} \ No newline at end of file +} From 4903b864791b4f5fb2adfe82fa387f7e9b367954 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 1 Aug 2019 16:32:19 +0530 Subject: [PATCH 151/861] update distro --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 0681d59750a..ea677177865 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.37.0", - "distro": "7565d95cd71597eda6885d2c4e8f5a6dd72bf62b", + "distro": "f9c5d20222a2776b589107efa7d2e3aa4b80050d", "author": { "name": "Microsoft Corporation" }, @@ -158,4 +158,4 @@ "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} +} \ No newline at end of file From f01d8c3b4d81033f05f57900a0e5d7721a6976b8 Mon Sep 17 00:00:00 2001 From: Arash Arbabi Date: Thu, 1 Aug 2019 16:02:29 +0430 Subject: [PATCH 152/861] fix: #78170 --- src/vs/editor/contrib/find/simpleFindWidget.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/editor/contrib/find/simpleFindWidget.ts b/src/vs/editor/contrib/find/simpleFindWidget.ts index e3723366157..e29852c3392 100644 --- a/src/vs/editor/contrib/find/simpleFindWidget.ts +++ b/src/vs/editor/contrib/find/simpleFindWidget.ts @@ -90,6 +90,7 @@ export abstract class SimpleFindWidget extends Widget { this._findInput.setRegex(this._state.isRegex); this._findInput.setWholeWords(this._state.wholeWord); this._findInput.setCaseSensitive(this._state.matchCase); + this.find(this._invertDefaultDirection); })); this._register(this._findInput.onKeyDown((e) => { From e3940aec615c31078bdbe7dffd29db4bcdd1d119 Mon Sep 17 00:00:00 2001 From: skprabhanjan Date: Thu, 1 Aug 2019 22:37:20 +0530 Subject: [PATCH 153/861] Moved the code down for better understanding and pushed the menu item down as a separate group --- .../search/browser/search.contribution.ts | 63 ++++++++++--------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/src/vs/workbench/contrib/search/browser/search.contribution.ts b/src/vs/workbench/contrib/search/browser/search.contribution.ts index 8d827d437d3..db23b909109 100644 --- a/src/vs/workbench/contrib/search/browser/search.contribution.ts +++ b/src/vs/workbench/contrib/search/browser/search.contribution.ts @@ -213,37 +213,6 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ } }); -CommandsRegistry.registerCommand({ - id: Constants.RevealInSideBarForSearchResults, - handler: (accessor, fileMatch: FileMatch) => { - const viewletService = accessor.get(IViewletService); - const explorerService = accessor.get(IExplorerService); - const contextService = accessor.get(IWorkspaceContextService); - const uri = fileMatch.resource; - - viewletService.openViewlet(VIEWLET_ID_FILES, false).then((viewlet: ExplorerViewlet) => { - if (uri && contextService.isInsideWorkspace(uri)) { - const explorerView = viewlet.getExplorerView(); - if (explorerView) { - explorerView.setExpanded(true); - explorerService.select(uri, true).then(() => explorerView.focus(), onUnexpectedError); - } - } - }); - } -}); - -const RevealInSideBarForSearchResultsCommand: ICommandAction = { - id: Constants.RevealInSideBarForSearchResults, - title: nls.localize('revealInSideBar', "Reveal in Explorer") -}; - -MenuRegistry.appendMenuItem(MenuId.SearchContext, { - command: RevealInSideBarForSearchResultsCommand, - when: ContextKeyExpr.and(Constants.FileFocusKey, Constants.HasSearchResults), - group: '2_files', -}); - MenuRegistry.appendMenuItem(MenuId.SearchContext, { command: { id: Constants.ReplaceActionId, @@ -343,6 +312,38 @@ CommandsRegistry.registerCommand({ handler: clearHistoryCommand }); +CommandsRegistry.registerCommand({ + id: Constants.RevealInSideBarForSearchResults, + handler: (accessor, fileMatch: FileMatch) => { + const viewletService = accessor.get(IViewletService); + const explorerService = accessor.get(IExplorerService); + const contextService = accessor.get(IWorkspaceContextService); + const uri = fileMatch.resource; + + viewletService.openViewlet(VIEWLET_ID_FILES, false).then((viewlet: ExplorerViewlet) => { + if (uri && contextService.isInsideWorkspace(uri)) { + const explorerView = viewlet.getExplorerView(); + if (explorerView) { + explorerView.setExpanded(true); + explorerService.select(uri, true).then(() => explorerView.focus(), onUnexpectedError); + } + } + }); + } +}); + +const RevealInSideBarForSearchResultsCommand: ICommandAction = { + id: Constants.RevealInSideBarForSearchResults, + title: nls.localize('revealInSideBar', "Reveal in Explorer") +}; + +MenuRegistry.appendMenuItem(MenuId.SearchContext, { + command: RevealInSideBarForSearchResultsCommand, + when: ContextKeyExpr.and(Constants.FileFocusKey, Constants.HasSearchResults), + group: 'search_3', + order: 1 +}); + const clearSearchHistoryLabel = nls.localize('clearSearchHistoryLabel', "Clear Search History"); const ClearSearchHistoryCommand: ICommandAction = { id: Constants.ClearSearchHistoryCommandId, From f738e58155f72509870ebe46c413850a1373c6aa Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 1 Aug 2019 10:55:34 -0700 Subject: [PATCH 154/861] fixes #76129 --- src/vs/base/browser/ui/menu/menu.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index 7913bb42fd5..c2b60a5dc92 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -626,8 +626,11 @@ class SubmenuMenuActionViewItem extends BaseMenuActionViewItem { this._register(addDisposableListener(this.element, EventType.KEY_DOWN, e => { let event = new StandardKeyboardEvent(e); - if (event.equals(KeyCode.RightArrow) || event.equals(KeyCode.Enter)) { - EventHelper.stop(e, true); + + if (document.activeElement === this.item) { + if (event.equals(KeyCode.RightArrow) || event.equals(KeyCode.Enter)) { + EventHelper.stop(e, true); + } } })); @@ -802,4 +805,4 @@ export function cleanMnemonic(label: string): string { const mnemonicInText = matches[0].charAt(0) === '&'; return label.replace(regex, mnemonicInText ? '$2' : '').trim(); -} \ No newline at end of file +} From 23b6a8d9d98adc0249e12f6c067ab19820a48b11 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Thu, 1 Aug 2019 11:55:42 -0700 Subject: [PATCH 155/861] Fix #78339 --- .../contrib/preferences/browser/settingsTree.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts index 424c8736ed2..7106918e292 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts @@ -698,9 +698,12 @@ export class SettingArrayRenderer extends AbstractSettingRenderer implements ITr private onDidChangeList(template: ISettingListItemTemplate, e: IListChangeEvent): void { if (template.context) { - const newValue: any[] = isArray(template.context.scopeValue) - ? [...template.context.scopeValue] - : [...template.context.value]; + let newValue: any[] = []; + if (isArray(template.context.scopeValue)) { + newValue = [...template.context.scopeValue]; + } else if (isArray(template.context.value)) { + newValue = [...template.context.value]; + } if (e.targetIndex !== undefined) { // Delete value From 9248ec2cb899cbe874ae411d8ae028309ffef313 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 2 Aug 2019 00:35:32 +0530 Subject: [PATCH 156/861] Fix microsoft/vscode-remote-release/issues/1067 --- .../workbench/contrib/extensions/browser/extensionsActions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index 32a97b64099..76f7d12778b 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -3121,7 +3121,7 @@ export class InstallLocalExtensionsInRemoteAction extends Action { this.notificationService.notify({ severity: Severity.Info, - message: localize('finished installing', "Completed installing the extensions. Please reload the window now."), + message: localize('finished installing', "Successfully installed extensions in {0}. Please reload the window to enable them.", this.extensionManagementServerService.remoteExtensionManagementServer!.label), actions: { primary: [new Action('realod', localize('reload', "Realod Window"), '', true, () => this.windowService.reloadWindow())] From e1367743984e2a49002904ddf798a81f2fa78bab Mon Sep 17 00:00:00 2001 From: Yisrael Date: Fri, 2 Aug 2019 00:01:14 +0300 Subject: [PATCH 157/861] make toggle-explain a SuggestCommand so that it has access to the suggest widget --- .../contrib/suggest/suggestController.ts | 14 ++++++++++ .../editor/contrib/suggest/suggestWidget.ts | 27 +++++++++---------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/vs/editor/contrib/suggest/suggestController.ts b/src/vs/editor/contrib/suggest/suggestController.ts index aac58cf801d..958cff7b534 100644 --- a/src/vs/editor/contrib/suggest/suggestController.ts +++ b/src/vs/editor/contrib/suggest/suggestController.ts @@ -370,6 +370,10 @@ export class SuggestController implements IEditorContribution { this._widget.getValue().toggleDetails(); } + toggleExplainMode(): void { + this._widget.getValue().toggleExplainMode(); + } + toggleSuggestionFocus(): void { this._widget.getValue().toggleDetailsFocus(); } @@ -521,6 +525,16 @@ registerEditorCommand(new SuggestCommand({ } })); +registerEditorCommand(new SuggestCommand({ + id: 'toggleExplainMode', + precondition: SuggestContext.Visible, + handler: x => x.toggleExplainMode(), + kbOpts: { + weight: KeybindingWeight.EditorContrib, + primary: KeyMod.CtrlCmd | KeyCode.US_SLASH, + } +})); + registerEditorCommand(new SuggestCommand({ id: 'toggleSuggestionFocus', precondition: SuggestContext.Visible, diff --git a/src/vs/editor/contrib/suggest/suggestWidget.ts b/src/vs/editor/contrib/suggest/suggestWidget.ts index e6ac05dab25..0af27a38f97 100644 --- a/src/vs/editor/contrib/suggest/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/suggestWidget.ts @@ -231,17 +231,6 @@ const enum State { } -let _explainMode = false; -KeybindingsRegistry.registerCommandAndKeybindingRule({ - id: 'suggest.toggleExplainMode', - handler() { - _explainMode = !_explainMode; - }, - when: SuggestContext.Visible, - weight: KeybindingWeight.EditorContrib, - primary: KeyMod.CtrlCmd | KeyCode.US_SLASH, -}); - class SuggestionDetails { private el: HTMLElement; @@ -300,13 +289,13 @@ class SuggestionDetails { this.docs.textContent = ''; } - renderItem(item: CompletionItem): void { + renderItem(item: CompletionItem, explainMode: boolean): void { this.renderDisposeable = dispose(this.renderDisposeable); let { documentation, detail } = item.completion; // --- documentation - if (_explainMode) { + if (explainMode) { let md = ''; md += `score: ${item.score[0]}${item.word ? `, compared '${item.completion.filterText && (item.completion.filterText + ' (filterText)') || item.completion.label}' with '${item.word}'` : ' (no prefix)'}\n`; md += `distance: ${item.distance}, see localityBonus-setting\n`; @@ -315,7 +304,7 @@ class SuggestionDetails { detail = `Provider: ${item.provider._debugDisplayName}`; } - if (!_explainMode && !canExpandCompletionItem(item)) { + if (!explainMode && !canExpandCompletionItem(item)) { this.type.textContent = ''; this.docs.textContent = ''; addClass(this.el, 'no-docs'); @@ -477,6 +466,7 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate Date: Thu, 1 Aug 2019 14:14:10 -0700 Subject: [PATCH 158/861] Add compound debug for json --- extensions/json-language-features/.vscode/launch.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/extensions/json-language-features/.vscode/launch.json b/extensions/json-language-features/.vscode/launch.json index b2d26ad6c35..bb5cde48bfd 100644 --- a/extensions/json-language-features/.vscode/launch.json +++ b/extensions/json-language-features/.vscode/launch.json @@ -33,6 +33,14 @@ "sourceMaps": true, "outFiles": ["${workspaceFolder}/server/out"] } - + ], + "compounds": [ + { + "name": "Launch Extension and Attach Language Server", + "configurations": [ + "Launch Extension", + "Attach Language Server" + ] + } ] } \ No newline at end of file From 23875a287e854eb558172c757ff4c6ac6df0eefe Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 1 Aug 2019 14:31:10 -0700 Subject: [PATCH 159/861] flip the default grid layout back for stable --- src/vs/workbench/browser/workbench.contribution.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index 54496ea933a..7c36ea51726 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -237,7 +237,7 @@ import { isMacintosh, isWindows, isLinux, isWeb } from 'vs/base/common/platform' 'workbench.useExperimentalGridLayout': { 'type': 'boolean', 'description': nls.localize('workbench.useExperimentalGridLayout', "Enables the grid layout for the workbench. This setting may enable additional layout options for workbench components."), - 'default': true, + 'default': false, 'scope': ConfigurationScope.APPLICATION } } @@ -360,4 +360,4 @@ import { isMacintosh, isWindows, isLinux, isWeb } from 'vs/base/common/platform' } } }); -})(); \ No newline at end of file +})(); From 1e3cc1a30d4fec3f4744e403e534f84c9b645217 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 1 Aug 2019 16:04:32 -0700 Subject: [PATCH 160/861] Don't fail hard when shell/shellArgs vars aren't resolved Fixes #78307 --- .../api/node/extHostTerminalService.ts | 5 ++-- .../terminal/common/terminalEnvironment.ts | 26 +++++++++++++++---- .../terminalInstanceService.ts | 8 ++++-- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index ef336f561a2..a17a9c0622f 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -371,7 +371,8 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'), process.env.windir, this._lastActiveWorkspace, - this._variableResolver + this._variableResolver, + this._logService ); } @@ -383,7 +384,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return this._apiInspectConfigToPlain(setting); }; - return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed, this._lastActiveWorkspace, this._variableResolver); + return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed, this._lastActiveWorkspace, this._variableResolver, this._logService); } public async resolveTerminalRenderer(id: number): Promise { diff --git a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index 820506f8fe9..4a75398475f 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -78,7 +78,11 @@ function resolveConfigurationVariables(configurationResolverService: IConfigurat Object.keys(env).forEach((key) => { const value = env[key]; if (typeof value === 'string' && lastActiveWorkspaceRoot !== null) { - env[key] = configurationResolverService.resolve(lastActiveWorkspaceRoot, value); + try { + env[key] = configurationResolverService.resolve(lastActiveWorkspaceRoot, value); + } catch (e) { + env[key] = value; + } } }); return env; @@ -143,7 +147,7 @@ export function getCwd( // There was an issue resolving a variable, just use the unresolved customCwd which // which will fail, and log the error in the console. if (logService) { - logService.error('Resolving terminal.integrated.cwd', e); + logService.error('Could not resolve terminal.integrated.cwd', e); } return customCwd; } @@ -192,7 +196,8 @@ export function getDefaultShell( windir: string | undefined, lastActiveWorkspace: IWorkspaceFolder | undefined, configurationResolverService: IConfigurationResolverService | undefined, - platformOverride: platform.Platform = platform.platform, + logService: ILogService, + platformOverride: platform.Platform = platform.platform ): string { const platformKey = platformOverride === platform.Platform.Windows ? 'windows' : platformOverride === platform.Platform.Mac ? 'osx' : 'linux'; const shellConfigValue = fetchSetting(`terminal.integrated.shell.${platformKey}`); @@ -214,7 +219,12 @@ export function getDefaultShell( } if (configurationResolverService) { - executable = configurationResolverService.resolve(lastActiveWorkspace, executable); + try { + executable = configurationResolverService.resolve(lastActiveWorkspace, executable); + } catch (e) { + logService.error(`Could not resolve terminal.integrated.shell.${platformKey}`, e); + executable = executable; + } } return executable; @@ -225,6 +235,7 @@ export function getDefaultShellArgs( isWorkspaceShellAllowed: boolean, lastActiveWorkspace: IWorkspaceFolder | undefined, configurationResolverService: IConfigurationResolverService | undefined, + logService: ILogService, platformOverride: platform.Platform = platform.platform, ): string | string[] { const platformKey = platformOverride === platform.Platform.Windows ? 'windows' : platformOverride === platform.Platform.Mac ? 'osx' : 'linux'; @@ -236,7 +247,12 @@ export function getDefaultShellArgs( if (configurationResolverService) { const resolvedArgs: string[] = []; for (const arg of args) { - resolvedArgs.push(configurationResolverService.resolve(lastActiveWorkspace, arg)); + try { + resolvedArgs.push(configurationResolverService.resolve(lastActiveWorkspace, arg)); + } catch (e) { + logService.error(`Could not resolve terminal.integrated.shellArgs.${platformKey}`, e); + resolvedArgs.push(arg); + } } args = resolvedArgs; } diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts index e9b13c0d68f..2b7fa1c4fa3 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts @@ -20,6 +20,7 @@ import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/term import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { ILogService } from 'vs/platform/log/common/log'; let Terminal: typeof XTermTerminal; let WebLinksAddon: typeof XTermWebLinksAddon; @@ -34,7 +35,8 @@ export class TerminalInstanceService implements ITerminalInstanceService { @IStorageService private readonly _storageService: IStorageService, @IConfigurationResolverService private readonly _configurationResolverService: IConfigurationResolverService, @IWorkspaceContextService private readonly _workspaceContextService: IWorkspaceContextService, - @IHistoryService private readonly _historyService: IHistoryService + @IHistoryService private readonly _historyService: IHistoryService, + @ILogService private readonly _logService: ILogService ) { } @@ -84,6 +86,7 @@ export class TerminalInstanceService implements ITerminalInstanceService { process.env.windir, lastActiveWorkspace, this._configurationResolverService, + this._logService, platformOverride ); const args = getDefaultShellArgs( @@ -91,6 +94,7 @@ export class TerminalInstanceService implements ITerminalInstanceService { isWorkspaceShellAllowed, lastActiveWorkspace, this._configurationResolverService, + this._logService, platformOverride ); return Promise.resolve({ shell, args }); @@ -99,4 +103,4 @@ export class TerminalInstanceService implements ITerminalInstanceService { public getMainProcessParentEnv(): Promise { return getMainProcessParentEnv(); } -} \ No newline at end of file +} From 69269cecb2c347b73f47d7c09528dcd68fa07643 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 2 Aug 2019 10:40:56 +0200 Subject: [PATCH 161/861] fix web build version --- build/azure-pipelines/web/publish.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/azure-pipelines/web/publish.sh b/build/azure-pipelines/web/publish.sh index 9d662fcfe8b..2c112362a25 100755 --- a/build/azure-pipelines/web/publish.sh +++ b/build/azure-pipelines/web/publish.sh @@ -7,6 +7,9 @@ ROOT="$REPO/.." WEB_BUILD_NAME="vscode-web" WEB_TARBALL_FILENAME="vscode-web.tar.gz" WEB_TARBALL_PATH="$ROOT/$WEB_TARBALL_FILENAME" +BUILD="$ROOT/$WEB_BUILD_NAME" +PACKAGEJSON="$BUILD/package.json" +VERSION=$(node -p "require(\"$PACKAGEJSON\").version") rm -rf $ROOT/vscode-web.tar.* From 2619364d9c502be644ccd0dfdce434fa05261fe6 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 2 Aug 2019 11:13:49 +0200 Subject: [PATCH 162/861] mooncake should wait for web --- build/azure-pipelines/product-build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index 469494c7d58..ad437466dac 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -123,6 +123,7 @@ jobs: - LinuxSnap - LinuxArmhf - LinuxAlpine + - LinuxWeb - macOS steps: - template: sync-mooncake.yml @@ -132,4 +133,4 @@ schedules: displayName: Mon-Fri at 7:00 branches: include: - - master \ No newline at end of file + - master From e2501299e9f6f4312579c43127a3f885d703a5a3 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Fri, 2 Aug 2019 11:37:27 +0200 Subject: [PATCH 163/861] rerender in tree throws on root courtesy of @joamoreno Fixes #78371 --- src/vs/base/browser/ui/tree/asyncDataTree.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/tree/asyncDataTree.ts b/src/vs/base/browser/ui/tree/asyncDataTree.ts index 86eaeb31618..385cd3556de 100644 --- a/src/vs/base/browser/ui/tree/asyncDataTree.ts +++ b/src/vs/base/browser/ui/tree/asyncDataTree.ts @@ -477,7 +477,7 @@ export class AsyncDataTree implements IDisposable // View rerender(element?: T): void { - if (element === undefined) { + if (element === undefined || element === this.root.element) { this.tree.rerender(); return; } From 74563de36d9f54f36fd8ca58c9f3f44e51c2a244 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 2 Aug 2019 15:26:51 +0530 Subject: [PATCH 164/861] fix typo --- .../workbench/contrib/extensions/browser/extensionsActions.ts | 2 +- .../contrib/extensions/browser/extensionsDependencyChecker.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index 76f7d12778b..b598b94ea4b 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -3123,7 +3123,7 @@ export class InstallLocalExtensionsInRemoteAction extends Action { severity: Severity.Info, message: localize('finished installing', "Successfully installed extensions in {0}. Please reload the window to enable them.", this.extensionManagementServerService.remoteExtensionManagementServer!.label), actions: { - primary: [new Action('realod', localize('reload', "Realod Window"), '', true, + primary: [new Action('realod', localize('reload', "Reload Window"), '', true, () => this.windowService.reloadWindow())] } }); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsDependencyChecker.ts b/src/vs/workbench/contrib/extensions/browser/extensionsDependencyChecker.ts index 95d8c05f1c1..6474d2f3c58 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsDependencyChecker.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsDependencyChecker.ts @@ -68,7 +68,7 @@ export class ExtensionDependencyChecker extends Disposable implements IWorkbench severity: Severity.Info, message: localize('finished installing missing deps', "Finished installing missing dependencies. Please reload the window now."), actions: { - primary: [new Action('realod', localize('reload', "Realod Window"), '', true, + primary: [new Action('realod', localize('reload', "Reload Window"), '', true, () => this.windowService.reloadWindow())] } }); @@ -77,4 +77,4 @@ export class ExtensionDependencyChecker extends Disposable implements IWorkbench this.notificationService.info(localize('no missing deps', "There are no missing dependencies to install.")); } } -} \ No newline at end of file +} From 310cb67b0e5df5b0644f42df93ada186130dcd1b Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 2 Aug 2019 15:56:29 +0530 Subject: [PATCH 165/861] Adopt to connection token - Add connection token to window configuration - Use it in window service while opening windows --- src/vs/platform/sign/browser/signService.ts | 17 +---------------- src/vs/platform/windows/common/windows.ts | 1 + src/vs/workbench/browser/web.main.ts | 5 +++-- .../workbench/browser/web.simpleservices.ts | 13 +++++++++++-- .../environment/browser/environmentService.ts | 19 +++++++++++++++++++ 5 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/vs/platform/sign/browser/signService.ts b/src/vs/platform/sign/browser/signService.ts index 164dfaef813..d142447abbd 100644 --- a/src/vs/platform/sign/browser/signService.ts +++ b/src/vs/platform/sign/browser/signService.ts @@ -13,22 +13,7 @@ export class SignService implements ISignService { private readonly _tkn: string | null; constructor(token: string | undefined) { - if (typeof token !== 'undefined') { - this._tkn = token; - } else { - this._tkn = SignService._readTokenFromURL(); - } - } - - private static _readTokenFromURL(): string | null { - if (!document.location.hash) { - return null; - } - const m = document.location.hash.match(/[#&]tkn=([^&]+)/); - if (!m) { - return null; - } - return m[1]; + this._tkn = token || null; } async sign(value: string): Promise { diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index 0339be71c36..8429e3495b9 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -444,6 +444,7 @@ export interface IWindowConfiguration extends ParsedArgs { filesToDiff?: IPath[]; filesToWait?: IPathsToWaitFor; termProgram?: string; + connectionToken?: string; } export interface IRunActionInWindowRequest { diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index f37f298931d..ede771a03ee 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -118,7 +118,8 @@ class CodeRendererMain extends Disposable { const environmentService = new BrowserWorkbenchEnvironmentService({ workspaceId: payload.id, remoteAuthority: this.configuration.remoteAuthority, - webviewEndpoint: this.configuration.webviewEndpoint + webviewEndpoint: this.configuration.webviewEndpoint, + connectionToken: this.configuration.connectionToken }); serviceCollection.set(IWorkbenchEnvironmentService, environmentService); @@ -131,7 +132,7 @@ class CodeRendererMain extends Disposable { serviceCollection.set(IRemoteAuthorityResolverService, remoteAuthorityResolverService); // Signing - const signService = new SignService(this.configuration.connectionToken); + const signService = new SignService(environmentService.configuration.connectionToken); serviceCollection.set(ISignService, signService); // Remote Agent diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 3a5be568517..25414d87335 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -37,6 +37,7 @@ import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteA // tslint:disable-next-line: import-patterns import { IExperimentService, IExperiment, ExperimentActionType, ExperimentState } from 'vs/workbench/contrib/experiments/common/experimentService'; import { ExtensionHostDebugChannelClient, ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc'; +import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; //#region Extension Tips @@ -293,7 +294,8 @@ export class SimpleWindowService extends Disposable implements IWindowService { @IConfigurationService private readonly configurationService: IConfigurationService, @IStorageService private readonly storageService: IStorageService, @IWorkspaceContextService private readonly workspaceService: IWorkspaceContextService, - @ILogService private readonly logService: ILogService + @ILogService private readonly logService: ILogService, + @IWorkbenchEnvironmentService private readonly workbenchEnvironmentService: IWorkbenchEnvironmentService ) { super(); @@ -489,7 +491,7 @@ export class SimpleWindowService extends Disposable implements IWindowService { for (let i = 0; i < _uris.length; i++) { const uri = _uris[i]; if ('folderUri' in uri) { - const newAddress = `${document.location.origin}/?folder=${uri.folderUri.path}`; + const newAddress = `${document.location.origin}/?folder=${uri.folderUri.path}${this.workbenchEnvironmentService.configuration.connectionToken ? `&tkn=${this.workbenchEnvironmentService.configuration.connectionToken}` : ''}`; if (openFolderInNewWindow) { window.open(newAddress); } else { @@ -608,6 +610,10 @@ export class SimpleWindowsService implements IWindowsService { readonly onWindowUnmaximize: Event = Event.None; readonly onRecentlyOpenedChange: Event = Event.None; + constructor( + @IWorkbenchEnvironmentService private readonly workbenchEnvironmentService: IWorkbenchEnvironmentService + ) { + } isFocused(_windowId: number): Promise { return Promise.resolve(true); } @@ -778,6 +784,9 @@ export class SimpleWindowsService implements IWindowsService { newAddress += `&ibe=${encodeURIComponent(ibe)}`; } + // add connection token + newAddress += `${this.workbenchEnvironmentService.configuration.connectionToken ? `tkn=${this.workbenchEnvironmentService.configuration.connectionToken}` : ''}`; + window.open(newAddress); return Promise.resolve(); diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts index 2bd39c97554..73e8b7c1d11 100644 --- a/src/vs/workbench/services/environment/browser/environmentService.ts +++ b/src/vs/workbench/services/environment/browser/environmentService.ts @@ -61,6 +61,7 @@ export interface IBrowserWindowConfiguration { workspaceId: string; remoteAuthority?: string; webviewEndpoint?: string; + connectionToken?: string; } export class BrowserWorkbenchEnvironmentService implements IEnvironmentService { @@ -81,6 +82,7 @@ export class BrowserWorkbenchEnvironmentService implements IEnvironmentService { this.localeResource = joinPath(this.userRoamingDataHome, 'locale.json'); this.backupHome = joinPath(this.userRoamingDataHome, BACKUPS); this.configuration.backupWorkspaceResource = joinPath(this.backupHome, configuration.workspaceId); + this.configuration.connectionToken = configuration.connectionToken || this.getConnectionTokenFromLocation(); this.logsPath = '/web/logs'; @@ -182,4 +184,21 @@ export class BrowserWorkbenchEnvironmentService implements IEnvironmentService { get webviewCspSource(): string { return this.webviewEndpoint ? this.webviewEndpoint : 'vscode-resource:'; } + + private getConnectionTokenFromLocation(): string | undefined { + // TODO: Check with @alexd where the token will be: search or hash? + let connectionToken: string | undefined = undefined; + if (document.location.search) { + connectionToken = this.getConnectionToken(document.location.search); + } + if (!connectionToken && document.location.hash) { + connectionToken = this.getConnectionToken(document.location.hash); + } + return connectionToken; + } + + private getConnectionToken(str: string): string | undefined { + const m = str.match(/[#&]tkn=([^&]+)/); + return m ? m[1] : undefined; + } } From f23f00bbb90fca963e12518be9b73bcb100f3fee Mon Sep 17 00:00:00 2001 From: Itamar Kestenbaum Date: Fri, 2 Aug 2019 07:11:45 -0400 Subject: [PATCH 166/861] cancel hide if still hovered --- .../contrib/debug/browser/debugEditorContribution.ts | 6 +++++- src/vs/workbench/contrib/debug/browser/debugHover.ts | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts b/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts index de8fe1e188d..1b6dbbb7d5f 100644 --- a/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts +++ b/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts @@ -385,7 +385,11 @@ export class DebugEditorContribution implements IDebugEditorContribution { @memoize private get hideHoverScheduler(): RunOnceScheduler { - const scheduler = new RunOnceScheduler(() => this.hoverWidget.hide(), 2 * HOVER_DELAY); + const scheduler = new RunOnceScheduler(() => { + if (!this.hoverWidget.isHovered()) { + this.hoverWidget.hide(); + } + }, 2 * HOVER_DELAY); this.toDispose.push(scheduler); return scheduler; diff --git a/src/vs/workbench/contrib/debug/browser/debugHover.ts b/src/vs/workbench/contrib/debug/browser/debugHover.ts index b198f1d9e15..37e81c80c52 100644 --- a/src/vs/workbench/contrib/debug/browser/debugHover.ts +++ b/src/vs/workbench/contrib/debug/browser/debugHover.ts @@ -122,6 +122,10 @@ export class DebugHoverWidget implements IContentWidget { })); } + isHovered(): boolean { + return this.domNode.matches(':hover'); + } + isVisible(): boolean { return this._isVisible; } From d7f957bdec0458705f8a662686a534d75ba481a7 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 2 Aug 2019 15:27:42 +0200 Subject: [PATCH 167/861] fix statusbar smoketests --- test/smoke/src/areas/statusbar/statusbar.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/smoke/src/areas/statusbar/statusbar.ts b/test/smoke/src/areas/statusbar/statusbar.ts index 66e1186fd4c..67a6e0a1af0 100644 --- a/test/smoke/src/areas/statusbar/statusbar.ts +++ b/test/smoke/src/areas/statusbar/statusbar.ts @@ -60,9 +60,9 @@ export class StatusBar { case StatusBarElement.LANGUAGE_STATUS: return `${this.mainSelector} ${this.rightSelector}[title="Select Language Mode"]`; case StatusBarElement.FEEDBACK_ICON: - return `${this.mainSelector} ${this.rightSelector} .monaco-dropdown.send-feedback`; + return `${this.mainSelector} .statusbar-item.right[id="status.feedback"]`; default: throw new Error(element); } } -} \ No newline at end of file +} From 709a07d51919d3266ca71699c6ddfb2d3547c0e1 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 2 Aug 2019 15:33:17 +0200 Subject: [PATCH 168/861] comment out i18n smoke test assertion --- test/smoke/src/areas/workbench/localization.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/smoke/src/areas/workbench/localization.test.ts b/test/smoke/src/areas/workbench/localization.test.ts index e9e0b44a4f0..dd301859606 100644 --- a/test/smoke/src/areas/workbench/localization.test.ts +++ b/test/smoke/src/areas/workbench/localization.test.ts @@ -39,8 +39,8 @@ export function setup() { await app.workbench.debug.openDebugViewlet(); await app.workbench.debug.waitForTitle(title => /debug/i.test(title)); - await app.workbench.extensions.openExtensionsViewlet(); - await app.workbench.extensions.waitForTitle(title => /erweiterungen/i.test(title)); + // await app.workbench.extensions.openExtensionsViewlet(); + // await app.workbench.extensions.waitForTitle(title => /erweiterungen/i.test(title)); }); }); -} \ No newline at end of file +} From 8e77bbe8b11f4bd1cd2da916b2988f442acdd64b Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 2 Aug 2019 16:53:29 +0200 Subject: [PATCH 169/861] fix #77575 --- src/vs/base/browser/ui/list/listWidget.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index a3bd2958421..e660fed0622 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -647,7 +647,6 @@ export class MouseController implements IDisposable { } const newSelection = disjunction(rangeSelection, relativeComplement(selection, contiguousRange)); - this.list.setFocus([focus]); this.list.setSelection(newSelection, e.browserEvent); } else if (this.isSelectionSingleChangeEvent(e)) { From 58d0639ac12c61ba20ac333e19689c1a91bc2f48 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Fri, 2 Aug 2019 17:19:36 +0200 Subject: [PATCH 170/861] Workaround for #78388 (twistie not updating on has children change) (#78390) * Workaround for #78388 (twistie not updating on has children change) Fixes #78389 --- src/vs/workbench/browser/parts/views/customView.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/views/customView.ts b/src/vs/workbench/browser/parts/views/customView.ts index d6557daf7a1..b4ab237e31c 100644 --- a/src/vs/workbench/browser/parts/views/customView.ts +++ b/src/vs/workbench/browser/parts/views/customView.ts @@ -597,8 +597,16 @@ export class CustomTreeView extends Disposable implements ITreeView { private async doRefresh(elements: ITreeItem[]): Promise { if (this.tree) { this.refreshing = true; - await Promise.all(elements.map(element => this.tree.updateChildren(element, true))); - elements.map(element => this.tree.rerender(element)); + const parents: Set = new Set(); + elements.forEach(element => { + if (element !== this.root) { + const parent = this.tree.getParentElement(element); + parents.add(parent); + } else { + parents.add(element); + } + }); + await Promise.all(Array.from(parents.values()).map(element => this.tree.updateChildren(element, true))); this.refreshing = false; this.updateContentAreas(); if (this.focused) { From 01fcb405fe9212835f732200ec642e0df14409db Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 2 Aug 2019 11:40:27 -0700 Subject: [PATCH 171/861] Disable esc sequence logging when toggling off Fixes #78399 --- src/vs/workbench/contrib/terminal/browser/terminalInstance.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 31cdb6fb01b..411d6bf2c29 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -1445,7 +1445,8 @@ export class TerminalInstance implements ITerminalInstance { } public toggleEscapeSequenceLogging(): void { - this._xterm.setOption('logLevel', 'debug'); + const isDebug = this._xterm.getOption('logLevel') === 'debug'; + this._xterm.setOption('logLevel', isDebug ? 'info' : 'debug'); } public getInitialCwd(): Promise { From 753263d4ad7734c7aa353322fa5b62ab263c52be Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Fri, 2 Aug 2019 13:09:42 -0700 Subject: [PATCH 172/861] Revert "Fix #78162" This reverts commit ce15ecb0d50cab9f0ca6ef443b145a144f428634. --- .../contrib/preferences/browser/settingsEditor2.ts | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts index b3567495097..0d080e7d577 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts @@ -970,15 +970,8 @@ export class SettingsEditor2 extends BaseEditor { // If a single setting is being refreshed, it's ok to refresh now if that is not the focused setting if (key) { const focusedKey = focusedSetting.getAttribute(AbstractSettingRenderer.SETTING_KEY_ATTR); - /** - * Update `list`s live if focused item is whole list or list item, - * as they have a separate "submit edit" step built in before this - */ - if ( - focusedKey === key && - !DOM.hasClass(focusedSetting, 'setting-item-list') && - !DOM.hasClass(focusedSetting, 'setting-item-contents') - ) { + if (focusedKey === key && + !DOM.hasClass(focusedSetting, 'setting-item-list')) { // update `list`s live, as they have a separate "submit edit" step built in before this this.updateModifiedLabelForKey(key); this.scheduleRefresh(focusedSetting, key); From 36b66fac1ee77ca1f0258b57f7ccefc0f1698e0f Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Fri, 2 Aug 2019 13:36:03 -0700 Subject: [PATCH 173/861] Fix #78404 --- .../workbench/contrib/preferences/browser/settingsEditor2.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts index 0d080e7d577..b1094d9a026 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts @@ -971,7 +971,9 @@ export class SettingsEditor2 extends BaseEditor { if (key) { const focusedKey = focusedSetting.getAttribute(AbstractSettingRenderer.SETTING_KEY_ATTR); if (focusedKey === key && - !DOM.hasClass(focusedSetting, 'setting-item-list')) { // update `list`s live, as they have a separate "submit edit" step built in before this + // update `list`s live, as they have a separate "submit edit" step built in before this + (focusedSetting.parentElement && !DOM.hasClass(focusedSetting.parentElement, 'setting-item-list')) + ) { this.updateModifiedLabelForKey(key); this.scheduleRefresh(focusedSetting, key); From 0767273a98d2ad1471515c02102739bc71a1a42a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 2 Aug 2019 13:43:07 -0700 Subject: [PATCH 174/861] Disable scroll to command keybindings on mac in a11y mode Part of #78402 --- .../contrib/terminal/browser/terminal.contribution.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts index 4dc89120557..f1481ee18f6 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts @@ -450,11 +450,11 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ResizePaneDownTe actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollToPreviousCommandAction, ScrollToPreviousCommandAction.ID, ScrollToPreviousCommandAction.LABEL, { primary: 0, mac: { primary: KeyMod.CtrlCmd | KeyCode.UpArrow } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll To Previous Command', category); +}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_FOCUS, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate())), 'Terminal: Scroll To Previous Command', category); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollToNextCommandAction, ScrollToNextCommandAction.ID, ScrollToNextCommandAction.LABEL, { primary: 0, mac: { primary: KeyMod.CtrlCmd | KeyCode.DownArrow } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll To Next Command', category); +}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_FOCUS, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate())), 'Terminal: Scroll To Next Command', category); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectToPreviousCommandAction, SelectToPreviousCommandAction.ID, SelectToPreviousCommandAction.LABEL, { primary: 0, mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.UpArrow } From b50235306abdddc6b03026b5687a9e36ec742c14 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 2 Aug 2019 14:00:07 -0700 Subject: [PATCH 175/861] Bump version --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index ea677177865..f2c8150eedc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "code-oss-dev", - "version": "1.37.0", + "version": "1.38.0", "distro": "f9c5d20222a2776b589107efa7d2e3aa4b80050d", "author": { "name": "Microsoft Corporation" @@ -158,4 +158,4 @@ "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} \ No newline at end of file +} From cf41b420d86c4da1db25c9475ff9319960e4f072 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 2 Aug 2019 12:08:19 -0700 Subject: [PATCH 176/861] Fix #33264. Move simple find to workbench. --- .../contrib/codeEditor/browser}/find/simpleFindWidget.css | 0 .../contrib/codeEditor/browser}/find/simpleFindWidget.ts | 0 .../workbench/contrib/terminal/browser/terminalFindWidget.ts | 2 +- src/vs/workbench/contrib/webview/browser/webviewFindWidget.ts | 4 ++-- 4 files changed, 3 insertions(+), 3 deletions(-) rename src/vs/{editor/contrib => workbench/contrib/codeEditor/browser}/find/simpleFindWidget.css (100%) rename src/vs/{editor/contrib => workbench/contrib/codeEditor/browser}/find/simpleFindWidget.ts (100%) diff --git a/src/vs/editor/contrib/find/simpleFindWidget.css b/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.css similarity index 100% rename from src/vs/editor/contrib/find/simpleFindWidget.css rename to src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.css diff --git a/src/vs/editor/contrib/find/simpleFindWidget.ts b/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts similarity index 100% rename from src/vs/editor/contrib/find/simpleFindWidget.ts rename to src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts diff --git a/src/vs/workbench/contrib/terminal/browser/terminalFindWidget.ts b/src/vs/workbench/contrib/terminal/browser/terminalFindWidget.ts index 1ab97705568..2714994ea2a 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalFindWidget.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalFindWidget.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { SimpleFindWidget } from 'vs/editor/contrib/find/simpleFindWidget'; +import { SimpleFindWidget } from 'vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { ITerminalService, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_INPUT_FOCUSED, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED } from 'vs/workbench/contrib/terminal/common/terminal'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; diff --git a/src/vs/workbench/contrib/webview/browser/webviewFindWidget.ts b/src/vs/workbench/contrib/webview/browser/webviewFindWidget.ts index 1f337cbc8e3..6f31cd49704 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewFindWidget.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewFindWidget.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { SimpleFindWidget } from 'vs/editor/contrib/find/simpleFindWidget'; +import { SimpleFindWidget } from 'vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; @@ -54,4 +54,4 @@ export class WebviewFindWidget extends SimpleFindWidget { protected onFindInputFocusTrackerFocus() { } protected onFindInputFocusTrackerBlur() { } -} \ No newline at end of file +} From c4c427198d3ca20787e5c2dc0e2564c29a60a002 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 2 Aug 2019 17:51:54 -0700 Subject: [PATCH 177/861] Fix #66284. --- .../client/src/jsonMain.ts | 2 +- src/vs/base/browser/ui/button/button.ts | 2 +- .../test/browser/controller/cursor.test.ts | 69 +++++++++++++++++++ 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/extensions/json-language-features/client/src/jsonMain.ts b/extensions/json-language-features/client/src/jsonMain.ts index 323e5f0ed94..6f1ca02d580 100644 --- a/extensions/json-language-features/client/src/jsonMain.ts +++ b/extensions/json-language-features/client/src/jsonMain.ts @@ -223,7 +223,7 @@ export function activate(context: ExtensionContext) { let languageConfiguration: LanguageConfiguration = { wordPattern: /("(?:[^\\\"]*(?:\\.)?)*"?)|[^\s{}\[\],:]+/, indentationRules: { - increaseIndentPattern: /^.*(\{[^}]*|\[[^\]]*)$/, + increaseIndentPattern: /({+(?=([^"]*"[^"]*")*[^"}]*$))|(\[+(?=([^"]*"[^"]*")*[^"\]]*$))/, decreaseIndentPattern: /^\s*[}\]],?\s*$/ } }; diff --git a/src/vs/base/browser/ui/button/button.ts b/src/vs/base/browser/ui/button/button.ts index 82c1a85b8fb..eeb7724e5fd 100644 --- a/src/vs/base/browser/ui/button/button.ts +++ b/src/vs/base/browser/ui/button/button.ts @@ -223,4 +223,4 @@ export class ButtonGroup extends Disposable { } } } -} \ No newline at end of file +} diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index c2a4e4a4560..6335cdddf8c 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -3633,6 +3633,75 @@ suite('Editor Controller - Indentation Rules', () => { model.dispose(); mode.dispose(); }); + + test('', () => { + class JSONMode extends MockMode { + private static readonly _id = new LanguageIdentifier('indentRulesMode', 4); + constructor() { + super(JSONMode._id); + this._register(LanguageConfigurationRegistry.register(this.getLanguageIdentifier(), { + brackets: [ + ['{', '}'], + ['[', ']'], + ['(', ')'] + ], + indentationRules: { + increaseIndentPattern: new RegExp('^.*\\{[^}\"\\\']*$|^.*\\([^\\)\"\\\']*$|^\\s*(public|private|protected):\\s*$|^\\s*@(public|private|protected)\\s*$|^\\s*\\{\\}$'), + decreaseIndentPattern: new RegExp('^\\s*(\\s*/[*].*[*]/\\s*)*\\}|^\\s*(\\s*/[*].*[*]/\\s*)*\\)|^\\s*(public|private|protected):\\s*$|^\\s*@(public|private|protected)\\s*$'), + } + })); + } + } + + let mode = new JSONMode(); + let model = createTextModel( + [ + '{', + ' "scripts: {"', + ' "watch": "a {"', + ' "build{": "b"', + ' "tasks": []', + ' "tasks": ["a"]', + ' "}"', + '"}"' + ].join('\n'), + { + tabSize: 2, + indentSize: 2 + }, + mode.getLanguageIdentifier() + ); + + withTestCodeEditor(null, { model: model, autoIndent: true }, (editor, cursor) => { + moveTo(cursor, 3, 19, false); + assertCursor(cursor, new Selection(3, 19, 3, 19)); + + cursorCommand(cursor, H.Type, { text: '\n' }, 'keyboard'); + assert.deepEqual(model.getLineContent(4), ' '); + + moveTo(cursor, 5, 18, false); + assertCursor(cursor, new Selection(5, 18, 5, 18)); + + cursorCommand(cursor, H.Type, { text: '\n' }, 'keyboard'); + assert.deepEqual(model.getLineContent(6), ' '); + + moveTo(cursor, 7, 15, false); + assertCursor(cursor, new Selection(7, 15, 7, 15)); + + cursorCommand(cursor, H.Type, { text: '\n' }, 'keyboard'); + assert.deepEqual(model.getLineContent(8), ' '); + assert.deepEqual(model.getLineContent(9), ' ]'); + + moveTo(cursor, 10, 18, false); + assertCursor(cursor, new Selection(10, 18, 10, 18)); + + cursorCommand(cursor, H.Type, { text: '\n' }, 'keyboard'); + assert.deepEqual(model.getLineContent(11), ' ]'); + }); + + model.dispose(); + mode.dispose(); + }); }); interface ICursorOpts { From 5741cba3ffe28b520f6d54e111e1183e8e34624c Mon Sep 17 00:00:00 2001 From: Arash Arbabi Date: Sun, 4 Aug 2019 12:06:19 +0430 Subject: [PATCH 178/861] fix: Resolving Review --- .../codeEditor/browser/find/simpleFindWidget.ts | 3 ++- .../contrib/terminal/browser/terminalFindWidget.ts | 10 ++++++++++ .../contrib/webview/browser/webviewFindWidget.ts | 2 ++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts b/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts index e29852c3392..1270b142228 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts @@ -90,7 +90,7 @@ export abstract class SimpleFindWidget extends Widget { this._findInput.setRegex(this._state.isRegex); this._findInput.setWholeWords(this._state.wholeWord); this._findInput.setCaseSensitive(this._state.matchCase); - this.find(this._invertDefaultDirection); + this.findFirst(); })); this._register(this._findInput.onKeyDown((e) => { @@ -166,6 +166,7 @@ export abstract class SimpleFindWidget extends Widget { protected abstract onInputChanged(): boolean; protected abstract find(previous: boolean): void; + protected abstract findFirst(): void; protected abstract onFocusTrackerFocus(): void; protected abstract onFocusTrackerBlur(): void; protected abstract onFindInputFocusTrackerFocus(): void; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalFindWidget.ts b/src/vs/workbench/contrib/terminal/browser/terminalFindWidget.ts index 2714994ea2a..87ca61f2d55 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalFindWidget.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalFindWidget.ts @@ -78,4 +78,14 @@ export class TerminalFindWidget extends SimpleFindWidget { protected onFindInputFocusTrackerBlur() { this._findInputFocused.reset(); } + + public findFirst() { + const instance = this._terminalService.getActiveInstance(); + if (instance) { + if (instance.hasSelection()) { + instance.clearSelection(); + } + instance.findPrevious(this.inputValue, { regex: this._getRegexValue(), wholeWord: this._getWholeWordValue(), caseSensitive: this._getCaseSensitiveValue() }); + } + } } diff --git a/src/vs/workbench/contrib/webview/browser/webviewFindWidget.ts b/src/vs/workbench/contrib/webview/browser/webviewFindWidget.ts index 6f31cd49704..0d8e6804bc0 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewFindWidget.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewFindWidget.ts @@ -54,4 +54,6 @@ export class WebviewFindWidget extends SimpleFindWidget { protected onFindInputFocusTrackerFocus() { } protected onFindInputFocusTrackerBlur() { } + + protected findFirst() { } } From bcc41d905caabc4a12414c6287558e8d377f3411 Mon Sep 17 00:00:00 2001 From: Yisrael Date: Sun, 4 Aug 2019 13:35:17 +0300 Subject: [PATCH 179/861] remove unused imports --- src/vs/editor/contrib/suggest/suggestWidget.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vs/editor/contrib/suggest/suggestWidget.ts b/src/vs/editor/contrib/suggest/suggestWidget.ts index 0af27a38f97..50694c9d87a 100644 --- a/src/vs/editor/contrib/suggest/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/suggestWidget.ts @@ -38,8 +38,6 @@ import { URI } from 'vs/base/common/uri'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { FileKind } from 'vs/platform/files/common/files'; import { MarkdownString } from 'vs/base/common/htmlContent'; -import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; -import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; const expandSuggestionDocsByDefault = false; From 56e7d6f9dc13b59003e5ea2bf1872aab23448cab Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 5 Aug 2019 09:01:32 +0200 Subject: [PATCH 180/861] fix build --- .../codeEditor/browser/find/images/chevron-next-dark.svg | 3 +++ .../codeEditor/browser/find/images/chevron-next-light.svg | 3 +++ .../codeEditor/browser/find/images/chevron-previous-dark.svg | 3 +++ .../codeEditor/browser/find/images/chevron-previous-light.svg | 3 +++ .../contrib/codeEditor/browser/find/images/close-dark.svg | 3 +++ .../contrib/codeEditor/browser/find/images/close-light.svg | 3 +++ 6 files changed, 18 insertions(+) create mode 100644 src/vs/workbench/contrib/codeEditor/browser/find/images/chevron-next-dark.svg create mode 100644 src/vs/workbench/contrib/codeEditor/browser/find/images/chevron-next-light.svg create mode 100644 src/vs/workbench/contrib/codeEditor/browser/find/images/chevron-previous-dark.svg create mode 100644 src/vs/workbench/contrib/codeEditor/browser/find/images/chevron-previous-light.svg create mode 100644 src/vs/workbench/contrib/codeEditor/browser/find/images/close-dark.svg create mode 100644 src/vs/workbench/contrib/codeEditor/browser/find/images/close-light.svg diff --git a/src/vs/workbench/contrib/codeEditor/browser/find/images/chevron-next-dark.svg b/src/vs/workbench/contrib/codeEditor/browser/find/images/chevron-next-dark.svg new file mode 100644 index 00000000000..dbe70d742de --- /dev/null +++ b/src/vs/workbench/contrib/codeEditor/browser/find/images/chevron-next-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/workbench/contrib/codeEditor/browser/find/images/chevron-next-light.svg b/src/vs/workbench/contrib/codeEditor/browser/find/images/chevron-next-light.svg new file mode 100644 index 00000000000..ec824f41cc0 --- /dev/null +++ b/src/vs/workbench/contrib/codeEditor/browser/find/images/chevron-next-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/workbench/contrib/codeEditor/browser/find/images/chevron-previous-dark.svg b/src/vs/workbench/contrib/codeEditor/browser/find/images/chevron-previous-dark.svg new file mode 100644 index 00000000000..5db4f79da85 --- /dev/null +++ b/src/vs/workbench/contrib/codeEditor/browser/find/images/chevron-previous-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/workbench/contrib/codeEditor/browser/find/images/chevron-previous-light.svg b/src/vs/workbench/contrib/codeEditor/browser/find/images/chevron-previous-light.svg new file mode 100644 index 00000000000..aac3a5020cd --- /dev/null +++ b/src/vs/workbench/contrib/codeEditor/browser/find/images/chevron-previous-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/workbench/contrib/codeEditor/browser/find/images/close-dark.svg b/src/vs/workbench/contrib/codeEditor/browser/find/images/close-dark.svg new file mode 100644 index 00000000000..75644595d19 --- /dev/null +++ b/src/vs/workbench/contrib/codeEditor/browser/find/images/close-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/workbench/contrib/codeEditor/browser/find/images/close-light.svg b/src/vs/workbench/contrib/codeEditor/browser/find/images/close-light.svg new file mode 100644 index 00000000000..cf5f28ca35c --- /dev/null +++ b/src/vs/workbench/contrib/codeEditor/browser/find/images/close-light.svg @@ -0,0 +1,3 @@ + + + From 4119bf3f9e3cff272b2825c9e327074b5f13ff78 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Mon, 5 Aug 2019 09:28:55 +0200 Subject: [PATCH 181/861] Fixes #78262 --- src/vs/editor/browser/controller/mouseTarget.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/browser/controller/mouseTarget.ts b/src/vs/editor/browser/controller/mouseTarget.ts index 9a37d512035..1f4c6ff52c7 100644 --- a/src/vs/editor/browser/controller/mouseTarget.ts +++ b/src/vs/editor/browser/controller/mouseTarget.ts @@ -16,6 +16,7 @@ import { Range as EditorRange } from 'vs/editor/common/core/range'; import { HorizontalRange } from 'vs/editor/common/view/renderingContext'; import { ViewContext } from 'vs/editor/common/view/viewContext'; import { IViewModel } from 'vs/editor/common/viewModel/viewModel'; +import { CursorColumns } from 'vs/editor/common/controller/cursorCommon'; export interface IViewZoneData { viewZoneId: number; @@ -410,7 +411,7 @@ class HitTestRequest extends BareHitTestRequest { let mouseColumn = this.mouseColumn; if (position && position.column < this._ctx.model.getLineMaxColumn(position.lineNumber)) { // Most likely, the line contains foreign decorations... - mouseColumn = position.column; + mouseColumn = CursorColumns.visibleColumnFromColumn(this._ctx.model.getLineContent(position.lineNumber), position.column, this._ctx.model.getOptions().tabSize) + 1; } return new MouseTarget(this.target, type, mouseColumn, position, range, detail); } From e428bed67d40bef5bb044509f654aa536360a0ab Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 5 Aug 2019 10:42:19 +0200 Subject: [PATCH 182/861] strict init work, #78168 --- .../contrib/inPlaceReplace/inPlaceReplace.ts | 4 +-- .../referenceSearch/referencesController.ts | 14 ++++---- .../referenceSearch/referencesWidget.ts | 25 +++++++------- .../editor/contrib/rename/renameInputField.ts | 34 +++++++++---------- .../contrib/snippet/snippetController2.ts | 2 +- .../editor/contrib/snippet/snippetSession.ts | 24 ++++++------- src/vs/editor/contrib/suggest/suggest.ts | 2 +- .../editor/contrib/suggest/suggestMemory.ts | 6 ++-- src/vs/editor/contrib/suggest/suggestModel.ts | 7 ++-- .../editor/contrib/suggest/suggestWidget.ts | 22 ++++++------ .../browser/menuEntryActionViewItem.ts | 4 +-- src/vs/platform/actions/common/menuService.ts | 4 +-- .../workbench/api/browser/mainThreadEditor.ts | 7 ++-- 13 files changed, 78 insertions(+), 77 deletions(-) diff --git a/src/vs/editor/contrib/inPlaceReplace/inPlaceReplace.ts b/src/vs/editor/contrib/inPlaceReplace/inPlaceReplace.ts index 195d83b849c..fce6fc23383 100644 --- a/src/vs/editor/contrib/inPlaceReplace/inPlaceReplace.ts +++ b/src/vs/editor/contrib/inPlaceReplace/inPlaceReplace.ts @@ -37,8 +37,8 @@ class InPlaceReplaceController implements IEditorContribution { private readonly editor: ICodeEditor; private readonly editorWorkerService: IEditorWorkerService; private decorationIds: string[] = []; - private currentRequest: CancelablePromise; - private decorationRemover: CancelablePromise; + private currentRequest?: CancelablePromise; + private decorationRemover?: CancelablePromise; constructor( editor: ICodeEditor, diff --git a/src/vs/editor/contrib/referenceSearch/referencesController.ts b/src/vs/editor/contrib/referenceSearch/referencesController.ts index 0f756a44550..6f0dcdff9de 100644 --- a/src/vs/editor/contrib/referenceSearch/referencesController.ts +++ b/src/vs/editor/contrib/referenceSearch/referencesController.ts @@ -34,8 +34,8 @@ export abstract class ReferencesController implements editorCommon.IEditorContri private readonly _disposables = new DisposableStore(); private readonly _editor: ICodeEditor; - private _widget: ReferenceWidget | null; - private _model: ReferencesModel | null; + private _widget?: ReferenceWidget; + private _model?: ReferencesModel; private _requestIdPool = 0; private _ignoreModelChangeEvent = false; @@ -68,11 +68,11 @@ export abstract class ReferencesController implements editorCommon.IEditorContri dispose(this._disposables); if (this._widget) { dispose(this._widget); - this._widget = null; + this._widget = undefined; } if (this._model) { dispose(this._model); - this._model = null; + this._model = undefined; } } @@ -107,7 +107,7 @@ export abstract class ReferencesController implements editorCommon.IEditorContri modelPromise.cancel(); if (this._widget) { this._storageService.store(storageKey, JSON.stringify(this._widget.layoutData), StorageScope.GLOBAL); - this._widget = null; + this._widget = undefined; } this.closeWidget(); })); @@ -202,13 +202,13 @@ export abstract class ReferencesController implements editorCommon.IEditorContri public closeWidget(): void { if (this._widget) { dispose(this._widget); - this._widget = null; + this._widget = undefined; } this._referenceSearchVisible.reset(); this._disposables.clear(); if (this._model) { dispose(this._model); - this._model = null; + this._model = undefined; } this._editor.focus(); this._requestIdPool += 1; // Cancel pending requests diff --git a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts index 20fc37f552e..78b59c046c2 100644 --- a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts +++ b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts @@ -158,8 +158,8 @@ class DecorationsManager implements IDisposable { } export class LayoutData { - ratio: number; - heightInLines: number; + ratio: number = 0.7; + heightInLines: number = 18; static fromJSON(raw: string): LayoutData { let ratio: number | undefined; @@ -191,22 +191,21 @@ export const ctxReferenceWidgetSearchTreeFocused = new RawContextKey('r */ export class ReferenceWidget extends PeekViewWidget { - private _model: ReferencesModel | undefined; - private _decorationsManager: DecorationsManager; + private _model?: ReferencesModel; + private _decorationsManager?: DecorationsManager; private readonly _disposeOnNewModel = new DisposableStore(); private readonly _callOnDispose = new DisposableStore(); private _onDidSelectReference = new Emitter(); - private _tree: WorkbenchAsyncDataTree; - private _treeContainer: HTMLElement; - // private _sash: VSash; - private _splitView: SplitView; - private _preview: ICodeEditor; - private _previewModelReference: IReference; - private _previewNotAvailableMessage: TextModel; - private _previewContainer: HTMLElement; - private _messageContainer: HTMLElement; + private _tree!: WorkbenchAsyncDataTree; + private _treeContainer!: HTMLElement; + private _splitView!: SplitView; + private _preview!: ICodeEditor; + private _previewModelReference!: IReference; + private _previewNotAvailableMessage!: TextModel; + private _previewContainer!: HTMLElement; + private _messageContainer!: HTMLElement; private _dim: dom.Dimension = { height: 0, width: 0 }; constructor( diff --git a/src/vs/editor/contrib/rename/renameInputField.ts b/src/vs/editor/contrib/rename/renameInputField.ts index 85e4c956911..c285d9707cd 100644 --- a/src/vs/editor/contrib/rename/renameInputField.ts +++ b/src/vs/editor/contrib/rename/renameInputField.ts @@ -19,10 +19,10 @@ export const CONTEXT_RENAME_INPUT_VISIBLE = new RawContextKey('renameIn export class RenameInputField implements IContentWidget, IDisposable { private _editor: ICodeEditor; - private _position: Position; - private _domNode: HTMLElement; - private _inputField: HTMLInputElement; - private _visible: boolean; + private _position?: Position; + private _domNode?: HTMLElement; + private _inputField?: HTMLInputElement; + private _visible?: boolean; private readonly _visibleContextKey: IContextKey; private readonly _disposables = new DisposableStore(); @@ -95,7 +95,7 @@ export class RenameInputField implements IContentWidget, IDisposable { this._inputField.style.borderStyle = border ? 'solid' : 'none'; this._inputField.style.borderColor = border ? border.toString() : 'none'; - this._domNode.style.boxShadow = widgetShadowColor ? ` 0 2px 8px ${widgetShadowColor}` : null; + this._domNode!.style.boxShadow = widgetShadowColor ? ` 0 2px 8px ${widgetShadowColor}` : null; } private updateFont(): void { @@ -111,7 +111,7 @@ export class RenameInputField implements IContentWidget, IDisposable { public getPosition(): IContentWidgetPosition | null { return this._visible - ? { position: this._position, preference: [ContentWidgetPositionPreference.BELOW, ContentWidgetPositionPreference.ABOVE] } + ? { position: this._position!, preference: [ContentWidgetPositionPreference.BELOW, ContentWidgetPositionPreference.ABOVE] } : null; } @@ -133,10 +133,10 @@ export class RenameInputField implements IContentWidget, IDisposable { public getInput(where: IRange, value: string, selectionStart: number, selectionEnd: number): Promise { this._position = new Position(where.startLineNumber, where.startColumn); - this._inputField.value = value; - this._inputField.setAttribute('selectionStart', selectionStart.toString()); - this._inputField.setAttribute('selectionEnd', selectionEnd.toString()); - this._inputField.size = Math.max((where.endColumn - where.startColumn) * 1.1, 20); + this._inputField!.value = value; + this._inputField!.setAttribute('selectionStart', selectionStart.toString()); + this._inputField!.setAttribute('selectionEnd', selectionEnd.toString()); + this._inputField!.size = Math.max((where.endColumn - where.startColumn) * 1.1, 20); const disposeOnDone = new DisposableStore(); const always = () => { @@ -154,7 +154,7 @@ export class RenameInputField implements IContentWidget, IDisposable { }; this._currentAcceptInput = () => { - if (this._inputField.value.trim().length === 0 || this._inputField.value === value) { + if (this._inputField!.value.trim().length === 0 || this._inputField!.value === value) { // empty or whitespace only or not changed this.cancelInput(true); return; @@ -162,7 +162,7 @@ export class RenameInputField implements IContentWidget, IDisposable { this._currentAcceptInput = null; this._currentCancelInput = null; - resolve(this._inputField.value); + resolve(this._inputField!.value); }; let onCursorChanged = () => { @@ -187,16 +187,16 @@ export class RenameInputField implements IContentWidget, IDisposable { } private _show(): void { - this._editor.revealLineInCenterIfOutsideViewport(this._position.lineNumber, ScrollType.Smooth); + this._editor.revealLineInCenterIfOutsideViewport(this._position!.lineNumber, ScrollType.Smooth); this._visible = true; this._visibleContextKey.set(true); this._editor.layoutContentWidget(this); setTimeout(() => { - this._inputField.focus(); - this._inputField.setSelectionRange( - parseInt(this._inputField.getAttribute('selectionStart')!), - parseInt(this._inputField.getAttribute('selectionEnd')!)); + this._inputField!.focus(); + this._inputField!.setSelectionRange( + parseInt(this._inputField!.getAttribute('selectionStart')!), + parseInt(this._inputField!.getAttribute('selectionEnd')!)); }, 100); } diff --git a/src/vs/editor/contrib/snippet/snippetController2.ts b/src/vs/editor/contrib/snippet/snippetController2.ts index c24659b44d2..cec786f46fe 100644 --- a/src/vs/editor/contrib/snippet/snippetController2.ts +++ b/src/vs/editor/contrib/snippet/snippetController2.ts @@ -54,7 +54,7 @@ export class SnippetController2 implements IEditorContribution { private _session?: SnippetSession; private _snippetListener = new DisposableStore(); - private _modelVersionId: number; + private _modelVersionId: number = -1; private _currentChoice?: Choice; constructor( diff --git a/src/vs/editor/contrib/snippet/snippetSession.ts b/src/vs/editor/contrib/snippet/snippetSession.ts index 6140e44858a..689b5567ed1 100644 --- a/src/vs/editor/contrib/snippet/snippetSession.ts +++ b/src/vs/editor/contrib/snippet/snippetSession.ts @@ -41,7 +41,7 @@ export class OneSnippet { private readonly _snippet: TextmateSnippet; private readonly _offset: number; - private _placeholderDecorations: Map; + private _placeholderDecorations?: Map; private _placeholderGroups: Placeholder[][]; _placeholderGroupsIdx: number; _nestingLevel: number = 1; @@ -92,7 +92,7 @@ export class OneSnippet { ); const options = placeholder.isFinalTabstop ? OneSnippet._decor.inactiveFinal : OneSnippet._decor.inactive; const handle = accessor.addDecoration(range, options); - this._placeholderDecorations.set(placeholder, handle); + this._placeholderDecorations!.set(placeholder, handle); } }); } @@ -111,7 +111,7 @@ export class OneSnippet { for (const placeholder of this._placeholderGroups[this._placeholderGroupsIdx]) { // Check if the placeholder has a transformation if (placeholder.transform) { - const id = this._placeholderDecorations.get(placeholder)!; + const id = this._placeholderDecorations!.get(placeholder)!; const range = this._editor.getModel().getDecorationRange(id)!; const currentValue = this._editor.getModel().getValueInRange(range); @@ -148,7 +148,7 @@ export class OneSnippet { // Special case #2: placeholders enclosing active placeholders const selections: Selection[] = []; for (const placeholder of this._placeholderGroups[this._placeholderGroupsIdx]) { - const id = this._placeholderDecorations.get(placeholder)!; + const id = this._placeholderDecorations!.get(placeholder)!; const range = this._editor.getModel().getDecorationRange(id)!; selections.push(new Selection(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn)); @@ -161,7 +161,7 @@ export class OneSnippet { activePlaceholders.add(placeholder); for (const enclosingPlaceholder of this._snippet.enclosingPlaceholders(placeholder)) { - const id = this._placeholderDecorations.get(enclosingPlaceholder)!; + const id = this._placeholderDecorations!.get(enclosingPlaceholder)!; accessor.changeDecorationOptions(id, enclosingPlaceholder.isFinalTabstop ? OneSnippet._decor.activeFinal : OneSnippet._decor.active); activePlaceholders.add(enclosingPlaceholder); } @@ -169,7 +169,7 @@ export class OneSnippet { // change stickness to never grow when typing at its edges // so that in-active tabstops never grow - this._placeholderDecorations.forEach((id, placeholder) => { + this._placeholderDecorations!.forEach((id, placeholder) => { if (!activePlaceholders.has(placeholder)) { accessor.changeDecorationOptions(id, placeholder.isFinalTabstop ? OneSnippet._decor.inactiveFinal : OneSnippet._decor.inactive); } @@ -188,7 +188,7 @@ export class OneSnippet { let marker: Marker | undefined = placeholder; while (marker) { if (marker instanceof Placeholder) { - const id = this._placeholderDecorations.get(marker)!; + const id = this._placeholderDecorations!.get(marker)!; const range = this._editor.getModel().getDecorationRange(id)!; if (range.isEmpty() && marker.toString().length > 0) { return true; @@ -227,7 +227,7 @@ export class OneSnippet { result.set(placeholder.index, ranges); } - const id = this._placeholderDecorations.get(placeholder)!; + const id = this._placeholderDecorations!.get(placeholder)!; const range = this._editor.getModel().getDecorationRange(id); if (!range) { // one of the placeholder lost its decoration and @@ -278,9 +278,9 @@ export class OneSnippet { // Remove the placeholder at which position are inserting // the snippet and also remove its decoration. - const id = this._placeholderDecorations.get(placeholder)!; + const id = this._placeholderDecorations!.get(placeholder)!; accessor.removeDecoration(id); - this._placeholderDecorations.delete(placeholder); + this._placeholderDecorations!.delete(placeholder); // For each *new* placeholder we create decoration to monitor // how and if it grows/shrinks. @@ -292,7 +292,7 @@ export class OneSnippet { model.getPositionAt(nested._offset + placeholderOffset + placeholderLen) ); const handle = accessor.addDecoration(range, OneSnippet._decor.inactive); - this._placeholderDecorations.set(placeholder, handle); + this._placeholderDecorations!.set(placeholder, handle); } } @@ -304,7 +304,7 @@ export class OneSnippet { public getEnclosingRange(): Range | undefined { let result: Range | undefined; const model = this._editor.getModel(); - this._placeholderDecorations.forEach((decorationId) => { + this._placeholderDecorations!.forEach((decorationId) => { const placeholderRange = withNullAsUndefined(model.getDecorationRange(decorationId)); if (!result) { result = placeholderRange; diff --git a/src/vs/editor/contrib/suggest/suggest.ts b/src/vs/editor/contrib/suggest/suggest.ts index 241a826a54c..d63e47c8811 100644 --- a/src/vs/editor/contrib/suggest/suggest.ts +++ b/src/vs/editor/contrib/suggest/suggest.ts @@ -27,7 +27,7 @@ export const Context = { export class CompletionItem { - _brand: 'ISuggestionItem'; + _brand!: 'ISuggestionItem'; readonly resolve: (token: CancellationToken) => Promise; diff --git a/src/vs/editor/contrib/suggest/suggestMemory.ts b/src/vs/editor/contrib/suggest/suggestMemory.ts index 7e19017b79e..f8997401fde 100644 --- a/src/vs/editor/contrib/suggest/suggestMemory.ts +++ b/src/vs/editor/contrib/suggest/suggestMemory.ts @@ -204,9 +204,9 @@ export class SuggestMemoryService extends Disposable implements ISuggestMemorySe private readonly _storagePrefix = 'suggest/memories'; private readonly _persistSoon: RunOnceScheduler; - private _mode: MemMode; - private _shareMem: boolean; - private _strategy: Memory; + private _mode!: MemMode; + private _shareMem!: boolean; + private _strategy!: Memory; constructor( @IStorageService private readonly _storageService: IStorageService, diff --git a/src/vs/editor/contrib/suggest/suggestModel.ts b/src/vs/editor/contrib/suggest/suggestModel.ts index 63de4055d7e..cabf449d896 100644 --- a/src/vs/editor/contrib/suggest/suggestModel.ts +++ b/src/vs/editor/contrib/suggest/suggestModel.ts @@ -92,8 +92,8 @@ export const enum State { export class SuggestModel implements IDisposable { private readonly _toDispose = new DisposableStore(); - private _quickSuggestDelay: number; - private _triggerCharacterListener: IDisposable; + private _quickSuggestDelay: number = 10; + private _triggerCharacterListener?: IDisposable; private readonly _triggerQuickSuggest = new TimeoutTimer(); private _state: State = State.Idle; @@ -161,7 +161,8 @@ export class SuggestModel implements IDisposable { } dispose(): void { - dispose([this._onDidCancel, this._onDidSuggest, this._onDidTrigger, this._triggerCharacterListener, this._triggerQuickSuggest]); + dispose(this._triggerCharacterListener); + dispose([this._onDidCancel, this._onDidSuggest, this._onDidTrigger, this._triggerQuickSuggest]); this._toDispose.dispose(); this._completionDisposables.dispose(); this.cancel(); diff --git a/src/vs/editor/contrib/suggest/suggestWidget.ts b/src/vs/editor/contrib/suggest/suggestWidget.ts index e6ac05dab25..f14ccafe115 100644 --- a/src/vs/editor/contrib/suggest/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/suggestWidget.ts @@ -253,7 +253,7 @@ class SuggestionDetails { private docs: HTMLElement; private ariaLabel: string | null; private readonly disposables: DisposableStore; - private renderDisposeable: IDisposable; + private renderDisposeable?: IDisposable; private borderWidth: number = 1; constructor( @@ -435,20 +435,20 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate | null; + private currentSuggestionDetails: CancelablePromise | null = null; private focusedItem: CompletionItem | null; - private ignoreFocusEvents = false; - private completionModel: CompletionModel | null; + private ignoreFocusEvents: boolean = false; + private completionModel: CompletionModel | null = null; private element: HTMLElement; private messageElement: HTMLElement; private listElement: HTMLElement; private details: SuggestionDetails; private list: List; - private listHeight: number; + private listHeight?: number; private readonly suggestWidgetVisible: IContextKey; private readonly suggestWidgetMultipleSuggestions: IContextKey; @@ -470,13 +470,13 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate { private readonly _subscriptions = new DisposableStore(); - private _isPressed: boolean; + private _isPressed: boolean = false; private static instance: AlternativeKeyEmitter; private _suppressAltKeyUp: boolean = false; @@ -137,7 +137,7 @@ export class MenuEntryActionViewItem extends ActionViewItem { static readonly ICON_PATH_TO_CSS_RULES: Map = new Map(); - private _wantsAltCommand: boolean; + private _wantsAltCommand: boolean = false; private readonly _itemClassDispose = this._register(new MutableDisposable()); private readonly _altKey: AlternativeKeyEmitter; diff --git a/src/vs/platform/actions/common/menuService.ts b/src/vs/platform/actions/common/menuService.ts index e0ee881b773..352a1ed945f 100644 --- a/src/vs/platform/actions/common/menuService.ts +++ b/src/vs/platform/actions/common/menuService.ts @@ -31,8 +31,8 @@ class Menu extends Disposable implements IMenu { private readonly _onDidChange = this._register(new Emitter()); - private _menuGroups: MenuItemGroup[]; - private _contextKeys: Set; + private _menuGroups!: MenuItemGroup[]; + private _contextKeys!: Set; constructor( private readonly _id: MenuId, diff --git a/src/vs/workbench/api/browser/mainThreadEditor.ts b/src/vs/workbench/api/browser/mainThreadEditor.ts index 669ff5063fa..ff8e1cd5138 100644 --- a/src/vs/workbench/api/browser/mainThreadEditor.ts +++ b/src/vs/workbench/api/browser/mainThreadEditor.ts @@ -178,7 +178,7 @@ export class MainThreadTextEditor { private readonly _focusTracker: IFocusTracker; private readonly _codeEditorListeners = new DisposableStore(); - private _properties: MainThreadTextEditorProperties; + private _properties: MainThreadTextEditorProperties | null; private readonly _onPropertiesChanged: Emitter; constructor( @@ -191,6 +191,7 @@ export class MainThreadTextEditor { this._id = id; this._model = model; this._codeEditor = null; + this._properties = null; this._focusTracker = focusTracker; this._modelService = modelService; @@ -289,7 +290,7 @@ export class MainThreadTextEditor { } public getProperties(): MainThreadTextEditorProperties { - return this._properties; + return this._properties!; } public get onPropertiesChanged(): Event { @@ -304,7 +305,7 @@ export class MainThreadTextEditor { const newSelections = selections.map(Selection.liftSelection); this._setProperties( - new MainThreadTextEditorProperties(newSelections, this._properties.options, this._properties.visibleRanges), + new MainThreadTextEditorProperties(newSelections, this._properties!.options, this._properties!.visibleRanges), null ); } From 629ef6a29575448799cd07d903221390be248566 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 5 Aug 2019 11:09:41 +0200 Subject: [PATCH 183/861] strict init, #78168 --- src/vs/base/common/actions.ts | 10 +++++----- .../editor/contrib/snippet/snippetParser.ts | 10 +++++----- .../snippet/test/snippetParser.test.ts | 2 +- .../editor/contrib/suggest/completionModel.ts | 20 ++++++++++--------- .../api/common/extHostApiCommands.ts | 10 +++++----- .../browser/callHierarchyPeek.ts | 16 +++++++-------- .../browser/callHierarchyTree.ts | 6 ++++-- .../electron-browser/extensionHost.ts | 1 + 8 files changed, 40 insertions(+), 35 deletions(-) diff --git a/src/vs/base/common/actions.ts b/src/vs/base/common/actions.ts index b0e1b6f161e..e6e769ea897 100644 --- a/src/vs/base/common/actions.ts +++ b/src/vs/base/common/actions.ts @@ -64,11 +64,11 @@ export class Action extends Disposable implements IAction { protected readonly _id: string; protected _label: string; - protected _tooltip: string; + protected _tooltip: string | undefined; protected _cssClass: string | undefined; - protected _enabled: boolean; - protected _checked: boolean; - protected _radio: boolean; + protected _enabled: boolean = true; + protected _checked: boolean = false; + protected _radio: boolean = false; protected readonly _actionCallback?: (event?: any) => Promise; constructor(id: string, label: string = '', cssClass: string = '', enabled: boolean = true, actionCallback?: (event?: any) => Promise) { @@ -100,7 +100,7 @@ export class Action extends Disposable implements IAction { } get tooltip(): string { - return this._tooltip; + return this._tooltip || ''; } set tooltip(value: string) { diff --git a/src/vs/editor/contrib/snippet/snippetParser.ts b/src/vs/editor/contrib/snippet/snippetParser.ts index 69b0f621302..c4b568d38fd 100644 --- a/src/vs/editor/contrib/snippet/snippetParser.ts +++ b/src/vs/editor/contrib/snippet/snippetParser.ts @@ -131,7 +131,7 @@ export abstract class Marker { readonly _markerBrand: any; - public parent: Marker; + public parent!: Marker; protected _children: Marker[] = []; appendChild(child: Marker): this { @@ -215,7 +215,7 @@ export class Text extends Marker { } export abstract class TransformableMarker extends Marker { - public transform: Transform; + public transform?: Transform; } export class Placeholder extends TransformableMarker { @@ -310,7 +310,7 @@ export class Choice extends Marker { export class Transform extends Marker { - regexp: RegExp; + regexp: RegExp = new RegExp(''); resolve(value: string): string { const _this = this; @@ -586,8 +586,8 @@ export class SnippetParser { return value.replace(/\$|}|\\/g, '\\$&'); } - private _scanner = new Scanner(); - private _token: Token; + private _scanner: Scanner = new Scanner(); + private _token: Token = { type: TokenType.EOF, pos: 0, len: 0 }; text(value: string): string { return this.parse(value).toString(); diff --git a/src/vs/editor/contrib/snippet/test/snippetParser.test.ts b/src/vs/editor/contrib/snippet/test/snippetParser.test.ts index 60bcebba8b0..165be28f1c7 100644 --- a/src/vs/editor/contrib/snippet/test/snippetParser.test.ts +++ b/src/vs/editor/contrib/snippet/test/snippetParser.test.ts @@ -418,7 +418,7 @@ suite('SnippetParser', () => { assert.ok(children[3] instanceof Placeholder); assert.equal(children[3].children.length, 0); assert.notEqual((children[3]).transform, undefined); - let transform = (children[3]).transform; + let transform = (children[3]).transform!; assert.equal(transform.regexp, '/\\s:=(.*)/'); assert.equal(transform.children.length, 2); assert.ok(transform.children[0] instanceof FormatString); diff --git a/src/vs/editor/contrib/suggest/completionModel.ts b/src/vs/editor/contrib/suggest/completionModel.ts index 29673ee6473..9a806ddf3de 100644 --- a/src/vs/editor/contrib/suggest/completionModel.ts +++ b/src/vs/editor/contrib/suggest/completionModel.ts @@ -29,8 +29,10 @@ export interface ICompletionStats { } export class LineContext { - leadingLineContent: string; - characterCountDelta: number; + constructor( + readonly leadingLineContent: string, + readonly characterCountDelta: number, + ) { } } const enum Refilter { @@ -49,9 +51,9 @@ export class CompletionModel { private _lineContext: LineContext; private _refilterKind: Refilter; - private _filteredItems: StrictCompletionItem[]; - private _isIncomplete: Set; - private _stats: ICompletionStats; + private _filteredItems?: StrictCompletionItem[]; + private _isIncomplete?: Set; + private _stats?: ICompletionStats; constructor( items: CompletionItem[], @@ -89,12 +91,12 @@ export class CompletionModel { get items(): CompletionItem[] { this._ensureCachedState(); - return this._filteredItems; + return this._filteredItems!; } get incomplete(): Set { this._ensureCachedState(); - return this._isIncomplete; + return this._isIncomplete!; } adopt(except: Set): CompletionItem[] { @@ -117,7 +119,7 @@ export class CompletionModel { get stats(): ICompletionStats { this._ensureCachedState(); - return this._stats; + return this._stats!; } private _ensureCachedState(): void { @@ -136,7 +138,7 @@ export class CompletionModel { let wordLow = ''; // incrementally filter less - const source = this._refilterKind === Refilter.All ? this._items : this._filteredItems; + const source = this._refilterKind === Refilter.All ? this._items : this._filteredItems!; const target: StrictCompletionItem[] = []; // picks a score function based on the number of diff --git a/src/vs/workbench/api/common/extHostApiCommands.ts b/src/vs/workbench/api/common/extHostApiCommands.ts index f6aa2e727a4..bafedf31454 100644 --- a/src/vs/workbench/api/common/extHostApiCommands.ts +++ b/src/vs/workbench/api/common/extHostApiCommands.ts @@ -470,11 +470,11 @@ export class ExtHostApiCommands { return res; } - detail: string; - range: vscode.Range; - selectionRange: vscode.Range; - children: vscode.DocumentSymbol[]; - containerName: string; + detail!: string; + range!: vscode.Range; + selectionRange!: vscode.Range; + children!: vscode.DocumentSymbol[]; + containerName!: string; } return value.map(MergedInfo.to); }); diff --git a/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyPeek.ts b/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyPeek.ts index 677ee37a697..3679e656809 100644 --- a/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyPeek.ts +++ b/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyPeek.ts @@ -91,15 +91,15 @@ class LayoutInfo { export class CallHierarchyTreePeekWidget extends PeekViewWidget { - private _changeDirectionAction: ChangeHierarchyDirectionAction; - private _parent: HTMLElement; - private _message: HTMLElement; - private _splitView: SplitView; - private _tree: WorkbenchAsyncDataTree; + private _changeDirectionAction?: ChangeHierarchyDirectionAction; + private _parent!: HTMLElement; + private _message!: HTMLElement; + private _splitView!: SplitView; + private _tree!: WorkbenchAsyncDataTree; private _treeViewStates = new Map(); - private _editor: EmbeddedCodeEditorWidget; - private _dim: Dimension; - private _layoutInfo: LayoutInfo; + private _editor!: EmbeddedCodeEditorWidget; + private _dim!: Dimension; + private _layoutInfo!: LayoutInfo; constructor( editor: ICodeEditor, diff --git a/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyTree.ts b/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyTree.ts index 5bc78e806fa..becdc2dc3ed 100644 --- a/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyTree.ts +++ b/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyTree.ts @@ -58,7 +58,9 @@ export class IdentityProvider implements IIdentityProvider { } class CallRenderingTemplate { - readonly iconLabel: IconLabel; + constructor( + readonly iconLabel: IconLabel + ) { } } export class CallRenderer implements ITreeRenderer { @@ -69,7 +71,7 @@ export class CallRenderer implements ITreeRenderer, _index: number, template: CallRenderingTemplate): void { diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index 8e923aea1cb..0ed2188509d 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -87,6 +87,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { this._terminating = false; this._namedPipeServer = null; + this._inspectPort = null; this._extensionHostProcess = null; this._extensionHostConnection = null; this._messageProtocol = null; From 8443b974734664d633137de8e1c50588c6efde39 Mon Sep 17 00:00:00 2001 From: Tony Xia Date: Mon, 5 Aug 2019 19:14:08 +1000 Subject: [PATCH 184/861] Fixed minor typos (#78042) --- test/smoke/src/areas/workbench/data-migration.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/smoke/src/areas/workbench/data-migration.test.ts b/test/smoke/src/areas/workbench/data-migration.test.ts index 55c2f74a362..3f6633c69c7 100644 --- a/test/smoke/src/areas/workbench/data-migration.test.ts +++ b/test/smoke/src/areas/workbench/data-migration.test.ts @@ -39,7 +39,7 @@ export function setup(stableCodePath: string, testDataPath: string) { insiderOptions.userDataDir = userDataDir; const insidersApp = new Application(insiderOptions); - await insidersApp!.start(false /* not expecting walkthrough parth */); + await insidersApp!.start(false /* not expecting walkthrough path */); // Verify 3 editors are open await insidersApp.workbench.editors.waitForEditorFocus('Untitled-1'); @@ -66,7 +66,7 @@ export function setup(stableCodePath: string, testDataPath: string) { await stableApp.workbench.editors.newUntitledFile(); const untitled = 'Untitled-1'; - const textToTypeInUntitled = 'Hello, Unitled Code'; + const textToTypeInUntitled = 'Hello, Untitled Code'; await stableApp.workbench.editor.waitForTypeInEditor(untitled, textToTypeInUntitled); const readmeMd = 'readme.md'; @@ -80,7 +80,7 @@ export function setup(stableCodePath: string, testDataPath: string) { insiderOptions.userDataDir = userDataDir; const insidersApp = new Application(insiderOptions); - await insidersApp!.start(false /* not expecting walkthrough parth */); + await insidersApp!.start(false /* not expecting walkthrough path */); await insidersApp.workbench.editors.waitForActiveTab(readmeMd, true); await insidersApp.workbench.editor.waitForEditorContents(readmeMd, c => c.indexOf(textToType) > -1); @@ -92,4 +92,4 @@ export function setup(stableCodePath: string, testDataPath: string) { await insidersApp.stop(); }); }); -} \ No newline at end of file +} From 154076b648328a41711bf2f35ccacf2c3f074794 Mon Sep 17 00:00:00 2001 From: qadram Date: Mon, 5 Aug 2019 11:16:48 +0200 Subject: [PATCH 185/861] #10027 confirmSave should check the goal of running an extension is actually to run tests (#78033) --- src/vs/platform/environment/common/environment.ts | 1 + src/vs/platform/environment/node/argv.ts | 1 + .../workbench/services/textfile/common/textFileService.ts | 6 ++++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index a6c9eb9d11c..3a53fd21524 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -38,6 +38,7 @@ export interface ParsedArgs { 'builtin-extensions-dir'?: string; extensionDevelopmentPath?: string | string[]; // one or more local paths or URIs extensionTestsPath?: string; // either a local path or a URI + 'extension-development-confirm-save'?: boolean; 'inspect-extensions'?: string; 'inspect-brk-extensions'?: string; debugId?: string; diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index a1d33c98577..ed9549be9c4 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -69,6 +69,7 @@ export const options: Option[] = [ { id: 'locate-extension', type: 'string' }, { id: 'extensionDevelopmentPath', type: 'string' }, { id: 'extensionTestsPath', type: 'string' }, + { id: 'extension-development-confirm-save', type: 'boolean' }, { id: 'debugId', type: 'string' }, { id: 'inspect-search', type: 'string', deprecates: 'debugSearch' }, { id: 'inspect-brk-search', type: 'string', deprecates: 'debugBrkSearch' }, diff --git a/src/vs/workbench/services/textfile/common/textFileService.ts b/src/vs/workbench/services/textfile/common/textFileService.ts index 33870009b83..905933d6b34 100644 --- a/src/vs/workbench/services/textfile/common/textFileService.ts +++ b/src/vs/workbench/services/textfile/common/textFileService.ts @@ -537,7 +537,9 @@ export abstract class TextFileService extends Disposable implements ITextFileSer async confirmSave(resources?: URI[]): Promise { if (this.environmentService.isExtensionDevelopment) { - return ConfirmResult.DONT_SAVE; // no veto when we are in extension dev mode because we cannot assume we run interactive (e.g. tests) + if (!this.environmentService.args['extension-development-confirm-save']) { + return ConfirmResult.DONT_SAVE; // no veto when we are in extension dev mode because we cannot assume we run interactive (e.g. tests) + } } const resourcesToConfirm = this.getDirty(resources); @@ -1027,4 +1029,4 @@ export abstract class TextFileService extends Disposable implements ITextFileSer super.dispose(); } -} \ No newline at end of file +} From 93af1ad14dffefa1bc05175757be37a2b516599a Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 5 Aug 2019 11:47:07 +0200 Subject: [PATCH 186/861] Add group to configure task This will help prevent confusion Fixes #78396 --- .vscode/tasks.json | 5 +++-- .../workbench/contrib/tasks/browser/abstractTaskService.ts | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 89aba8e5fe0..5db8fb3fbc5 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -81,6 +81,7 @@ "type": "gulp", "task": "hygiene", "problemMatcher": [] - } + }, + ] -} \ No newline at end of file +} diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 1dad734a227..8b120c0a125 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -796,6 +796,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (task.configurationProperties.problemMatchers && task.configurationProperties.problemMatchers.length > 0 && Types.isStringArray(task.configurationProperties.problemMatchers)) { toCustomize.problemMatcher = task.configurationProperties.problemMatchers; } + if (task.configurationProperties.group) { + toCustomize.group = task.configurationProperties.group; + } } if (!toCustomize) { return Promise.resolve(undefined); From da3b599b789697b3813f36fac8f3ec55510f86e2 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 5 Aug 2019 12:04:01 +0200 Subject: [PATCH 187/861] grid - do not use onBeforeShutdown for saving state --- src/vs/workbench/browser/layout.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index a213ed7b024..54c94f6cdce 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -791,15 +791,11 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi this.setEditorHidden(!visible, true); })); - this._register(this.lifecycleService.onBeforeShutdown(beforeShutdownEvent => { - beforeShutdownEvent.veto(new Promise((resolve) => { - const grid = this.workbenchGrid as SerializableGrid; - const serializedGrid = grid.serialize(); + this._register(this.storageService.onWillSaveState(() => { + const grid = this.workbenchGrid as SerializableGrid; + const serializedGrid = grid.serialize(); - this.storageService.store(Storage.GRID_LAYOUT, JSON.stringify(serializedGrid), StorageScope.GLOBAL); - - resolve(); - })); + this.storageService.store(Storage.GRID_LAYOUT, JSON.stringify(serializedGrid), StorageScope.GLOBAL); })); } else { this.workbenchGrid = instantiationService.createInstance( From 63526965e223417fa872c5cbd61e3aeb4ae93648 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 5 Aug 2019 12:04:22 +0200 Subject: [PATCH 188/861] strict init, #78168 --- src/vs/base/common/map.ts | 10 +++++----- .../contrib/codelens/codelensController.ts | 2 +- src/vs/editor/contrib/codelens/codelensWidget.ts | 6 +++--- .../editor/contrib/gotoError/gotoErrorWidget.ts | 10 +++++----- .../browser/parts/editor/breadcrumbsPicker.ts | 8 ++++---- .../contrib/outline/browser/outlinePanel.ts | 16 ++++++++-------- 6 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/vs/base/common/map.ts b/src/vs/base/common/map.ts index 39ec64381aa..f1cce9af4ce 100644 --- a/src/vs/base/common/map.ts +++ b/src/vs/base/common/map.ts @@ -112,9 +112,9 @@ export class StringIterator implements IKeyIterator { export class PathIterator implements IKeyIterator { - private _value: string; - private _from: number; - private _to: number; + private _value!: string; + private _from!: number; + private _to!: number; reset(key: string): this { this._value = key.replace(/\\$|\/$/, ''); @@ -176,9 +176,9 @@ export class PathIterator implements IKeyIterator { } class TernarySearchTreeNode { - segment: string; + segment!: string; value: E | undefined; - key: string; + key!: string; left: TernarySearchTreeNode | undefined; mid: TernarySearchTreeNode | undefined; right: TernarySearchTreeNode | undefined; diff --git a/src/vs/editor/contrib/codelens/codelensController.ts b/src/vs/editor/contrib/codelens/codelensController.ts index 9f36b691705..1aed8453777 100644 --- a/src/vs/editor/contrib/codelens/codelensController.ts +++ b/src/vs/editor/contrib/codelens/codelensController.ts @@ -32,7 +32,7 @@ export class CodeLensContribution implements editorCommon.IEditorContribution { private _currentCodeLensModel: CodeLensModel | undefined; private _modelChangeCounter: number = 0; private _currentResolveCodeLensSymbolsPromise: CancelablePromise | undefined; - private _detectVisibleLenses: RunOnceScheduler; + private _detectVisibleLenses!: RunOnceScheduler; constructor( private readonly _editor: editorBrowser.ICodeEditor, diff --git a/src/vs/editor/contrib/codelens/codelensWidget.ts b/src/vs/editor/contrib/codelens/codelensWidget.ts index 2f34263e0fd..cb41dc9f459 100644 --- a/src/vs/editor/contrib/codelens/codelensWidget.ts +++ b/src/vs/editor/contrib/codelens/codelensWidget.ts @@ -192,9 +192,9 @@ export class CodeLensHelper { export class CodeLensWidget { private readonly _editor: editorBrowser.ICodeEditor; - private readonly _viewZone: CodeLensViewZone; - private readonly _viewZoneId: number; - private readonly _contentWidget: CodeLensContentWidget; + private readonly _viewZone!: CodeLensViewZone; + private readonly _viewZoneId!: number; + private readonly _contentWidget!: CodeLensContentWidget; private _decorationIds: string[]; private _data: CodeLensItem[]; diff --git a/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts b/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts index 7d93dc2fb37..89f2f75d243 100644 --- a/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts +++ b/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts @@ -165,15 +165,15 @@ class MessageWidget { export class MarkerNavigationWidget extends PeekViewWidget { - private _parentContainer: HTMLElement; - private _container: HTMLElement; - private _icon: HTMLElement; - private _message: MessageWidget; + private _parentContainer!: HTMLElement; + private _container!: HTMLElement; + private _icon!: HTMLElement; + private _message!: MessageWidget; private readonly _callOnDispose = new DisposableStore(); private _severity: MarkerSeverity; private _backgroundColor?: Color; private _onDidSelectRelatedInformation = new Emitter(); - private _heightInPixel: number; + private _heightInPixel!: number; readonly onDidSelectRelatedInformation: Event = this._onDidSelectRelatedInformation.event; diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts index 42ca9e2d502..16a20027c9e 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts @@ -56,11 +56,11 @@ export abstract class BreadcrumbsPicker { protected readonly _disposables = new DisposableStore(); protected readonly _domNode: HTMLDivElement; - protected _arrow: HTMLDivElement; - protected _treeContainer: HTMLDivElement; - protected _tree: Tree; + protected _arrow!: HTMLDivElement; + protected _treeContainer!: HTMLDivElement; + protected _tree!: Tree; protected _fakeEvent = new UIEvent('fakeEvent'); - protected _layoutInfo: ILayoutInfo; + protected _layoutInfo!: ILayoutInfo; private readonly _onDidPickElement = new Emitter(); readonly onDidPickElement: Event = this._onDidPickElement.event; diff --git a/src/vs/workbench/contrib/outline/browser/outlinePanel.ts b/src/vs/workbench/contrib/outline/browser/outlinePanel.ts index fd070d880eb..00152554349 100644 --- a/src/vs/workbench/contrib/outline/browser/outlinePanel.ts +++ b/src/vs/workbench/contrib/outline/browser/outlinePanel.ts @@ -238,14 +238,14 @@ export class OutlinePanel extends ViewletPanel { private _editorDisposables = new DisposableStore(); private _outlineViewState = new OutlineViewState(); private _requestOracle?: RequestOracle; - private _domNode: HTMLElement; - private _message: HTMLDivElement; - private _inputContainer: HTMLDivElement; - private _progressBar: ProgressBar; - private _tree: WorkbenchDataTree; - private _treeDataSource: OutlineDataSource; - private _treeRenderer: OutlineElementRenderer; - private _treeComparator: OutlineItemComparator; + private _domNode!: HTMLElement; + private _message!: HTMLDivElement; + private _inputContainer!: HTMLDivElement; + private _progressBar!: ProgressBar; + private _tree!: WorkbenchDataTree; + private _treeDataSource!: OutlineDataSource; + private _treeRenderer!: OutlineElementRenderer; + private _treeComparator!: OutlineItemComparator; private _treeStates = new LRUCache(10); private _treeFakeUIEvent = new UIEvent('me'); From edf34d39310bfa97c2bdb73d62727d3746ca15d8 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 5 Aug 2019 12:44:23 +0200 Subject: [PATCH 189/861] Update grammars --- extensions/cpp/cgmanifest.json | 4 +- extensions/cpp/syntaxes/c.tmLanguage.json | 90 +- extensions/cpp/syntaxes/cpp.tmLanguage.json | 4478 ++++++++++++----- extensions/fsharp/cgmanifest.json | 2 +- .../fsharp/syntaxes/fsharp.tmLanguage.json | 61 +- .../syntaxes/JavaScript.tmLanguage.json | 30 +- .../syntaxes/JavaScriptReact.tmLanguage.json | 30 +- .../syntaxes/markdown.tmLanguage.json | 2 +- extensions/perl/cgmanifest.json | 2 +- extensions/powershell/cgmanifest.json | 8 +- .../syntaxes/powershell.tmLanguage.json | 6 +- extensions/ruby/cgmanifest.json | 2 +- extensions/ruby/syntaxes/ruby.tmLanguage.json | 50 +- .../swift/syntaxes/swift.tmLanguage.json | 69 +- extensions/typescript-basics/cgmanifest.json | 2 +- .../syntaxes/TypeScript.tmLanguage.json | 30 +- .../syntaxes/TypeScriptReact.tmLanguage.json | 30 +- 17 files changed, 3421 insertions(+), 1475 deletions(-) diff --git a/extensions/cpp/cgmanifest.json b/extensions/cpp/cgmanifest.json index 6716fa1a223..768ca68ecbc 100644 --- a/extensions/cpp/cgmanifest.json +++ b/extensions/cpp/cgmanifest.json @@ -6,11 +6,11 @@ "git": { "name": "jeff-hykin/cpp-textmate-grammar", "repositoryUrl": "https://github.com/jeff-hykin/cpp-textmate-grammar", - "commitHash": "992c5ba8789288707f2a13778452d644677d9699" + "commitHash": "cbd71f90cd9be0f99ddc9b0f65cec62fc3ada6d1" } }, "license": "MIT", - "version": "1.12.18", + "version": "1.12.21", "description": "The files syntaxes/c.json and syntaxes/c++.json were derived from https://github.com/atom/language-c which was originally converted from the C TextMate bundle https://github.com/textmate/c.tmbundle." }, { diff --git a/extensions/cpp/syntaxes/c.tmLanguage.json b/extensions/cpp/syntaxes/c.tmLanguage.json index 91be1a66bdf..1a95c101984 100644 --- a/extensions/cpp/syntaxes/c.tmLanguage.json +++ b/extensions/cpp/syntaxes/c.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/jeff-hykin/cpp-textmate-grammar/commit/1a24b4aa383169919f0d92cf2735ac35a3e7db3c", + "version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/5209e7f9df7661db6f163753141eeb3de6fb02b3", "name": "C", "scopeName": "source.c", "patterns": [ @@ -67,32 +67,71 @@ "include": "#strings" }, { - "begin": "(?x)\n^\\s* ((\\#)\\s*define) \\s+\t# define\n((?[a-zA-Z_$][\\w$]*))\t # macro name\n(?:\n (\\()\n\t(\n\t \\s* \\g \\s*\t\t # first argument\n\t ((,) \\s* \\g \\s*)* # additional arguments\n\t (?:\\.\\.\\.)?\t\t\t# varargs ellipsis?\n\t)\n (\\))\n)?", + "name": "meta.preprocessor.macro.c", + "begin": "((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((#)\\s*define\\b)\\s+((?(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/))", + "captures": { + "1": { + "name": "comment.block.c punctuation.definition.comment.begin.c" + }, + "2": { + "name": "comment.block.c" + }, + "3": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.c punctuation.definition.comment.end.c" + }, + { + "match": "\\*", + "name": "comment.block.c" + } + ] + } + } + }, "default_statement": { "name": "meta.conditional.case.c", "begin": "((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?]*|[^>]*+<[^>]*+>)++>\\s*", + "match": "((?(?:(?>[^<>]*)\\g<1>?)+)>)\\s*", "captures": { "0": { "name": "meta.template.call.cpp", @@ -2078,7 +2091,7 @@ "name": "storage.type.template.cpp" }, "9": { - "name": "ellipses.cpp punctuation.vararg-ellipses.template.definition.cpp" + "name": "punctuation.vararg-ellipses.template.definition.cpp" }, "10": { "name": "entity.name.type.template.cpp" @@ -2089,7 +2102,7 @@ } }, "scope_resolution": { - "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+", + "match": "(::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -2097,11 +2110,22 @@ "include": "#scope_resolution_inner_generated" } ] + }, + "1": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" + }, + "3": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] } } }, "scope_resolution_inner_generated": { - "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::)", + "match": "((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -2111,9 +2135,9 @@ ] }, "2": { - "name": "entity.name.scope-resolution.cpp" + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" }, - "3": { + "4": { "name": "meta.template.call.cpp", "patterns": [ { @@ -2121,13 +2145,24 @@ } ] }, - "4": { + "6": { + "name": "entity.name.scope-resolution.cpp" + }, + "7": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "9": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.cpp" } } }, "scope_resolution_template_call": { - "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+", + "match": "(::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -2135,11 +2170,22 @@ "include": "#scope_resolution_template_call_inner_generated" } ] + }, + "1": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.template.call.cpp" + }, + "3": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] } } }, "scope_resolution_template_call_inner_generated": { - "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::)", + "match": "((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -2149,9 +2195,9 @@ ] }, "2": { - "name": "entity.name.scope-resolution.template.call.cpp" + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.template.call.cpp" }, - "3": { + "4": { "name": "meta.template.call.cpp", "patterns": [ { @@ -2159,13 +2205,24 @@ } ] }, - "4": { + "6": { + "name": "entity.name.scope-resolution.template.call.cpp" + }, + "7": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "9": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.template.call.cpp" } } }, "scope_resolution_template_definition": { - "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+", + "match": "(::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -2173,11 +2230,22 @@ "include": "#scope_resolution_template_definition_inner_generated" } ] + }, + "1": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.template.definition.cpp" + }, + "3": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] } } }, "scope_resolution_template_definition_inner_generated": { - "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::)", + "match": "((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -2187,9 +2255,9 @@ ] }, "2": { - "name": "entity.name.scope-resolution.template.definition.cpp" + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.template.definition.cpp" }, - "3": { + "4": { "name": "meta.template.call.cpp", "patterns": [ { @@ -2197,13 +2265,24 @@ } ] }, - "4": { + "6": { + "name": "entity.name.scope-resolution.template.definition.cpp" + }, + "7": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "9": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.template.definition.cpp" } } }, "scope_resolution_function_call": { - "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+", + "match": "(::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -2211,11 +2290,22 @@ "include": "#scope_resolution_function_call_inner_generated" } ] + }, + "1": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.call.cpp" + }, + "3": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] } } }, "scope_resolution_function_call_inner_generated": { - "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::)", + "match": "((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -2225,9 +2315,9 @@ ] }, "2": { - "name": "entity.name.scope-resolution.function.call.cpp" + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.call.cpp" }, - "3": { + "4": { "name": "meta.template.call.cpp", "patterns": [ { @@ -2235,13 +2325,24 @@ } ] }, - "4": { + "6": { + "name": "entity.name.scope-resolution.function.call.cpp" + }, + "7": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "9": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.call.cpp" } } }, "scope_resolution_function_definition": { - "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+", + "match": "(::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -2249,11 +2350,22 @@ "include": "#scope_resolution_function_definition_inner_generated" } ] + }, + "1": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.definition.cpp" + }, + "3": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] } } }, "scope_resolution_function_definition_inner_generated": { - "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::)", + "match": "((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -2263,9 +2375,9 @@ ] }, "2": { - "name": "entity.name.scope-resolution.function.definition.cpp" + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.definition.cpp" }, - "3": { + "4": { "name": "meta.template.call.cpp", "patterns": [ { @@ -2273,13 +2385,24 @@ } ] }, - "4": { + "6": { + "name": "entity.name.scope-resolution.function.definition.cpp" + }, + "7": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "9": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.definition.cpp" } } }, "scope_resolution_namespace_alias": { - "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+", + "match": "(::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -2287,11 +2410,22 @@ "include": "#scope_resolution_namespace_alias_inner_generated" } ] + }, + "1": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.namespace.alias.cpp" + }, + "3": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] } } }, "scope_resolution_namespace_alias_inner_generated": { - "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::)", + "match": "((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -2301,9 +2435,9 @@ ] }, "2": { - "name": "entity.name.scope-resolution.namespace.alias.cpp" + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.namespace.alias.cpp" }, - "3": { + "4": { "name": "meta.template.call.cpp", "patterns": [ { @@ -2311,13 +2445,24 @@ } ] }, - "4": { + "6": { + "name": "entity.name.scope-resolution.namespace.alias.cpp" + }, + "7": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "9": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.namespace.alias.cpp" } } }, "scope_resolution_namespace_using": { - "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+", + "match": "(::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -2325,11 +2470,22 @@ "include": "#scope_resolution_namespace_using_inner_generated" } ] + }, + "1": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.namespace.using.cpp" + }, + "3": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] } } }, "scope_resolution_namespace_using_inner_generated": { - "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::)", + "match": "((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -2339,9 +2495,9 @@ ] }, "2": { - "name": "entity.name.scope-resolution.namespace.using.cpp" + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.namespace.using.cpp" }, - "3": { + "4": { "name": "meta.template.call.cpp", "patterns": [ { @@ -2349,13 +2505,24 @@ } ] }, - "4": { + "6": { + "name": "entity.name.scope-resolution.namespace.using.cpp" + }, + "7": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "9": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.namespace.using.cpp" } } }, "scope_resolution_namespace_block": { - "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+", + "match": "(::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -2363,11 +2530,22 @@ "include": "#scope_resolution_namespace_block_inner_generated" } ] + }, + "1": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.namespace.block.cpp" + }, + "3": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] } } }, "scope_resolution_namespace_block_inner_generated": { - "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::)", + "match": "((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -2377,9 +2555,9 @@ ] }, "2": { - "name": "entity.name.scope-resolution.namespace.block.cpp" + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.namespace.block.cpp" }, - "3": { + "4": { "name": "meta.template.call.cpp", "patterns": [ { @@ -2387,13 +2565,24 @@ } ] }, - "4": { + "6": { + "name": "entity.name.scope-resolution.namespace.block.cpp" + }, + "7": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "9": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.namespace.block.cpp" } } }, "scope_resolution_parameter": { - "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+", + "match": "(::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -2401,11 +2590,22 @@ "include": "#scope_resolution_parameter_inner_generated" } ] + }, + "1": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.parameter.cpp" + }, + "3": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] } } }, "scope_resolution_parameter_inner_generated": { - "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::)", + "match": "((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -2415,8 +2615,45 @@ ] }, "2": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.parameter.cpp" + }, + "4": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "6": { "name": "entity.name.scope-resolution.parameter.cpp" }, + "7": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "9": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.parameter.cpp" + } + } + }, + "scope_resolution_function_definition_operator_overload": { + "match": "(::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", + "captures": { + "0": { + "patterns": [ + { + "include": "#scope_resolution_function_definition_operator_overload_inner_generated" + } + ] + }, + "1": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.definition.operator-overload.cpp" + }, "3": { "name": "meta.template.call.cpp", "patterns": [ @@ -2424,26 +2661,11 @@ "include": "#template_call_range" } ] - }, - "4": { - "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.parameter.cpp" - } - } - }, - "scope_resolution_function_definition_operator_overload": { - "match": "(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+", - "captures": { - "0": { - "patterns": [ - { - "include": "#scope_resolution_function_definition_operator_overload_inner_generated" - } - ] } } }, "scope_resolution_function_definition_operator_overload_inner_generated": { - "match": "((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::)", + "match": "((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -2453,9 +2675,9 @@ ] }, "2": { - "name": "entity.name.scope-resolution.function.definition.operator-overload.cpp" + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.definition.operator-overload.cpp" }, - "3": { + "4": { "name": "meta.template.call.cpp", "patterns": [ { @@ -2463,19 +2685,30 @@ } ] }, - "4": { + "6": { + "name": "entity.name.scope-resolution.function.definition.operator-overload.cpp" + }, + "7": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "9": { "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.definition.operator-overload.cpp" } } }, "qualified_type": { - "match": "\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])", + "match": "\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<26>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<26>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<26>?)+)>)\\s*)?(?![\\w<:.])", "captures": { "0": { "name": "meta.qualified_type.cpp", "patterns": [ { - "match": "(?:class|struct|union|enum)", + "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?", + "match": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?", "captures": { "1": { "name": "meta.qualified_type.cpp", "patterns": [ { - "match": "(?:class|struct|union|enum)", + "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))\\s*(\\=)\\s*((?:typename)?)\\s*((?:(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))|(.*(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:(\\[)(\\w*)(\\])\\s*)?\\s*(?:(;)|\\n)", + "match": "(using)\\s*(?!namespace)(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<58>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<58>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<58>?)+)>)\\s*)?(?![\\w<:.]))\\s*(\\=)\\s*((?:typename)?)\\s*((?:(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<58>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<58>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<58>?)+)>)\\s*)?(?![\\w<:.]))|(.*(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:(\\[)(\\w*)(\\])\\s*)?\\s*(?:(;)|\\n)", "captures": { "1": { "name": "keyword.other.using.directive.cpp" @@ -2873,7 +3144,7 @@ "name": "meta.qualified_type.cpp", "patterns": [ { - "match": "(?:class|struct|union|enum)", + "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))", + "match": "(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<36>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<36>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<36>?)+)>)\\s*)?(?![\\w<:.]))", "captures": { "1": { "name": "storage.modifier.cpp" @@ -3379,7 +3688,7 @@ "name": "meta.qualified_type.cpp", "patterns": [ { - "match": "(?:class|struct|union|enum)", + "match": "(?))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\())", + "begin": "((?:(?:^|\\G|(?<=;|\\}))|(?<=>))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<69>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<69>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<69>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<69>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\())", "beginCaptures": { "1": { "name": "meta.head.function.definition.cpp" @@ -4635,7 +4963,7 @@ "name": "meta.qualified_type.cpp", "patterns": [ { - "match": "(?:class|struct|union|enum)", + "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*)(operator)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*)(?:(?:((?:\\+\\+|\\-\\-|\\(\\)|\\[\\]|\\->|\\+\\+|\\-\\-|\\+|\\-|!|~|\\*|&|new|new\\[\\]|delete|delete\\[\\]|\\->\\*|\\*|\\/|%|\\+|\\-|<<|>>|<=>|<|<=|>|>=|==|!=|&|\\^|\\||&&|\\|\\||=|\\+=|\\-=|\\*=|\\/=|%=|<<=|>>=|&=|\\^=|\\|=|,))|((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:\\[\\])?)))|(\"\")((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\<|\\())", + "begin": "((?:(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<67>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<67>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<67>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<67>?)+)>)\\s*)?::)*)(operator)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<67>?)+)>)\\s*)?::)*)(?:(?:((?:\\+\\+|\\-\\-|\\(\\)|\\[\\]|\\->|\\+\\+|\\-\\-|\\+|\\-|!|~|\\*|&|new|new\\[\\]|delete|delete\\[\\]|\\->\\*|\\*|\\/|%|\\+|\\-|<<|>>|<=>|<|<=|>|>=|==|!=|&|\\^|\\||&&|\\|\\||=|\\+=|\\-=|\\*=|\\/=|%=|<<=|>>=|&=|\\^=|\\|=|,))|((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:\\[\\])?)))|(\"\")((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\<|\\())", "beginCaptures": { "1": { "name": "meta.head.function.definition.special.operator-overload.cpp" @@ -5071,7 +5432,7 @@ "name": "meta.qualified_type.cpp", "patterns": [ { - "match": "(?:class|struct|union|enum)", + "match": "(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?]*|[^>]*+<[^>]*+>)++>\\s*)?(\\()", + "begin": "((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<12>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(((?(?:(?>[^<>]*)\\g<12>?)+)>)\\s*)?(\\()", "beginCaptures": { "1": { "patterns": [ @@ -5825,22 +6224,33 @@ ] }, "2": { + "name": "punctuation.separator.namespace.access.cpp punctuation.separator.scope-resolution.function.call.cpp" + }, + "4": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "6": { "name": "entity.name.function.call.cpp" }, - "3": { + "7": { "patterns": [ { "include": "#inline_comment" } ] }, - "4": { + "8": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, - "5": { + "9": { "name": "comment.block.cpp" }, - "6": { + "10": { "patterns": [ { "match": "\\*\\/", @@ -5852,7 +6262,7 @@ } ] }, - "7": { + "11": { "name": "meta.template.call.cpp", "patterns": [ { @@ -5860,7 +6270,7 @@ } ] }, - "8": { + "13": { "name": "punctuation.section.arguments.begin.bracket.round.function.call.cpp" } }, @@ -5878,13 +6288,13 @@ }, "curly_initializer": { "name": "meta.initialization.cpp", - "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\{)", + "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\{)", "beginCaptures": { "1": { "name": "meta.qualified_type.cpp", "patterns": [ { - "match": "(?:class|struct|union|enum)", + "match": "(?(?:(?>[^<>]*)\\g<3>?)+)>)\\s*)?(\\()", "beginCaptures": { "1": { "name": "entity.name.function.call.initializer.cpp" }, "2": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "4": { "name": "punctuation.section.arguments.begin.bracket.round.function.call.initializer.cpp" } }, @@ -6460,6 +6900,9 @@ } }, "patterns": [ + { + "include": "#ever_present_context" + }, { "include": "#evaluation_context" } @@ -6483,6 +6926,9 @@ } }, "patterns": [ + { + "include": "#ever_present_context" + }, { "include": "#evaluation_context" } @@ -6517,7 +6963,7 @@ ] }, { - "include": "$base" + "include": "$self" } ] }, @@ -6542,7 +6988,7 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "include": "$base" + "include": "$self" } ] } @@ -6550,7 +6996,7 @@ }, "constructor_root": { "name": "meta.function.definition.special.constructor.cpp", - "begin": "(\\s*+((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*)(((?>(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))::((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\13((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\()))", + "begin": "(\\s*+((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<14>?)+)>)\\s*)?::)*)(((?>(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))::((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\16((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\()))", "beginCaptures": { "1": { "name": "meta.head.function.definition.special.constructor.cpp" @@ -6623,7 +7069,15 @@ } ] }, - "12": { + "13": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "15": { "patterns": [ { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?=:)", @@ -6639,45 +7093,20 @@ } ] }, - "14": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "15": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "16": { - "name": "comment.block.cpp" - }, "17": { "patterns": [ { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" + "include": "#inline_comment" } ] }, "18": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "19": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, - "20": { + "19": { "name": "comment.block.cpp" }, - "21": { + "20": { "patterns": [ { "match": "\\*\\/", @@ -6689,20 +7118,45 @@ } ] }, - "22": { + "21": { "patterns": [ { "include": "#inline_comment" } ] }, - "23": { + "22": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, - "24": { + "23": { "name": "comment.block.cpp" }, + "24": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, "25": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "26": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "27": { + "name": "comment.block.cpp" + }, + "28": { "patterns": [ { "match": "\\*\\/", @@ -6785,14 +7239,25 @@ }, "end": "(?=\\{)", "patterns": [ + { + "include": "#ever_present_context" + }, { "contentName": "meta.parameter.initialization.cpp", - "begin": "((?(?:(?>[^<>]*)\\g<3>?)+)>)\\s*)?(\\()", "beginCaptures": { "1": { "name": "entity.name.function.call.initializer.cpp" }, "2": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "4": { "name": "punctuation.section.arguments.begin.bracket.round.function.call.initializer.cpp" } }, @@ -6803,6 +7268,9 @@ } }, "patterns": [ + { + "include": "#ever_present_context" + }, { "include": "#evaluation_context" } @@ -6826,6 +7294,9 @@ } }, "patterns": [ + { + "include": "#ever_present_context" + }, { "include": "#evaluation_context" } @@ -6860,7 +7331,7 @@ ] }, { - "include": "$base" + "include": "$self" } ] }, @@ -6885,7 +7356,7 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "include": "$base" + "include": "$self" } ] } @@ -7086,7 +7557,7 @@ } }, { - "include": "$base" + "include": "$self" } ] }, @@ -7111,7 +7582,7 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "include": "$base" + "include": "$self" } ] } @@ -7119,7 +7590,7 @@ }, "destructor_root": { "name": "meta.function.definition.special.member.destructor.cpp", - "begin": "(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*)(((?>(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))::((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))~\\13((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\()))", + "begin": "(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<14>?)+)>)\\s*)?::)*)(((?>(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))::((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))~\\16((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\()))", "beginCaptures": { "1": { "name": "meta.head.function.definition.special.member.destructor.cpp" @@ -7192,7 +7663,15 @@ } ] }, - "12": { + "13": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "15": { "patterns": [ { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?=:)", @@ -7208,45 +7687,20 @@ } ] }, - "14": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "15": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "16": { - "name": "comment.block.cpp" - }, "17": { "patterns": [ { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" + "include": "#inline_comment" } ] }, "18": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "19": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, - "20": { + "19": { "name": "comment.block.cpp" }, - "21": { + "20": { "patterns": [ { "match": "\\*\\/", @@ -7258,20 +7712,45 @@ } ] }, - "22": { + "21": { "patterns": [ { "include": "#inline_comment" } ] }, - "23": { + "22": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, - "24": { + "23": { "name": "comment.block.cpp" }, + "24": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, "25": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "26": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "27": { + "name": "comment.block.cpp" + }, + "28": { "patterns": [ { "match": "\\*\\/", @@ -7358,7 +7837,7 @@ } }, { - "include": "$base" + "include": "$self" } ] }, @@ -7383,7 +7862,7 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "include": "$base" + "include": "$self" } ] } @@ -7757,15 +8236,15 @@ { "include": "#builtin_storage_type_initilizer" }, + { + "include": "#storage_types" + }, { "include": "#qualifiers_and_specifiers_post_parameters" }, { "include": "#functional_specifiers_pre_parameters" }, - { - "include": "#storage_types" - }, { "include": "#misc_storage_modifiers" }, @@ -7799,13 +8278,13 @@ ] }, "function_pointer": { - "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()(\\*)\\s*((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)\\s*(?:(\\[)(\\w*)(\\])\\s*)*(\\))\\s*(\\()", + "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()(\\*)\\s*((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)\\s*(?:(\\[)(\\w*)(\\])\\s*)*(\\))\\s*(\\()", "beginCaptures": { "1": { "name": "meta.qualified_type.cpp", "patterns": [ { - "match": "(?:class|struct|union|enum)", + "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()(\\*)\\s*((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)\\s*(?:(\\[)(\\w*)(\\])\\s*)*(\\))\\s*(\\()", + "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()(\\*)\\s*((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)\\s*(?:(\\[)(\\w*)(\\])\\s*)*(\\))\\s*(\\()", "beginCaptures": { "1": { "name": "meta.qualified_type.cpp", "patterns": [ { - "match": "(?:class|struct|union|enum)", + "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()(\\*)\\s*((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)\\s*(?:(\\[)(\\w*)(\\])\\s*)*(\\))\\s*(\\()", + "beginCaptures": { + "1": { + "name": "meta.qualified_type.cpp", + "patterns": [ + { + "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "29": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "30": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "31": { + "name": "comment.block.cpp" + }, + "32": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "33": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "34": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "35": { + "name": "comment.block.cpp" + }, + "36": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "37": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "38": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "39": { + "name": "comment.block.cpp" + }, + "40": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "41": { + "name": "punctuation.section.parens.begin.bracket.round.function.pointer.cpp" + }, + "42": { + "name": "punctuation.definition.function.pointer.dereference.cpp" + }, + "43": { + "name": "entity.name.type.alias.cpp entity.name.type.pointer.function.cpp" + }, + "44": { + "name": "punctuation.definition.begin.bracket.square.cpp" + }, + "45": { + "patterns": [ + { + "include": "#evaluation_context" + } + ] + }, + "46": { + "name": "punctuation.definition.end.bracket.square.cpp" + }, + "47": { + "name": "punctuation.section.parens.end.bracket.round.function.pointer.cpp" + }, + "48": { + "name": "punctuation.section.parameters.begin.bracket.round.function.pointer.cpp" + } + }, + "end": "(\\))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=[{=,);]|\\n)(?!\\()", + "endCaptures": { + "1": { + "name": "punctuation.section.parameters.end.bracket.round.function.pointer.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "patterns": [ + { + "include": "#function_parameter_context" + } + ] + } + ] + }, "parameter_or_maybe_value": { "name": "meta.parameter.cpp", "begin": "((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\w)", @@ -8504,6 +9384,9 @@ { "include": "#ever_present_context" }, + { + "include": "#function_pointer_parameter" + }, { "include": "#memory_operators" }, @@ -8513,9 +9396,6 @@ { "include": "#curly_initializer" }, - { - "include": "#function_pointer_parameter" - }, { "include": "#decltype" }, @@ -9758,7 +10638,7 @@ }, "using_namespace": { "name": "meta.using-namespace.cpp", - "begin": "(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)?((?(?:(?>[^<>]*)\\g<7>?)+)>)\\s*)?::)*\\s*+)?((?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)\\s*((?(?:(?>[^<>]*)\\g<9>?)+)>)\\s*)?::)*\\s*+)\\s*((?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)\\s*((?(?:(?>[^<>]*)\\g<5>?)+)>)\\s*)?::)*\\s*+)\\s*((?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?\\s*((?(?:(?>[^<>]*)\\g<15>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<15>?)+)>)\\s*)?(::))?\\s*((?|\\?\\?>)\\s*(;)|(;))|(?=[;>\\[\\]=]))", @@ -10131,7 +11055,7 @@ }, "patterns": [ { - "include": "$base" + "include": "$self" } ] }, @@ -10146,10 +11070,10 @@ }, "patterns": [ { - "include": "#enumerator_list" + "include": "#ever_present_context" }, { - "include": "#comments" + "include": "#enumerator_list" }, { "include": "#comma" @@ -10165,7 +11089,7 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "include": "$base" + "include": "$self" } ] } @@ -10186,10 +11110,172 @@ "name": "storage.type.modifier.virtual.cpp" }, { - "match": "(?<=virtual|private|protected|public|,|:)\\s*(?!(?:(?:private|protected|public)|virtual))((?:\\s*+(?:(?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))", + "match": "(?<=virtual|private|protected|public|,|:)\\s*(?!(?:(?:private|protected|public)|virtual))(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))", "captures": { "1": { - "name": "entity.name.type.inherited.cpp" + "name": "meta.qualified_type.cpp", + "patterns": [ + { + "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", "beginCaptures": { "1": { "name": "meta.head.class.cpp" @@ -10349,7 +11435,7 @@ "include": "#destructor_inline" }, { - "include": "$base" + "include": "$self" } ] }, @@ -10359,7 +11445,7 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "include": "$base" + "include": "$self" } ] } @@ -10367,7 +11453,7 @@ }, "struct_block": { "name": "meta.block.struct.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", "beginCaptures": { "1": { "name": "meta.head.struct.cpp" @@ -10519,7 +11605,7 @@ "include": "#destructor_inline" }, { - "include": "$base" + "include": "$self" } ] }, @@ -10529,7 +11615,7 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "include": "$base" + "include": "$self" } ] } @@ -10537,7 +11623,7 @@ }, "union_block": { "name": "meta.block.union.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", "beginCaptures": { "1": { "name": "meta.head.union.cpp" @@ -10689,7 +11775,7 @@ "include": "#destructor_inline" }, { - "include": "$base" + "include": "$self" } ] }, @@ -10699,7 +11785,7 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "include": "$base" + "include": "$self" } ] } @@ -10762,7 +11848,7 @@ }, "patterns": [ { - "include": "$base" + "include": "$self" } ] }, @@ -10777,7 +11863,7 @@ }, "patterns": [ { - "include": "$base" + "include": "$self" } ] }, @@ -10787,12 +11873,12 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "include": "$base" + "include": "$self" } ] }, { - "include": "$base" + "include": "$self" } ] }, @@ -10807,7 +11893,7 @@ "patterns": [ { "name": "meta.block.class.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", "beginCaptures": { "1": { "name": "meta.head.class.cpp" @@ -10959,7 +12045,7 @@ "include": "#destructor_inline" }, { - "include": "$base" + "include": "$self" } ] }, @@ -11114,7 +12200,7 @@ "patterns": [ { "name": "meta.block.struct.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", "beginCaptures": { "1": { "name": "meta.head.struct.cpp" @@ -11266,7 +12352,7 @@ "include": "#destructor_inline" }, { - "include": "$base" + "include": "$self" } ] }, @@ -11421,7 +12507,7 @@ "patterns": [ { "name": "meta.block.union.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", "beginCaptures": { "1": { "name": "meta.head.union.cpp" @@ -11573,7 +12659,7 @@ "include": "#destructor_inline" }, { - "include": "$base" + "include": "$self" } ] }, @@ -13692,31 +14778,70 @@ }, "meta_preprocessor_macro": { "name": "meta.preprocessor.macro.cpp", - "begin": "(?x)\n^\\s* ((\\#)\\s*define) \\s+\t# define\n((?(?-mix:[a-zA-Z_$][\\w$]*)))\t # macro name\n(?:\n (\\()\n\t(\n\t \\s* \\g \\s*\t\t # first argument\n\t ((,) \\s* \\g \\s*)* # additional arguments\n\t (?:\\.\\.\\.)?\t\t\t# varargs ellipsis?\n\t)\n (\\))\n)?", + "begin": "(?:^)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((#)\\s*define\\b)\\s+((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)(?:(\\()([^()\\\\]+)(\\)))?", "beginCaptures": { "1": { - "name": "keyword.control.directive.define.cpp" + "patterns": [ + { + "include": "#inline_comment" + } + ] }, "2": { - "name": "punctuation.definition.directive.cpp" + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "3": { - "name": "entity.name.function.preprocessor.cpp" + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "5": { - "name": "punctuation.definition.parameters.begin.cpp" + "name": "keyword.control.directive.define.cpp" }, "6": { - "name": "variable.parameter.preprocessor.cpp" + "name": "punctuation.definition.directive.cpp" + }, + "7": { + "name": "entity.name.function.preprocessor.cpp" }, "8": { - "name": "punctuation.separator.parameters.cpp" + "name": "punctuation.definition.parameters.begin.cpp" }, "9": { + "patterns": [ + { + "match": "(?<=[(,])\\s*((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*", + "captures": { + "1": { + "name": "variable.parameter.preprocessor.cpp" + } + } + }, + { + "match": ",", + "name": "punctuation.separator.parameters.cpp" + }, + { + "match": "\\.\\.\\.", + "name": "punctuation.vararg-ellipses.variable.parameter.preprocessor.cpp" + } + ] + }, + "10": { "name": "punctuation.definition.parameters.end.cpp" } }, - "end": "(?=(?://|/\\*))|(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((#)\\s*((?:(?:include|include_next)|import))\\b)\\s*(?:(?:(?:((<)[^>]*(>?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:\\n|$)|(?=\\/\\/)))|((\\\")[^\\\"]*(\\\"?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:\\n|$)|(?=\\/\\/))))|((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:\\n|$)|(?=\\/\\/))))|((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:\\n|$)|(?=\\/\\/)))", + "captures": { "1": { - "name": "keyword.control.directive.$3.cpp" + "patterns": [ + { + "include": "#inline_comment" + } + ] }, "2": { - "name": "punctuation.definition.directive.cpp" - } - }, - "end": "(?=(?://|/\\*))|(?", - "endCaptures": { - "0": { - "name": "punctuation.definition.string.end.cpp" + ] + }, + "19": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "20": { + "name": "comment.block.cpp" + }, + "21": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" } - }, - "name": "string.quoted.other.lt-gt.include.cpp" + ] + }, + "22": { + "name": "entity.name.other.preprocessor.macro.include.cpp" + }, + "23": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "24": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "25": { + "name": "comment.block.cpp" + }, + "26": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "27": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "28": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "29": { + "name": "comment.block.cpp" + }, + "30": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] } - ] + }, + "name": "meta.preprocessor.include.cpp" }, "meta_preprocessor_line": { "name": "meta.preprocessor.cpp", @@ -13981,28 +15216,78 @@ ] }, { - "begin": "((?:u|u8|U|L)?R)\"(?:([^ ()\\\\\\t]{0,16})|([^ ()\\\\\\t]*))\\(", - "beginCaptures": { - "0": { - "name": "punctuation.definition.string.begin.cpp" + "patterns": [ + { + "name": "string.quoted.double.raw.regex.cpp", + "begin": "(((?:[uUL]8?)?R)\\\"(?:(?:_r|re)|regex)\\()", + "beginCaptures": { + "1": { + "name": "punctuation.definition.string.begin.cpp" + }, + "2": { + "name": "meta.encoding.cpp" + } + }, + "end": "(\\)(?:(?:_r|re)|regex)\\\")", + "endCaptures": { + "1": { + "name": "punctuation.definition.string.end.cpp" + } + }, + "patterns": [ + { + "include": "source.regexp.python" + } + ] }, - "1": { - "name": "meta.encoding.cpp" + { + "name": "string.quoted.double.raw.sql.cpp", + "begin": "(((?:[uUL]8?)?R)\\\"(?:[pP]?(?:sql|SQL|)|d[dm]l)\\()", + "beginCaptures": { + "1": { + "name": "punctuation.definition.string.begin.cpp" + }, + "2": { + "name": "meta.encoding.cpp" + } + }, + "end": "(\\)(?:[pP]?(?:sql|SQL|)|d[dm]l)\\\")", + "endCaptures": { + "1": { + "name": "punctuation.definition.string.end.cpp" + } + }, + "patterns": [ + { + "include": "source.sql" + } + ] }, - "3": { - "name": "invalid.illegal.delimiter-too-long.cpp" + { + "begin": "((?:u|u8|U|L)?R)\"(?:([^ ()\\\\\\t]{0,16})|([^ ()\\\\\\t]*))\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.cpp" + }, + "1": { + "name": "meta.encoding.cpp" + }, + "3": { + "name": "invalid.illegal.delimiter-too-long.cpp" + } + }, + "end": "\\)\\2(\\3)\"", + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.cpp" + }, + "1": { + "name": "invalid.illegal.delimiter-too-long.cpp" + } + }, + "name": "string.quoted.double.raw.cpp" } - }, - "end": "\\)\\2(\\3)\"", - "endCaptures": { - "0": { - "name": "punctuation.definition.string.end.cpp" - }, - "1": { - "name": "invalid.illegal.delimiter-too-long.cpp" - } - }, - "name": "string.quoted.double.raw.cpp" + ] } ] }, @@ -14070,6 +15355,9 @@ }, { "include": "#evaluation_context" + }, + { + "include": "#vararg_ellipses" } ] }, @@ -14224,7 +15512,7 @@ ] }, { - "include": "$base" + "include": "$self" } ] }, @@ -14292,7 +15580,7 @@ ] }, { - "include": "$base" + "include": "$self" } ] }, @@ -14442,7 +15730,7 @@ ] }, { - "include": "$base" + "include": "$self" } ] }, @@ -14535,7 +15823,7 @@ ] }, { - "include": "$base" + "include": "$self" } ] }, @@ -14692,7 +15980,7 @@ "end": "(?=^\\s*((#)\\s*(?:else|elif|endif)\\b))", "patterns": [ { - "include": "$base" + "include": "$self" } ] } @@ -14790,7 +16078,7 @@ "end": "(?=^\\s*((#)\\s*(?:else|elif|endif)\\b))", "patterns": [ { - "include": "$base" + "include": "$self" } ] } @@ -14877,7 +16165,7 @@ ] }, { - "include": "$base" + "include": "$self" } ] } @@ -14964,7 +16252,7 @@ ] }, { - "include": "$base" + "include": "$self" } ] } @@ -14986,7 +16274,7 @@ "end": "(?=^\\s*((#)\\s*endif\\b))", "patterns": [ { - "include": "$base" + "include": "$self" } ] }, @@ -15006,7 +16294,7 @@ "end": "(?=^\\s*((#)\\s*endif\\b))", "patterns": [ { - "include": "$base" + "include": "$self" } ] }, @@ -15103,7 +16391,7 @@ ] }, { - "include": "$base" + "include": "$self" } ] }, @@ -15204,7 +16492,7 @@ }, "macro_safe_constructor_root": { "name": "meta.function.definition.special.constructor.cpp", - "begin": "(\\s*+((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*)(((?>(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))::((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\13((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\()))", + "begin": "(\\s*+((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<14>?)+)>)\\s*)?::)*)(((?>(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))::((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\16((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\()))", "beginCaptures": { "1": { "name": "meta.head.function.definition.special.constructor.cpp" @@ -15277,7 +16565,15 @@ } ] }, - "12": { + "13": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "15": { "patterns": [ { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?=:)", @@ -15293,45 +16589,20 @@ } ] }, - "14": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "15": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "16": { - "name": "comment.block.cpp" - }, "17": { "patterns": [ { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" + "include": "#inline_comment" } ] }, "18": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "19": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, - "20": { + "19": { "name": "comment.block.cpp" }, - "21": { + "20": { "patterns": [ { "match": "\\*\\/", @@ -15343,20 +16614,45 @@ } ] }, - "22": { + "21": { "patterns": [ { "include": "#inline_comment" } ] }, - "23": { + "22": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, - "24": { + "23": { "name": "comment.block.cpp" }, + "24": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, "25": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "26": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "27": { + "name": "comment.block.cpp" + }, + "28": { "patterns": [ { "match": "\\*\\/", @@ -15439,14 +16735,25 @@ }, "end": "(?=\\{)", "patterns": [ + { + "include": "#ever_present_context" + }, { "contentName": "meta.parameter.initialization.cpp", - "begin": "((?(?:(?>[^<>]*)\\g<3>?)+)>)\\s*)?(\\()", "beginCaptures": { "1": { "name": "entity.name.function.call.initializer.cpp" }, "2": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "4": { "name": "punctuation.section.arguments.begin.bracket.round.function.call.initializer.cpp" } }, @@ -15457,6 +16764,9 @@ } }, "patterns": [ + { + "include": "#ever_present_context" + }, { "include": "#evaluation_context" } @@ -15480,6 +16790,9 @@ } }, "patterns": [ + { + "include": "#ever_present_context" + }, { "include": "#evaluation_context" } @@ -15514,7 +16827,7 @@ ] }, { - "include": "$base" + "include": "$self" } ] }, @@ -15539,7 +16852,7 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "include": "$base" + "include": "$self" } ] } @@ -15547,7 +16860,7 @@ }, "macro_safe_destructor_root": { "name": "meta.function.definition.special.member.destructor.cpp", - "begin": "(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*)(((?>(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))::((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))~\\13((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\()))", + "begin": "(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<14>?)+)>)\\s*)?::)*)(((?>(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))::((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))~\\16((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\()))", "beginCaptures": { "1": { "name": "meta.head.function.definition.special.member.destructor.cpp" @@ -15620,7 +16933,15 @@ } ] }, - "12": { + "13": { + "name": "meta.template.call.cpp", + "patterns": [ + { + "include": "#template_call_range" + } + ] + }, + "15": { "patterns": [ { "match": "(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?=:)", @@ -15636,45 +16957,20 @@ } ] }, - "14": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "15": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "16": { - "name": "comment.block.cpp" - }, "17": { "patterns": [ { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" + "include": "#inline_comment" } ] }, "18": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "19": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, - "20": { + "19": { "name": "comment.block.cpp" }, - "21": { + "20": { "patterns": [ { "match": "\\*\\/", @@ -15686,20 +16982,45 @@ } ] }, - "22": { + "21": { "patterns": [ { "include": "#inline_comment" } ] }, - "23": { + "22": { "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, - "24": { + "23": { "name": "comment.block.cpp" }, + "24": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, "25": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "26": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "27": { + "name": "comment.block.cpp" + }, + "28": { "patterns": [ { "match": "\\*\\/", @@ -15786,7 +17107,7 @@ } }, { - "include": "$base" + "include": "$self" } ] }, @@ -15811,7 +17132,7 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "include": "$base" + "include": "$self" } ] } @@ -15819,7 +17140,7 @@ }, "macro_safe_function_definition": { "name": "meta.function.definition.cpp", - "begin": "((?:(?:^|\\G|(?<=;|\\}))|(?<=>))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\())", + "begin": "((?:(?:^|\\G|(?<=;|\\}))|(?<=>))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<69>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<69>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<69>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<69>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\())", "beginCaptures": { "1": { "name": "meta.head.function.definition.cpp" @@ -15909,7 +17230,7 @@ "name": "meta.qualified_type.cpp", "patterns": [ { - "match": "(?:class|struct|union|enum)", + "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*)(operator)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*)(?:(?:((?:\\+\\+|\\-\\-|\\(\\)|\\[\\]|\\->|\\+\\+|\\-\\-|\\+|\\-|!|~|\\*|&|new|new\\[\\]|delete|delete\\[\\]|\\->\\*|\\*|\\/|%|\\+|\\-|<<|>>|<=>|<|<=|>|>=|==|!=|&|\\^|\\||&&|\\|\\||=|\\+=|\\-=|\\*=|\\/=|%=|<<=|>>=|&=|\\^=|\\|=|,))|((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:\\[\\])?)))|(\"\")((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\<|\\())", + "begin": "((?:(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<67>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<67>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<67>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<67>?)+)>)\\s*)?::)*)(operator)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<67>?)+)>)\\s*)?::)*)(?:(?:((?:\\+\\+|\\-\\-|\\(\\)|\\[\\]|\\->|\\+\\+|\\-\\-|\\+|\\-|!|~|\\*|&|new|new\\[\\]|delete|delete\\[\\]|\\->\\*|\\*|\\/|%|\\+|\\-|<<|>>|<=>|<|<=|>|>=|==|!=|&|\\^|\\||&&|\\|\\||=|\\+=|\\-=|\\*=|\\/=|%=|<<=|>>=|&=|\\^=|\\|=|,))|((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:\\[\\])?)))|(\"\")((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\<|\\())", "beginCaptures": { "1": { "name": "meta.head.function.definition.special.operator-overload.cpp" @@ -16345,7 +17699,7 @@ "name": "meta.qualified_type.cpp", "patterns": [ { - "match": "(?:class|struct|union|enum)", + "match": "(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)?((?(?:(?>[^<>]*)\\g<7>?)+)>)\\s*)?::)*\\s*+)?((?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)\\s*((?(?:(?>[^<>]*)\\g<5>?)+)>)\\s*)?::)*\\s*+)\\s*((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", "beginCaptures": { "1": { "name": "meta.head.class.cpp" @@ -17359,7 +18773,7 @@ "include": "#destructor_inline" }, { - "include": "$base" + "include": "$self" } ] }, @@ -17514,7 +18928,7 @@ "patterns": [ { "name": "meta.block.struct.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", "beginCaptures": { "1": { "name": "meta.head.struct.cpp" @@ -17666,7 +19080,7 @@ "include": "#destructor_inline" }, { - "include": "$base" + "include": "$self" } ] }, @@ -17821,7 +19235,7 @@ "patterns": [ { "name": "meta.block.union.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", "beginCaptures": { "1": { "name": "meta.head.union.cpp" @@ -17973,7 +19387,7 @@ "include": "#destructor_inline" }, { - "include": "$base" + "include": "$self" } ] }, @@ -18117,9 +19531,372 @@ } ] }, + "macro_safe_typedef_function_pointer": { + "begin": "((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()(\\*)\\s*((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)\\s*(?:(\\[)(\\w*)(\\])\\s*)*(\\))\\s*(\\()", + "beginCaptures": { + "1": { + "name": "meta.qualified_type.cpp", + "patterns": [ + { + "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "invalid.illegal.reference-type.cpp" + }, + { + "match": "\\&", + "name": "storage.modifier.reference.cpp" + } + ] + }, + "29": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "30": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "31": { + "name": "comment.block.cpp" + }, + "32": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "33": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "34": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "35": { + "name": "comment.block.cpp" + }, + "36": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "37": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "38": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "39": { + "name": "comment.block.cpp" + }, + "40": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "41": { + "name": "punctuation.section.parens.begin.bracket.round.function.pointer.cpp" + }, + "42": { + "name": "punctuation.definition.function.pointer.dereference.cpp" + }, + "43": { + "name": "entity.name.type.alias.cpp entity.name.type.pointer.function.cpp" + }, + "44": { + "name": "punctuation.definition.begin.bracket.square.cpp" + }, + "45": { + "patterns": [ + { + "include": "#evaluation_context" + } + ] + }, + "46": { + "name": "punctuation.definition.end.bracket.square.cpp" + }, + "47": { + "name": "punctuation.section.parens.end.bracket.round.function.pointer.cpp" + }, + "48": { + "name": "punctuation.section.parameters.begin.bracket.round.function.pointer.cpp" + } + }, + "end": "(\\))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=[{=,);]|\\n)(?!\\()", + "endCaptures": { + "1": { + "name": "punctuation.section.parameters.end.bracket.round.function.pointer.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "patterns": [ + { + "include": "#function_parameter_context" + } + ] + } + ] + }, "macro_safe_class_block": { "name": "meta.block.class.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", "beginCaptures": { "1": { "name": "meta.head.class.cpp" @@ -18271,7 +20048,7 @@ "include": "#destructor_inline" }, { - "include": "$base" + "include": "$self" } ] }, @@ -18281,7 +20058,7 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "include": "$base" + "include": "$self" } ] } @@ -18289,7 +20066,7 @@ }, "macro_safe_struct_block": { "name": "meta.block.struct.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", "beginCaptures": { "1": { "name": "meta.head.struct.cpp" @@ -18441,7 +20218,7 @@ "include": "#destructor_inline" }, { - "include": "$base" + "include": "$self" } ] }, @@ -18451,7 +20228,7 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "include": "$base" + "include": "$self" } ] } @@ -18459,7 +20236,7 @@ }, "macro_safe_union_block": { "name": "meta.block.union.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", "beginCaptures": { "1": { "name": "meta.head.union.cpp" @@ -18611,7 +20388,7 @@ "include": "#destructor_inline" }, { - "include": "$base" + "include": "$self" } ] }, @@ -18621,7 +20398,7 @@ "end": "[\\s\\n]*(?=;)", "patterns": [ { - "include": "$base" + "include": "$self" } ] } @@ -18629,7 +20406,7 @@ }, "macro_safe_enum_block": { "name": "meta.block.enum.cpp", - "begin": "(((?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?\\s*((?(?:(?>[^<>]*)\\g<15>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<15>?)+)>)\\s*)?(::))?\\s*((?|\\?\\?>)\\s*(;)|(;))|(?=[;>\\[\\]=]))|(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((?:::)?(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*\\s*+(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+((?]*|[^>]*+<[^>]*+>)++>\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?]*|[^>]*+<[^>]*+>)++>\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()(\\*)\\s*((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)\\s*(?:(\\[)(\\w*)(\\])\\s*)*(\\))\\s*(\\()", + "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()(\\*)\\s*((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)\\s*(?:(\\[)(\\w*)(\\])\\s*)*(\\))\\s*(\\()", "beginCaptures": { "1": { "name": "meta.qualified_type.cpp", "patterns": [ { - "match": "(?:class|struct|union|enum)", + "match": "(?)\\s*(``([[:alpha:]0-9'^._ ]+)``|[[:alpha:]0-9'`^._]+)", - "captures": { - "1": { - "name": "entity.name.type.fsharp" - } - } - }, { "include": "#variables" }, @@ -978,6 +981,29 @@ "include": "#common_binding_definition" } ] + }, + { + "name": "binding.fsharp", + "begin": "\\b(new)\\b\\s+(\\()", + "end": "(\\))", + "beginCaptures": { + "1": { + "name": "keyword.fsharp" + }, + "2": { + "name": "keyword.fsharp" + } + }, + "endCaptures": { + "1": { + "name": "keyword.fsharp" + } + }, + "patterns": [ + { + "include": "#common_binding_definition" + } + ] } ] }, @@ -1037,7 +1063,7 @@ "patterns": [ { "name": "keyword.fsharp", - "match": "\\b(private|to|public|internal|function|yield!|yield|class|exception|match|delegate|of|new|in|as|if|then|else|elif|for|begin|end|inherit|do|let\\!|return\\!|return|interface|with|abstract|property|union|enum|member|try|finally|and|when|or|use|use\\!|struct|while|mutable)(?!')\\b" + "match": "\\b(private|to|public|internal|function|yield!|yield|class|exception|match|delegate|of|new|in|as|if|then|else|elif|for|begin|end|inherit|do|let\\!|return\\!|return|interface|with|abstract|enum|member|try|finally|and|when|or|use|use\\!|struct|while|mutable|assert|base|done|downcast|downto|extern|fixed|global|lazy|upcast|not)(?!')\\b" }, { "name": "keyword.symbol.fsharp", @@ -1049,7 +1075,7 @@ "patterns": [ { "name": "entity.name.section.fsharp", - "begin": "\\b(namespace|module)\\s*(public|internal|private)?\\s+([[:alpha:]][[:alpha:]0-9'_. ]*)", + "begin": "\\b(namespace global)|(namespace|module)\\s*(public|internal|private|rec)?\\s+([[:alpha:]][[:alpha:]0-9'_. ]*)", "end": "(\\s?=|\\s|$)", "beginCaptures": { "1": { @@ -1059,6 +1085,9 @@ "name": "keyword.fsharp" }, "3": { + "name": "keyword.fsharp" + }, + "4": { "name": "entity.name.section.fsharp" } }, diff --git a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json index a90d452bddf..ed16712a061 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/cf7b1ec2c20b5fe28695249596128ff514e1a659", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/84238ef0fa1c7e4e2c9fe77875d832dab9f57e5d", "name": "JavaScript (with React support)", "scopeName": "source.js", "patterns": [ @@ -605,7 +605,7 @@ "include": "#comment" }, { - "begin": "(?x)(?=((\\b(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", + "begin": "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", "beginCaptures": { "1": { "name": "storage.modifier.js" @@ -1350,7 +1350,7 @@ }, "object-literal-method-declaration": { "name": "meta.method.declaration.js", - "begin": "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", + "begin": "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", "beginCaptures": { "1": { "name": "storage.modifier.async.js" @@ -1371,7 +1371,7 @@ "include": "#function-body" }, { - "begin": "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", + "begin": "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", "beginCaptures": { "1": { "name": "storage.modifier.async.js" @@ -1393,7 +1393,7 @@ ] }, "method-declaration-name": { - "begin": "(?x)(?=((\\b(?\\s*$)", + "begin": "^(///)\\s*(?=<(reference|amd-dependency|amd-module)(\\s+(path|types|no-default-lib|lib|name)\\s*=\\s*((\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`)))+\\s*/>\\s*$)", "beginCaptures": { "1": { "name": "punctuation.definition.comment.js" diff --git a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json index 067eda2d5e6..ee685716166 100644 --- a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json +++ b/extensions/javascript/syntaxes/JavaScriptReact.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/cf7b1ec2c20b5fe28695249596128ff514e1a659", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/84238ef0fa1c7e4e2c9fe77875d832dab9f57e5d", "name": "JavaScript (with React support)", "scopeName": "source.js.jsx", "patterns": [ @@ -605,7 +605,7 @@ "include": "#comment" }, { - "begin": "(?x)(?=((\\b(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", + "begin": "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", "beginCaptures": { "1": { "name": "storage.modifier.js.jsx" @@ -1350,7 +1350,7 @@ }, "object-literal-method-declaration": { "name": "meta.method.declaration.js.jsx", - "begin": "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", + "begin": "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", "beginCaptures": { "1": { "name": "storage.modifier.async.js.jsx" @@ -1371,7 +1371,7 @@ "include": "#function-body" }, { - "begin": "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", + "begin": "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", "beginCaptures": { "1": { "name": "storage.modifier.async.js.jsx" @@ -1393,7 +1393,7 @@ ] }, "method-declaration-name": { - "begin": "(?x)(?=((\\b(?\\s*$)", + "begin": "^(///)\\s*(?=<(reference|amd-dependency|amd-module)(\\s+(path|types|no-default-lib|lib|name)\\s*=\\s*((\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`)))+\\s*/>\\s*$)", "beginCaptures": { "1": { "name": "punctuation.definition.comment.js.jsx" diff --git a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json index b94e9eba4a3..f63c46a878d 100644 --- a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json +++ b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json @@ -2566,4 +2566,4 @@ "name": "markup.inline.raw.string.markdown" } } -} \ No newline at end of file +} diff --git a/extensions/perl/cgmanifest.json b/extensions/perl/cgmanifest.json index b7c850dd1aa..83d91107671 100644 --- a/extensions/perl/cgmanifest.json +++ b/extensions/perl/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "textmate/perl.tmbundle", "repositoryUrl": "https://github.com/textmate/perl.tmbundle", - "commitHash": "d9841a0878239fa43f88c640f8d458590f97e8f5" + "commitHash": "80826abe75250286c2a1a07958e50e8551d3f50c" } }, "licenseDetail": [ diff --git a/extensions/powershell/cgmanifest.json b/extensions/powershell/cgmanifest.json index e9adf03ca04..c8dcfd7cc80 100644 --- a/extensions/powershell/cgmanifest.json +++ b/extensions/powershell/cgmanifest.json @@ -5,13 +5,13 @@ "type": "git", "git": { "name": "PowerShell/EditorSyntax", - "repositoryUrl": "https://github.com/powershell/editorsyntax", - "commitHash": "12b7d7257eb493e45a9af0af9094ec0c2a996712" + "repositoryUrl": "https://github.com/PowerShell/EditorSyntax", + "commitHash": "d10ae29c0d3ceb248172c383a159ae43b9ccfb4d" } }, "license": "MIT", - "version": "0.0.0" + "version": "1.0.0" } ], "version": 1 -} \ No newline at end of file +} diff --git a/extensions/powershell/syntaxes/powershell.tmLanguage.json b/extensions/powershell/syntaxes/powershell.tmLanguage.json index 59ee6fbd130..de473e19fb8 100644 --- a/extensions/powershell/syntaxes/powershell.tmLanguage.json +++ b/extensions/powershell/syntaxes/powershell.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/PowerShell/EditorSyntax/commit/44eac8702f3cbe55a4ec70c1fdb163d42b4162fc", + "version": "https://github.com/PowerShell/EditorSyntax/commit/d10ae29c0d3ceb248172c383a159ae43b9ccfb4d", "name": "PowerShell", "scopeName": "source.powershell", "patterns": [ @@ -670,7 +670,7 @@ } }, "comment": "Style preference variables as language variables so that they stand out.", - "match": "(\\$)(?i:(ConfirmPreference|DebugPreference|ErrorActionPreference|ErrorView|FormatEnumerationLimit|MaximumAliasCount|MaximumDriveCount|MaximumErrorCount|MaximumFunctionCount|MaximumHistoryCount|MaximumVariableCount|OFS|OutputEncoding|ProgressPreference|PsCulture|PSDebugContext|PSDefaultParameterValues|PSEmailServer|PSItem|PSModuleAutoloadingPreference|PSSenderInfo|PSSessionApplicationName|PSSessionConfigurationName|PSSessionOption|VerbosePreference|WarningPreference|WhatIfPreference))((?:\\.(?:\\p{L}|\\d|_)+)*\\b)?\\b" + "match": "(\\$)(?i:(ConfirmPreference|DebugPreference|ErrorActionPreference|ErrorView|FormatEnumerationLimit|InformationPreference|LogCommandHealthEvent|LogCommandLifecycleEvent|LogEngineHealthEvent|LogEngineLifecycleEvent|LogProviderHealthEvent|LogProviderLifecycleEvent|MaximumAliasCount|MaximumDriveCount|MaximumErrorCount|MaximumFunctionCount|MaximumHistoryCount|MaximumVariableCount|OFS|OutputEncoding|PSCulture|PSDebugContext|PSDefaultParameterValues|PSEmailServer|PSItem|PSModuleAutoLoadingPreference|PSModuleAutoloadingPreference|PSSenderInfo|PSSessionApplicationName|PSSessionConfigurationName|PSSessionOption|ProgressPreference|VerbosePreference|WarningPreference|WhatIfPreference))((?:\\.(?:\\p{L}|\\d|_)+)*\\b)?\\b" }, { "captures": { @@ -848,7 +848,7 @@ } }, "comment": "Style preference variables as language variables so that they stand out.", - "match": "(\\$)(?i:(ConfirmPreference|DebugPreference|ErrorActionPreference|ErrorView|FormatEnumerationLimit|MaximumAliasCount|MaximumDriveCount|MaximumErrorCount|MaximumFunctionCount|MaximumHistoryCount|MaximumVariableCount|OFS|OutputEncoding|ProgressPreference|PsCulture|PSDebugContext|PSDefaultParameterValues|PSEmailServer|PSItem|PSModuleAutoloadingPreference|PSSenderInfo|PSSessionApplicationName|PSSessionConfigurationName|PSSessionOption|VerbosePreference|WarningPreference|WhatIfPreference))\\b" + "match": "(\\$)(?i:(ConfirmPreference|DebugPreference|ErrorActionPreference|ErrorView|FormatEnumerationLimit|InformationPreference|LogCommandHealthEvent|LogCommandLifecycleEvent|LogEngineHealthEvent|LogEngineLifecycleEvent|LogProviderHealthEvent|LogProviderLifecycleEvent|MaximumAliasCount|MaximumDriveCount|MaximumErrorCount|MaximumFunctionCount|MaximumHistoryCount|MaximumVariableCount|OFS|OutputEncoding|PSCulture|PSDebugContext|PSDefaultParameterValues|PSEmailServer|PSItem|PSModuleAutoLoadingPreference|PSModuleAutoloadingPreference|PSSenderInfo|PSSessionApplicationName|PSSessionConfigurationName|PSSessionOption|ProgressPreference|VerbosePreference|WarningPreference|WhatIfPreference))\\b" }, { "captures": { diff --git a/extensions/ruby/cgmanifest.json b/extensions/ruby/cgmanifest.json index ffbbb7b71c6..8f04db20f54 100644 --- a/extensions/ruby/cgmanifest.json +++ b/extensions/ruby/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "textmate/ruby.tmbundle", "repositoryUrl": "https://github.com/textmate/ruby.tmbundle", - "commitHash": "74713556df10fbc7b1f9e99013ab1e34cd836f56" + "commitHash": "05698e99314d8653e2e9d8f198d3c83e387ee1eb" } }, "licenseDetail": [ diff --git a/extensions/ruby/syntaxes/ruby.tmLanguage.json b/extensions/ruby/syntaxes/ruby.tmLanguage.json index 62fbbc265e5..8b6c98616d8 100644 --- a/extensions/ruby/syntaxes/ruby.tmLanguage.json +++ b/extensions/ruby/syntaxes/ruby.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/textmate/ruby.tmbundle/commit/74713556df10fbc7b1f9e99013ab1e34cd836f56", + "version": "https://github.com/textmate/ruby.tmbundle/commit/05698e99314d8653e2e9d8f198d3c83e387ee1eb", "name": "Ruby", "scopeName": "source.ruby", "comment": "\n\tTODO: unresolved issues\n\n\ttext:\n\t\"p <<<[-~](\"?)((?:[_\\w]+_|)HTML)\\b\\1))", "comment": "Heredoc with embedded html", diff --git a/extensions/swift/syntaxes/swift.tmLanguage.json b/extensions/swift/syntaxes/swift.tmLanguage.json index 490388e079a..2e2148073db 100644 --- a/extensions/swift/syntaxes/swift.tmLanguage.json +++ b/extensions/swift/syntaxes/swift.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/textmate/swift.tmbundle/commit/cec27af6662e3799120b208e64483efdfe5521f5", + "version": "https://github.com/textmate/swift.tmbundle/commit/bdc8ae07562060a566b33da3f62601bb5aababd1", "name": "Swift", "scopeName": "source.swift", "comment": "See swift.tmbundle/grammar-test.swift for test cases.", @@ -46,7 +46,7 @@ "name": "constant.numeric.swift" } }, - "match": "\\b((?:iOS|macOS|OSX|watchOS|tvOS)(?:ApplicationExtension)?)\\b(?:\\s+([0-9]+(?:\\.[0-9]+)*\\b))?" + "match": "\\b(swift|(?:iOS|macOS|OSX|watchOS|tvOS|UIKitForMac)(?:ApplicationExtension)?)\\b(?:\\s+([0-9]+(?:\\.[0-9]+)*\\b))?" }, { "begin": "\\b(introduced|deprecated|obsoleted)\\s*(:)\\s*", @@ -587,7 +587,24 @@ "match": "\\b(os)\\s*(\\()\\s*(?:(macOS|OSX|iOS|tvOS|watchOS|Android|Linux|FreeBSD|Windows|PS4)|\\w+)\\s*(\\))" }, { - "begin": "\\b(swift)\\s*(\\()", + "captures": { + "1": { + "name": "keyword.other.condition.swift" + }, + "2": { + "name": "punctuation.definition.parameters.begin.swift" + }, + "3": { + "name": "entity.name.type.module.swift" + }, + "4": { + "name": "punctuation.definition.parameters.end.swift" + } + }, + "match": "\\b(canImport)\\s*(\\()([\\p{L}_][\\p{L}_\\p{N}\\p{M}]*)(\\))" + }, + { + "begin": "\\b(targetEnvironment)\\s*(\\()", "beginCaptures": { "1": { "name": "keyword.other.condition.swift" @@ -604,7 +621,30 @@ }, "patterns": [ { - "match": ">=", + "match": "\\b(simulator|UIKitForMac)\\b", + "name": "support.constant.platform.environment.swift" + } + ] + }, + { + "begin": "\\b(swift|compiler)\\s*(\\()", + "beginCaptures": { + "1": { + "name": "keyword.other.condition.swift" + }, + "2": { + "name": "punctuation.definition.parameters.begin.swift" + } + }, + "end": "(\\))|$", + "endCaptures": { + "1": { + "name": "punctuation.definition.parameters.end.swift" + } + }, + "patterns": [ + { + "match": ">=|<", "name": "keyword.operator.comparison.swift" }, { @@ -1977,22 +2017,27 @@ "include": "#comments" }, { - "captures": { + "begin": "(?x)\n\t\t\t\t\t\t\t\t\t\t(?:(_)|((?`?)[\\p{L}_][\\p{L}_\\p{N}\\p{M}]*\\k))\n\t\t\t\t\t\t\t\t\t\t\\s+\n\t\t\t\t\t\t\t\t\t\t(((?`?)[\\p{L}_][\\p{L}_\\p{N}\\p{M}]*\\k))\n\t\t\t\t\t\t\t\t\t\t\\s*(:)", + "beginCaptures": { "1": { - "name": "invalid.illegal.distinct-labels-not-allowed.swift" - }, - "3": { "name": "entity.name.function.swift" }, - "4": { + "2": { + "name": "invalid.illegal.distinct-labels-not-allowed.swift" + }, + "5": { "name": "variable.parameter.function.swift" }, - "6": { + "7": { "name": "punctuation.separator.argument-label.swift" } }, "end": "(?=[,)\\]])", - "match": "(?x)\n\t\t\t\t\t\t\t\t\t\t((?`?)[\\p{L}_][\\p{L}_\\p{N}\\p{M}]*\\k)\n\t\t\t\t\t\t\t\t\t\t\\s+\n\t\t\t\t\t\t\t\t\t\t(((?`?)[\\p{L}_][\\p{L}_\\p{N}\\p{M}]*\\k))\n\t\t\t\t\t\t\t\t\t\t\\s*(:)" + "patterns": [ + { + "include": "#available-types" + } + ] }, { "begin": "(((?`?)[\\p{L}_][\\p{L}_\\p{N}\\p{M}]*\\k))\\s*(:)", @@ -2279,7 +2324,7 @@ "name": "constant.numeric.swift" } }, - "match": "\\s*\\b((?:iOS|macOS|OSX|watchOS|tvOS)(?:ApplicationExtension)?)\\b(?:\\s+([0-9]+(?:\\.[0-9]+)*\\b))" + "match": "\\s*\\b((?:iOS|macOS|OSX|watchOS|tvOS|UIKitForMac)(?:ApplicationExtension)?)\\b(?:\\s+([0-9]+(?:\\.[0-9]+)*\\b))" }, { "captures": { diff --git a/extensions/typescript-basics/cgmanifest.json b/extensions/typescript-basics/cgmanifest.json index cd8c1071a82..077f5f0424e 100644 --- a/extensions/typescript-basics/cgmanifest.json +++ b/extensions/typescript-basics/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "TypeScript-TmLanguage", "repositoryUrl": "https://github.com/Microsoft/TypeScript-TmLanguage", - "commitHash": "cf7b1ec2c20b5fe28695249596128ff514e1a659" + "commitHash": "84238ef0fa1c7e4e2c9fe77875d832dab9f57e5d" } }, "license": "MIT", diff --git a/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json b/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json index ce5a34d5f9a..3d1b37da01e 100644 --- a/extensions/typescript-basics/syntaxes/TypeScript.tmLanguage.json +++ b/extensions/typescript-basics/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/11b1a4f8dc3a3eaa4df71e8cc1ad6f01a688961d", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/84238ef0fa1c7e4e2c9fe77875d832dab9f57e5d", "name": "TypeScript", "scopeName": "source.ts", "patterns": [ @@ -602,7 +602,7 @@ "include": "#comment" }, { - "begin": "(?x)(?=((\\b(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", + "begin": "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", "beginCaptures": { "1": { "name": "storage.modifier.ts" @@ -1347,7 +1347,7 @@ }, "object-literal-method-declaration": { "name": "meta.method.declaration.ts", - "begin": "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", + "begin": "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", "beginCaptures": { "1": { "name": "storage.modifier.async.ts" @@ -1368,7 +1368,7 @@ "include": "#function-body" }, { - "begin": "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", + "begin": "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", "beginCaptures": { "1": { "name": "storage.modifier.async.ts" @@ -1390,7 +1390,7 @@ ] }, "method-declaration-name": { - "begin": "(?x)(?=((\\b(?\\s*$)", + "begin": "^(///)\\s*(?=<(reference|amd-dependency|amd-module)(\\s+(path|types|no-default-lib|lib|name)\\s*=\\s*((\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`)))+\\s*/>\\s*$)", "beginCaptures": { "1": { "name": "punctuation.definition.comment.ts" diff --git a/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json b/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json index 68776811480..d50da9102c9 100644 --- a/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json +++ b/extensions/typescript-basics/syntaxes/TypeScriptReact.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/cf7b1ec2c20b5fe28695249596128ff514e1a659", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/84238ef0fa1c7e4e2c9fe77875d832dab9f57e5d", "name": "TypeScriptReact", "scopeName": "source.tsx", "patterns": [ @@ -605,7 +605,7 @@ "include": "#comment" }, { - "begin": "(?x)(?=((\\b(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", + "begin": "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", "beginCaptures": { "1": { "name": "storage.modifier.tsx" @@ -1350,7 +1350,7 @@ }, "object-literal-method-declaration": { "name": "meta.method.declaration.tsx", - "begin": "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", + "begin": "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", "beginCaptures": { "1": { "name": "storage.modifier.async.tsx" @@ -1371,7 +1371,7 @@ "include": "#function-body" }, { - "begin": "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", + "begin": "(?x)(?]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<]|\\<\\s*([_$[:alpha:]]|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\]))([^=<>]|=[^<])*\\>)*\\>)*>\\s*))?[\\(])", "beginCaptures": { "1": { "name": "storage.modifier.async.tsx" @@ -1393,7 +1393,7 @@ ] }, "method-declaration-name": { - "begin": "(?x)(?=((\\b(?\\s*$)", + "begin": "^(///)\\s*(?=<(reference|amd-dependency|amd-module)(\\s+(path|types|no-default-lib|lib|name)\\s*=\\s*((\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`)))+\\s*/>\\s*$)", "beginCaptures": { "1": { "name": "punctuation.definition.comment.tsx" From 222401c661559aa4d655f91181fda3f917c5d000 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 5 Aug 2019 14:35:39 +0200 Subject: [PATCH 190/861] fix #77996 --- src/vs/workbench/common/editor.ts | 2 +- .../services/editor/browser/editorService.ts | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/common/editor.ts b/src/vs/workbench/common/editor.ts index 4cd3bb02e5d..9827b74e519 100644 --- a/src/vs/workbench/common/editor.ts +++ b/src/vs/workbench/common/editor.ts @@ -1127,4 +1127,4 @@ export async function pathsToEditors(paths: IPathData[] | undefined, fileService })); return coalesce(editors); -} \ No newline at end of file +} diff --git a/src/vs/workbench/services/editor/browser/editorService.ts b/src/vs/workbench/services/editor/browser/editorService.ts index 444045e8825..96f36a7053a 100644 --- a/src/vs/workbench/services/editor/browser/editorService.ts +++ b/src/vs/workbench/services/editor/browser/editorService.ts @@ -315,7 +315,7 @@ export class EditorService extends Disposable implements EditorServiceImpl { } const textOptions: ITextEditorOptions = options; - if (!!textOptions.selection) { + if (textOptions.selection || textOptions.viewState) { return TextEditorOptions.create(options); } @@ -448,13 +448,14 @@ export class EditorService extends Disposable implements EditorServiceImpl { typedEditors.push(replaceEditorArg as IEditorReplacement); } else { const editor = replaceEditorArg.editor as IResourceEditor; + const replacement = replaceEditorArg.replacement as IResourceEditor; const typedEditor = this.createInput(editor); - const replacementEditor = this.createInput(replaceEditorArg.replacement as IResourceEditor); + const typedReplacement = this.createInput(replacement); typedEditors.push({ editor: typedEditor, - replacement: replacementEditor, - options: this.toOptions(editor.options) + replacement: typedReplacement, + options: this.toOptions(replacement.options) }); } }); @@ -664,4 +665,4 @@ export class DelegatingEditorService extends EditorService { } } -registerSingleton(IEditorService, EditorService); \ No newline at end of file +registerSingleton(IEditorService, EditorService); From 780a5085d7d007ca7bec68daf4ddcde870556e05 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 5 Aug 2019 14:38:04 +0200 Subject: [PATCH 191/861] Strict init for tasks, file picker, and custom view Part of #78168 --- .../workbench/api/browser/mainThreadTask.ts | 2 +- .../workbench/api/common/extHostTreeViews.ts | 14 +++++----- .../tasks/node/processRunnerDetector.ts | 14 +++++----- .../dialogs/browser/remoteFileDialog.ts | 28 +++++++++---------- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTask.ts b/src/vs/workbench/api/browser/mainThreadTask.ts index dbc3da9fafd..3e022e13cab 100644 --- a/src/vs/workbench/api/browser/mainThreadTask.ts +++ b/src/vs/workbench/api/browser/mainThreadTask.ts @@ -420,7 +420,7 @@ namespace TaskFilterDTO { @extHostNamedCustomer(MainContext.MainThreadTask) export class MainThreadTask implements MainThreadTaskShape { - private readonly _extHostContext: IExtHostContext; + private readonly _extHostContext: IExtHostContext | undefined; private readonly _proxy: ExtHostTaskShape; private readonly _providers: Map; diff --git a/src/vs/workbench/api/common/extHostTreeViews.ts b/src/vs/workbench/api/common/extHostTreeViews.ts index bd3b82994d5..6b5d8d02c58 100644 --- a/src/vs/workbench/api/common/extHostTreeViews.ts +++ b/src/vs/workbench/api/common/extHostTreeViews.ts @@ -247,7 +247,7 @@ class ExtHostTreeView extends Disposable { .then(treeNode => this.proxy.$reveal(this.viewId, treeNode.item, parentChain.map(p => p.item), { select, focus, expand })), error => this.logService.error(error)); } - private _message: string | MarkdownString; + private _message: string | MarkdownString = ''; get message(): string | MarkdownString { return this._message; } @@ -565,9 +565,9 @@ class ExtHostTreeView extends Disposable { if (node) { if (node.children) { for (const child of node.children) { - const childEleement = this.elements.get(child.item.handle); - if (childEleement) { - this.clear(childEleement); + const childElement = this.elements.get(child.item.handle); + if (childElement) { + this.clear(childElement); } } } @@ -583,9 +583,9 @@ class ExtHostTreeView extends Disposable { if (node) { if (node.children) { for (const child of node.children) { - const childEleement = this.elements.get(child.item.handle); - if (childEleement) { - this.clear(childEleement); + const childElement = this.elements.get(child.item.handle); + if (childElement) { + this.clear(childElement); } } } diff --git a/src/vs/workbench/contrib/tasks/node/processRunnerDetector.ts b/src/vs/workbench/contrib/tasks/node/processRunnerDetector.ts index 85b3465b41b..538cb57ad6c 100644 --- a/src/vs/workbench/contrib/tasks/node/processRunnerDetector.ts +++ b/src/vs/workbench/contrib/tasks/node/processRunnerDetector.ts @@ -59,9 +59,9 @@ class RegexpTaskMatcher implements TaskDetectorMatcher { } class GruntTaskMatcher implements TaskDetectorMatcher { - private tasksStart: boolean; - private tasksEnd: boolean; - private descriptionOffset: number | null; + private tasksStart!: boolean; + private tasksEnd!: boolean; + private descriptionOffset!: number | null; init() { this.tasksStart = false; @@ -179,7 +179,7 @@ export class ProcessRunnerDetector { commandExecutable, isShellCommand, config.matcher, ProcessRunnerDetector.DefaultProblemMatchers, list)); } else { if (detectSpecific) { - let detectorPromise: Promise; + let detectorPromise: Promise; if ('gulp' === detectSpecific) { detectorPromise = this.tryDetectGulp(this._workspaceRoot, list); } else if ('jake' === detectSpecific) { @@ -229,7 +229,7 @@ export class ProcessRunnerDetector { return result; } - private tryDetectGulp(workspaceFolder: IWorkspaceFolder, list: boolean): Promise { + private tryDetectGulp(workspaceFolder: IWorkspaceFolder, list: boolean): Promise { return Promise.resolve(this.fileService.resolve(workspaceFolder.toResource('gulpfile.js'))).then((stat) => { // TODO@Dirk (https://github.com/Microsoft/vscode/issues/29454) let config = ProcessRunnerDetector.detectorConfig('gulp'); let process = new LineProcess('gulp', [config.arg, '--no-color'], true, { cwd: this._cwd }); @@ -239,7 +239,7 @@ export class ProcessRunnerDetector { }); } - private tryDetectGrunt(workspaceFolder: IWorkspaceFolder, list: boolean): Promise { + private tryDetectGrunt(workspaceFolder: IWorkspaceFolder, list: boolean): Promise { return Promise.resolve(this.fileService.resolve(workspaceFolder.toResource('Gruntfile.js'))).then((stat) => { // TODO@Dirk (https://github.com/Microsoft/vscode/issues/29454) let config = ProcessRunnerDetector.detectorConfig('grunt'); let process = new LineProcess('grunt', [config.arg, '--no-color'], true, { cwd: this._cwd }); @@ -249,7 +249,7 @@ export class ProcessRunnerDetector { }); } - private tryDetectJake(workspaceFolder: IWorkspaceFolder, list: boolean): Promise { + private tryDetectJake(workspaceFolder: IWorkspaceFolder, list: boolean): Promise { let run = () => { let config = ProcessRunnerDetector.detectorConfig('jake'); let process = new LineProcess('jake', [config.arg], true, { cwd: this._cwd }); diff --git a/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts b/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts index 7c70bf3fecb..696f4681b4e 100644 --- a/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts +++ b/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts @@ -46,24 +46,24 @@ enum UpdateResult { } export class RemoteFileDialog { - private options: IOpenDialogOptions; - private currentFolder: URI; - private filePickBox: IQuickPick; - private hidden: boolean; - private allowFileSelection: boolean; - private allowFolderSelection: boolean; + private options!: IOpenDialogOptions; + private currentFolder!: URI; + private filePickBox!: IQuickPick; + private hidden: boolean = false; + private allowFileSelection: boolean = true; + private allowFolderSelection: boolean = false; private remoteAuthority: string | undefined; - private requiresTrailing: boolean; + private requiresTrailing: boolean = false; private trailing: string | undefined; private scheme: string = REMOTE_HOST_SCHEME; private contextKey: IContextKey; - private userEnteredPathSegment: string; - private autoCompletePathSegment: string; - private activeItem: FileQuickPickItem; - private userHome: URI; + private userEnteredPathSegment: string = ''; + private autoCompletePathSegment: string = ''; + private activeItem: FileQuickPickItem | undefined; + private userHome!: URI; private badPath: string | undefined; - private remoteAgentEnvironment: IRemoteAgentEnvironment | null; - private separator: string; + private remoteAgentEnvironment: IRemoteAgentEnvironment | null | undefined; + private separator: string = '/'; private onBusyChangeEmitter = new Emitter(); private updatingPromise: CancelablePromise | undefined; @@ -865,4 +865,4 @@ export class RemoteFileDialog { return undefined; } } -} \ No newline at end of file +} From d03a91e63b551283bdc7533ec7971f4ea5a8ec77 Mon Sep 17 00:00:00 2001 From: Bayu Rizki Rahmadi Date: Mon, 5 Aug 2019 19:51:37 +0700 Subject: [PATCH 192/861] Implement Task Provider resolveTask on grunt extension (#76731) * Implement Task Provider resolveTask on grunt extension * Move find grunt command code on computeTask to findGruntCommand function * Fix set detectors and detector dispose * Update grunt resolve task to use same definition object Fixes #76518 --- extensions/grunt/src/main.ts | 98 +++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 29 deletions(-) diff --git a/extensions/grunt/src/main.ts b/extensions/grunt/src/main.ts index deec1587cc2..22b6e9e41cd 100644 --- a/extensions/grunt/src/main.ts +++ b/extensions/grunt/src/main.ts @@ -70,12 +70,27 @@ interface GruntTaskDefinition extends vscode.TaskDefinition { file?: string; } +async function findGruntCommand(rootPath: string): Promise { + 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'; + } + return command; +} + class FolderDetector { private fileWatcher: vscode.FileSystemWatcher | undefined; private promise: Thenable | undefined; - constructor(private _workspaceFolder: vscode.WorkspaceFolder) { + constructor( + private _workspaceFolder: vscode.WorkspaceFolder, + private _gruntCommand: Promise) { } public get workspaceFolder(): vscode.WorkspaceFolder { @@ -95,10 +110,28 @@ class FolderDetector { } public async getTasks(): Promise { - if (!this.promise) { - this.promise = this.computeTasks(); + if (this.isEnabled()) { + if (!this.promise) { + this.promise = this.computeTasks(); + } + return this.promise; + } else { + return []; } - return this.promise; + } + + public async getTask(_task: vscode.Task): Promise { + const gruntTask = (_task.definition).task; + if (gruntTask) { + let kind: GruntTaskDefinition = (_task.definition); + let options: vscode.ShellExecutionOptions = { cwd: this.workspaceFolder.uri.fsPath }; + let source = 'grunt'; + let task = gruntTask.indexOf(' ') === -1 + ? new vscode.Task(kind, this.workspaceFolder, gruntTask, source, new vscode.ShellExecution(`${await this._gruntCommand} ${name}`, options)) + : new vscode.Task(kind, this.workspaceFolder, gruntTask, source, new vscode.ShellExecution(`${await this._gruntCommand} "${name}"`, options)); + return task; + } + return undefined; } private async computeTasks(): Promise { @@ -111,17 +144,7 @@ class FolderDetector { 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`; + let commandLine = `${await this._gruntCommand} --help --no-color`; try { let { stdout, stderr } = await exec(commandLine, { cwd: rootPath }); if (stderr) { @@ -168,8 +191,8 @@ class FolderDetector { 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)); + ? new vscode.Task(kind, this.workspaceFolder, name, source, new vscode.ShellExecution(`${await this._gruntCommand} ${name}`, options)) + : new vscode.Task(kind, this.workspaceFolder, name, source, new vscode.ShellExecution(`${await this._gruntCommand} "${name}"`, options)); result.push(task); let lowerCaseTaskName = name.toLowerCase(); if (isBuildTask(lowerCaseTaskName)) { @@ -239,9 +262,9 @@ class TaskDetector { } } for (let add of added) { - let detector = new FolderDetector(add); + let detector = new FolderDetector(add, findGruntCommand(add.uri.fsPath)); + this.detectors.set(add.uri.toString(), detector); if (detector.isEnabled()) { - this.detectors.set(add.uri.toString(), detector); detector.start(); } } @@ -250,18 +273,16 @@ class TaskDetector { private updateConfiguration(): void { for (let detector of this.detectors.values()) { - if (!detector.isEnabled()) { - detector.dispose(); - this.detectors.delete(detector.workspaceFolder.uri.toString()); - } + 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); + let detector = new FolderDetector(folder, findGruntCommand(folder.uri.fsPath)); + this.detectors.set(folder.uri.toString(), detector); if (detector.isEnabled()) { - this.detectors.set(folder.uri.toString(), detector); detector.start(); } } @@ -272,12 +293,13 @@ class TaskDetector { private updateProvider(): void { if (!this.taskProvider && this.detectors.size > 0) { + const thisCapture = this; this.taskProvider = vscode.workspace.registerTaskProvider('grunt', { - provideTasks: () => { - return this.getTasks(); + provideTasks: (): Promise => { + return thisCapture.getTasks(); }, - resolveTask(_task: vscode.Task): vscode.Task | undefined { - return undefined; + resolveTask(_task: vscode.Task): Promise { + return thisCapture.getTask(_task); } }); } @@ -312,6 +334,24 @@ class TaskDetector { }); } } + + public async getTask(task: vscode.Task): Promise { + if (this.detectors.size === 0) { + return undefined; + } else if (this.detectors.size === 1) { + return this.detectors.values().next().value.getTask(task); + } else { + if ((task.scope === vscode.TaskScope.Workspace) || (task.scope === vscode.TaskScope.Global)) { + return undefined; + } else if (task.scope) { + const detector = this.detectors.get(task.scope.uri.toString()); + if (detector) { + return detector.getTask(task); + } + } + return undefined; + } + } } let detector: TaskDetector; From 5f145f3f994e05284852d5631ec7eafecc8dd57c Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 5 Aug 2019 15:01:18 +0200 Subject: [PATCH 193/861] debug.focusWindowOnBreak update name --- src/vs/workbench/contrib/debug/browser/debug.contribution.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts index 249c1499bb9..f3dd7181695 100644 --- a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts +++ b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts @@ -260,9 +260,9 @@ configurationRegistry.registerConfiguration({ default: { configurations: [], compounds: [] }, $ref: launchSchemaId }, - 'debug.autoFocusEditor': { + 'debug.focusWindowOnBreak': { type: 'boolean', - description: nls.localize('debug.autoFocusEditor', "Controls whether the workbench window should be focused when the debugger stops."), + description: nls.localize('debug.focusWindowOnBreak', "Controls whether the workbench window should be focused when the debugger breaks."), default: true } } From 682cb31dc17c23ee705d90745bdb4e1f4bd09366 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 5 Aug 2019 15:03:13 +0200 Subject: [PATCH 194/861] fixes #73101 --- .../common/inactiveExtensionUrlHandler.ts | 39 ++++++++++++++++++- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/services/extensions/common/inactiveExtensionUrlHandler.ts b/src/vs/workbench/services/extensions/common/inactiveExtensionUrlHandler.ts index 7330ceedefb..22f8c02a13c 100644 --- a/src/vs/workbench/services/extensions/common/inactiveExtensionUrlHandler.ts +++ b/src/vs/workbench/services/extensions/common/inactiveExtensionUrlHandler.ts @@ -20,6 +20,9 @@ import { IWindowService } from 'vs/platform/windows/common/windows'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { IWorkbenchContribution, Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; +import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; const FIVE_MINUTES = 5 * 60 * 1000; const THIRTY_SECONDS = 30 * 1000; @@ -48,7 +51,7 @@ export interface IExtensionUrlHandler { * * It also makes sure the user confirms opening URLs directed towards extensions. */ -export class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler { +class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler { readonly _serviceBrand: any; @@ -67,7 +70,6 @@ export class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler { @IExtensionGalleryService private readonly galleryService: IExtensionGalleryService, @IStorageService private readonly storageService: IStorageService, @IConfigurationService private readonly configurationService: IConfigurationService - ) { const interval = setInterval(() => this.garbageCollect(), THIRTY_SECONDS); const urlToHandleValue = this.storageService.get(URL_TO_HANDLE, StorageScope.WORKSPACE); @@ -80,6 +82,9 @@ export class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler { urlService.registerHandler(this), toDisposable(() => clearInterval(interval)) ); + + const cache = ExtensionUrlBootstrapHandler.cache; + setTimeout(() => cache.forEach(uri => this.handleURL(uri))); } async handleURL(uri: URI, confirmed?: boolean): Promise { @@ -333,3 +338,33 @@ export class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler { } registerSingleton(IExtensionUrlHandler, ExtensionUrlHandler); + +/** + * This class handles URLs before `ExtensionUrlHandler` is instantiated. + * More info: https://github.com/microsoft/vscode/issues/73101 + */ +class ExtensionUrlBootstrapHandler implements IWorkbenchContribution, IURLHandler { + + private static _cache: URI[] = []; + private static disposable: IDisposable; + + static get cache(): URI[] { + ExtensionUrlBootstrapHandler.disposable.dispose(); + + const result = ExtensionUrlBootstrapHandler._cache; + ExtensionUrlBootstrapHandler._cache = []; + return result; + } + + constructor(@IURLService urlService: IURLService) { + ExtensionUrlBootstrapHandler.disposable = urlService.registerHandler(this); + } + + handleURL(uri: URI): Promise { + ExtensionUrlBootstrapHandler._cache.push(uri); + return Promise.resolve(true); + } +} + +const workbenchRegistry = Registry.as(WorkbenchExtensions.Workbench); +workbenchRegistry.registerWorkbenchContribution(ExtensionUrlBootstrapHandler, LifecyclePhase.Ready); From bbb69b2245913b79a813d6d049fb830d13fce8b4 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Mon, 5 Aug 2019 15:05:50 +0200 Subject: [PATCH 195/861] Improve #78168 --- src/vs/base/browser/browser.ts | 2 +- src/vs/base/browser/ui/findinput/findInput.ts | 246 +++++++++--------- .../browser/ui/scrollbar/abstractScrollbar.ts | 2 +- .../browser/ui/scrollbar/scrollableElement.ts | 16 +- src/vs/base/common/color.ts | 4 +- .../browser/controller/textAreaInput.ts | 1 + src/vs/editor/browser/core/editorState.ts | 9 + .../browser/services/codeEditorServiceImpl.ts | 6 +- src/vs/editor/browser/view/viewImpl.ts | 31 +-- src/vs/editor/browser/view/viewLayer.ts | 4 +- .../contentWidgets/contentWidgets.ts | 20 +- .../viewParts/lineNumbers/lineNumbers.ts | 12 +- .../editor/browser/viewParts/margin/margin.ts | 25 +- .../overviewRuler/decorationsOverviewRuler.ts | 2 +- .../viewParts/viewCursors/viewCursor.ts | 8 +- .../viewParts/viewCursors/viewCursors.ts | 2 + .../editor/browser/widget/codeEditorWidget.ts | 2 +- .../editor/browser/widget/diffEditorWidget.ts | 55 ++-- .../editor/common/commands/replaceCommand.ts | 5 +- src/vs/editor/common/commands/shiftCommand.ts | 5 +- .../commands/trimTrailingWhitespaceCommand.ts | 17 +- .../common/config/commonEditorConfig.ts | 2 +- .../common/controller/cursorTypeOperations.ts | 1 + src/vs/editor/common/controller/oneCursor.ts | 4 +- src/vs/editor/common/diff/diffComputer.ts | 2 + .../editor/common/model/indentationGuesser.ts | 4 +- .../pieceTreeTextBuffer/pieceTreeBase.ts | 20 +- src/vs/editor/common/model/textModel.ts | 10 +- src/vs/editor/common/model/textModelTokens.ts | 5 +- .../modes/languageConfigurationRegistry.ts | 12 +- .../services/editorWorkerServiceImpl.ts | 1 + .../editor/common/view/minimapCharRenderer.ts | 4 +- .../common/viewModel/splitLinesCollection.ts | 6 +- .../common/viewModel/viewModelDecorations.ts | 3 +- .../contrib/codeAction/codeActionWidget.ts | 1 + .../contrib/comment/lineCommentCommand.ts | 6 +- src/vs/editor/contrib/find/findController.ts | 16 +- 37 files changed, 298 insertions(+), 273 deletions(-) diff --git a/src/vs/base/browser/browser.ts b/src/vs/base/browser/browser.ts index 6d4436c23eb..1641b7304af 100644 --- a/src/vs/base/browser/browser.ts +++ b/src/vs/base/browser/browser.ts @@ -56,7 +56,7 @@ class WindowManager { } // --- Fullscreen - private _fullscreen: boolean; + private _fullscreen: boolean = false; private readonly _onDidChangeFullscreen = new Emitter(); public readonly onDidChangeFullscreen: Event = this._onDidChangeFullscreen.event; diff --git a/src/vs/base/browser/ui/findinput/findInput.ts b/src/vs/base/browser/ui/findinput/findInput.ts index 180e660f3a5..2a2964beeef 100644 --- a/src/vs/base/browser/ui/findinput/findInput.ts +++ b/src/vs/base/browser/ui/findinput/findInput.ts @@ -114,7 +114,130 @@ export class FindInput extends Widget { this.inputValidationErrorBackground = options.inputValidationErrorBackground; this.inputValidationErrorForeground = options.inputValidationErrorForeground; - this.buildDomNode(options.appendCaseSensitiveLabel || '', options.appendWholeWordsLabel || '', options.appendRegexLabel || '', options.history || [], !!options.flexibleHeight); + const appendCaseSensitiveLabel = options.appendCaseSensitiveLabel || ''; + const appendWholeWordsLabel = options.appendWholeWordsLabel || ''; + const appendRegexLabel = options.appendRegexLabel || ''; + const history = options.history || []; + const flexibleHeight = !!options.flexibleHeight; + + this.domNode = document.createElement('div'); + dom.addClass(this.domNode, 'monaco-findInput'); + + this.inputBox = this._register(new HistoryInputBox(this.domNode, this.contextViewProvider, { + placeholder: this.placeholder || '', + ariaLabel: this.label || '', + validationOptions: { + validation: this.validation + }, + inputBackground: this.inputBackground, + inputForeground: this.inputForeground, + inputBorder: this.inputBorder, + inputValidationInfoBackground: this.inputValidationInfoBackground, + inputValidationInfoForeground: this.inputValidationInfoForeground, + inputValidationInfoBorder: this.inputValidationInfoBorder, + inputValidationWarningBackground: this.inputValidationWarningBackground, + inputValidationWarningForeground: this.inputValidationWarningForeground, + inputValidationWarningBorder: this.inputValidationWarningBorder, + inputValidationErrorBackground: this.inputValidationErrorBackground, + inputValidationErrorForeground: this.inputValidationErrorForeground, + inputValidationErrorBorder: this.inputValidationErrorBorder, + history, + flexibleHeight + })); + + this.regex = this._register(new RegexCheckbox({ + appendTitle: appendRegexLabel, + isChecked: false, + inputActiveOptionBorder: this.inputActiveOptionBorder, + inputActiveOptionBackground: this.inputActiveOptionBackground + })); + this._register(this.regex.onChange(viaKeyboard => { + this._onDidOptionChange.fire(viaKeyboard); + if (!viaKeyboard && this.fixFocusOnOptionClickEnabled) { + this.inputBox.focus(); + } + this.validate(); + })); + this._register(this.regex.onKeyDown(e => { + this._onRegexKeyDown.fire(e); + })); + + this.wholeWords = this._register(new WholeWordsCheckbox({ + appendTitle: appendWholeWordsLabel, + isChecked: false, + inputActiveOptionBorder: this.inputActiveOptionBorder, + inputActiveOptionBackground: this.inputActiveOptionBackground + })); + this._register(this.wholeWords.onChange(viaKeyboard => { + this._onDidOptionChange.fire(viaKeyboard); + if (!viaKeyboard && this.fixFocusOnOptionClickEnabled) { + this.inputBox.focus(); + } + this.validate(); + })); + + this.caseSensitive = this._register(new CaseSensitiveCheckbox({ + appendTitle: appendCaseSensitiveLabel, + isChecked: false, + inputActiveOptionBorder: this.inputActiveOptionBorder, + inputActiveOptionBackground: this.inputActiveOptionBackground + })); + this._register(this.caseSensitive.onChange(viaKeyboard => { + this._onDidOptionChange.fire(viaKeyboard); + if (!viaKeyboard && this.fixFocusOnOptionClickEnabled) { + this.inputBox.focus(); + } + this.validate(); + })); + this._register(this.caseSensitive.onKeyDown(e => { + this._onCaseSensitiveKeyDown.fire(e); + })); + + if (this._showOptionButtons) { + const paddingRight = (this.caseSensitive.width() + this.wholeWords.width() + this.regex.width()) + 'px'; + this.inputBox.inputElement.style.paddingRight = paddingRight; + if (this.inputBox.mirrorElement) { + this.inputBox.mirrorElement.style.paddingRight = paddingRight; + } + } + + // Arrow-Key support to navigate between options + let indexes = [this.caseSensitive.domNode, this.wholeWords.domNode, this.regex.domNode]; + this.onkeydown(this.domNode, (event: IKeyboardEvent) => { + if (event.equals(KeyCode.LeftArrow) || event.equals(KeyCode.RightArrow) || event.equals(KeyCode.Escape)) { + let index = indexes.indexOf(document.activeElement); + if (index >= 0) { + let newIndex: number = -1; + if (event.equals(KeyCode.RightArrow)) { + newIndex = (index + 1) % indexes.length; + } else if (event.equals(KeyCode.LeftArrow)) { + if (index === 0) { + newIndex = indexes.length - 1; + } else { + newIndex = index - 1; + } + } + + if (event.equals(KeyCode.Escape)) { + indexes[index].blur(); + } else if (newIndex >= 0) { + indexes[newIndex].focus(); + } + + dom.EventHelper.stop(event, true); + } + } + }); + + + let controls = document.createElement('div'); + controls.className = 'controls'; + controls.style.display = this._showOptionButtons ? 'block' : 'none'; + controls.appendChild(this.caseSensitive.domNode); + controls.appendChild(this.wholeWords.domNode); + controls.appendChild(this.regex.domNode); + + this.domNode.appendChild(controls); if (parent) { parent.appendChild(this.domNode); @@ -270,127 +393,6 @@ export class FindInput extends Widget { dom.addClass(this.domNode, 'highlight-' + (this._lastHighlightFindOptions)); } - private buildDomNode(appendCaseSensitiveLabel: string, appendWholeWordsLabel: string, appendRegexLabel: string, history: string[], flexibleHeight: boolean): void { - this.domNode = document.createElement('div'); - dom.addClass(this.domNode, 'monaco-findInput'); - - this.inputBox = this._register(new HistoryInputBox(this.domNode, this.contextViewProvider, { - placeholder: this.placeholder || '', - ariaLabel: this.label || '', - validationOptions: { - validation: this.validation - }, - inputBackground: this.inputBackground, - inputForeground: this.inputForeground, - inputBorder: this.inputBorder, - inputValidationInfoBackground: this.inputValidationInfoBackground, - inputValidationInfoForeground: this.inputValidationInfoForeground, - inputValidationInfoBorder: this.inputValidationInfoBorder, - inputValidationWarningBackground: this.inputValidationWarningBackground, - inputValidationWarningForeground: this.inputValidationWarningForeground, - inputValidationWarningBorder: this.inputValidationWarningBorder, - inputValidationErrorBackground: this.inputValidationErrorBackground, - inputValidationErrorForeground: this.inputValidationErrorForeground, - inputValidationErrorBorder: this.inputValidationErrorBorder, - history, - flexibleHeight - })); - - this.regex = this._register(new RegexCheckbox({ - appendTitle: appendRegexLabel, - isChecked: false, - inputActiveOptionBorder: this.inputActiveOptionBorder, - inputActiveOptionBackground: this.inputActiveOptionBackground - })); - this._register(this.regex.onChange(viaKeyboard => { - this._onDidOptionChange.fire(viaKeyboard); - if (!viaKeyboard && this.fixFocusOnOptionClickEnabled) { - this.inputBox.focus(); - } - this.validate(); - })); - this._register(this.regex.onKeyDown(e => { - this._onRegexKeyDown.fire(e); - })); - - this.wholeWords = this._register(new WholeWordsCheckbox({ - appendTitle: appendWholeWordsLabel, - isChecked: false, - inputActiveOptionBorder: this.inputActiveOptionBorder, - inputActiveOptionBackground: this.inputActiveOptionBackground - })); - this._register(this.wholeWords.onChange(viaKeyboard => { - this._onDidOptionChange.fire(viaKeyboard); - if (!viaKeyboard && this.fixFocusOnOptionClickEnabled) { - this.inputBox.focus(); - } - this.validate(); - })); - - this.caseSensitive = this._register(new CaseSensitiveCheckbox({ - appendTitle: appendCaseSensitiveLabel, - isChecked: false, - inputActiveOptionBorder: this.inputActiveOptionBorder, - inputActiveOptionBackground: this.inputActiveOptionBackground - })); - this._register(this.caseSensitive.onChange(viaKeyboard => { - this._onDidOptionChange.fire(viaKeyboard); - if (!viaKeyboard && this.fixFocusOnOptionClickEnabled) { - this.inputBox.focus(); - } - this.validate(); - })); - this._register(this.caseSensitive.onKeyDown(e => { - this._onCaseSensitiveKeyDown.fire(e); - })); - - if (this._showOptionButtons) { - const paddingRight = (this.caseSensitive.width() + this.wholeWords.width() + this.regex.width()) + 'px'; - this.inputBox.inputElement.style.paddingRight = paddingRight; - if (this.inputBox.mirrorElement) { - this.inputBox.mirrorElement.style.paddingRight = paddingRight; - } - } - - // Arrow-Key support to navigate between options - let indexes = [this.caseSensitive.domNode, this.wholeWords.domNode, this.regex.domNode]; - this.onkeydown(this.domNode, (event: IKeyboardEvent) => { - if (event.equals(KeyCode.LeftArrow) || event.equals(KeyCode.RightArrow) || event.equals(KeyCode.Escape)) { - let index = indexes.indexOf(document.activeElement); - if (index >= 0) { - let newIndex: number = -1; - if (event.equals(KeyCode.RightArrow)) { - newIndex = (index + 1) % indexes.length; - } else if (event.equals(KeyCode.LeftArrow)) { - if (index === 0) { - newIndex = indexes.length - 1; - } else { - newIndex = index - 1; - } - } - - if (event.equals(KeyCode.Escape)) { - indexes[index].blur(); - } else if (newIndex >= 0) { - indexes[newIndex].focus(); - } - - dom.EventHelper.stop(event, true); - } - } - }); - - - let controls = document.createElement('div'); - controls.className = 'controls'; - controls.style.display = this._showOptionButtons ? 'block' : 'none'; - controls.appendChild(this.caseSensitive.domNode); - controls.appendChild(this.wholeWords.domNode); - controls.appendChild(this.regex.domNode); - - this.domNode.appendChild(controls); - } - public validate(): void { if (this.inputBox) { this.inputBox.validate(); diff --git a/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts b/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts index 21ccdfa0eb7..4e9245ade07 100644 --- a/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +++ b/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts @@ -49,7 +49,7 @@ export abstract class AbstractScrollbar extends Widget { private _mouseMoveMonitor: GlobalMouseMoveMonitor; public domNode: FastDomNode; - public slider: FastDomNode; + public slider!: FastDomNode; protected _shouldRender: boolean; diff --git a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts index 1c1ded9eb2c..f7216dfdb10 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts @@ -148,9 +148,9 @@ export abstract class AbstractScrollableElement extends Widget { private readonly _horizontalScrollbar: HorizontalScrollbar; private readonly _domNode: HTMLElement; - private readonly _leftShadowDomNode: FastDomNode; - private readonly _topShadowDomNode: FastDomNode; - private readonly _topLeftShadowDomNode: FastDomNode; + private readonly _leftShadowDomNode: FastDomNode | null; + private readonly _topShadowDomNode: FastDomNode | null; + private readonly _topLeftShadowDomNode: FastDomNode | null; private readonly _listenOnDomNode: HTMLElement; @@ -207,6 +207,10 @@ export abstract class AbstractScrollableElement extends Widget { this._topLeftShadowDomNode = createFastDomNode(document.createElement('div')); this._topLeftShadowDomNode.setClassName('shadow top-left-corner'); this._domNode.appendChild(this._topLeftShadowDomNode.domNode); + } else { + this._leftShadowDomNode = null; + this._topShadowDomNode = null; + this._topLeftShadowDomNode = null; } this._listenOnDomNode = this._options.listenOnDomNode || this._domNode; @@ -430,9 +434,9 @@ export abstract class AbstractScrollableElement extends Widget { let enableTop = scrollState.scrollTop > 0; let enableLeft = scrollState.scrollLeft > 0; - this._leftShadowDomNode.setClassName('shadow' + (enableLeft ? ' left' : '')); - this._topShadowDomNode.setClassName('shadow' + (enableTop ? ' top' : '')); - this._topLeftShadowDomNode.setClassName('shadow top-left-corner' + (enableTop ? ' top' : '') + (enableLeft ? ' left' : '')); + this._leftShadowDomNode!.setClassName('shadow' + (enableLeft ? ' left' : '')); + this._topShadowDomNode!.setClassName('shadow' + (enableTop ? ' top' : '')); + this._topLeftShadowDomNode!.setClassName('shadow top-left-corner' + (enableTop ? ' top' : '') + (enableLeft ? ' left' : '')); } } diff --git a/src/vs/base/common/color.ts b/src/vs/base/common/color.ts index 163ecbe74cd..97528a4534c 100644 --- a/src/vs/base/common/color.ts +++ b/src/vs/base/common/color.ts @@ -293,7 +293,7 @@ export class Color { } } - equals(other: Color): boolean { + equals(other: Color | null): boolean { return !!other && RGBA.equals(this.rgba, other.rgba) && HSLA.equals(this.hsla, other.hsla) && HSVA.equals(this.hsva, other.hsva); } @@ -608,4 +608,4 @@ export namespace Color { } } } -} \ No newline at end of file +} diff --git a/src/vs/editor/browser/controller/textAreaInput.ts b/src/vs/editor/browser/controller/textAreaInput.ts index df11729f02d..86e226d86c9 100644 --- a/src/vs/editor/browser/controller/textAreaInput.ts +++ b/src/vs/editor/browser/controller/textAreaInput.ts @@ -119,6 +119,7 @@ export class TextAreaInput extends Disposable { this._asyncTriggerCut = this._register(new RunOnceScheduler(() => this._onCut.fire(), 0)); this._textAreaState = TextAreaState.EMPTY; + this._selectionChangeListener = null; this.writeScreenReaderContent('ctor'); this._hasFocus = false; diff --git a/src/vs/editor/browser/core/editorState.ts b/src/vs/editor/browser/core/editorState.ts index 9b244cd770f..9d469299bbb 100644 --- a/src/vs/editor/browser/core/editorState.ts +++ b/src/vs/editor/browser/core/editorState.ts @@ -35,16 +35,25 @@ export class EditorState { if ((this.flags & CodeEditorStateFlag.Value) !== 0) { const model = editor.getModel(); this.modelVersionId = model ? strings.format('{0}#{1}', model.uri.toString(), model.getVersionId()) : null; + } else { + this.modelVersionId = null; } if ((this.flags & CodeEditorStateFlag.Position) !== 0) { this.position = editor.getPosition(); + } else { + this.position = null; } if ((this.flags & CodeEditorStateFlag.Selection) !== 0) { this.selection = editor.getSelection(); + } else { + this.selection = null; } if ((this.flags & CodeEditorStateFlag.Scroll) !== 0) { this.scrollLeft = editor.getScrollLeft(); this.scrollTop = editor.getScrollTop(); + } else { + this.scrollLeft = -1; + this.scrollTop = -1; } } diff --git a/src/vs/editor/browser/services/codeEditorServiceImpl.ts b/src/vs/editor/browser/services/codeEditorServiceImpl.ts index f439007c476..106c75b5d04 100644 --- a/src/vs/editor/browser/services/codeEditorServiceImpl.ts +++ b/src/vs/editor/browser/services/codeEditorServiceImpl.ts @@ -127,13 +127,13 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider { public refCount: number; public className: string | undefined; - public inlineClassName: string; - public inlineClassNameAffectsLetterSpacing: boolean; + public inlineClassName: string | undefined; + public inlineClassNameAffectsLetterSpacing: boolean | undefined; public beforeContentClassName: string | undefined; public afterContentClassName: string | undefined; public glyphMarginClassName: string | undefined; public isWholeLine: boolean; - public overviewRuler: IModelDecorationOverviewRulerOptions; + public overviewRuler: IModelDecorationOverviewRulerOptions | undefined; public stickiness: TrackedRangeStickiness | undefined; constructor(themeService: IThemeService, providerArgs: ProviderArguments) { diff --git a/src/vs/editor/browser/view/viewImpl.ts b/src/vs/editor/browser/view/viewImpl.ts index 41afb8404aa..a476c33912a 100644 --- a/src/vs/editor/browser/view/viewImpl.ts +++ b/src/vs/editor/browser/view/viewImpl.ts @@ -128,22 +128,6 @@ export class View extends ViewEventHandler { this._textAreaHandler = new TextAreaHandler(this._context, viewController, this.createTextAreaHandlerHelper()); this.viewParts.push(this._textAreaHandler); - this.createViewParts(); - this._setLayout(); - - // Pointer handler - this.pointerHandler = this._register(new PointerHandler(this._context, viewController, this.createPointerHandlerHelper())); - - this._register(model.addEventListener((events: viewEvents.ViewEvent[]) => { - this.eventDispatcher.emitMany(events); - })); - - this._register(this._cursor.addEventListener((events: viewEvents.ViewEvent[]) => { - this.eventDispatcher.emitMany(events); - })); - } - - private createViewParts(): void { // These two dom nodes must be constructed up front, since references are needed in the layout provider (scrolling & co.) this.linesContent = createFastDomNode(document.createElement('div')); this.linesContent.setClassName('lines-content' + ' monaco-editor-background'); @@ -233,6 +217,19 @@ export class View extends ViewEventHandler { this.overflowGuardContainer.appendChild(minimap.getDomNode()); this.domNode.appendChild(this.overflowGuardContainer); this.domNode.appendChild(this.contentWidgets.overflowingContentWidgetsDomNode); + + this._setLayout(); + + // Pointer handler + this.pointerHandler = this._register(new PointerHandler(this._context, viewController, this.createPointerHandlerHelper())); + + this._register(model.addEventListener((events: viewEvents.ViewEvent[]) => { + this.eventDispatcher.emitMany(events); + })); + + this._register(this._cursor.addEventListener((events: viewEvents.ViewEvent[]) => { + this.eventDispatcher.emitMany(events); + })); } private _flushAccumulatedAndRenderNow(): void { @@ -541,7 +538,7 @@ export class View extends ViewEventHandler { public layoutContentWidget(widgetData: IContentWidgetData): void { const newPosition = widgetData.position ? widgetData.position.position : null; - const newRange = widgetData.position ? widgetData.position.range : null; + const newRange = widgetData.position ? widgetData.position.range || null : null; const newPreference = widgetData.position ? widgetData.position.preference : null; this.contentWidgets.setWidgetPosition(widgetData.widget, newPosition, newRange, newPreference); this._scheduleRender(); diff --git a/src/vs/editor/browser/view/viewLayer.ts b/src/vs/editor/browser/view/viewLayer.ts index b16f615c3b1..ecdd665be73 100644 --- a/src/vs/editor/browser/view/viewLayer.ts +++ b/src/vs/editor/browser/view/viewLayer.ts @@ -34,8 +34,8 @@ export interface ILine { export class RenderedLinesCollection { private readonly _createLine: () => T; - private _lines: T[]; - private _rendLineNumberStart: number; + private _lines!: T[]; + private _rendLineNumberStart!: number; constructor(createLine: () => T) { this._createLine = createLine; diff --git a/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts b/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts index c275168cca7..cae3be1ed16 100644 --- a/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts +++ b/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts @@ -14,7 +14,6 @@ import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/v import { ViewContext } from 'vs/editor/common/view/viewContext'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData'; -import { withUndefinedAsNull } from 'vs/base/common/types'; class Coordinate { _coordinateBrand: void; @@ -111,7 +110,7 @@ export class ViewContentWidgets extends ViewPart { this.setShouldRender(); } - public setWidgetPosition(widget: IContentWidget, position: IPosition | null | undefined, range: IRange | null | undefined, preference: ContentWidgetPositionPreference[] | null | undefined): void { + public setWidgetPosition(widget: IContentWidget, position: IPosition | null, range: IRange | null, preference: ContentWidgetPositionPreference[] | null): void { const myWidget = this._widgets[widget.getId()]; myWidget.setPosition(position, range, preference); @@ -202,8 +201,8 @@ class Widget { this._context = context; this._viewDomNode = viewDomNode; this._actual = actual; - this.domNode = createFastDomNode(this._actual.getDomNode()); + this.domNode = createFastDomNode(this._actual.getDomNode()); this.id = this._actual.getId(); this.allowEditorOverflow = this._actual.allowEditorOverflow || false; this.suppressMouseDown = this._actual.suppressMouseDown || false; @@ -213,7 +212,10 @@ class Widget { this._contentLeft = this._context.configuration.editor.layoutInfo.contentLeft; this._lineHeight = this._context.configuration.editor.lineHeight; - this._setPosition(null, null); + this._position = null; + this._range = null; + this._viewPosition = null; + this._viewRange = null; this._preference = []; this._cachedDomNodeClientWidth = -1; this._cachedDomNodeClientHeight = -1; @@ -242,9 +244,9 @@ class Widget { this._setPosition(this._position, this._range); } - private _setPosition(position: IPosition | null | undefined, range: IRange | null | undefined): void { - this._position = withUndefinedAsNull(position); - this._range = withUndefinedAsNull(range); + private _setPosition(position: IPosition | null, range: IRange | null): void { + this._position = position; + this._range = range; this._viewPosition = null; this._viewRange = null; @@ -270,9 +272,9 @@ class Widget { ); } - public setPosition(position: IPosition | null | undefined, range: IRange | null | undefined, preference: ContentWidgetPositionPreference[] | null | undefined): void { + public setPosition(position: IPosition | null, range: IRange | null, preference: ContentWidgetPositionPreference[] | null): void { this._setPosition(position, range); - this._preference = withUndefinedAsNull(preference); + this._preference = preference; this._cachedDomNodeClientWidth = -1; this._cachedDomNodeClientHeight = -1; } diff --git a/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.ts b/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.ts index 8ccd25f7453..3e9b2d6c68b 100644 --- a/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.ts +++ b/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.ts @@ -20,12 +20,12 @@ export class LineNumbersOverlay extends DynamicViewOverlay { private readonly _context: ViewContext; - private _lineHeight: number; - private _renderLineNumbers: RenderLineNumbersType; - private _renderCustomLineNumbers: ((lineNumber: number) => string) | null; - private _renderFinalNewline: boolean; - private _lineNumbersLeft: number; - private _lineNumbersWidth: number; + private _lineHeight!: number; + private _renderLineNumbers!: RenderLineNumbersType; + private _renderCustomLineNumbers!: ((lineNumber: number) => string) | null; + private _renderFinalNewline!: boolean; + private _lineNumbersLeft!: number; + private _lineNumbersWidth!: number; private _lastCursorModelPosition: Position; private _renderResult: string[] | null; diff --git a/src/vs/editor/browser/viewParts/margin/margin.ts b/src/vs/editor/browser/viewParts/margin/margin.ts index eda44ab11d6..ab4f24c7bf3 100644 --- a/src/vs/editor/browser/viewParts/margin/margin.ts +++ b/src/vs/editor/browser/viewParts/margin/margin.ts @@ -28,7 +28,16 @@ export class Margin extends ViewPart { this._glyphMarginLeft = this._context.configuration.editor.layoutInfo.glyphMarginLeft; this._glyphMarginWidth = this._context.configuration.editor.layoutInfo.glyphMarginWidth; - this._domNode = this._createDomNode(); + this._domNode = createFastDomNode(document.createElement('div')); + this._domNode.setClassName(Margin.OUTER_CLASS_NAME); + this._domNode.setPosition('absolute'); + this._domNode.setAttribute('role', 'presentation'); + this._domNode.setAttribute('aria-hidden', 'true'); + + this._glyphMarginBackgroundDomNode = createFastDomNode(document.createElement('div')); + this._glyphMarginBackgroundDomNode.setClassName(Margin.CLASS_NAME); + + this._domNode.appendChild(this._glyphMarginBackgroundDomNode); } public dispose(): void { @@ -39,20 +48,6 @@ export class Margin extends ViewPart { return this._domNode; } - private _createDomNode(): FastDomNode { - const domNode = createFastDomNode(document.createElement('div')); - domNode.setClassName(Margin.OUTER_CLASS_NAME); - domNode.setPosition('absolute'); - domNode.setAttribute('role', 'presentation'); - domNode.setAttribute('aria-hidden', 'true'); - - this._glyphMarginBackgroundDomNode = createFastDomNode(document.createElement('div')); - this._glyphMarginBackgroundDomNode.setClassName(Margin.CLASS_NAME); - - domNode.appendChild(this._glyphMarginBackgroundDomNode); - return domNode; - } - // --- begin event handlers public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean { diff --git a/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts b/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts index 2aaaac909bf..c186568ad8f 100644 --- a/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts +++ b/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts @@ -201,7 +201,7 @@ export class DecorationsOverviewRuler extends ViewPart { private readonly _tokensColorTrackerListener: IDisposable; private readonly _domNode: FastDomNode; - private _settings: Settings; + private _settings!: Settings; private _cursorPositions: Position[]; constructor(context: ViewContext) { diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts index 3cf99a75291..37105276557 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts @@ -68,7 +68,7 @@ export class ViewCursor { Configuration.applyFontInfo(this._domNode, this._context.configuration.editor.fontInfo); this._domNode.setDisplay('none'); - this.updatePosition(new Position(1, 1)); + this._position = new Position(1, 1); this._lastRenderedContent = ''; this._renderData = null; @@ -113,7 +113,7 @@ export class ViewCursor { } public onCursorPositionChanged(position: Position): boolean { - this.updatePosition(position); + this._position = position; return true; } @@ -210,8 +210,4 @@ export class ViewCursor { width: 2 }; } - - private updatePosition(newPosition: Position): void { - this._position = newPosition; - } } diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts index 982b021bd1a..023e031dd02 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts @@ -49,6 +49,8 @@ export class ViewCursors extends ViewPart { this._cursorSmoothCaretAnimation = this._context.configuration.editor.viewInfo.cursorSmoothCaretAnimation; this._selectionIsEmpty = true; + this._isVisible = false; + this._primaryCursor = new ViewCursor(this._context); this._secondaryCursors = []; this._renderData = []; diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index d83f185fdf1..e6a4fd05977 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -279,7 +279,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE this._instantiationService = instantiationService.createChild(new ServiceCollection([IContextKeyService, this._contextKeyService])); - this._attachModel(null); + this._modelData = null; this._contributions = {}; this._actions = {}; diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index 9c3c0df63e8..4bb1a3b218f 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -159,12 +159,12 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE private readonly _measureDomElementToken: number; private originalEditor: CodeEditorWidget; - private _originalDomNode: HTMLElement; + private readonly _originalDomNode: HTMLElement; private readonly _originalEditorState: VisualEditorState; private _originalOverviewRuler: editorBrowser.IOverviewRuler; private modifiedEditor: CodeEditorWidget; - private _modifiedDomNode: HTMLElement; + private readonly _modifiedDomNode: HTMLElement; private readonly _modifiedEditorState: VisualEditorState; private _modifiedOverviewRuler: editorBrowser.IOverviewRuler; @@ -264,8 +264,19 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE })); this._containerDomElement.appendChild(this._overviewDomElement); - this._createLeftHandSide(); - this._createRightHandSide(); + // Create left side + this._originalDomNode = document.createElement('div'); + this._originalDomNode.className = 'editor original'; + this._originalDomNode.style.position = 'absolute'; + this._originalDomNode.style.height = '100%'; + this._containerDomElement.appendChild(this._originalDomNode); + + // Create right side + this._modifiedDomNode = document.createElement('div'); + this._modifiedDomNode.className = 'editor modified'; + this._modifiedDomNode.style.position = 'absolute'; + this._modifiedDomNode.style.height = '100%'; + this._containerDomElement.appendChild(this._modifiedDomNode); this._beginUpdateDecorationsTimeout = -1; this._currentlyChangingViewZones = false; @@ -386,22 +397,6 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE this._layoutOverviewRulers(); } - private _createLeftHandSide(): void { - this._originalDomNode = document.createElement('div'); - this._originalDomNode.className = 'editor original'; - this._originalDomNode.style.position = 'absolute'; - this._originalDomNode.style.height = '100%'; - this._containerDomElement.appendChild(this._originalDomNode); - } - - private _createRightHandSide(): void { - this._modifiedDomNode = document.createElement('div'); - this._modifiedDomNode.className = 'editor modified'; - this._modifiedDomNode.style.position = 'absolute'; - this._modifiedDomNode.style.height = '100%'; - this._containerDomElement.appendChild(this._modifiedDomNode); - } - private _createLeftHandSideEditor(options: editorOptions.IDiffEditorOptions, instantiationService: IInstantiationService): void { this.originalEditor = this._createInnerEditor(instantiationService, this._originalDomNode, this._adjustOptionsForLeftHandSide(options, this._originalIsEditable)); @@ -1186,12 +1181,14 @@ interface IDataSource { abstract class DiffEditorWidgetStyle extends Disposable implements IDiffEditorWidgetStyle { _dataSource: IDataSource; - _insertColor: Color; - _removeColor: Color; + _insertColor: Color | null; + _removeColor: Color | null; constructor(dataSource: IDataSource) { super(); this._dataSource = dataSource; + this._insertColor = null; + this._removeColor = null; } public applyColors(theme: ITheme): boolean { @@ -1257,6 +1254,7 @@ class ForeignViewZonesIterator { constructor(source: IEditorWhitespace[]) { this._source = source; this._index = -1; + this.current = null; this.advance(); } @@ -1535,7 +1533,7 @@ class DiffEditorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffE private readonly _sash: Sash; private _sashRatio: number | null; private _sashPosition: number | null; - private _startSashPosition: number; + private _startSashPosition: number | null; constructor(dataSource: IDataSource, enableSplitViewResizing: boolean) { super(dataSource); @@ -1543,6 +1541,7 @@ class DiffEditorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffE this._disableSash = (enableSplitViewResizing === false); this._sashRatio = null; this._sashPosition = null; + this._startSashPosition = null; this._sash = this._register(new Sash(this._dataSource.getContainerDomNode(), this)); if (this._disableSash) { @@ -1599,7 +1598,7 @@ class DiffEditorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffE private onSashDrag(e: ISashEvent): void { let w = this._dataSource.getWidth(); let contentWidth = w - DiffEditorWidget.ENTIRE_DIFF_OVERVIEW_WIDTH; - let sashPosition = this.layout((this._startSashPosition + (e.currentX - e.startX)) / contentWidth); + let sashPosition = this.layout((this._startSashPosition! + (e.currentX - e.startX)) / contentWidth); this._sashRatio = sashPosition / contentWidth; @@ -1634,7 +1633,7 @@ class DiffEditorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffE } protected _getOriginalEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations { - const overviewZoneColor = this._removeColor.toString(); + const overviewZoneColor = String(this._removeColor); let result: IEditorDiffDecorations = { decorations: [], @@ -1694,7 +1693,7 @@ class DiffEditorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffE } protected _getModifiedEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations { - const overviewZoneColor = this._insertColor.toString(); + const overviewZoneColor = String(this._insertColor); let result: IEditorDiffDecorations = { decorations: [], @@ -1814,7 +1813,7 @@ class DiffEditorWidgetInline extends DiffEditorWidgetStyle implements IDiffEdito } protected _getOriginalEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations { - const overviewZoneColor = this._removeColor.toString(); + const overviewZoneColor = String(this._removeColor); let result: IEditorDiffDecorations = { decorations: [], @@ -1843,7 +1842,7 @@ class DiffEditorWidgetInline extends DiffEditorWidgetStyle implements IDiffEdito } protected _getModifiedEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations { - const overviewZoneColor = this._insertColor.toString(); + const overviewZoneColor = String(this._insertColor); let result: IEditorDiffDecorations = { decorations: [], diff --git a/src/vs/editor/common/commands/replaceCommand.ts b/src/vs/editor/common/commands/replaceCommand.ts index c6cd6494050..6cd736b2adf 100644 --- a/src/vs/editor/common/commands/replaceCommand.ts +++ b/src/vs/editor/common/commands/replaceCommand.ts @@ -101,12 +101,13 @@ export class ReplaceCommandThatPreservesSelection implements ICommand { private readonly _range: Range; private readonly _text: string; private readonly _initialSelection: Selection; - private _selectionId: string; + private _selectionId: string | null; constructor(editRange: Range, text: string, initialSelection: Selection) { this._range = editRange; this._text = text; this._initialSelection = initialSelection; + this._selectionId = null; } public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { @@ -115,6 +116,6 @@ export class ReplaceCommandThatPreservesSelection implements ICommand { } public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection { - return helper.getTrackedSelection(this._selectionId); + return helper.getTrackedSelection(this._selectionId!); } } diff --git a/src/vs/editor/common/commands/shiftCommand.ts b/src/vs/editor/common/commands/shiftCommand.ts index 16ff871c456..b4cbf839717 100644 --- a/src/vs/editor/common/commands/shiftCommand.ts +++ b/src/vs/editor/common/commands/shiftCommand.ts @@ -70,13 +70,14 @@ export class ShiftCommand implements ICommand { private readonly _opts: IShiftCommandOpts; private readonly _selection: Selection; - private _selectionId: string; + private _selectionId: string | null; private _useLastEditRangeForCursorEndPosition: boolean; private _selectionStartColumnStaysPut: boolean; constructor(range: Selection, opts: IShiftCommandOpts) { this._opts = opts; this._selection = range; + this._selectionId = null; this._useLastEditRangeForCursorEndPosition = false; this._selectionStartColumnStaysPut = false; } @@ -241,7 +242,7 @@ export class ShiftCommand implements ICommand { let lastOp = helper.getInverseEditOperations()[0]; return new Selection(lastOp.range.endLineNumber, lastOp.range.endColumn, lastOp.range.endLineNumber, lastOp.range.endColumn); } - const result = helper.getTrackedSelection(this._selectionId); + const result = helper.getTrackedSelection(this._selectionId!); if (this._selectionStartColumnStaysPut) { // The selection start should not move diff --git a/src/vs/editor/common/commands/trimTrailingWhitespaceCommand.ts b/src/vs/editor/common/commands/trimTrailingWhitespaceCommand.ts index 2d442842b97..1197109912d 100644 --- a/src/vs/editor/common/commands/trimTrailingWhitespaceCommand.ts +++ b/src/vs/editor/common/commands/trimTrailingWhitespaceCommand.ts @@ -13,28 +13,29 @@ import { IIdentifiedSingleEditOperation, ITextModel } from 'vs/editor/common/mod export class TrimTrailingWhitespaceCommand implements ICommand { - private readonly selection: Selection; - private selectionId: string; - private readonly cursors: Position[]; + private readonly _selection: Selection; + private _selectionId: string | null; + private readonly _cursors: Position[]; constructor(selection: Selection, cursors: Position[]) { - this.selection = selection; - this.cursors = cursors; + this._selection = selection; + this._cursors = cursors; + this._selectionId = null; } public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { - let ops = trimTrailingWhitespace(model, this.cursors); + let ops = trimTrailingWhitespace(model, this._cursors); for (let i = 0, len = ops.length; i < len; i++) { let op = ops[i]; builder.addEditOperation(op.range, op.text); } - this.selectionId = builder.trackSelection(this.selection); + this._selectionId = builder.trackSelection(this._selection); } public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection { - return helper.getTrackedSelection(this.selectionId); + return helper.getTrackedSelection(this._selectionId!); } } diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index 5d1818712b0..ce4ee056c46 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -68,7 +68,7 @@ export abstract class CommonEditorConfiguration extends Disposable implements ed public readonly isSimpleWidget: boolean; protected _rawOptions: editorOptions.IEditorOptions; protected _validatedOptions: editorOptions.IValidatedEditorOptions; - public editor: editorOptions.InternalEditorOptions; + public editor!: editorOptions.InternalEditorOptions; private _isDominatedByLongLines: boolean; private _lineNumbersDigitCount: number; diff --git a/src/vs/editor/common/controller/cursorTypeOperations.ts b/src/vs/editor/common/controller/cursorTypeOperations.ts index 73d984cfb62..efa30c1b5cc 100644 --- a/src/vs/editor/common/controller/cursorTypeOperations.ts +++ b/src/vs/editor/common/controller/cursorTypeOperations.ts @@ -947,6 +947,7 @@ export class TypeWithAutoClosingCommand extends ReplaceCommandWithOffsetCursorSt super(selection, openCharacter + closeCharacter, 0, -closeCharacter.length); this._closeCharacter = closeCharacter; this.closeCharacterRange = null; + this.enclosingRange = null; } public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection { diff --git a/src/vs/editor/common/controller/oneCursor.ts b/src/vs/editor/common/controller/oneCursor.ts index e19068883ef..2bb09583133 100644 --- a/src/vs/editor/common/controller/oneCursor.ts +++ b/src/vs/editor/common/controller/oneCursor.ts @@ -11,8 +11,8 @@ import { TrackedRangeStickiness } from 'vs/editor/common/model'; export class OneCursor { - public modelState: SingleCursorState; - public viewState: SingleCursorState; + public modelState!: SingleCursorState; + public viewState!: SingleCursorState; private _selTrackedRange: string | null; private _trackSelection: boolean; diff --git a/src/vs/editor/common/diff/diffComputer.ts b/src/vs/editor/common/diff/diffComputer.ts index be2d727328a..67ccd7e5c4e 100644 --- a/src/vs/editor/common/diff/diffComputer.ts +++ b/src/vs/editor/common/diff/diffComputer.ts @@ -328,6 +328,8 @@ export class DiffComputer { this.modifiedLines = modifiedLines; this.original = new LineMarkerSequence(originalLines); this.modified = new LineMarkerSequence(modifiedLines); + + this.computationStartTime = (new Date()).getTime(); } public computeDiff(): ILineChange[] { diff --git a/src/vs/editor/common/model/indentationGuesser.ts b/src/vs/editor/common/model/indentationGuesser.ts index 24c449c60c4..709e6ddd741 100644 --- a/src/vs/editor/common/model/indentationGuesser.ts +++ b/src/vs/editor/common/model/indentationGuesser.ts @@ -7,8 +7,8 @@ import { CharCode } from 'vs/base/common/charCode'; import { ITextBuffer } from 'vs/editor/common/model'; class SpacesDiffResult { - public spacesDiff: number; - public looksLikeAlignment: boolean; + public spacesDiff: number = 0; + public looksLikeAlignment: boolean = false; } /** diff --git a/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts b/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts index 445ddde972f..9e38117e9e7 100644 --- a/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts +++ b/src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts @@ -265,16 +265,16 @@ class PieceTreeSearchCache { } export class PieceTreeBase { - root: TreeNode; - protected _buffers: StringBuffer[]; // 0 is change buffer, others are readonly original buffer. - protected _lineCnt: number; - protected _length: number; - protected _EOL: string; - protected _EOLLength: number; - protected _EOLNormalized: boolean; - private _lastChangeBufferPos: BufferCursor; - private _searchCache: PieceTreeSearchCache; - private _lastVisitedLine: { lineNumber: number; value: string; }; + root!: TreeNode; + protected _buffers!: StringBuffer[]; // 0 is change buffer, others are readonly original buffer. + protected _lineCnt!: number; + protected _length!: number; + protected _EOL!: string; + protected _EOLLength!: number; + protected _EOLNormalized!: boolean; + private _lastChangeBufferPos!: BufferCursor; + private _searchCache!: PieceTreeSearchCache; + private _lastVisitedLine!: { lineNumber: number; value: string; }; constructor(chunks: StringBuffer[], eol: '\r\n' | '\n', eolNormalized: boolean) { this.create(chunks, eol, eolNormalized); diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index e73183b0bcc..874d7428cf3 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -329,7 +329,9 @@ export class TextModel extends Disposable implements model.ITextModel { this._isTooLargeForSyncing = (bufferTextLength > TextModel.MODEL_SYNC_LIMIT); - this._setVersionId(1); + this._versionId = 1; + this._alternativeVersionId = 1; + this._isDisposed = false; this._isDisposing = false; @@ -693,11 +695,7 @@ export class TextModel extends Disposable implements model.ITextModel { } private _increaseVersionId(): void { - this._setVersionId(this._versionId + 1); - } - - private _setVersionId(newVersionId: number): void { - this._versionId = newVersionId; + this._versionId = this._versionId + 1; this._alternativeVersionId = this._versionId; } diff --git a/src/vs/editor/common/model/textModelTokens.ts b/src/vs/editor/common/model/textModelTokens.ts index 076b142db79..03e1c4bd6b7 100644 --- a/src/vs/editor/common/model/textModelTokens.ts +++ b/src/vs/editor/common/model/textModelTokens.ts @@ -28,7 +28,10 @@ export class TokenizationStateStore { private _invalidLineStartIndex: number; constructor() { - this._reset(null); + this._beginState = []; + this._valid = []; + this._len = 0; + this._invalidLineStartIndex = 0; } private _reset(initialState: IState | null): void { diff --git a/src/vs/editor/common/modes/languageConfigurationRegistry.ts b/src/vs/editor/common/modes/languageConfigurationRegistry.ts index 713df07ca0d..baf47379af9 100644 --- a/src/vs/editor/common/modes/languageConfigurationRegistry.ts +++ b/src/vs/editor/common/modes/languageConfigurationRegistry.ts @@ -53,7 +53,7 @@ export class RichEditSupport { public readonly characterPair: CharacterPairSupport; public readonly wordDefinition: RegExp; public readonly onEnter: OnEnterSupport | null; - public readonly indentRulesSupport: IndentRulesSupport; + public readonly indentRulesSupport: IndentRulesSupport | null; public readonly indentationRules: IndentationRule | undefined; public readonly foldingRules: FoldingRules; @@ -81,6 +81,8 @@ export class RichEditSupport { this.indentationRules = this._conf.indentationRules; if (this._conf.indentationRules) { this.indentRulesSupport = new IndentRulesSupport(this._conf.indentationRules); + } else { + this.indentRulesSupport = null; } this.foldingRules = this._conf.folding || {}; @@ -170,7 +172,9 @@ export class RichEditSupport { } export class LanguageConfigurationChangeEvent { - languageIdentifier: LanguageIdentifier; + constructor( + public readonly languageIdentifier: LanguageIdentifier + ) { } } export class LanguageConfigurationRegistryImpl { @@ -184,11 +188,11 @@ export class LanguageConfigurationRegistryImpl { let previous = this._getRichEditSupport(languageIdentifier.id); let current = new RichEditSupport(languageIdentifier, previous, configuration); this._entries.set(languageIdentifier.id, current); - this._onDidChange.fire({ languageIdentifier }); + this._onDidChange.fire(new LanguageConfigurationChangeEvent(languageIdentifier)); return toDisposable(() => { if (this._entries.get(languageIdentifier.id) === current) { this._entries.set(languageIdentifier.id, previous); - this._onDidChange.fire({ languageIdentifier }); + this._onDidChange.fire(new LanguageConfigurationChangeEvent(languageIdentifier)); } }); } diff --git a/src/vs/editor/common/services/editorWorkerServiceImpl.ts b/src/vs/editor/common/services/editorWorkerServiceImpl.ts index 1d46cc3a263..74ff7b7fbfa 100644 --- a/src/vs/editor/common/services/editorWorkerServiceImpl.ts +++ b/src/vs/editor/common/services/editorWorkerServiceImpl.ts @@ -167,6 +167,7 @@ class WorkerManager extends Disposable { super(); this._modelService = modelService; this._editorWorkerClient = null; + this._lastWorkerUsedTime = (new Date()).getTime(); let stopWorkerInterval = this._register(new IntervalTimer()); stopWorkerInterval.cancelAndSet(() => this._checkStopIdleWorker(), Math.round(STOP_WORKER_DELTA_TIME_MS / 2)); diff --git a/src/vs/editor/common/view/minimapCharRenderer.ts b/src/vs/editor/common/view/minimapCharRenderer.ts index adae1644741..17c835d8c2e 100644 --- a/src/vs/editor/common/view/minimapCharRenderer.ts +++ b/src/vs/editor/common/view/minimapCharRenderer.ts @@ -16,8 +16,8 @@ export class MinimapTokensColorTracker { return this._INSTANCE; } - private _colors: RGBA8[]; - private _backgroundIsLight: boolean; + private _colors!: RGBA8[]; + private _backgroundIsLight!: boolean; private _onDidChange = new Emitter(); public readonly onDidChange: Event = this._onDidChange.event; diff --git a/src/vs/editor/common/viewModel/splitLinesCollection.ts b/src/vs/editor/common/viewModel/splitLinesCollection.ts index f593fdbc563..5ff99437b1b 100644 --- a/src/vs/editor/common/viewModel/splitLinesCollection.ts +++ b/src/vs/editor/common/viewModel/splitLinesCollection.ts @@ -155,13 +155,13 @@ export class SplitLinesCollection implements IViewModelLinesCollection { private columnsForFullWidthChar: number; private wrappingIndent: WrappingIndent; private tabSize: number; - private lines: ISplitLine[]; + private lines!: ISplitLine[]; - private prefixSumComputer: PrefixSumComputerWithCache; + private prefixSumComputer!: PrefixSumComputerWithCache; private readonly linePositionMapperFactory: ILineMapperFactory; - private hiddenAreasIds: string[]; + private hiddenAreasIds!: string[]; constructor(model: ITextModel, linePositionMapperFactory: ILineMapperFactory, tabSize: number, wrappingColumn: number, columnsForFullWidthChar: number, wrappingIndent: WrappingIndent) { this.model = model; diff --git a/src/vs/editor/common/viewModel/viewModelDecorations.ts b/src/vs/editor/common/viewModel/viewModelDecorations.ts index 96944088919..07df48c622e 100644 --- a/src/vs/editor/common/viewModel/viewModelDecorations.ts +++ b/src/vs/editor/common/viewModel/viewModelDecorations.ts @@ -42,7 +42,8 @@ export class ViewModelDecorations implements IDisposable { this._linesCollection = linesCollection; this._coordinatesConverter = coordinatesConverter; this._decorationsCache = Object.create(null); - this._clearCachedModelDecorationsResolver(); + this._cachedModelDecorationsResolver = null; + this._cachedModelDecorationsResolverViewRange = null; } private _clearCachedModelDecorationsResolver(): void { diff --git a/src/vs/editor/contrib/codeAction/codeActionWidget.ts b/src/vs/editor/contrib/codeAction/codeActionWidget.ts index ebbeeccb1ee..4f31015c81c 100644 --- a/src/vs/editor/contrib/codeAction/codeActionWidget.ts +++ b/src/vs/editor/contrib/codeAction/codeActionWidget.ts @@ -30,6 +30,7 @@ export class CodeActionWidget extends Disposable { private readonly _delegate: CodeActionWidgetDelegate, ) { super(); + this._visible = false; } public async show(codeActions: CodeActionSet, at?: IAnchor | IPosition): Promise { diff --git a/src/vs/editor/contrib/comment/lineCommentCommand.ts b/src/vs/editor/contrib/comment/lineCommentCommand.ts index 26b3f9e9111..a097d994648 100644 --- a/src/vs/editor/contrib/comment/lineCommentCommand.ts +++ b/src/vs/editor/contrib/comment/lineCommentCommand.ts @@ -49,7 +49,7 @@ export const enum Type { export class LineCommentCommand implements editorCommon.ICommand { private readonly _selection: Selection; - private _selectionId: string; + private _selectionId: string | null; private _deltaColumn: number; private _moveEndPositionDown: boolean; private readonly _tabSize: number; @@ -57,9 +57,11 @@ export class LineCommentCommand implements editorCommon.ICommand { constructor(selection: Selection, tabSize: number, type: Type) { this._selection = selection; + this._selectionId = null; this._tabSize = tabSize; this._type = type; this._deltaColumn = 0; + this._moveEndPositionDown = false; } /** @@ -323,7 +325,7 @@ export class LineCommentCommand implements editorCommon.ICommand { } public computeCursorState(model: ITextModel, helper: editorCommon.ICursorStateComputerData): Selection { - let result = helper.getTrackedSelection(this._selectionId); + let result = helper.getTrackedSelection(this._selectionId!); if (this._moveEndPositionDown) { result = result.setEndPosition(result.endLineNumber + 1, 1); diff --git a/src/vs/editor/contrib/find/findController.ts b/src/vs/editor/contrib/find/findController.ts index 739cde26fef..ed3544d10ff 100644 --- a/src/vs/editor/contrib/find/findController.ts +++ b/src/vs/editor/contrib/find/findController.ts @@ -374,8 +374,8 @@ export class CommonFindController extends Disposable implements editorCommon.IEd export class FindController extends CommonFindController implements IFindController { - private _widget: FindWidget; - private _findOptionsWidget: FindOptionsWidget; + private _widget: FindWidget | null; + private _findOptionsWidget: FindOptionsWidget | null; constructor( editor: ICodeEditor, @@ -387,6 +387,8 @@ export class FindController extends CommonFindController implements IFindControl @optional(IClipboardService) clipboardService: IClipboardService ) { super(editor, _contextKeyService, storageService, clipboardService); + this._widget = null; + this._findOptionsWidget = null; } protected _start(opts: IFindStartOptions): void { @@ -394,7 +396,7 @@ export class FindController extends CommonFindController implements IFindControl this._createFindWidget(); } - if (!this._widget.getPosition() && this._editor.getConfiguration().contribInfo.find.autoFindInSelection) { + if (!this._widget!.getPosition() && this._editor.getConfiguration().contribInfo.find.autoFindInSelection) { // not visible yet so we need to set search scope if `editor.find.autoFindInSelection` is `true` opts.updateSearchScope = true; } @@ -402,9 +404,9 @@ export class FindController extends CommonFindController implements IFindControl super._start(opts); if (opts.shouldFocus === FindStartFocusAction.FocusReplaceInput) { - this._widget.focusReplaceInput(); + this._widget!.focusReplaceInput(); } else if (opts.shouldFocus === FindStartFocusAction.FocusFindInput) { - this._widget.focusFindInput(); + this._widget!.focusFindInput(); } } @@ -413,9 +415,9 @@ export class FindController extends CommonFindController implements IFindControl this._createFindWidget(); } if (this._state.isRevealed) { - this._widget.highlightFindOptions(); + this._widget!.highlightFindOptions(); } else { - this._findOptionsWidget.highlightFindOptions(); + this._findOptionsWidget!.highlightFindOptions(); } } From ea123f75479830b03b270015c22c105c2611c098 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 5 Aug 2019 15:12:11 +0200 Subject: [PATCH 196/861] web - make service worker optional --- src/vs/base/browser/dom.ts | 2 +- .../browser/resourceServiceWorker.ts | 40 ++--- .../browser/resourceServiceWorkerClient.ts | 148 +++--------------- .../browser/resourceServiceWorkerMain.ts | 2 +- 4 files changed, 33 insertions(+), 159 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index fa12f629000..fdaab73b0b7 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -1200,7 +1200,7 @@ export function asDomUri(uri: URI): URI { if (Schemas.vscodeRemote === uri.scheme) { // rewrite vscode-remote-uris to uris of the window location // so that they can be intercepted by the service worker - return _location.with({ path: '/vscode-resources/fetch', query: `u=${JSON.stringify(uri)}` }); + return _location.with({ path: '/vscode-remote', query: JSON.stringify(uri) }); } return uri; } diff --git a/src/vs/workbench/contrib/resources/browser/resourceServiceWorker.ts b/src/vs/workbench/contrib/resources/browser/resourceServiceWorker.ts index 622bb7889be..48b238d10f3 100644 --- a/src/vs/workbench/contrib/resources/browser/resourceServiceWorker.ts +++ b/src/vs/workbench/contrib/resources/browser/resourceServiceWorker.ts @@ -4,8 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import { URI } from 'vs/base/common/uri'; -import { generateUuid } from 'vs/base/common/uuid'; -import { getMediaMime } from 'vs/base/common/mime'; //https://stackoverflow.com/questions/56356655/structuring-a-typescript-project-with-workers/56374158#56374158 declare var self: ServiceWorkerGlobalScope; @@ -35,8 +33,8 @@ self.addEventListener('activate', event => { //#region --- fetching/caching -const _cacheName = 'vscode-resources'; -const _resourcePrefix = '/vscode-resources/fetch'; +const _cacheName = 'vscode-extension-resources'; +const _resourcePrefix = '/vscode-remote'; const _pendingFetch = new Map(); self.addEventListener('message', event => { @@ -71,38 +69,18 @@ async function respondWithDefault(event: FetchEvent): Promise { } async function respondWithResource(event: FetchEvent, uri: URI): Promise { - const cacheKey = event.request.url.replace('&r=1', ''); - const cachedValue = await caches.open(_cacheName).then(cache => cache.match(cacheKey)); + + const cachedValue = await caches.open(_cacheName).then(cache => cache.match(event.request)); if (cachedValue) { return cachedValue; } - return new Promise(resolve => { + const response: Response = await event.preloadResponse || await fetch(event.request); + if (response.headers.get('X-VSCode-Extension') === 'true') { + await caches.open(_cacheName).then(cache => cache.put(event.request, response.clone())); + } - const token = generateUuid(); - const [first] = uri.query.split('&'); - const components = JSON.parse(first.substr(2)); - - _pendingFetch.set(token, async (data: ArrayBuffer, isExtensionResource: boolean) => { - - const res = new Response(data, { - status: 200, - headers: { 'Content-Type': getMediaMime(components.path) || 'text/plain' } - }); - - if (isExtensionResource) { - // only cache extension resources but not other - // resources, esp not workspace resources - await caches.open(_cacheName).then(cache => cache.put(cacheKey, res.clone())); - } - - return resolve(res); - }); - - self.clients.get(event.clientId).then(client => { - client.postMessage({ uri: components, token }); - }); - }); + return response; } //#endregion diff --git a/src/vs/workbench/contrib/resources/browser/resourceServiceWorkerClient.ts b/src/vs/workbench/contrib/resources/browser/resourceServiceWorkerClient.ts index dfda6a1cfbb..326dfb49eea 100644 --- a/src/vs/workbench/contrib/resources/browser/resourceServiceWorkerClient.ts +++ b/src/vs/workbench/contrib/resources/browser/resourceServiceWorkerClient.ts @@ -3,145 +3,41 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IFileService } from 'vs/platform/files/common/files'; -import { URI } from 'vs/base/common/uri'; import { Registry } from 'vs/platform/registry/common/platform'; import { IWorkbenchContributionsRegistry, Extensions } from 'vs/workbench/common/contributions'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; -import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; -import { isEqualOrParent } from 'vs/base/common/resources'; import { ILogService } from 'vs/platform/log/common/log'; - -// load and start service worker as soon as this file -// is being loaded and later, when services are ready, -// claim this service worker so that messages can be -// replied to -const _serviceWorker = new class ServiceWorkerStarter { - - private static _url = require.toUrl('./resourceServiceWorkerMain.js'); - - private _beforeReadyEvents: ExtendableMessageEvent[] = []; - private _messageHandler?: (event: ExtendableMessageEvent) => void; - - constructor() { - navigator.serviceWorker.register(ServiceWorkerStarter._url, { scope: '/' }).then(reg => { - // console.debug('SW#reg', reg); - return reg.update(); - // }).then(() => { - // // console.debug('SW#updated', reg); - // return navigator.serviceWorker.ready; - }).then(() => { - console.info('SW#ready'); - }).catch(err => { - console.error('SW#init', err); - }); - - const handleMessage = (event: ExtendableMessageEvent) => { - if (!this._messageHandler) { - this._beforeReadyEvents.push(event); - console.debug('SW#buffered', event.data); - } else { - this._messageHandler(event); - } - }; - - navigator.serviceWorker.addEventListener('message', e => handleMessage(e as ExtendableMessageEvent)); - } - - dispose(): void { - // when to dispose? - } - - claim(handler: (event: ExtendableMessageEvent) => void): void { - this._messageHandler = handler; - this._beforeReadyEvents.forEach(this._messageHandler); - } -}; +import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; class ResourceServiceWorker { + private static _url = require.toUrl('./resourceServiceWorkerMain.js'); + + private readonly _disposables = new DisposableStore(); + constructor( - @IFileService private readonly _fileService: IFileService, - @IExtensionService private readonly _extensionService: IExtensionService, @ILogService private readonly _logService: ILogService, ) { - this._updateEarlyResourceUris(); - _serviceWorker.claim(e => this._handleMessage(e)); + navigator.serviceWorker.register(ResourceServiceWorker._url, { scope: '/' }).then(reg => { + this._logService.trace('SW#reg', reg); + return reg.update(); + }).then(() => { + this._logService.info('SW#ready'); + }).catch(err => { + this._logService.error('SW#init', err); + }); + + const handler = (e: ExtendableMessageEvent) => this._handleMessage(e); + navigator.serviceWorker.addEventListener('message', handler); + this._disposables.add(toDisposable(() => navigator.serviceWorker.removeEventListener('message', handler))); + } + + dispose(): void { + this._disposables.dispose(); } private _handleMessage(event: ExtendableMessageEvent): void { - this._logService.trace('SW - fetch', event.data.uri); - - const uri = URI.revive(event.data.uri); - Promise.all([ - this._fileService.readFile(uri), - this._isExtensionResource(uri) - ]).then(([file, isExtensionResource]) => { - if (!event.source) { - return; - } - event.source.postMessage({ - token: event.data.token, - data: file.value.buffer.buffer, - isExtensionResource - }, [file.value.buffer.buffer]); - }); - } - - private async _isExtensionResource(uri: URI): Promise { - for (const ext of await this._extensionService.getExtensions()) { - if (isEqualOrParent(uri, ext.extensionLocation)) { - return true; - } - } - return false; - } - - private _updateEarlyResourceUris(): void { - - let updateCount = 0; - - // find style-tags - const styleElements = document.querySelectorAll('style'); - for (let i = 0; i < styleElements.length; i++) { - const el = styleElements.item(i); - if (!el.sheet) { - continue; - } - const rules = (el.sheet).rules; - for (let j = 0; j < rules.length; j++) { - const rule = rules[j]; - const newCssText = this._updateResourceUris(rule.cssText); - if (newCssText) { - (el.sheet).deleteRule(j); - (el.sheet).insertRule(newCssText, j); - updateCount += 1; - } - } - } - - // find any tag using remote uris - const htmlElements = document.querySelectorAll('[style*="/vscode-resources/fetch"]'); - for (let i = 0; i < htmlElements.length; i++) { - const el = htmlElements.item(i); - const newCssText = this._updateResourceUris(el.style.cssText); - if (newCssText) { - el.style.cssText = newCssText; - updateCount += 1; - } - } - - this._logService.trace('SW - count of changed, early dom element: ', updateCount); - } - - private _updateResourceUris(cssText: string): string | undefined { - let changed = false; - let newCssText = cssText.replace(/url\((["'])?(.+?\/vscode-resources\/fetch\?.+?)\1\)/g, (_match, g1, g2, _offset, _input) => { - changed = true; - return `url(${g1 || ''}${g2}&r=1${g1 || ''})`; - }); - - return changed ? newCssText : undefined; + this._logService.trace('SW', event.data); } } diff --git a/src/vs/workbench/contrib/resources/browser/resourceServiceWorkerMain.ts b/src/vs/workbench/contrib/resources/browser/resourceServiceWorkerMain.ts index 49f317ecd55..0dc883addcc 100644 --- a/src/vs/workbench/contrib/resources/browser/resourceServiceWorkerMain.ts +++ b/src/vs/workbench/contrib/resources/browser/resourceServiceWorkerMain.ts @@ -10,7 +10,7 @@ // statement. // trigger service worker updates -const _tag = 'a6f9835e-c10e-4299-ab39-b8e29547c20a'; +const _tag = '52278406-3ca9-48af-a8fb-8495add5bb4e'; // loader world const baseUrl = '../../../../../'; From c880f7fee0161514c48898571b39984422752cec Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 5 Aug 2019 15:15:02 +0200 Subject: [PATCH 197/861] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f2c8150eedc..cd2ed9a3334 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "f9c5d20222a2776b589107efa7d2e3aa4b80050d", + "distro": "1f46578f6299fb1c3313c049aef73f96a710f8f8", "author": { "name": "Microsoft Corporation" }, From bb8bf06dc9c856fcf604832dc5eb76e3bbe1033e Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 5 Aug 2019 15:16:02 +0200 Subject: [PATCH 198/861] strictPropertyInitialization #78168 --- src/vs/base/browser/touch.ts | 2 +- src/vs/base/browser/ui/centered/centeredViewLayout.ts | 11 +++++++---- src/vs/base/browser/ui/checkbox/checkbox.ts | 4 ++-- src/vs/base/browser/ui/inputbox/inputBox.ts | 4 ++-- src/vs/base/browser/ui/selectBox/selectBox.ts | 5 +---- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/vs/base/browser/touch.ts b/src/vs/base/browser/touch.ts index 2499d715f8f..f1ea0ee56ca 100644 --- a/src/vs/base/browser/touch.ts +++ b/src/vs/base/browser/touch.ts @@ -69,7 +69,7 @@ export class Gesture extends Disposable { private static INSTANCE: Gesture; private static HOLD_DELAY = 700; - private dispatched: boolean; + private dispatched = false; private targets: HTMLElement[]; private handle: IDisposable | null; diff --git a/src/vs/base/browser/ui/centered/centeredViewLayout.ts b/src/vs/base/browser/ui/centered/centeredViewLayout.ts index 299b6534873..f0580e81911 100644 --- a/src/vs/base/browser/ui/centered/centeredViewLayout.ts +++ b/src/vs/base/browser/ui/centered/centeredViewLayout.ts @@ -20,10 +20,12 @@ const GOLDEN_RATIO = { rightMarginRatio: 0.1909 }; -function createEmptyView(background: Color): ISplitViewView { +function createEmptyView(background: Color | undefined): ISplitViewView { const element = $('.centered-layout-margin'); element.style.height = '100%'; - element.style.backgroundColor = background.toString(); + if (background) { + element.style.backgroundColor = background.toString(); + } return { element, @@ -53,7 +55,7 @@ export class CenteredViewLayout implements IDisposable { private splitView?: SplitView; private width: number = 0; private height: number = 0; - private style: ICenteredViewStyles; + private style: ICenteredViewStyles | undefined; private didLayout = false; private emptyViews: ISplitViewView[] | undefined; private readonly splitViewDisposables = new DisposableStore(); @@ -132,7 +134,8 @@ export class CenteredViewLayout implements IDisposable { this.splitView.layout(this.width); this.splitView.addView(toSplitViewView(this.view, () => this.height), 0); - this.emptyViews = [createEmptyView(this.style.background), createEmptyView(this.style.background)]; + const backgroundColor = this.style ? this.style.background : undefined; + this.emptyViews = [createEmptyView(backgroundColor), createEmptyView(backgroundColor)]; this.splitView.addView(this.emptyViews[0], this.state.leftMarginRatio * this.width, 0); this.splitView.addView(this.emptyViews[1], this.state.rightMarginRatio * this.width, 2); } else { diff --git a/src/vs/base/browser/ui/checkbox/checkbox.ts b/src/vs/base/browser/ui/checkbox/checkbox.ts index 723f64dc4fa..fbd1df96fae 100644 --- a/src/vs/base/browser/ui/checkbox/checkbox.ts +++ b/src/vs/base/browser/ui/checkbox/checkbox.ts @@ -32,7 +32,7 @@ const defaultOpts = { export class CheckboxActionViewItem extends BaseActionViewItem { - private checkbox: Checkbox; + private checkbox: Checkbox | undefined; private readonly disposables = new DisposableStore(); render(container: HTMLElement): void { @@ -45,7 +45,7 @@ export class CheckboxActionViewItem extends BaseActionViewItem { title: this._action.label }); this.disposables.add(this.checkbox); - this.disposables.add(this.checkbox.onChange(() => this._action.checked = this.checkbox.checked, this)); + this.disposables.add(this.checkbox.onChange(() => this._action.checked = this.checkbox!.checked, this)); this.element.appendChild(this.checkbox.domNode); } diff --git a/src/vs/base/browser/ui/inputbox/inputBox.ts b/src/vs/base/browser/ui/inputbox/inputBox.ts index 011d1f56dc1..d92ae6e2dae 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.ts +++ b/src/vs/base/browser/ui/inputbox/inputBox.ts @@ -86,7 +86,7 @@ export class InputBox extends Widget { private contextViewProvider?: IContextViewProvider; element: HTMLElement; private input: HTMLInputElement; - private mirror: HTMLElement; + private mirror: HTMLElement | undefined; private actionbar?: ActionBar; private options: IInputOptions; private message: IMessage | null; @@ -230,7 +230,7 @@ export class InputBox extends Widget { } } - public get mirrorElement(): HTMLElement { + public get mirrorElement(): HTMLElement | undefined { return this.mirror; } diff --git a/src/vs/base/browser/ui/selectBox/selectBox.ts b/src/vs/base/browser/ui/selectBox/selectBox.ts index 7832680e2ae..d450f76d360 100644 --- a/src/vs/base/browser/ui/selectBox/selectBox.ts +++ b/src/vs/base/browser/ui/selectBox/selectBox.ts @@ -8,7 +8,7 @@ import 'vs/css!./selectBox'; import { Event } from 'vs/base/common/event'; import { Widget } from 'vs/base/browser/ui/widget'; import { Color } from 'vs/base/common/color'; -import { deepClone, mixin } from 'vs/base/common/objects'; +import { deepClone } from 'vs/base/common/objects'; import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview'; import { IListStyles } from 'vs/base/browser/ui/list/listWidget'; import { SelectBoxNative } from 'vs/base/browser/ui/selectBox/selectBoxNative'; @@ -72,14 +72,11 @@ export interface ISelectData { } export class SelectBox extends Widget implements ISelectBoxDelegate { - private styles: ISelectBoxStyles; private selectBoxDelegate: ISelectBoxDelegate; constructor(options: ISelectOptionItem[], selected: number, contextViewProvider: IContextViewProvider, styles: ISelectBoxStyles = deepClone(defaultStyles), selectBoxOptions?: ISelectBoxOptions) { super(); - mixin(this.styles, defaultStyles, false); - // Default to native SelectBox for OSX unless overridden if (isMacintosh && !(selectBoxOptions && selectBoxOptions.useCustomDrawn)) { this.selectBoxDelegate = new SelectBoxNative(options, selected, styles, selectBoxOptions); From b082da1f199b8322b01e0d549872b9668bc115d1 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 5 Aug 2019 15:30:28 +0200 Subject: [PATCH 199/861] Enable simple fullscreen again (fix #75054) --- src/vs/code/electron-main/window.ts | 17 ++++++++--------- src/vs/platform/windows/common/windows.ts | 2 +- .../electron-browser/main.contribution.ts | 4 ++-- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 48055ea9071..517417b9867 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -838,17 +838,16 @@ export class CodeWindow extends Disposable implements ICodeWindow { } private useNativeFullScreen(): boolean { - return true; // TODO@ben enable simple fullscreen again (https://github.com/microsoft/vscode/issues/75054) - // const windowConfig = this.configurationService.getValue('window'); - // if (!windowConfig || typeof windowConfig.nativeFullScreen !== 'boolean') { - // return true; // default - // } + const windowConfig = this.configurationService.getValue('window'); + if (!windowConfig || typeof windowConfig.nativeFullScreen !== 'boolean') { + return true; // default + } - // if (windowConfig.nativeTabs) { - // return true; // https://github.com/electron/electron/issues/16142 - // } + if (windowConfig.nativeTabs) { + return true; // https://github.com/electron/electron/issues/16142 + } - // return windowConfig.nativeFullScreen !== false; + return windowConfig.nativeFullScreen !== false; } isMinimized(): boolean { diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index 8429e3495b9..9be9dbfc291 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -303,7 +303,7 @@ export function getTitleBarStyle(configurationService: IConfigurationService, en return 'native'; // native tabs on sierra do not work with custom title style } - const useSimpleFullScreen = false; //isMacintosh && configuration.nativeFullScreen === false; + const useSimpleFullScreen = isMacintosh && configuration.nativeFullScreen === false; if (useSimpleFullScreen) { return 'native'; // simple fullscreen does not work well with custom title style (https://github.com/Microsoft/vscode/issues/63291) } diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 10557fccab0..97a9dfe1744 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -506,7 +506,7 @@ import product from 'vs/platform/product/node/product'; 'default': true, 'description': nls.localize('window.nativeFullScreen', "Controls if native full-screen should be used on macOS. Disable this option to prevent macOS from creating a new space when going full-screen."), 'scope': ConfigurationScope.APPLICATION, - 'included': false /* isMacintosh */ + 'included': isMacintosh }, 'window.clickThroughInactive': { 'type': 'boolean', @@ -533,4 +533,4 @@ import product from 'vs/platform/product/node/product'; } } }); -})(); \ No newline at end of file +})(); From 3015179c041579bd6ecc22c69c3289140cf87339 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 5 Aug 2019 15:36:23 +0200 Subject: [PATCH 200/861] strictPropertyInitialization related to #78168 --- src/vs/base/browser/ui/actionbar/actionbar.ts | 4 ++-- .../browser/ui/centered/centeredViewLayout.ts | 2 +- src/vs/base/browser/ui/checkbox/checkbox.ts | 2 +- .../browser/ui/contextview/contextview.ts | 21 ++++++++---------- .../base/browser/ui/countBadge/countBadge.ts | 2 +- src/vs/base/browser/ui/grid/gridview.ts | 2 +- src/vs/base/browser/ui/list/listPaging.ts | 2 +- src/vs/base/browser/ui/list/listView.ts | 7 +++--- src/vs/base/browser/ui/list/listWidget.ts | 2 +- src/vs/base/browser/ui/sash/sash.ts | 2 +- src/vs/base/browser/ui/splitview/panelview.ts | 8 +++---- src/vs/base/browser/ui/splitview/splitview.ts | 12 +++++----- src/vs/base/browser/ui/toolbar/toolbar.ts | 5 +++-- src/vs/base/browser/ui/tree/abstractTree.ts | 6 ++--- .../browser/ui/tree/compressedObjectTree.ts | 2 +- src/vs/base/browser/ui/tree/dataTree.ts | 2 +- src/vs/base/browser/ui/tree/indexTree.ts | 2 +- src/vs/base/browser/ui/tree/objectTree.ts | 2 +- src/vs/base/parts/tree/browser/treeModel.ts | 6 ++--- src/vs/base/parts/tree/browser/treeView.ts | 22 +++++++++---------- .../sharedProcess/sharedProcessMain.ts | 2 +- .../diagnostics/node/diagnosticsIpc.ts | 4 ++-- src/vs/platform/files/common/fileService.ts | 4 ++-- src/vs/platform/url/common/urlService.ts | 2 +- .../windows/electron-main/windowsService.ts | 2 +- 25 files changed, 62 insertions(+), 65 deletions(-) diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts index 413a256483f..538f7fa0dbe 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.ts +++ b/src/vs/base/browser/ui/actionbar/actionbar.ts @@ -37,7 +37,7 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem { _context: any; _action: IAction; - private _actionRunner: IActionRunner; + private _actionRunner!: IActionRunner; constructor(context: any, action: IAction, protected options?: IBaseActionViewItemOptions) { super(); @@ -232,7 +232,7 @@ export interface IActionViewItemOptions extends IBaseActionViewItemOptions { export class ActionViewItem extends BaseActionViewItem { - protected label: HTMLElement; + protected label!: HTMLElement; protected options: IActionViewItemOptions; private cssClass?: string; diff --git a/src/vs/base/browser/ui/centered/centeredViewLayout.ts b/src/vs/base/browser/ui/centered/centeredViewLayout.ts index f0580e81911..43f665fbd00 100644 --- a/src/vs/base/browser/ui/centered/centeredViewLayout.ts +++ b/src/vs/base/browser/ui/centered/centeredViewLayout.ts @@ -55,7 +55,7 @@ export class CenteredViewLayout implements IDisposable { private splitView?: SplitView; private width: number = 0; private height: number = 0; - private style: ICenteredViewStyles | undefined; + private style!: ICenteredViewStyles; private didLayout = false; private emptyViews: ISplitViewView[] | undefined; private readonly splitViewDisposables = new DisposableStore(); diff --git a/src/vs/base/browser/ui/checkbox/checkbox.ts b/src/vs/base/browser/ui/checkbox/checkbox.ts index fbd1df96fae..ed0bcfa0ab1 100644 --- a/src/vs/base/browser/ui/checkbox/checkbox.ts +++ b/src/vs/base/browser/ui/checkbox/checkbox.ts @@ -32,7 +32,7 @@ const defaultOpts = { export class CheckboxActionViewItem extends BaseActionViewItem { - private checkbox: Checkbox | undefined; + private checkbox!: Checkbox; private readonly disposables = new DisposableStore(); render(container: HTMLElement): void { diff --git a/src/vs/base/browser/ui/contextview/contextview.ts b/src/vs/base/browser/ui/contextview/contextview.ts index 719126e63d9..8b8bb3b16eb 100644 --- a/src/vs/base/browser/ui/contextview/contextview.ts +++ b/src/vs/base/browser/ui/contextview/contextview.ts @@ -5,7 +5,7 @@ import 'vs/css!./contextview'; import * as DOM from 'vs/base/browser/dom'; -import { IDisposable, dispose, toDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { IDisposable, toDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { Range } from 'vs/base/common/range'; export interface IAnchor { @@ -100,11 +100,11 @@ export class ContextView extends Disposable { private static readonly BUBBLE_UP_EVENTS = ['click', 'keydown', 'focus', 'blur']; private static readonly BUBBLE_DOWN_EVENTS = ['click']; - private container: HTMLElement | null; + private container: HTMLElement | null = null; private view: HTMLElement; - private delegate: IDelegate | null; - private toDisposeOnClean: IDisposable | null; - private toDisposeOnSetContainer: IDisposable; + private delegate: IDelegate | null = null; + private toDisposeOnClean: IDisposable = Disposable.None; + private toDisposeOnSetContainer: IDisposable = Disposable.None; constructor(container: HTMLElement) { super(); @@ -120,7 +120,7 @@ export class ContextView extends Disposable { setContainer(container: HTMLElement | null): void { if (this.container) { - dispose(this.toDisposeOnSetContainer); + this.toDisposeOnSetContainer.dispose(); this.container.removeChild(this.view); this.container = null; } @@ -159,7 +159,7 @@ export class ContextView extends Disposable { DOM.show(this.view); // Render content - this.toDisposeOnClean = delegate.render(this.view); + this.toDisposeOnClean = delegate.render(this.view) || Disposable.None; // Set active delegate this.delegate = delegate; @@ -267,10 +267,7 @@ export class ContextView extends Disposable { delegate.onHide(data); } - if (this.toDisposeOnClean) { - this.toDisposeOnClean.dispose(); - this.toDisposeOnClean = null; - } + this.toDisposeOnClean.dispose(); DOM.hide(this.view); } @@ -294,4 +291,4 @@ export class ContextView extends Disposable { super.dispose(); } -} \ No newline at end of file +} diff --git a/src/vs/base/browser/ui/countBadge/countBadge.ts b/src/vs/base/browser/ui/countBadge/countBadge.ts index c35b5733ff9..e4b1f68568f 100644 --- a/src/vs/base/browser/ui/countBadge/countBadge.ts +++ b/src/vs/base/browser/ui/countBadge/countBadge.ts @@ -29,7 +29,7 @@ const defaultOpts = { export class CountBadge { private element: HTMLElement; - private count: number; + private count: number = 0; private countFormat: string; private titleFormat: string; diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts index 81a6950a65b..7ec49f3b343 100644 --- a/src/vs/base/browser/ui/grid/gridview.ts +++ b/src/vs/base/browser/ui/grid/gridview.ts @@ -610,7 +610,7 @@ export class GridView implements IDisposable { private styles: IGridViewStyles; private proportionalLayout: boolean; - private _root: BranchNode; + private _root!: BranchNode; private onDidSashResetRelay = new Relay(); readonly onDidSashReset: Event = this.onDidSashResetRelay.event; diff --git a/src/vs/base/browser/ui/list/listPaging.ts b/src/vs/base/browser/ui/list/listPaging.ts index 90736af0a46..788c0045f2d 100644 --- a/src/vs/base/browser/ui/list/listPaging.ts +++ b/src/vs/base/browser/ui/list/listPaging.ts @@ -73,7 +73,7 @@ class PagedRenderer implements IListRenderer implements IDisposable { private list: List; - private _model: IPagedModel; + private _model!: IPagedModel; constructor( container: HTMLElement, diff --git a/src/vs/base/browser/ui/list/listView.ts b/src/vs/base/browser/ui/list/listView.ts index d42777bec4b..c35ddf1e1dd 100644 --- a/src/vs/base/browser/ui/list/listView.ts +++ b/src/vs/base/browser/ui/list/listView.ts @@ -163,16 +163,15 @@ export class ListView implements ISpliceable, IDisposable { private lastRenderTop: number; private lastRenderHeight: number; private renderWidth = 0; - private gesture: Gesture; private rowsContainer: HTMLElement; private scrollableElement: ScrollableElement; - private _scrollHeight: number; + private _scrollHeight: number = 0; private scrollableElementUpdateDisposable: IDisposable | null = null; private scrollableElementWidthDelayer = new Delayer(50); private splicing = false; private dragOverAnimationDisposable: IDisposable | undefined; private dragOverAnimationStopDisposable: IDisposable = Disposable.None; - private dragOverMouseY: number; + private dragOverMouseY: number = 0; private setRowLineHeight: boolean; private supportDynamicHeights: boolean; private horizontalScrolling: boolean; @@ -245,7 +244,7 @@ export class ListView implements ISpliceable, IDisposable { this.domNode.appendChild(this.scrollableElement.getDomNode()); container.appendChild(this.domNode); - this.disposables = [this.rangeMap, this.gesture, this.scrollableElement, this.cache]; + this.disposables = [this.rangeMap, this.scrollableElement, this.cache]; this.scrollableElement.onScroll(this.onScroll, this, this.disposables); domEvent(this.rowsContainer, TouchEventType.Change)(this.onTouchChange, this, this.disposables); diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index e660fed0622..24fec080908 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -519,7 +519,7 @@ const DefaultOpenController: IOpenController = { export class MouseController implements IDisposable { private multipleSelectionSupport: boolean; - readonly multipleSelectionController: IMultipleSelectionController; + readonly multipleSelectionController: IMultipleSelectionController | undefined; private openController: IOpenController; private mouseSupport: boolean; private readonly disposables = new DisposableStore(); diff --git a/src/vs/base/browser/ui/sash/sash.ts b/src/vs/base/browser/ui/sash/sash.ts index 874bc9482e1..e394df1e790 100644 --- a/src/vs/base/browser/ui/sash/sash.ts +++ b/src/vs/base/browser/ui/sash/sash.ts @@ -61,7 +61,7 @@ export class Sash extends Disposable { private el: HTMLElement; private layoutProvider: ISashLayoutProvider; private hidden: boolean; - private orientation: Orientation; + private orientation!: Orientation; private _state: SashState = SashState.Enabled; get state(): SashState { return this._state; } diff --git a/src/vs/base/browser/ui/splitview/panelview.ts b/src/vs/base/browser/ui/splitview/panelview.ts index 4d2fc8a6144..7c337dc62da 100644 --- a/src/vs/base/browser/ui/splitview/panelview.ts +++ b/src/vs/base/browser/ui/splitview/panelview.ts @@ -42,8 +42,8 @@ export abstract class Panel extends Disposable implements IView { private static readonly HEADER_SIZE = 22; readonly element: HTMLElement; - private header: HTMLElement; - private body: HTMLElement; + private header!: HTMLElement; + private body!: HTMLElement; protected _expanded: boolean; @@ -109,7 +109,7 @@ export abstract class Panel extends Disposable implements IView { return headerSize + maximumBodySize; } - width: number; + width: number = 0; constructor(options: IPanelOptions = {}) { super(); @@ -371,7 +371,7 @@ export class PanelView extends Disposable { private dndContext: IDndContext = { draggable: null }; private el: HTMLElement; private panelItems: IPanelItem[] = []; - private width: number; + private width: number = 0; private splitview: SplitView; private animationTimer: number | undefined = undefined; diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index 6f031dac570..07f860ecb57 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -203,7 +203,7 @@ export class SplitView extends Disposable { private proportions: undefined | number[] = undefined; private viewItems: ViewItem[] = []; private sashItems: ISashItem[] = []; - private sashDragState: ISashDragState; + private sashDragState: ISashDragState | undefined; private state: State = State.Idle; private inverseAltBehavior: boolean; private proportionalLayout: boolean; @@ -499,8 +499,8 @@ export class SplitView extends Disposable { // This way, we can press Alt while we resize a sash, macOS style! const disposable = combinedDisposable( - domEvent(document.body, 'keydown')(e => resetSashDragState(this.sashDragState.current, e.altKey)), - domEvent(document.body, 'keyup')(() => resetSashDragState(this.sashDragState.current, false)) + domEvent(document.body, 'keydown')(e => resetSashDragState(this.sashDragState!.current, e.altKey)), + domEvent(document.body, 'keyup')(() => resetSashDragState(this.sashDragState!.current, false)) ); const resetSashDragState = (start: number, alt: boolean) => { @@ -572,8 +572,8 @@ export class SplitView extends Disposable { } private onSashChange({ current }: ISashEvent): void { - const { index, start, sizes, alt, minDelta, maxDelta, snapBefore, snapAfter } = this.sashDragState; - this.sashDragState.current = current; + const { index, start, sizes, alt, minDelta, maxDelta, snapBefore, snapAfter } = this.sashDragState!; + this.sashDragState!.current = current; const delta = current - start; const newDelta = this.resize(index, delta, sizes, undefined, undefined, minDelta, maxDelta, snapBefore, snapAfter); @@ -596,7 +596,7 @@ export class SplitView extends Disposable { private onSashEnd(index: number): void { this._onDidSashChange.fire(index); - this.sashDragState.disposable.dispose(); + this.sashDragState!.disposable.dispose(); this.saveProportions(); } diff --git a/src/vs/base/browser/ui/toolbar/toolbar.ts b/src/vs/base/browser/ui/toolbar/toolbar.ts index 4aa201e1a68..b6329a0ce4d 100644 --- a/src/vs/base/browser/ui/toolbar/toolbar.ts +++ b/src/vs/base/browser/ui/toolbar/toolbar.ts @@ -33,7 +33,7 @@ export class ToolBar extends Disposable { private actionBar: ActionBar; private toggleMenuAction: ToggleMenuAction; private toggleMenuActionViewItem = this._register(new MutableDisposable()); - private hasSecondaryActions: boolean; + private hasSecondaryActions: boolean = false; private lookupKeybindings: boolean; constructor(container: HTMLElement, contextMenuProvider: IContextMenuProvider, options: IToolBarOptions = { orientation: ActionsOrientation.HORIZONTAL }) { @@ -162,6 +162,7 @@ class ToggleMenuAction extends Action { title = title || nls.localize('moreActions', "More Actions..."); super(ToggleMenuAction.ID, title, undefined, true); + this._menuActions = []; this.toggleDropdownMenu = toggleDropdownMenu; } @@ -178,4 +179,4 @@ class ToggleMenuAction extends Action { set menuActions(actions: ReadonlyArray) { this._menuActions = actions; } -} \ No newline at end of file +} diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index c3094ca36f2..05f6841fd72 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -451,8 +451,8 @@ class TypeFilter implements ITreeFilter, IDisposable { private _matchCount = 0; get matchCount(): number { return this._matchCount; } - private _pattern: string; - private _lowercasePattern: string; + private _pattern: string = ''; + private _lowercasePattern: string = ''; private disposables: IDisposable[] = []; set pattern(pattern: string) { @@ -543,7 +543,7 @@ class TypeFilterController implements IDisposable { private _filterOnType: boolean; get filterOnType(): boolean { return this._filterOnType; } - private _empty: boolean; + private _empty: boolean = false; get empty(): boolean { return this._empty; } private _onDidChangeEmptyState = new Emitter(); diff --git a/src/vs/base/browser/ui/tree/compressedObjectTree.ts b/src/vs/base/browser/ui/tree/compressedObjectTree.ts index 5d1b80462c5..dd98e865909 100644 --- a/src/vs/base/browser/ui/tree/compressedObjectTree.ts +++ b/src/vs/base/browser/ui/tree/compressedObjectTree.ts @@ -17,7 +17,7 @@ export interface IObjectTreeOptions extends IAbstractTree export class CompressedObjectTree, TFilterData = void> extends AbstractTree | null, TFilterData, T | null> { - protected model: CompressedTreeModel; + protected model!: CompressedTreeModel; get onDidChangeCollapseState(): Event | null, TFilterData>> { return this.model.onDidChangeCollapseState; } diff --git a/src/vs/base/browser/ui/tree/dataTree.ts b/src/vs/base/browser/ui/tree/dataTree.ts index 9f51021a2e0..9a67a381edb 100644 --- a/src/vs/base/browser/ui/tree/dataTree.ts +++ b/src/vs/base/browser/ui/tree/dataTree.ts @@ -23,7 +23,7 @@ export interface IDataTreeViewState { export class DataTree extends AbstractTree { - protected model: ObjectTreeModel; + protected model!: ObjectTreeModel; private input: TInput | undefined; private identityProvider: IIdentityProvider | undefined; diff --git a/src/vs/base/browser/ui/tree/indexTree.ts b/src/vs/base/browser/ui/tree/indexTree.ts index 4378ffd3e1a..b0b86e0a6f9 100644 --- a/src/vs/base/browser/ui/tree/indexTree.ts +++ b/src/vs/base/browser/ui/tree/indexTree.ts @@ -15,7 +15,7 @@ export interface IIndexTreeOptions extends IAbstractTreeO export class IndexTree extends AbstractTree { - protected model: IndexTreeModel; + protected model!: IndexTreeModel; constructor( container: HTMLElement, diff --git a/src/vs/base/browser/ui/tree/objectTree.ts b/src/vs/base/browser/ui/tree/objectTree.ts index 51873462959..25397807106 100644 --- a/src/vs/base/browser/ui/tree/objectTree.ts +++ b/src/vs/base/browser/ui/tree/objectTree.ts @@ -17,7 +17,7 @@ export interface IObjectTreeOptions extends IAbstractTree export class ObjectTree, TFilterData = void> extends AbstractTree { - protected model: IObjectTreeModel; + protected model!: IObjectTreeModel; get onDidChangeCollapseState(): Event> { return this.model.onDidChangeCollapseState; } diff --git a/src/vs/base/parts/tree/browser/treeModel.ts b/src/vs/base/parts/tree/browser/treeModel.ts index 54ec61756da..6f157d62e05 100644 --- a/src/vs/base/parts/tree/browser/treeModel.ts +++ b/src/vs/base/parts/tree/browser/treeModel.ts @@ -862,10 +862,10 @@ export interface IRefreshEvent extends IBaseEvent { export class TreeModel { private context: _.ITreeContext; - private lock: Lock; + private lock!: Lock; private input: Item | null; - private registry: ItemRegistry; - private registryDisposable: IDisposable; + private registry!: ItemRegistry; + private registryDisposable!: IDisposable; private traitsToItems: ITraitMap; private _onSetInput = new Emitter(); diff --git a/src/vs/base/parts/tree/browser/treeView.ts b/src/vs/base/parts/tree/browser/treeView.ts index 2042f576d55..71f583acc26 100644 --- a/src/vs/base/parts/tree/browser/treeView.ts +++ b/src/vs/base/parts/tree/browser/treeView.ts @@ -121,15 +121,15 @@ export class ViewItem implements IViewItem { public top: number; public height: number; public width: number = 0; - public onDragStart: (e: DragEvent) => void; + public onDragStart!: (e: DragEvent) => void; - public needsRender: boolean; - public uri: string | null; + public needsRender: boolean = false; + public uri: string | null = null; public unbindDragStart: Lifecycle.IDisposable = Lifecycle.Disposable.None; public loadingTimer: any; public _styles: any; - private _draggable: boolean; + private _draggable: boolean = false; constructor(context: IViewContext, model: Model.Item) { this.context = context; @@ -174,7 +174,7 @@ export class ViewItem implements IViewItem { return (this.row && this.row.element)!; } - private _templateId: string; + private _templateId: string | undefined; private get templateId(): string { return this._templateId || (this._templateId = (this.context.renderer!.getTemplateId && this.context.renderer!.getTemplateId(this.context.tree, this.model.getElement()))); } @@ -415,8 +415,8 @@ export class TreeView extends HeightMap { private treeStyler: _.ITreeStyler; private rowsContainer: HTMLElement; private scrollableElement: ScrollableElement; - private msGesture: MSGesture; - private lastPointerType: string; + private msGesture: MSGesture | undefined; + private lastPointerType: string = ''; private lastClickTimeStamp: number = 0; private horizontalScrolling: boolean; @@ -425,14 +425,14 @@ export class TreeView extends HeightMap { private lastRenderTop: number; private lastRenderHeight: number; - private inputItem: ViewItem; + private inputItem!: ViewItem; private items: { [id: string]: ViewItem; }; private isRefreshing = false; private refreshingPreviousChildrenIds: { [id: string]: string[] } = {}; private currentDragAndDropData: IDragAndDropData | null = null; private currentDropElement: any; - private currentDropElementReaction: _.IDragOverReaction; + private currentDropElementReaction!: _.IDragOverReaction; private currentDropTarget: ViewItem | null = null; private shouldInvalidateDropReaction: boolean; private currentDropTargets: ViewItem[] | null = null; @@ -443,7 +443,7 @@ export class TreeView extends HeightMap { private didJustPressContextMenuKey: boolean; - private highlightedItemWasDraggable: boolean; + private highlightedItemWasDraggable: boolean = false; private onHiddenScrollTop: number | null = null; private readonly _onDOMFocus = new Emitter(); @@ -633,7 +633,7 @@ export class TreeView extends HeightMap { private setupMSGesture(): void { if ((window).MSGesture) { this.msGesture = new MSGesture(); - setTimeout(() => this.msGesture.target = this.wrapper, 100); // TODO@joh, TODO@IETeam + setTimeout(() => this.msGesture!.target = this.wrapper, 100); // TODO@joh, TODO@IETeam } } diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index b85c29ffc4a..905e9fd88db 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -77,7 +77,7 @@ const eventPrefix = 'monacoworkbench'; class MainProcessService implements IMainProcessService { constructor(private server: Server, private mainRouter: StaticRouter) { } - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; getChannel(channelName: string): IChannel { return this.server.getChannel(channelName, this.mainRouter); diff --git a/src/vs/platform/diagnostics/node/diagnosticsIpc.ts b/src/vs/platform/diagnostics/node/diagnosticsIpc.ts index 28cabc55e7b..2e2bf87472b 100644 --- a/src/vs/platform/diagnostics/node/diagnosticsIpc.ts +++ b/src/vs/platform/diagnostics/node/diagnosticsIpc.ts @@ -36,7 +36,7 @@ export class DiagnosticsChannel implements IServerChannel { export class DiagnosticsService implements IDiagnosticsService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; constructor(private channel: IChannel) { } @@ -55,4 +55,4 @@ export class DiagnosticsService implements IDiagnosticsService { public reportWorkspaceStats(workspace: IWorkspace): Promise { return this.channel.call('reportWorkspaceStats', workspace); } -} \ No newline at end of file +} diff --git a/src/vs/platform/files/common/fileService.ts b/src/vs/platform/files/common/fileService.ts index 5beb3a1c8b8..4d9ecebb95e 100644 --- a/src/vs/platform/files/common/fileService.ts +++ b/src/vs/platform/files/common/fileService.ts @@ -21,7 +21,7 @@ import { Schemas } from 'vs/base/common/network'; export class FileService extends Disposable implements IFileService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private readonly BUFFER_SIZE = 64 * 1024; @@ -1077,4 +1077,4 @@ export class FileService extends Disposable implements IFileService { } //#endregion -} \ No newline at end of file +} diff --git a/src/vs/platform/url/common/urlService.ts b/src/vs/platform/url/common/urlService.ts index afcfff01be4..66d4abd6722 100644 --- a/src/vs/platform/url/common/urlService.ts +++ b/src/vs/platform/url/common/urlService.ts @@ -12,7 +12,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio export class URLService implements IURLService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private handlers = new Set(); diff --git a/src/vs/platform/windows/electron-main/windowsService.ts b/src/vs/platform/windows/electron-main/windowsService.ts index c33bbb42b8a..00af7fe6715 100644 --- a/src/vs/platform/windows/electron-main/windowsService.ts +++ b/src/vs/platform/windows/electron-main/windowsService.ts @@ -27,7 +27,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio export class WindowsService extends Disposable implements IWindowsService, IURLHandler { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private readonly disposables = this._register(new DisposableStore()); From 8abc9e4a17077d0b1c647c3012d86b9af7565b81 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Mon, 5 Aug 2019 15:46:54 +0200 Subject: [PATCH 201/861] more improvements for #78168 --- .../editor/contrib/hover/modesContentHover.ts | 1 + .../editor/contrib/hover/modesGlyphHover.ts | 2 ++ .../editor/contrib/indentation/indentation.ts | 15 +++++----- .../linesOperations/copyLinesCommand.ts | 8 +++-- .../linesOperations/moveLinesCommand.ts | 7 +++-- .../linesOperations/sortLinesCommand.ts | 5 ++-- .../wordHighlighter/wordHighlighter.ts | 1 + .../iPadShowKeyboard/iPadShowKeyboard.ts | 1 + .../standalone/browser/simpleServices.ts | 23 ++++++++------- .../browser/standaloneCodeEditor.ts | 4 +-- .../browser/standaloneThemeServiceImpl.ts | 2 +- .../common/remoteAgentFileSystemChannel.ts | 2 +- .../api/node/extHostRequireInterceptor.ts | 6 ++-- .../common/extensionDescriptionRegistry.ts | 6 ++-- .../extensions/common/proxyIdentifier.ts | 2 +- .../cachedExtensionScanner.ts | 4 +-- .../extensions/node/extensionPoints.ts | 4 +-- .../extensions/test/node/rpcProtocol.test.ts | 4 +-- .../common/abstractRemoteAgentService.ts | 1 + .../textMate/common/TMScopeRegistry.ts | 2 +- .../electron-browser/textMateWorker.ts | 29 +++++++++++-------- .../electron-browser/api/testRPCProtocol.ts | 2 +- 22 files changed, 76 insertions(+), 55 deletions(-) diff --git a/src/vs/editor/contrib/hover/modesContentHover.ts b/src/vs/editor/contrib/hover/modesContentHover.ts index 7bc5a7fb022..ee2c456fdfa 100644 --- a/src/vs/editor/contrib/hover/modesContentHover.ts +++ b/src/vs/editor/contrib/hover/modesContentHover.ts @@ -70,6 +70,7 @@ class ModesContentComputer implements IHoverComputer { private readonly _markerDecorationsService: IMarkerDecorationsService ) { this._editor = editor; + this._result = []; } setRange(range: Range): void { diff --git a/src/vs/editor/contrib/hover/modesGlyphHover.ts b/src/vs/editor/contrib/hover/modesGlyphHover.ts index b2b78438a79..85dece77b64 100644 --- a/src/vs/editor/contrib/hover/modesGlyphHover.ts +++ b/src/vs/editor/contrib/hover/modesGlyphHover.ts @@ -27,6 +27,7 @@ class MarginComputer implements IHoverComputer { constructor(editor: ICodeEditor) { this._editor = editor; this._lineNumber = -1; + this._result = []; } public setLineNumber(lineNumber: number): void { @@ -100,6 +101,7 @@ export class ModesGlyphHoverWidget extends GlyphHoverWidget { ) { super(ModesGlyphHoverWidget.ID, editor); + this._messages = []; this._lastLineNumber = -1; this._markdownRenderer = this._register(new MarkdownRenderer(this._editor, modeService, openerService)); diff --git a/src/vs/editor/contrib/indentation/indentation.ts b/src/vs/editor/contrib/indentation/indentation.ts index dc51d0faf45..fd9fcee54ea 100644 --- a/src/vs/editor/contrib/indentation/indentation.ts +++ b/src/vs/editor/contrib/indentation/indentation.ts @@ -378,11 +378,12 @@ export class AutoIndentOnPasteCommand implements ICommand { private readonly _edits: { range: IRange; text: string; eol?: EndOfLineSequence; }[]; private readonly _initialSelection: Selection; - private _selectionId: string; + private _selectionId: string | null; constructor(edits: TextEdit[], initialSelection: Selection) { this._initialSelection = initialSelection; this._edits = []; + this._selectionId = null; for (let edit of edits) { if (edit.range && typeof edit.text === 'string') { @@ -415,7 +416,7 @@ export class AutoIndentOnPasteCommand implements ICommand { } public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection { - return helper.getTrackedSelection(this._selectionId); + return helper.getTrackedSelection(this._selectionId!); } } @@ -651,7 +652,7 @@ function getIndentationEditOperations(model: ITextModel, builder: IEditOperation export class IndentationToSpacesCommand implements ICommand { - private selectionId: string; + private selectionId: string | null = null; constructor(private readonly selection: Selection, private tabSize: number) { } @@ -661,13 +662,13 @@ export class IndentationToSpacesCommand implements ICommand { } public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection { - return helper.getTrackedSelection(this.selectionId); + return helper.getTrackedSelection(this.selectionId!); } } export class IndentationToTabsCommand implements ICommand { - private selectionId: string; + private selectionId: string | null = null; constructor(private readonly selection: Selection, private tabSize: number) { } @@ -677,7 +678,7 @@ export class IndentationToTabsCommand implements ICommand { } public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection { - return helper.getTrackedSelection(this.selectionId); + return helper.getTrackedSelection(this.selectionId!); } } @@ -688,4 +689,4 @@ registerEditorAction(IndentUsingTabs); registerEditorAction(IndentUsingSpaces); registerEditorAction(DetectIndentation); registerEditorAction(ReindentLinesAction); -registerEditorAction(ReindentSelectedLinesAction); \ No newline at end of file +registerEditorAction(ReindentSelectedLinesAction); diff --git a/src/vs/editor/contrib/linesOperations/copyLinesCommand.ts b/src/vs/editor/contrib/linesOperations/copyLinesCommand.ts index 799b61088f2..3d207820061 100644 --- a/src/vs/editor/contrib/linesOperations/copyLinesCommand.ts +++ b/src/vs/editor/contrib/linesOperations/copyLinesCommand.ts @@ -14,13 +14,17 @@ export class CopyLinesCommand implements editorCommon.ICommand { private readonly _isCopyingDown: boolean; private _selectionDirection: SelectionDirection; - private _selectionId: string; + private _selectionId: string | null; private _startLineNumberDelta: number; private _endLineNumberDelta: number; constructor(selection: Selection, isCopyingDown: boolean) { this._selection = selection; this._isCopyingDown = isCopyingDown; + this._selectionDirection = SelectionDirection.LTR; + this._selectionId = null; + this._startLineNumberDelta = 0; + this._endLineNumberDelta = 0; } public getEditOperations(model: ITextModel, builder: editorCommon.IEditOperationBuilder): void { @@ -58,7 +62,7 @@ export class CopyLinesCommand implements editorCommon.ICommand { } public computeCursorState(model: ITextModel, helper: editorCommon.ICursorStateComputerData): Selection { - let result = helper.getTrackedSelection(this._selectionId); + let result = helper.getTrackedSelection(this._selectionId!); if (this._startLineNumberDelta !== 0 || this._endLineNumberDelta !== 0) { let startLineNumber = result.startLineNumber; diff --git a/src/vs/editor/contrib/linesOperations/moveLinesCommand.ts b/src/vs/editor/contrib/linesOperations/moveLinesCommand.ts index 1053f758bdd..f1b0fd7befb 100644 --- a/src/vs/editor/contrib/linesOperations/moveLinesCommand.ts +++ b/src/vs/editor/contrib/linesOperations/moveLinesCommand.ts @@ -20,7 +20,7 @@ export class MoveLinesCommand implements ICommand { private readonly _isMovingDown: boolean; private readonly _autoIndent: boolean; - private _selectionId: string; + private _selectionId: string | null; private _moveEndPositionDown?: boolean; private _moveEndLineSelectionShrink: boolean; @@ -28,6 +28,7 @@ export class MoveLinesCommand implements ICommand { this._selection = selection; this._isMovingDown = isMovingDown; this._autoIndent = autoIndent; + this._selectionId = null; this._moveEndLineSelectionShrink = false; } @@ -36,9 +37,11 @@ export class MoveLinesCommand implements ICommand { let modelLineCount = model.getLineCount(); if (this._isMovingDown && this._selection.endLineNumber === modelLineCount) { + this._selectionId = builder.trackSelection(this._selection); return; } if (!this._isMovingDown && this._selection.startLineNumber === 1) { + this._selectionId = builder.trackSelection(this._selection); return; } @@ -328,7 +331,7 @@ export class MoveLinesCommand implements ICommand { } public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection { - let result = helper.getTrackedSelection(this._selectionId); + let result = helper.getTrackedSelection(this._selectionId!); if (this._moveEndPositionDown) { result = result.setEndPosition(result.endLineNumber + 1, 1); diff --git a/src/vs/editor/contrib/linesOperations/sortLinesCommand.ts b/src/vs/editor/contrib/linesOperations/sortLinesCommand.ts index 304084db5f2..6c52081947c 100644 --- a/src/vs/editor/contrib/linesOperations/sortLinesCommand.ts +++ b/src/vs/editor/contrib/linesOperations/sortLinesCommand.ts @@ -12,12 +12,13 @@ import { IIdentifiedSingleEditOperation, ITextModel } from 'vs/editor/common/mod export class SortLinesCommand implements editorCommon.ICommand { private readonly selection: Selection; - private selectionId: string; private readonly descending: boolean; + private selectionId: string | null; constructor(selection: Selection, descending: boolean) { this.selection = selection; this.descending = descending; + this.selectionId = null; } public getEditOperations(model: ITextModel, builder: editorCommon.IEditOperationBuilder): void { @@ -30,7 +31,7 @@ export class SortLinesCommand implements editorCommon.ICommand { } public computeCursorState(model: ITextModel, helper: editorCommon.ICursorStateComputerData): Selection { - return helper.getTrackedSelection(this.selectionId); + return helper.getTrackedSelection(this.selectionId!); } public static canRun(model: ITextModel | null, selection: Selection, descending: boolean): boolean { diff --git a/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts b/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts index 0820b22ce51..4fd4f5d2db0 100644 --- a/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts +++ b/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts @@ -469,6 +469,7 @@ class WordHighlighterContribution extends Disposable implements editorCommon.IEd constructor(editor: ICodeEditor, @IContextKeyService contextKeyService: IContextKeyService) { super(); + this.wordHighligher = null; const createWordHighlighterIfPossible = () => { if (editor.hasModel()) { this.wordHighligher = new WordHighlighter(editor, contextKeyService); diff --git a/src/vs/editor/standalone/browser/iPadShowKeyboard/iPadShowKeyboard.ts b/src/vs/editor/standalone/browser/iPadShowKeyboard/iPadShowKeyboard.ts index 1fc21b5fc7f..b36f6ecdc23 100644 --- a/src/vs/editor/standalone/browser/iPadShowKeyboard/iPadShowKeyboard.ts +++ b/src/vs/editor/standalone/browser/iPadShowKeyboard/iPadShowKeyboard.ts @@ -21,6 +21,7 @@ export class IPadShowKeyboard extends Disposable implements IEditorContribution constructor(editor: ICodeEditor) { super(); this.editor = editor; + this.widget = null; if (browser.isIPad) { this._register(editor.onDidChangeConfiguration(() => this.update())); this.update(); diff --git a/src/vs/editor/standalone/browser/simpleServices.ts b/src/vs/editor/standalone/browser/simpleServices.ts index 423b8497be7..54804eb3c0f 100644 --- a/src/vs/editor/standalone/browser/simpleServices.ts +++ b/src/vs/editor/standalone/browser/simpleServices.ts @@ -98,17 +98,20 @@ function withTypedEditor(widget: editorCommon.IEditor, codeEditorCallback: (e export class SimpleEditorModelResolverService implements ITextModelService { public _serviceBrand: any; - private editor: editorCommon.IEditor; + private editor?: editorCommon.IEditor; public setEditor(editor: editorCommon.IEditor): void { this.editor = editor; } public createModelReference(resource: URI): Promise> { - let model: ITextModel | null = withTypedEditor(this.editor, - (editor) => this.findModel(editor, resource), - (diffEditor) => this.findModel(diffEditor.getOriginalEditor(), resource) || this.findModel(diffEditor.getModifiedEditor(), resource) - ); + let model: ITextModel | null = null; + if (this.editor) { + model = withTypedEditor(this.editor, + (editor) => this.findModel(editor, resource), + (diffEditor) => this.findModel(diffEditor.getOriginalEditor(), resource) || this.findModel(diffEditor.getModifiedEditor(), resource) + ); + } if (!model) { return Promise.reject(new Error(`Model not found`)); @@ -477,12 +480,12 @@ export class SimpleResourceConfigurationService implements ITextResourceConfigur _serviceBrand: any; - public readonly onDidChangeConfiguration: Event; - private readonly _onDidChangeConfigurationEmitter = new Emitter(); + private readonly _onDidChangeConfiguration = new Emitter(); + public readonly onDidChangeConfiguration = this._onDidChangeConfiguration.event; constructor(private readonly configurationService: SimpleConfigurationService) { this.configurationService.onDidChangeConfiguration((e) => { - this._onDidChangeConfigurationEmitter.fire(e); + this._onDidChangeConfiguration.fire(e); }); } @@ -519,7 +522,7 @@ export class SimpleResourcePropertiesService implements ITextResourcePropertiesS } export class StandaloneTelemetryService implements ITelemetryService { - _serviceBrand: void; + _serviceBrand: void = undefined; public isOptedIn = false; @@ -687,7 +690,7 @@ export class SimpleLayoutService implements ILayoutService { public onLayout = Event.None; - private _dimension: IDimension; + private _dimension?: IDimension; get dimension(): IDimension { if (!this._dimension) { this._dimension = dom.getClientArea(window.document.body); diff --git a/src/vs/editor/standalone/browser/standaloneCodeEditor.ts b/src/vs/editor/standalone/browser/standaloneCodeEditor.ts index 85b3aaaf0cf..7a00d9f2291 100644 --- a/src/vs/editor/standalone/browser/standaloneCodeEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneCodeEditor.ts @@ -176,9 +176,7 @@ export class StandaloneCodeEditor extends CodeEditorWidget implements IStandalon ); super(domElement, options, {}, instantiationService, codeEditorService, commandService, contextKeyService, themeService, notificationService, accessibilityService); - if (keybindingService instanceof StandaloneKeybindingService) { - this._standaloneKeybindingService = keybindingService; - } + this._standaloneKeybindingService = keybindingService; // Create the ARIA dom node as soon as the first editor is instantiated createAriaDomNode(); diff --git a/src/vs/editor/standalone/browser/standaloneThemeServiceImpl.ts b/src/vs/editor/standalone/browser/standaloneThemeServiceImpl.ts index 3f04994e55c..2a47cc6113b 100644 --- a/src/vs/editor/standalone/browser/standaloneThemeServiceImpl.ts +++ b/src/vs/editor/standalone/browser/standaloneThemeServiceImpl.ts @@ -160,7 +160,7 @@ export class StandaloneThemeServiceImpl implements IStandaloneThemeService { private readonly _knownThemes: Map; private readonly _styleElement: HTMLStyleElement; - private _theme: IStandaloneTheme; + private _theme!: IStandaloneTheme; private readonly _onThemeChange: Emitter; private readonly _onIconThemeChange: Emitter; private readonly environment: IEnvironmentService = Object.create(null); diff --git a/src/vs/platform/remote/common/remoteAgentFileSystemChannel.ts b/src/vs/platform/remote/common/remoteAgentFileSystemChannel.ts index cefb3518ba0..1f8b5fee33c 100644 --- a/src/vs/platform/remote/common/remoteAgentFileSystemChannel.ts +++ b/src/vs/platform/remote/common/remoteAgentFileSystemChannel.ts @@ -33,7 +33,7 @@ export class RemoteExtensionsFileSystemProvider extends Disposable implements IF private readonly _onDidChangeCapabilities = this._register(new Emitter()); readonly onDidChangeCapabilities: Event = this._onDidChangeCapabilities.event; - private _capabilities: FileSystemProviderCapabilities; + private _capabilities!: FileSystemProviderCapabilities; get capabilities(): FileSystemProviderCapabilities { return this._capabilities; } constructor(private readonly channel: IChannel, environment: Promise) { diff --git a/src/vs/workbench/api/node/extHostRequireInterceptor.ts b/src/vs/workbench/api/node/extHostRequireInterceptor.ts index 789ece36253..8633dc023bc 100644 --- a/src/vs/workbench/api/node/extHostRequireInterceptor.ts +++ b/src/vs/workbench/api/node/extHostRequireInterceptor.ts @@ -75,7 +75,7 @@ export class VSCodeNodeModuleFactory implements INodeModuleFactory { public readonly nodeModuleName = 'vscode'; private readonly _extApiImpl = new Map(); - private _defaultApiImpl: typeof vscode; + private _defaultApiImpl?: typeof vscode; constructor( private readonly _apiFactory: IExtensionApiFactory, @@ -191,7 +191,7 @@ export class OpenNodeModuleFactory implements INodeModuleFactory { public readonly nodeModuleName: string[] = ['open', 'opn']; private _extensionId: string | undefined; - private _original: IOriginalOpen; + private _original?: IOriginalOpen; private _impl: IOpenModule; constructor(mainThreadWindow: MainThreadWindowShape, private _mainThreadTelemerty: MainThreadTelemetryShape, private readonly _extensionPaths: TernarySearchTree) { @@ -224,7 +224,7 @@ export class OpenNodeModuleFactory implements INodeModuleFactory { private callOriginal(target: string, options: OpenOptions | undefined): Thenable { this.sendNoForwardTelemetry(); - return this._original(target, options); + return this._original!(target, options); } private sendShimmingTelemetry(): void { diff --git a/src/vs/workbench/services/extensions/common/extensionDescriptionRegistry.ts b/src/vs/workbench/services/extensions/common/extensionDescriptionRegistry.ts index 0c3523f555e..38c4b63eda7 100644 --- a/src/vs/workbench/services/extensions/common/extensionDescriptionRegistry.ts +++ b/src/vs/workbench/services/extensions/common/extensionDescriptionRegistry.ts @@ -17,9 +17,9 @@ export class ExtensionDescriptionRegistry { public readonly onDidChange = this._onDidChange.event; private _extensionDescriptions: IExtensionDescription[]; - private _extensionsMap: Map; - private _extensionsArr: IExtensionDescription[]; - private _activationMap: Map; + private _extensionsMap!: Map; + private _extensionsArr!: IExtensionDescription[]; + private _activationMap!: Map; constructor(extensionDescriptions: IExtensionDescription[]) { this._extensionDescriptions = extensionDescriptions; diff --git a/src/vs/workbench/services/extensions/common/proxyIdentifier.ts b/src/vs/workbench/services/extensions/common/proxyIdentifier.ts index fdf7d366c94..311d9e7cd07 100644 --- a/src/vs/workbench/services/extensions/common/proxyIdentifier.ts +++ b/src/vs/workbench/services/extensions/common/proxyIdentifier.ts @@ -20,10 +20,10 @@ export interface IRPCProtocol { assertRegistered(identifiers: ProxyIdentifier[]): void; } +// @ts-ignore export class ProxyIdentifier { public static count = 0; _proxyIdentifierBrand: void; - _suppressCompilerUnusedWarning: T; public readonly isMain: boolean; public readonly sid: string; diff --git a/src/vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts b/src/vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts index 10fd66cbdc9..5558123d19a 100644 --- a/src/vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts +++ b/src/vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts @@ -48,8 +48,8 @@ function getExtraDevSystemExtensionsRoot(): string { export class CachedExtensionScanner { public readonly scannedExtensions: Promise; - private _scannedExtensionsResolve: (result: IExtensionDescription[]) => void; - private _scannedExtensionsReject: (err: any) => void; + private _scannedExtensionsResolve!: (result: IExtensionDescription[]) => void; + private _scannedExtensionsReject!: (err: any) => void; public readonly translationConfig: Promise; constructor( diff --git a/src/vs/workbench/services/extensions/node/extensionPoints.ts b/src/vs/workbench/services/extensions/node/extensionPoints.ts index 5a7efd1462b..f20f824a2e2 100644 --- a/src/vs/workbench/services/extensions/node/extensionPoints.ts +++ b/src/vs/workbench/services/extensions/node/extensionPoints.ts @@ -409,7 +409,7 @@ class ExtensionManifestValidator extends ExtensionManifestHandler { export class ExtensionScannerInput { - public mtime: number; + public mtime: number | undefined; constructor( public readonly ourVersion: string, @@ -609,4 +609,4 @@ export class ExtensionScanner { return resultArr; }); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/services/extensions/test/node/rpcProtocol.test.ts b/src/vs/workbench/services/extensions/test/node/rpcProtocol.test.ts index cf1658b05c5..6e0669eb0d2 100644 --- a/src/vs/workbench/services/extensions/test/node/rpcProtocol.test.ts +++ b/src/vs/workbench/services/extensions/test/node/rpcProtocol.test.ts @@ -14,7 +14,7 @@ import { VSBuffer } from 'vs/base/common/buffer'; suite('RPCProtocol', () => { class MessagePassingProtocol implements IMessagePassingProtocol { - private _pair: MessagePassingProtocol; + private _pair?: MessagePassingProtocol; private readonly _onMessage = new Emitter(); public readonly onMessage: Event = this._onMessage.event; @@ -25,7 +25,7 @@ suite('RPCProtocol', () => { public send(buffer: VSBuffer): void { process.nextTick(() => { - this._pair._onMessage.fire(buffer); + this._pair!._onMessage.fire(buffer); }); } } diff --git a/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts b/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts index 5168e7f16c3..3a789e23d98 100644 --- a/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts +++ b/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts @@ -31,6 +31,7 @@ export abstract class AbstractRemoteAgentService extends Disposable { @IEnvironmentService protected readonly _environmentService: IEnvironmentService ) { super(); + this._environment = null; } abstract getConnection(): IRemoteAgentConnection | null; diff --git a/src/vs/workbench/services/textMate/common/TMScopeRegistry.ts b/src/vs/workbench/services/textMate/common/TMScopeRegistry.ts index 4c352da67a4..4c6d3c5fdb7 100644 --- a/src/vs/workbench/services/textMate/common/TMScopeRegistry.ts +++ b/src/vs/workbench/services/textMate/common/TMScopeRegistry.ts @@ -31,7 +31,7 @@ export class TMScopeRegistry extends Disposable { constructor() { super(); - this.reset(); + this._scopeNameToLanguageRegistration = Object.create(null); } public reset(): void { diff --git a/src/vs/workbench/services/textMate/electron-browser/textMateWorker.ts b/src/vs/workbench/services/textMate/electron-browser/textMateWorker.ts index a5c24f1d7f7..6f78679f1fd 100644 --- a/src/vs/workbench/services/textMate/electron-browser/textMateWorker.ts +++ b/src/vs/workbench/services/textMate/electron-browser/textMateWorker.ts @@ -80,7 +80,7 @@ class TextMateWorkerModel extends MirrorTextModel { const languageId = this._languageId; this._worker.getOrCreateGrammar(languageId).then((r) => { - if (this._isDisposed || languageId !== this._languageId) { + if (this._isDisposed || languageId !== this._languageId || !r) { return; } @@ -118,7 +118,7 @@ export class TextMateWorker { private readonly _host: TextMateWorkerHost; private readonly _models: { [uri: string]: TextMateWorkerModel; }; private readonly _grammarCache: Promise[]; - private readonly _grammarFactory: TMGrammarFactory; + private readonly _grammarFactory: TMGrammarFactory | null; constructor(ctx: IWorkerContext, createData: ICreateData) { this._host = ctx.host; @@ -135,23 +135,23 @@ export class TextMateWorker { }; }); - let vscodeTextmate: typeof import('vscode-textmate'); const globalDefine = (self).define; try { (self).define.amd = undefined; - vscodeTextmate = require.__$__nodeRequire('vscode-textmate'); + const vscodeTextmate = require.__$__nodeRequire('vscode-textmate'); + + this._grammarFactory = new TMGrammarFactory({ + logTrace: (msg: string) => {/* console.log(msg) */ }, + logError: (msg: string, err: any) => console.error(msg, err), + readFile: (resource: URI) => this._host.readFile(resource) + }, grammarDefinitions, vscodeTextmate, undefined); } catch (err) { console.error(err); + this._grammarFactory = null; return; } finally { (self).define = globalDefine; } - - this._grammarFactory = new TMGrammarFactory({ - logTrace: (msg: string) => {/* console.log(msg) */ }, - logError: (msg: string, err: any) => console.error(msg, err), - readFile: (resource: URI) => this._host.readFile(resource) - }, grammarDefinitions, vscodeTextmate, undefined); } public acceptNewModel(data: IRawModelData): void { @@ -175,7 +175,10 @@ export class TextMateWorker { } } - public getOrCreateGrammar(languageId: LanguageId): Promise { + public getOrCreateGrammar(languageId: LanguageId): Promise { + if (!this._grammarFactory) { + return Promise.resolve(null); + } if (!this._grammarCache[languageId]) { this._grammarCache[languageId] = this._grammarFactory.createGrammar(languageId); } @@ -183,7 +186,9 @@ export class TextMateWorker { } public acceptTheme(theme: IRawTheme): void { - this._grammarFactory.setTheme(theme); + if (this._grammarFactory) { + this._grammarFactory.setTheme(theme); + } } public _setTokens(resource: URI, versionId: number, tokens: Uint8Array): void { diff --git a/src/vs/workbench/test/electron-browser/api/testRPCProtocol.ts b/src/vs/workbench/test/electron-browser/api/testRPCProtocol.ts index 9391351cdae..64fa203834f 100644 --- a/src/vs/workbench/test/electron-browser/api/testRPCProtocol.ts +++ b/src/vs/workbench/test/electron-browser/api/testRPCProtocol.ts @@ -27,7 +27,7 @@ export class TestRPCProtocol implements IExtHostContext { private _callCountValue: number = 0; private _idle?: Promise; - private _completeIdle: Function; + private _completeIdle?: Function; private readonly _locals: { [id: string]: any; }; private readonly _proxies: { [id: string]: any; }; From 466e5ef6c2188d61a8c93c53748aa9e9788bcfc9 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 5 Aug 2019 15:54:13 +0200 Subject: [PATCH 202/861] Use resolveTask in npm extension Fixes #76520 --- extensions/npm/src/tasks.ts | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/extensions/npm/src/tasks.ts b/extensions/npm/src/tasks.ts index f60f7531516..0e6a28bfc33 100644 --- a/extensions/npm/src/tasks.ts +++ b/extensions/npm/src/tasks.ts @@ -5,7 +5,7 @@ import { TaskDefinition, Task, TaskGroup, WorkspaceFolder, RelativePattern, ShellExecution, Uri, workspace, - DebugConfiguration, debug, TaskProvider, TextDocument, tasks + DebugConfiguration, debug, TaskProvider, TextDocument, tasks, TaskScope } from 'vscode'; import * as path from 'path'; import * as fs from 'fs'; @@ -34,6 +34,21 @@ export class NpmTaskProvider implements TaskProvider { } public resolveTask(_task: Task): Task | undefined { + const npmTask = (_task.definition).script; + if (npmTask) { + const kind: NpmTaskDefinition = (_task.definition); + let packageJsonUri: Uri; + if (_task.scope === undefined || _task.scope === TaskScope.Global || _task.scope === TaskScope.Workspace) { + // scope is required to be a WorkspaceFolder for resolveTask + return undefined; + } + if (kind.path) { + packageJsonUri = _task.scope.uri.with({ path: _task.scope.uri.path + '/' + kind.path + 'package.json' }); + } else { + packageJsonUri = _task.scope.uri.with({ path: _task.scope.uri.path + '/package.json' }); + } + return createTask(kind, `run ${kind.script}`, _task.scope, packageJsonUri); + } return undefined; } } @@ -221,7 +236,13 @@ export function getTaskName(script: string, relativePath: string | undefined) { return script; } -export function createTask(script: string, cmd: string, folder: WorkspaceFolder, packageJsonUri: Uri, matcher?: any): Task { +export function createTask(script: NpmTaskDefinition | string, cmd: string, folder: WorkspaceFolder, packageJsonUri: Uri, matcher?: any): Task { + let kind: NpmTaskDefinition; + if (typeof script === 'string') { + kind = { type: 'npm', script: script }; + } else { + kind = script; + } function getCommandLine(folder: WorkspaceFolder, cmd: string): string { let packageManager = getPackageManager(folder); @@ -237,15 +258,11 @@ export function createTask(script: string, cmd: string, folder: WorkspaceFolder, return absolutePath.substring(rootUri.path.length + 1); } - let kind: NpmTaskDefinition = { - type: 'npm', - script: script - }; let relativePackageJson = getRelativePath(folder, packageJsonUri); if (relativePackageJson.length) { kind.path = getRelativePath(folder, packageJsonUri); } - let taskName = getTaskName(script, relativePackageJson); + let taskName = getTaskName(kind.script, relativePackageJson); let cwd = path.dirname(packageJsonUri.fsPath); return new Task(kind, folder, taskName, 'npm', new ShellExecution(getCommandLine(folder, cmd), { cwd: cwd }), matcher); } From 1fa8c2f111bd55f1f90792525cf3ada6cce8a227 Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 5 Aug 2019 16:00:04 +0200 Subject: [PATCH 203/861] fix focusWindowOnBreak --- src/vs/workbench/contrib/debug/browser/debugSession.ts | 2 +- src/vs/workbench/contrib/debug/common/debug.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugSession.ts b/src/vs/workbench/contrib/debug/browser/debugSession.ts index 037d333ed25..16f62f1d7dd 100644 --- a/src/vs/workbench/contrib/debug/browser/debugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/debugSession.ts @@ -675,7 +675,7 @@ export class DebugSession implements IDebugSession { this.viewletService.openViewlet(VIEWLET_ID); } - if (this.configurationService.getValue('debug.autoFocusEditor')) { + if (this.configurationService.getValue('debug').focusWindowOnBreak) { this.windowService.focusWindow(); } } diff --git a/src/vs/workbench/contrib/debug/common/debug.ts b/src/vs/workbench/contrib/debug/common/debug.ts index 1ac7b96593d..1798b2838c6 100644 --- a/src/vs/workbench/contrib/debug/common/debug.ts +++ b/src/vs/workbench/contrib/debug/common/debug.ts @@ -440,6 +440,7 @@ export interface IDebugConfiguration { lineHeight: number; wordWrap: boolean; }; + focusWindowOnBreak: boolean; } export interface IGlobalConfig { From 8b14c93c7728a8918f5013e9f1bf8ea0eff48b13 Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 5 Aug 2019 16:00:32 +0200 Subject: [PATCH 204/861] strictPropertyInitialization #78168 --- src/vs/base/browser/ui/selectBox/selectBoxNative.ts | 2 +- src/vs/base/common/history.ts | 4 ++-- src/vs/workbench/browser/actions.ts | 2 +- src/vs/workbench/browser/composite.ts | 8 ++++---- src/vs/workbench/browser/panel.ts | 2 +- src/vs/workbench/browser/parts/compositePart.ts | 10 +++++----- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/vs/base/browser/ui/selectBox/selectBoxNative.ts b/src/vs/base/browser/ui/selectBox/selectBoxNative.ts index c17caf43770..afaed056d4c 100644 --- a/src/vs/base/browser/ui/selectBox/selectBoxNative.ts +++ b/src/vs/base/browser/ui/selectBox/selectBoxNative.ts @@ -16,7 +16,7 @@ export class SelectBoxNative extends Disposable implements ISelectBoxDelegate { private selectElement: HTMLSelectElement; private selectBoxOptions: ISelectBoxOptions; private options: ISelectOptionItem[]; - private selected: number; + private selected = 0; private readonly _onDidSelect: Emitter; private styles: ISelectBoxStyles; diff --git a/src/vs/base/common/history.ts b/src/vs/base/common/history.ts index 19dada92a3e..4aa6b3216e5 100644 --- a/src/vs/base/common/history.ts +++ b/src/vs/base/common/history.ts @@ -7,9 +7,9 @@ import { INavigator, ArrayNavigator } from 'vs/base/common/iterator'; export class HistoryNavigator implements INavigator { - private _history: Set; + private _history!: Set; private _limit: number; - private _navigator: ArrayNavigator; + private _navigator!: ArrayNavigator; constructor(history: T[] = [], limit: number = 10) { this._initialize(history); diff --git a/src/vs/workbench/browser/actions.ts b/src/vs/workbench/browser/actions.ts index e3d71c85338..aac3da30445 100644 --- a/src/vs/workbench/browser/actions.ts +++ b/src/vs/workbench/browser/actions.ts @@ -156,7 +156,7 @@ export interface IActionBarRegistry { class ActionBarRegistry implements IActionBarRegistry { private readonly actionBarContributorConstructors: { scope: string; ctor: IConstructorSignature0; }[] = []; private readonly actionBarContributorInstances: Map = new Map(); - private instantiationService: IInstantiationService; + private instantiationService!: IInstantiationService; start(accessor: ServicesAccessor): void { this.instantiationService = accessor.get(IInstantiationService); diff --git a/src/vs/workbench/browser/composite.ts b/src/vs/workbench/browser/composite.ts index 123e9a9b692..bab3dcfb849 100644 --- a/src/vs/workbench/browser/composite.ts +++ b/src/vs/workbench/browser/composite.ts @@ -35,7 +35,7 @@ export abstract class Composite extends Component implements IComposite { private readonly _onDidChangeVisibility: Emitter = this._register(new Emitter()); readonly onDidChangeVisibility: Event = this._onDidChangeVisibility.event; - private _onDidFocus: Emitter; + private _onDidFocus!: Emitter; get onDidFocus(): Event { if (!this._onDidFocus) { this.registerFocusTrackEvents(); @@ -50,7 +50,7 @@ export abstract class Composite extends Component implements IComposite { } } - private _onDidBlur: Emitter; + private _onDidBlur!: Emitter; get onDidBlur(): Event { if (!this._onDidBlur) { this.registerFocusTrackEvents(); @@ -68,10 +68,10 @@ export abstract class Composite extends Component implements IComposite { this._register(focusTracker.onDidBlur(() => this._onDidBlur.fire())); } - protected actionRunner: IActionRunner; + protected actionRunner: IActionRunner | undefined; private visible: boolean; - private parent: HTMLElement; + private parent!: HTMLElement; constructor( id: string, diff --git a/src/vs/workbench/browser/panel.ts b/src/vs/workbench/browser/panel.ts index 889c107932f..3e1a33fbe2c 100644 --- a/src/vs/workbench/browser/panel.ts +++ b/src/vs/workbench/browser/panel.ts @@ -25,7 +25,7 @@ export class PanelDescriptor extends CompositeDescriptor { } export class PanelRegistry extends CompositeRegistry { - private defaultPanelId: string; + private defaultPanelId!: string; /** * Registers a panel to the platform. diff --git a/src/vs/workbench/browser/parts/compositePart.ts b/src/vs/workbench/browser/parts/compositePart.ts index e5d7cfbe7c8..95c15731550 100644 --- a/src/vs/workbench/browser/parts/compositePart.ts +++ b/src/vs/workbench/browser/parts/compositePart.ts @@ -58,18 +58,18 @@ export abstract class CompositePart extends Part { protected readonly onDidCompositeOpen = this._register(new Emitter<{ composite: IComposite, focus: boolean }>()); protected readonly onDidCompositeClose = this._register(new Emitter()); - protected toolBar: ToolBar; + protected toolBar!: ToolBar; private mapCompositeToCompositeContainer = new Map(); private mapActionsBindingToComposite = new Map void>(); private activeComposite: Composite | null; private lastActiveCompositeId: string; private instantiatedCompositeItems: Map; - private titleLabel: ICompositeTitleLabel; - private progressBar: ProgressBar; - private contentAreaSize: Dimension; + private titleLabel!: ICompositeTitleLabel; + private progressBar!: ProgressBar; + private contentAreaSize: Dimension | undefined; private readonly telemetryActionsListener = this._register(new MutableDisposable()); - private currentCompositeOpenToken: string; + private currentCompositeOpenToken: string | undefined; constructor( private notificationService: INotificationService, From 0d5596bbc3bedd25adbd65ad402654e7bbada23d Mon Sep 17 00:00:00 2001 From: Howard Hung Date: Mon, 5 Aug 2019 22:07:19 +0800 Subject: [PATCH 205/861] Feat. #77878 - trim git clone --- extensions/git/src/commands.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index d75e6f9bc45..09387d3e28f 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -450,6 +450,11 @@ export class CommandCenter { return; } + const match = /git\s+clone\s+(.*)/.exec(url); + if (match) { + url = match[1]; + } + const config = workspace.getConfiguration('git'); let defaultCloneDirectory = config.get('defaultCloneDirectory') || os.homedir(); defaultCloneDirectory = defaultCloneDirectory.replace(/^~/, os.homedir()); From 051b669b61cd175cb06c8f4500498dbeef79114c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 5 Aug 2019 16:12:05 +0200 Subject: [PATCH 206/861] :lipstick: --- .../workbench/api/common/extHostWorkspace.ts | 3 +-- .../extensions/node/extensionHostMain.ts | 23 ++++++++----------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/vs/workbench/api/common/extHostWorkspace.ts b/src/vs/workbench/api/common/extHostWorkspace.ts index a97d82b4935..3c176107270 100644 --- a/src/vs/workbench/api/common/extHostWorkspace.ts +++ b/src/vs/workbench/api/common/extHostWorkspace.ts @@ -171,11 +171,10 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac constructor( mainContext: IMainContext, logService: ILogService, - requestIdProvider: Counter, data?: IStaticWorkspaceData ) { this._logService = logService; - this._requestIdProvider = requestIdProvider; + this._requestIdProvider = new Counter(); this._barrier = new Barrier(); this._proxy = mainContext.getProxy(MainContext.MainThreadWorkspace); diff --git a/src/vs/workbench/services/extensions/node/extensionHostMain.ts b/src/vs/workbench/services/extensions/node/extensionHostMain.ts index 9e58237b634..b5913991608 100644 --- a/src/vs/workbench/services/extensions/node/extensionHostMain.ts +++ b/src/vs/workbench/services/extensions/node/extensionHostMain.ts @@ -5,8 +5,7 @@ import { timeout } from 'vs/base/common/async'; import * as errors from 'vs/base/common/errors'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; -import { Counter } from 'vs/base/common/numbers'; +import { DisposableStore } from 'vs/base/common/lifecycle'; import { URI, setUriThrowOnMissingScheme } from 'vs/base/common/uri'; import { IURITransformer } from 'vs/base/common/uriIpc'; import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; @@ -41,10 +40,7 @@ export class ExtensionHostMain { private _isTerminating: boolean; private readonly _hostUtils: IHostUtils; private readonly _extensionService: ExtHostExtensionService; - private readonly _extHostLogService: ExtHostLogService; - private disposables: IDisposable[] = []; - - private _searchRequestIdProvider: Counter; + private readonly disposables = new DisposableStore(); constructor( protocol: IMessagePassingProtocol, @@ -65,14 +61,13 @@ export class ExtensionHostMain { consolePatchFn(rpcProtocol.getProxy(MainContext.MainThreadConsole)); // services - this._extHostLogService = new ExtHostLogService(logServiceFn(initData), initData.logsLocation.fsPath); - this.disposables.push(this._extHostLogService); + const extHostLogService = new ExtHostLogService(logServiceFn(initData), initData.logsLocation.fsPath); + this.disposables.add(extHostLogService); - this._searchRequestIdProvider = new Counter(); - const extHostWorkspace = new ExtHostWorkspace(rpcProtocol, this._extHostLogService, this._searchRequestIdProvider, withNullAsUndefined(initData.workspace)); + const extHostWorkspace = new ExtHostWorkspace(rpcProtocol, extHostLogService, withNullAsUndefined(initData.workspace)); - this._extHostLogService.info('extension host started'); - this._extHostLogService.trace('initData', initData); + extHostLogService.info('extension host started'); + extHostLogService.trace('initData', initData); const extHostConfiguraiton = new ExtHostConfiguration(rpcProtocol.getProxy(MainContext.MainThreadConfiguration), extHostWorkspace); this._extensionService = new ExtHostExtensionService( @@ -82,7 +77,7 @@ export class ExtensionHostMain { extHostWorkspace, extHostConfiguraiton, initData.environment, - this._extHostLogService, + extHostLogService, uriTransformer ); @@ -127,7 +122,7 @@ export class ExtensionHostMain { } this._isTerminating = true; - this.disposables = dispose(this.disposables); + this.disposables.dispose(); errors.setUnexpectedErrorHandler((err) => { // TODO: write to log once we have one From 873fdf8acde6800bbe0b92ccabd53bb4c5415434 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 5 Aug 2019 07:25:23 -0700 Subject: [PATCH 207/861] Fix nav mode and windows shell helper strict prop init --- .../browser/addons/navigationModeAddon.ts | 15 +++++++++++++-- .../contrib/terminal/node/windowsShellHelper.ts | 10 +++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/addons/navigationModeAddon.ts b/src/vs/workbench/contrib/terminal/browser/addons/navigationModeAddon.ts index 74542173298..6997a4dbef1 100644 --- a/src/vs/workbench/contrib/terminal/browser/addons/navigationModeAddon.ts +++ b/src/vs/workbench/contrib/terminal/browser/addons/navigationModeAddon.ts @@ -9,7 +9,7 @@ import { addDisposableListener } from 'vs/base/browser/dom'; import { INavigationMode } from 'vs/workbench/contrib/terminal/common/terminal'; export class NavigationModeAddon implements INavigationMode, ITerminalAddon { - private _terminal: Terminal; + private _terminal: Terminal | undefined; constructor( private _navigationModeContextKey: IContextKey @@ -22,11 +22,18 @@ export class NavigationModeAddon implements INavigationMode, ITerminalAddon { dispose() { } exitNavigationMode(): void { + if (!this._terminal) { + return; + } this._terminal.scrollToBottom(); this._terminal.focus(); } focusPreviousLine(): void { + if (!this._terminal) { + return; + } + // Focus previous row if a row is already focused if (document.activeElement && document.activeElement.parentElement && document.activeElement.parentElement.classList.contains('xterm-accessibility-tree')) { const element = document.activeElement.previousElementSibling; @@ -66,6 +73,10 @@ export class NavigationModeAddon implements INavigationMode, ITerminalAddon { } focusNextLine(): void { + if (!this._terminal) { + return; + } + // Focus previous row if a row is already focused if (document.activeElement && document.activeElement.parentElement && document.activeElement.parentElement.classList.contains('xterm-accessibility-tree')) { const element = document.activeElement.nextElementSibling; @@ -103,4 +114,4 @@ export class NavigationModeAddon implements INavigationMode, ITerminalAddon { }); this._navigationModeContextKey.set(true); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts b/src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts index ced2d3ee265..030dcd89100 100644 --- a/src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts +++ b/src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts @@ -25,10 +25,10 @@ const SHELL_EXECUTABLES = [ let windowsProcessTree: typeof WindowsProcessTreeType; export class WindowsShellHelper implements IWindowsShellHelper { - private _onCheckShell: Emitter | undefined>; + private _onCheckShell: Emitter | undefined> = new Emitter | undefined>(); private _isDisposed: boolean; - private _currentRequest: Promise | null; - private _newLineFeed: boolean; + private _currentRequest: Promise | undefined; + private _newLineFeed: boolean = false; public constructor( private _rootProcessId: number, @@ -47,7 +47,6 @@ export class WindowsShellHelper implements IWindowsShellHelper { } windowsProcessTree = mod; - this._onCheckShell = new Emitter>(); // The debounce is necessary to prevent multiple processes from spawning when // the enter key or output is spammed Event.debounce(this._onCheckShell.event, (l, e) => e, 150, true)(() => { @@ -65,6 +64,7 @@ export class WindowsShellHelper implements IWindowsShellHelper { this._xterm.onCursorMove(() => { if (this._newLineFeed) { this._onCheckShell.fire(undefined); + this._newLineFeed = false; } }); @@ -127,7 +127,7 @@ export class WindowsShellHelper implements IWindowsShellHelper { this._currentRequest = new Promise(resolve => { windowsProcessTree.getProcessTree(this._rootProcessId, (tree) => { const name = this.traverseTree(tree); - this._currentRequest = null; + this._currentRequest = undefined; resolve(name); }); }); From 15a523f2a02de0d296b9406fc656736184aa5289 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 5 Aug 2019 16:28:33 +0200 Subject: [PATCH 208/861] fixes #78505 --- .../workbench/contrib/preferences/browser/settingsEditor2.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts index b1094d9a026..ab5ec782a39 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts @@ -281,6 +281,11 @@ export class SettingsEditor2 extends BaseEditor { layout(dimension: DOM.Dimension): void { this.dimension = dimension; + + if (!this.isVisible()) { + return; + } + this.layoutTrees(dimension); const innerWidth = Math.min(1000, dimension.width) - 24 * 2; // 24px padding on left and right; From 046c3f5fb04da96655258fb8c70eae5fe8d185c9 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 5 Aug 2019 07:35:36 -0700 Subject: [PATCH 209/861] strict prop init terminal --- .../api/node/extHostTerminalService.ts | 24 +++++++++++-------- .../terminal/browser/terminalInstance.ts | 4 ++-- .../browser/terminalProcessManager.ts | 2 +- .../terminal/browser/terminalWidgetManager.ts | 10 ++++---- .../contrib/terminal/common/terminal.ts | 2 +- 5 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index a17a9c0622f..97ddadc09e1 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -27,9 +27,9 @@ import { IDisposable } from 'vs/base/common/lifecycle'; const RENDERER_NO_PROCESS_ID = -1; export class BaseExtHostTerminal { - public _id: number; + public _id: number | undefined; protected _idPromise: Promise; - private _idPromiseComplete: (value: number) => any; + private _idPromiseComplete: ((value: number) => any) | undefined; private _disposed: boolean = false; private _queuedRequests: ApiRequest[] = []; @@ -71,9 +71,12 @@ export class BaseExtHostTerminal { public _runQueuedRequests(id: number): void { this._id = id; - this._idPromiseComplete(id); + if (this._idPromiseComplete) { + this._idPromiseComplete(id); + this._idPromiseComplete = undefined; + } this._queuedRequests.forEach((r) => { - r.run(this._proxy, this._id); + r.run(this._proxy, id); }); this._queuedRequests.length = 0; } @@ -82,14 +85,14 @@ export class BaseExtHostTerminal { export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Terminal { private _pidPromise: Promise; private _cols: number | undefined; - private _pidPromiseComplete: ((value: number | undefined) => any) | null; + private _pidPromiseComplete: ((value: number | undefined) => any) | undefined; private _rows: number | undefined; private readonly _onData = new Emitter(); public get onDidWriteData(): Event { // Tell the main side to start sending data if it's not already - this._idPromise.then(c => { - this._proxy.$registerOnDataListener(this._id); + this._idPromise.then(id => { + this._proxy.$registerOnDataListener(id); }); return this._onData.event; } @@ -124,10 +127,11 @@ export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Termi this._runQueuedRequests(terminal.id); } - public async createExtensionTerminal(): Promise { + public async createExtensionTerminal(): Promise { const terminal = await this._proxy.$createTerminal({ name: this._name, isExtensionTerminal: true }); this._name = terminal.name; this._runQueuedRequests(terminal.id); + return terminal.id; } public get name(): string { @@ -181,7 +185,7 @@ export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Termi // The event may fire 2 times when the panel is restored if (this._pidPromiseComplete) { this._pidPromiseComplete(processId); - this._pidPromiseComplete = null; + this._pidPromiseComplete = undefined; } else { // Recreate the promise if this is the nth processId set (e.g. reused task terminals) this._pidPromise.then(pid => { @@ -332,7 +336,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { public createExtensionTerminal(options: vscode.ExtensionTerminalOptions): vscode.Terminal { const terminal = new ExtHostTerminal(this._proxy, options.name); const p = new ExtHostPseudoterminal(options.pty); - terminal.createExtensionTerminal().then(() => this._setupExtHostProcessListeners(terminal._id, p)); + terminal.createExtensionTerminal().then(id => this._setupExtHostProcessListeners(id, p)); this._terminals.push(terminal); return terminal; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 411d6bf2c29..a645388dfe4 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -991,8 +991,8 @@ export class TerminalInstance implements ITerminalInstance { return; } this._xtermReadyPromise.then(() => { - if (!this._isDisposed) { - this._windowsShellHelper = this._terminalInstanceService.createWindowsShellHelper(this._processManager!.shellProcessId, this, this._xterm); + if (!this._isDisposed && this._processManager && this._processManager.shellProcessId) { + this._windowsShellHelper = this._terminalInstanceService.createWindowsShellHelper(this._processManager.shellProcessId, this, this._xterm); } }); }); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index 37dc39b51f6..9684a8830f3 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -45,7 +45,7 @@ enum ProcessType { export class TerminalProcessManager implements ITerminalProcessManager { public processState: ProcessState = ProcessState.UNINITIALIZED; public ptyProcessReady: Promise; - public shellProcessId: number; + public shellProcessId: number | undefined; public remoteAuthority: string | undefined; public os: platform.OperatingSystem | undefined; public userHome: string | undefined; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalWidgetManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalWidgetManager.ts index 8beb67cb689..8c9efe0314f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalWidgetManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalWidgetManager.ts @@ -8,8 +8,8 @@ import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle' const WIDGET_HEIGHT = 29; export class TerminalWidgetManager implements IDisposable { - private _container: HTMLElement | null; - private _xtermViewport: HTMLElement | null; + private _container: HTMLElement | undefined; + private _xtermViewport: HTMLElement | undefined; private _messageWidget: MessageWidget; private readonly _messageListeners = new DisposableStore(); @@ -27,9 +27,9 @@ export class TerminalWidgetManager implements IDisposable { public dispose(): void { if (this._container && this._container.parentElement) { this._container.parentElement.removeChild(this._container); - this._container = null; + this._container = undefined; } - this._xtermViewport = null; + this._xtermViewport = undefined; this._messageListeners.dispose(); } @@ -108,4 +108,4 @@ class MessageWidget { this._container.removeChild(this.domNode); } } -} \ No newline at end of file +} diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index f6413d9857e..ae7b445e9f8 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -697,7 +697,7 @@ export interface IBeforeProcessDataEvent { export interface ITerminalProcessManager extends IDisposable { readonly processState: ProcessState; readonly ptyProcessReady: Promise; - readonly shellProcessId: number; + readonly shellProcessId: number | undefined; readonly remoteAuthority: string | undefined; readonly os: OperatingSystem | undefined; readonly userHome: string | undefined; From 41df3bcb7cec1ae80b11482207bb458a54f4cb19 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 5 Aug 2019 16:45:16 +0200 Subject: [PATCH 210/861] debt - test all optional modules --- .../test/electron-main/nativeHelpers.test.ts | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/vs/code/test/electron-main/nativeHelpers.test.ts b/src/vs/code/test/electron-main/nativeHelpers.test.ts index ff0f589d511..c8ffd0c8dbc 100644 --- a/src/vs/code/test/electron-main/nativeHelpers.test.ts +++ b/src/vs/code/test/electron-main/nativeHelpers.test.ts @@ -7,22 +7,33 @@ import * as assert from 'assert'; import { isWindows } from 'vs/base/common/platform'; suite('Windows Native Helpers', () => { - test('windows-mutex', async () => { - if (!isWindows) { - return; - } + if (!isWindows) { + return; + } + test('windows-mutex', async () => { const mutex = await import('windows-mutex'); - assert.ok(mutex, 'Unable to load windows-mutex dependency.'); + assert.ok(mutex && typeof mutex.isActive === 'function', 'Unable to load windows-mutex dependency.'); assert.ok(typeof mutex.isActive === 'function', 'Unable to load windows-mutex dependency.'); }); test('windows-foreground-love', async () => { - if (!isWindows) { - return; - } - const foregroundLove = await import('windows-foreground-love'); - assert.ok(foregroundLove, 'Unable to load windows-foreground-love dependency.'); + assert.ok(foregroundLove && typeof foregroundLove.allowSetForegroundWindow === 'function', 'Unable to load windows-foreground-love dependency.'); }); -}); \ No newline at end of file + + test('windows-process-tree', async () => { + const processTree = await import('windows-process-tree'); + assert.ok(processTree && typeof processTree.getProcessTree === 'function', 'Unable to load windows-process-tree dependency.'); + }); + + test('vscode-windows-ca-certs', async () => { + const windowsCerts = await import('vscode-windows-ca-certs'); + assert.ok(windowsCerts, 'Unable to load vscode-windows-ca-certs dependency.'); + }); + + test('vscode-windows-registry', async () => { + const windowsRegistry = await import('vscode-windows-registry'); + assert.ok(windowsRegistry && typeof windowsRegistry.GetStringRegKey === 'function', 'Unable to load vscode-windows-registry dependency.'); + }); +}); From 32da48e7a00e184d850e0ff68513c6d29a386988 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 5 Aug 2019 16:48:13 +0200 Subject: [PATCH 211/861] consistent dto namings --- .../api/browser/mainThreadEditors.ts | 4 +- .../api/browser/mainThreadLanguageFeatures.ts | 82 ++++---- .../api/browser/mainThreadTerminalService.ts | 4 +- .../workbench/api/common/extHost.protocol.ts | 190 +++++++++--------- .../api/common/extHostApiCommands.ts | 4 +- .../workbench/api/common/extHostCommands.ts | 6 +- .../common/extHostDocumentSaveParticipant.ts | 4 +- .../common/extHostFileSystemEventService.ts | 4 +- .../api/common/extHostLanguageFeatures.ts | 86 ++++---- src/vs/workbench/api/common/extHostSCM.ts | 4 +- .../api/common/extHostTypeConverters.ts | 24 +-- .../api/node/extHostTerminalService.ts | 4 +- .../extHostDocumentSaveParticipant.test.ts | 12 +- .../api/extHostTextEditors.test.ts | 6 +- 14 files changed, 217 insertions(+), 217 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadEditors.ts b/src/vs/workbench/api/browser/mainThreadEditors.ts index 8601055aeeb..76334b577b1 100644 --- a/src/vs/workbench/api/browser/mainThreadEditors.ts +++ b/src/vs/workbench/api/browser/mainThreadEditors.ts @@ -20,7 +20,7 @@ import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation import { IOpenerService } from 'vs/platform/opener/common/opener'; import { MainThreadDocumentsAndEditors } from 'vs/workbench/api/browser/mainThreadDocumentsAndEditors'; import { MainThreadTextEditor } from 'vs/workbench/api/browser/mainThreadEditor'; -import { ExtHostContext, ExtHostEditorsShape, IApplyEditsOptions, IExtHostContext, ITextDocumentShowOptions, ITextEditorConfigurationUpdate, ITextEditorPositionData, IUndoStopOptions, MainThreadTextEditorsShape, TextEditorRevealType, WorkspaceEditDto, reviveWorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostContext, ExtHostEditorsShape, IApplyEditsOptions, IExtHostContext, ITextDocumentShowOptions, ITextEditorConfigurationUpdate, ITextEditorPositionData, IUndoStopOptions, MainThreadTextEditorsShape, TextEditorRevealType, IWorkspaceEditDto, reviveWorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol'; import { EditorViewColumn, editorGroupToViewColumn, viewColumnToEditorGroup } from 'vs/workbench/api/common/shared/editor'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; @@ -212,7 +212,7 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape { return Promise.resolve(editor.applyEdits(modelVersionId, edits, opts)); } - $tryApplyWorkspaceEdit(dto: WorkspaceEditDto): Promise { + $tryApplyWorkspaceEdit(dto: IWorkspaceEditDto): Promise { const { edits } = reviveWorkspaceEditDto(dto); return this._bulkEditService.apply({ edits }, undefined).then(() => true, err => false); } diff --git a/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts b/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts index 75af9eebf01..5cc6f7fa4c9 100644 --- a/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts +++ b/src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts @@ -11,7 +11,7 @@ import * as search from 'vs/workbench/contrib/search/common/search'; import { CancellationToken } from 'vs/base/common/cancellation'; import { Position as EditorPosition } from 'vs/editor/common/core/position'; import { Range as EditorRange, IRange } from 'vs/editor/common/core/range'; -import { ExtHostContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, MainContext, IExtHostContext, ISerializedLanguageConfiguration, ISerializedRegExp, ISerializedIndentationRule, ISerializedOnEnterRule, LocationDto, WorkspaceSymbolDto, reviveWorkspaceEditDto, ISerializedDocumentFilter, DefinitionLinkDto, ISerializedSignatureHelpProviderMetadata, LinkDto, CallHierarchyDto, SuggestDataDto, CodeActionDto } from '../common/extHost.protocol'; +import { ExtHostContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, MainContext, IExtHostContext, ILanguageConfigurationDto, IRegExpDto, IIndentationRuleDto, IOnEnterRuleDto, ILocationDto, IWorkspaceSymbolDto, reviveWorkspaceEditDto, IDocumentFilterDto, IDefinitionLinkDto, ISignatureHelpProviderMetadataDto, ILinkDto, ICallHierarchyDto, ISuggestDataDto, ICodeActionDto } from '../common/extHost.protocol'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; import { LanguageConfiguration, IndentationRule, OnEnterRule } from 'vs/editor/common/modes/languageConfiguration'; import { IModeService } from 'vs/editor/common/services/modeService'; @@ -54,9 +54,9 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha //#region --- revive functions - private static _reviveLocationDto(data: LocationDto): modes.Location; - private static _reviveLocationDto(data: LocationDto[]): modes.Location[]; - private static _reviveLocationDto(data: LocationDto | LocationDto[]): modes.Location | modes.Location[] { + private static _reviveLocationDto(data: ILocationDto): modes.Location; + private static _reviveLocationDto(data: ILocationDto[]): modes.Location[]; + private static _reviveLocationDto(data: ILocationDto | ILocationDto[]): modes.Location | modes.Location[] { if (!data) { return data; } else if (Array.isArray(data)) { @@ -68,9 +68,9 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha } } - private static _reviveLocationLinkDto(data: DefinitionLinkDto): modes.LocationLink; - private static _reviveLocationLinkDto(data: DefinitionLinkDto[]): modes.LocationLink[]; - private static _reviveLocationLinkDto(data: DefinitionLinkDto | DefinitionLinkDto[]): modes.LocationLink | modes.LocationLink[] { + private static _reviveLocationLinkDto(data: IDefinitionLinkDto): modes.LocationLink; + private static _reviveLocationLinkDto(data: IDefinitionLinkDto[]): modes.LocationLink[]; + private static _reviveLocationLinkDto(data: IDefinitionLinkDto | IDefinitionLinkDto[]): modes.LocationLink | modes.LocationLink[] { if (!data) { return data; } else if (Array.isArray(data)) { @@ -82,10 +82,10 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha } } - private static _reviveWorkspaceSymbolDto(data: WorkspaceSymbolDto): search.IWorkspaceSymbol; - private static _reviveWorkspaceSymbolDto(data: WorkspaceSymbolDto[]): search.IWorkspaceSymbol[]; + private static _reviveWorkspaceSymbolDto(data: IWorkspaceSymbolDto): search.IWorkspaceSymbol; + private static _reviveWorkspaceSymbolDto(data: IWorkspaceSymbolDto[]): search.IWorkspaceSymbol[]; private static _reviveWorkspaceSymbolDto(data: undefined): undefined; - private static _reviveWorkspaceSymbolDto(data: WorkspaceSymbolDto | WorkspaceSymbolDto[] | undefined): search.IWorkspaceSymbol | search.IWorkspaceSymbol[] | undefined { + private static _reviveWorkspaceSymbolDto(data: IWorkspaceSymbolDto | IWorkspaceSymbolDto[] | undefined): search.IWorkspaceSymbol | search.IWorkspaceSymbol[] | undefined { if (!data) { return data; } else if (Array.isArray(data)) { @@ -97,21 +97,21 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha } } - private static _reviveCodeActionDto(data: ReadonlyArray): modes.CodeAction[] { + private static _reviveCodeActionDto(data: ReadonlyArray): modes.CodeAction[] { if (data) { data.forEach(code => reviveWorkspaceEditDto(code.edit)); } return data; } - private static _reviveLinkDTO(data: LinkDto): modes.ILink { + private static _reviveLinkDTO(data: ILinkDto): modes.ILink { if (data.url && typeof data.url !== 'string') { data.url = URI.revive(data.url); } return data; } - private static _reviveCallHierarchyItemDto(data: CallHierarchyDto | undefined): callh.CallHierarchyItem { + private static _reviveCallHierarchyItemDto(data: ICallHierarchyDto | undefined): callh.CallHierarchyItem { if (data) { data.uri = URI.revive(data.uri); } @@ -122,7 +122,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha // --- outline - $registerDocumentSymbolProvider(handle: number, selector: ISerializedDocumentFilter[], displayName: string): void { + $registerDocumentSymbolProvider(handle: number, selector: IDocumentFilterDto[], displayName: string): void { this._registrations.set(handle, modes.DocumentSymbolProviderRegistry.register(selector, { displayName, provideDocumentSymbols: (model: ITextModel, token: CancellationToken): Promise => { @@ -133,7 +133,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha // --- code lens - $registerCodeLensSupport(handle: number, selector: ISerializedDocumentFilter[], eventHandle: number | undefined): void { + $registerCodeLensSupport(handle: number, selector: IDocumentFilterDto[], eventHandle: number | undefined): void { const provider = { provideCodeLenses: (model: ITextModel, token: CancellationToken): Promise => { @@ -170,7 +170,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha // --- declaration - $registerDefinitionSupport(handle: number, selector: ISerializedDocumentFilter[]): void { + $registerDefinitionSupport(handle: number, selector: IDocumentFilterDto[]): void { this._registrations.set(handle, modes.DefinitionProviderRegistry.register(selector, { provideDefinition: (model, position, token): Promise => { return this._proxy.$provideDefinition(handle, model.uri, position, token).then(MainThreadLanguageFeatures._reviveLocationLinkDto); @@ -178,7 +178,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha })); } - $registerDeclarationSupport(handle: number, selector: ISerializedDocumentFilter[]): void { + $registerDeclarationSupport(handle: number, selector: IDocumentFilterDto[]): void { this._registrations.set(handle, modes.DeclarationProviderRegistry.register(selector, { provideDeclaration: (model, position, token) => { return this._proxy.$provideDeclaration(handle, model.uri, position, token).then(MainThreadLanguageFeatures._reviveLocationLinkDto); @@ -186,7 +186,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha })); } - $registerImplementationSupport(handle: number, selector: ISerializedDocumentFilter[]): void { + $registerImplementationSupport(handle: number, selector: IDocumentFilterDto[]): void { this._registrations.set(handle, modes.ImplementationProviderRegistry.register(selector, { provideImplementation: (model, position, token): Promise => { return this._proxy.$provideImplementation(handle, model.uri, position, token).then(MainThreadLanguageFeatures._reviveLocationLinkDto); @@ -194,7 +194,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha })); } - $registerTypeDefinitionSupport(handle: number, selector: ISerializedDocumentFilter[]): void { + $registerTypeDefinitionSupport(handle: number, selector: IDocumentFilterDto[]): void { this._registrations.set(handle, modes.TypeDefinitionProviderRegistry.register(selector, { provideTypeDefinition: (model, position, token): Promise => { return this._proxy.$provideTypeDefinition(handle, model.uri, position, token).then(MainThreadLanguageFeatures._reviveLocationLinkDto); @@ -204,7 +204,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha // --- extra info - $registerHoverProvider(handle: number, selector: ISerializedDocumentFilter[]): void { + $registerHoverProvider(handle: number, selector: IDocumentFilterDto[]): void { this._registrations.set(handle, modes.HoverProviderRegistry.register(selector, { provideHover: (model: ITextModel, position: EditorPosition, token: CancellationToken): Promise => { return this._proxy.$provideHover(handle, model.uri, position, token); @@ -214,7 +214,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha // --- occurrences - $registerDocumentHighlightProvider(handle: number, selector: ISerializedDocumentFilter[]): void { + $registerDocumentHighlightProvider(handle: number, selector: IDocumentFilterDto[]): void { this._registrations.set(handle, modes.DocumentHighlightProviderRegistry.register(selector, { provideDocumentHighlights: (model: ITextModel, position: EditorPosition, token: CancellationToken): Promise => { return this._proxy.$provideDocumentHighlights(handle, model.uri, position, token); @@ -224,7 +224,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha // --- references - $registerReferenceSupport(handle: number, selector: ISerializedDocumentFilter[]): void { + $registerReferenceSupport(handle: number, selector: IDocumentFilterDto[]): void { this._registrations.set(handle, modes.ReferenceProviderRegistry.register(selector, { provideReferences: (model: ITextModel, position: EditorPosition, context: modes.ReferenceContext, token: CancellationToken): Promise => { return this._proxy.$provideReferences(handle, model.uri, position, context, token).then(MainThreadLanguageFeatures._reviveLocationDto); @@ -234,7 +234,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha // --- quick fix - $registerQuickFixSupport(handle: number, selector: ISerializedDocumentFilter[], providedCodeActionKinds?: string[]): void { + $registerQuickFixSupport(handle: number, selector: IDocumentFilterDto[], providedCodeActionKinds?: string[]): void { this._registrations.set(handle, modes.CodeActionProviderRegistry.register(selector, { provideCodeActions: async (model: ITextModel, rangeOrSelection: EditorRange | Selection, context: modes.CodeActionContext, token: CancellationToken): Promise => { const listDto = await this._proxy.$provideCodeActions(handle, model.uri, rangeOrSelection, context, token); @@ -256,7 +256,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha // --- formatting - $registerDocumentFormattingSupport(handle: number, selector: ISerializedDocumentFilter[], extensionId: ExtensionIdentifier, displayName: string): void { + $registerDocumentFormattingSupport(handle: number, selector: IDocumentFilterDto[], extensionId: ExtensionIdentifier, displayName: string): void { this._registrations.set(handle, modes.DocumentFormattingEditProviderRegistry.register(selector, { extensionId, displayName, @@ -266,7 +266,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha })); } - $registerRangeFormattingSupport(handle: number, selector: ISerializedDocumentFilter[], extensionId: ExtensionIdentifier, displayName: string): void { + $registerRangeFormattingSupport(handle: number, selector: IDocumentFilterDto[], extensionId: ExtensionIdentifier, displayName: string): void { this._registrations.set(handle, modes.DocumentRangeFormattingEditProviderRegistry.register(selector, { extensionId, displayName, @@ -276,7 +276,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha })); } - $registerOnTypeFormattingSupport(handle: number, selector: ISerializedDocumentFilter[], autoFormatTriggerCharacters: string[], extensionId: ExtensionIdentifier): void { + $registerOnTypeFormattingSupport(handle: number, selector: IDocumentFilterDto[], autoFormatTriggerCharacters: string[], extensionId: ExtensionIdentifier): void { this._registrations.set(handle, modes.OnTypeFormattingEditProviderRegistry.register(selector, { extensionId, autoFormatTriggerCharacters, @@ -313,7 +313,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha // --- rename - $registerRenameSupport(handle: number, selector: ISerializedDocumentFilter[], supportResolveLocation: boolean): void { + $registerRenameSupport(handle: number, selector: IDocumentFilterDto[], supportResolveLocation: boolean): void { this._registrations.set(handle, modes.RenameProviderRegistry.register(selector, { provideRenameEdits: (model: ITextModel, position: EditorPosition, newName: string, token: CancellationToken): Promise => { return this._proxy.$provideRenameEdits(handle, model.uri, position, newName, token).then(reviveWorkspaceEditDto); @@ -326,7 +326,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha // --- suggest - private static _inflateSuggestDto(defaultRange: IRange, data: SuggestDataDto): modes.CompletionItem { + private static _inflateSuggestDto(defaultRange: IRange, data: ISuggestDataDto): modes.CompletionItem { return { label: data.a, kind: data.b, @@ -346,7 +346,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha }; } - $registerSuggestSupport(handle: number, selector: ISerializedDocumentFilter[], triggerCharacters: string[], supportsResolveDetails: boolean, extensionId: ExtensionIdentifier): void { + $registerSuggestSupport(handle: number, selector: IDocumentFilterDto[], triggerCharacters: string[], supportsResolveDetails: boolean, extensionId: ExtensionIdentifier): void { const provider: modes.CompletionItemProvider = { triggerCharacters, _debugDisplayName: extensionId.value, @@ -379,7 +379,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha // --- parameter hints - $registerSignatureHelpProvider(handle: number, selector: ISerializedDocumentFilter[], metadata: ISerializedSignatureHelpProviderMetadata): void { + $registerSignatureHelpProvider(handle: number, selector: IDocumentFilterDto[], metadata: ISignatureHelpProviderMetadataDto): void { this._registrations.set(handle, modes.SignatureHelpProviderRegistry.register(selector, { signatureHelpTriggerCharacters: metadata.triggerCharacters, @@ -402,7 +402,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha // --- links - $registerDocumentLinkProvider(handle: number, selector: ISerializedDocumentFilter[], supportsResolve: boolean): void { + $registerDocumentLinkProvider(handle: number, selector: IDocumentFilterDto[], supportsResolve: boolean): void { const provider: modes.LinkProvider = { provideLinks: (model, token) => { return this._proxy.$provideDocumentLinks(handle, model.uri, token).then(dto => { @@ -422,7 +422,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha }; if (supportsResolve) { provider.resolveLink = (link, token) => { - const dto: LinkDto = link; + const dto: ILinkDto = link; if (!dto.cacheId) { return link; } @@ -436,7 +436,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha // --- colors - $registerDocumentColorProvider(handle: number, selector: ISerializedDocumentFilter[]): void { + $registerDocumentColorProvider(handle: number, selector: IDocumentFilterDto[]): void { const proxy = this._proxy; this._registrations.set(handle, modes.ColorProviderRegistry.register(selector, { provideDocumentColors: (model, token) => { @@ -470,7 +470,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha // --- folding - $registerFoldingRangeProvider(handle: number, selector: ISerializedDocumentFilter[]): void { + $registerFoldingRangeProvider(handle: number, selector: IDocumentFilterDto[]): void { const proxy = this._proxy; this._registrations.set(handle, modes.FoldingRangeProviderRegistry.register(selector, { provideFoldingRanges: (model, context, token) => { @@ -481,7 +481,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha // -- smart select - $registerSelectionRangeProvider(handle: number, selector: ISerializedDocumentFilter[]): void { + $registerSelectionRangeProvider(handle: number, selector: IDocumentFilterDto[]): void { this._registrations.set(handle, modes.SelectionRangeRegistry.register(selector, { provideSelectionRanges: (model, positions, token) => { return this._proxy.$provideSelectionRanges(handle, model.uri, positions, token); @@ -491,7 +491,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha // --- call hierarchy - $registerCallHierarchyProvider(handle: number, selector: ISerializedDocumentFilter[]): void { + $registerCallHierarchyProvider(handle: number, selector: IDocumentFilterDto[]): void { this._registrations.set(handle, callh.CallHierarchyProviderRegistry.register(selector, { provideCallHierarchyItem: (document, position, token) => { return this._proxy.$provideCallHierarchyItem(handle, document.uri, position, token).then(MainThreadLanguageFeatures._reviveCallHierarchyItemDto); @@ -515,11 +515,11 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha // --- configuration - private static _reviveRegExp(regExp: ISerializedRegExp): RegExp { + private static _reviveRegExp(regExp: IRegExpDto): RegExp { return new RegExp(regExp.pattern, regExp.flags); } - private static _reviveIndentationRule(indentationRule: ISerializedIndentationRule): IndentationRule { + private static _reviveIndentationRule(indentationRule: IIndentationRuleDto): IndentationRule { return { decreaseIndentPattern: MainThreadLanguageFeatures._reviveRegExp(indentationRule.decreaseIndentPattern), increaseIndentPattern: MainThreadLanguageFeatures._reviveRegExp(indentationRule.increaseIndentPattern), @@ -528,7 +528,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha }; } - private static _reviveOnEnterRule(onEnterRule: ISerializedOnEnterRule): OnEnterRule { + private static _reviveOnEnterRule(onEnterRule: IOnEnterRuleDto): OnEnterRule { return { beforeText: MainThreadLanguageFeatures._reviveRegExp(onEnterRule.beforeText), afterText: onEnterRule.afterText ? MainThreadLanguageFeatures._reviveRegExp(onEnterRule.afterText) : undefined, @@ -537,11 +537,11 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha }; } - private static _reviveOnEnterRules(onEnterRules: ISerializedOnEnterRule[]): OnEnterRule[] { + private static _reviveOnEnterRules(onEnterRules: IOnEnterRuleDto[]): OnEnterRule[] { return onEnterRules.map(MainThreadLanguageFeatures._reviveOnEnterRule); } - $setLanguageConfiguration(handle: number, languageId: string, _configuration: ISerializedLanguageConfiguration): void { + $setLanguageConfiguration(handle: number, languageId: string, _configuration: ILanguageConfigurationDto): void { const configuration: LanguageConfiguration = { comments: _configuration.comments, diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index f23b625d140..fcb1f70bfb6 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -5,7 +5,7 @@ import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalProcessExtHostProxy, ISpawnExtHostProcessRequest, ITerminalDimensions, EXT_HOST_CREATION_DELAY, IAvailableShellsRequest, IDefaultShellAndArgsRequest, IStartExtensionTerminalRequest } from 'vs/workbench/contrib/terminal/common/terminal'; -import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceShape, MainContext, IExtHostContext, ShellLaunchConfigDto, TerminalLaunchConfig, ITerminalDimensionsDto } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceShape, MainContext, IExtHostContext, IShellLaunchConfigDto, TerminalLaunchConfig, ITerminalDimensionsDto } from 'vs/workbench/api/common/extHost.protocol'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { URI } from 'vs/base/common/uri'; import { StopWatch } from 'vs/base/common/stopwatch'; @@ -254,7 +254,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape } else { this._terminalProcesses.set(proxy.terminalId, Promise.resolve(proxy)); } - const shellLaunchConfigDto: ShellLaunchConfigDto = { + const shellLaunchConfigDto: IShellLaunchConfigDto = { name: request.shellLaunchConfig.name, executable: request.shellLaunchConfig.executable, args: request.shellLaunchConfig.args, diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 29177f997ea..ea98e0fec0e 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -236,7 +236,7 @@ export interface MainThreadTextEditorsShape extends IDisposable { $tryRevealRange(id: string, range: IRange, revealType: TextEditorRevealType): Promise; $trySetSelections(id: string, selections: ISelection[]): Promise; $tryApplyEdits(id: string, modelVersionId: number, edits: ISingleEditOperation[], opts: IApplyEditsOptions): Promise; - $tryApplyWorkspaceEdit(workspaceEditDto: WorkspaceEditDto): Promise; + $tryApplyWorkspaceEdit(workspaceEditDto: IWorkspaceEditDto): Promise; $tryInsertSnippet(id: string, template: string, selections: readonly IRange[], opts: IUndoStopOptions): Promise; $getDiffInformation(id: string): Promise; } @@ -267,28 +267,28 @@ export interface MainThreadKeytarShape extends IDisposable { $findPassword(service: string): Promise; } -export interface ISerializedRegExp { +export interface IRegExpDto { pattern: string; flags?: string; } -export interface ISerializedIndentationRule { - decreaseIndentPattern: ISerializedRegExp; - increaseIndentPattern: ISerializedRegExp; - indentNextLinePattern?: ISerializedRegExp; - unIndentedLinePattern?: ISerializedRegExp; +export interface IIndentationRuleDto { + decreaseIndentPattern: IRegExpDto; + increaseIndentPattern: IRegExpDto; + indentNextLinePattern?: IRegExpDto; + unIndentedLinePattern?: IRegExpDto; } -export interface ISerializedOnEnterRule { - beforeText: ISerializedRegExp; - afterText?: ISerializedRegExp; - oneLineAboveText?: ISerializedRegExp; +export interface IOnEnterRuleDto { + beforeText: IRegExpDto; + afterText?: IRegExpDto; + oneLineAboveText?: IRegExpDto; action: EnterAction; } -export interface ISerializedLanguageConfiguration { +export interface ILanguageConfigurationDto { comments?: CommentRule; brackets?: CharacterPair[]; - wordPattern?: ISerializedRegExp; - indentationRules?: ISerializedIndentationRule; - onEnterRules?: ISerializedOnEnterRule[]; + wordPattern?: IRegExpDto; + indentationRules?: IIndentationRuleDto; + onEnterRules?: IOnEnterRuleDto[]; __electricCharacterSupport?: { brackets?: any; docComment?: { @@ -309,7 +309,7 @@ export interface ISerializedLanguageConfiguration { export type GlobPattern = string | { base: string; pattern: string }; -export interface ISerializedDocumentFilter { +export interface IDocumentFilterDto { $serialized: true; language?: string; scheme?: string; @@ -317,37 +317,37 @@ export interface ISerializedDocumentFilter { exclusive?: boolean; } -export interface ISerializedSignatureHelpProviderMetadata { +export interface ISignatureHelpProviderMetadataDto { readonly triggerCharacters: readonly string[]; readonly retriggerCharacters: readonly string[]; } export interface MainThreadLanguageFeaturesShape extends IDisposable { $unregister(handle: number): void; - $registerDocumentSymbolProvider(handle: number, selector: ISerializedDocumentFilter[], label: string): void; - $registerCodeLensSupport(handle: number, selector: ISerializedDocumentFilter[], eventHandle: number | undefined): void; + $registerDocumentSymbolProvider(handle: number, selector: IDocumentFilterDto[], label: string): void; + $registerCodeLensSupport(handle: number, selector: IDocumentFilterDto[], eventHandle: number | undefined): void; $emitCodeLensEvent(eventHandle: number, event?: any): void; - $registerDefinitionSupport(handle: number, selector: ISerializedDocumentFilter[]): void; - $registerDeclarationSupport(handle: number, selector: ISerializedDocumentFilter[]): void; - $registerImplementationSupport(handle: number, selector: ISerializedDocumentFilter[]): void; - $registerTypeDefinitionSupport(handle: number, selector: ISerializedDocumentFilter[]): void; - $registerHoverProvider(handle: number, selector: ISerializedDocumentFilter[]): void; - $registerDocumentHighlightProvider(handle: number, selector: ISerializedDocumentFilter[]): void; - $registerReferenceSupport(handle: number, selector: ISerializedDocumentFilter[]): void; - $registerQuickFixSupport(handle: number, selector: ISerializedDocumentFilter[], supportedKinds?: string[]): void; - $registerDocumentFormattingSupport(handle: number, selector: ISerializedDocumentFilter[], extensionId: ExtensionIdentifier, displayName: string): void; - $registerRangeFormattingSupport(handle: number, selector: ISerializedDocumentFilter[], extensionId: ExtensionIdentifier, displayName: string): void; - $registerOnTypeFormattingSupport(handle: number, selector: ISerializedDocumentFilter[], autoFormatTriggerCharacters: string[], extensionId: ExtensionIdentifier): void; + $registerDefinitionSupport(handle: number, selector: IDocumentFilterDto[]): void; + $registerDeclarationSupport(handle: number, selector: IDocumentFilterDto[]): void; + $registerImplementationSupport(handle: number, selector: IDocumentFilterDto[]): void; + $registerTypeDefinitionSupport(handle: number, selector: IDocumentFilterDto[]): void; + $registerHoverProvider(handle: number, selector: IDocumentFilterDto[]): void; + $registerDocumentHighlightProvider(handle: number, selector: IDocumentFilterDto[]): void; + $registerReferenceSupport(handle: number, selector: IDocumentFilterDto[]): void; + $registerQuickFixSupport(handle: number, selector: IDocumentFilterDto[], supportedKinds?: string[]): void; + $registerDocumentFormattingSupport(handle: number, selector: IDocumentFilterDto[], extensionId: ExtensionIdentifier, displayName: string): void; + $registerRangeFormattingSupport(handle: number, selector: IDocumentFilterDto[], extensionId: ExtensionIdentifier, displayName: string): void; + $registerOnTypeFormattingSupport(handle: number, selector: IDocumentFilterDto[], autoFormatTriggerCharacters: string[], extensionId: ExtensionIdentifier): void; $registerNavigateTypeSupport(handle: number): void; - $registerRenameSupport(handle: number, selector: ISerializedDocumentFilter[], supportsResolveInitialValues: boolean): void; - $registerSuggestSupport(handle: number, selector: ISerializedDocumentFilter[], triggerCharacters: string[], supportsResolveDetails: boolean, extensionId: ExtensionIdentifier): void; - $registerSignatureHelpProvider(handle: number, selector: ISerializedDocumentFilter[], metadata: ISerializedSignatureHelpProviderMetadata): void; - $registerDocumentLinkProvider(handle: number, selector: ISerializedDocumentFilter[], supportsResolve: boolean): void; - $registerDocumentColorProvider(handle: number, selector: ISerializedDocumentFilter[]): void; - $registerFoldingRangeProvider(handle: number, selector: ISerializedDocumentFilter[]): void; - $registerSelectionRangeProvider(handle: number, selector: ISerializedDocumentFilter[]): void; - $registerCallHierarchyProvider(handle: number, selector: ISerializedDocumentFilter[]): void; - $setLanguageConfiguration(handle: number, languageId: string, configuration: ISerializedLanguageConfiguration): void; + $registerRenameSupport(handle: number, selector: IDocumentFilterDto[], supportsResolveInitialValues: boolean): void; + $registerSuggestSupport(handle: number, selector: IDocumentFilterDto[], triggerCharacters: string[], supportsResolveDetails: boolean, extensionId: ExtensionIdentifier): void; + $registerSignatureHelpProvider(handle: number, selector: IDocumentFilterDto[], metadata: ISignatureHelpProviderMetadataDto): void; + $registerDocumentLinkProvider(handle: number, selector: IDocumentFilterDto[], supportsResolve: boolean): void; + $registerDocumentColorProvider(handle: number, selector: IDocumentFilterDto[]): void; + $registerFoldingRangeProvider(handle: number, selector: IDocumentFilterDto[]): void; + $registerSelectionRangeProvider(handle: number, selector: IDocumentFilterDto[]): void; + $registerCallHierarchyProvider(handle: number, selector: IDocumentFilterDto[]): void; + $setLanguageConfiguration(handle: number, languageId: string, configuration: ILanguageConfigurationDto): void; } export interface MainThreadLanguagesShape extends IDisposable { @@ -649,7 +649,7 @@ export interface SCMProviderFeatures { count?: number; commitTemplate?: string; acceptInputCommand?: modes.Command; - statusBarCommands?: CommandDto[]; + statusBarCommands?: ICommandDto[]; } export interface SCMGroupFeatures { @@ -928,7 +928,7 @@ export class IdObject { } } -export interface SuggestDataDto { +export interface ISuggestDataDto { a/* label */: string; b/* kind */: modes.CompletionItemKind; c/* detail */?: string; @@ -946,51 +946,51 @@ export interface SuggestDataDto { x?: ChainedCacheId; } -export interface SuggestResultDto { +export interface ISuggestResultDto { x?: number; a: IRange; - b: SuggestDataDto[]; + b: ISuggestDataDto[]; c?: boolean; } -export interface SignatureHelpDto { +export interface ISignatureHelpDto { id: CacheId; signatures: modes.SignatureInformation[]; activeSignature: number; activeParameter: number; } -export interface SignatureHelpContextDto { +export interface ISignatureHelpContextDto { readonly triggerKind: modes.SignatureHelpTriggerKind; readonly triggerCharacter?: string; readonly isRetrigger: boolean; - readonly activeSignatureHelp?: SignatureHelpDto; + readonly activeSignatureHelp?: ISignatureHelpDto; } -export interface LocationDto { +export interface ILocationDto { uri: UriComponents; range: IRange; } -export interface DefinitionLinkDto { +export interface IDefinitionLinkDto { originSelectionRange?: IRange; uri: UriComponents; range: IRange; targetSelectionRange?: IRange; } -export interface WorkspaceSymbolDto extends IdObject { +export interface IWorkspaceSymbolDto extends IdObject { name: string; containerName?: string; kind: modes.SymbolKind; - location: LocationDto; + location: ILocationDto; } -export interface WorkspaceSymbolsDto extends IdObject { - symbols: WorkspaceSymbolDto[]; +export interface IWorkspaceSymbolsDto extends IdObject { + symbols: IWorkspaceSymbolDto[]; } -export interface ResourceFileEditDto { +export interface IResourceFileEditDto { oldUri?: UriComponents; newUri?: UriComponents; options?: { @@ -1001,76 +1001,76 @@ export interface ResourceFileEditDto { }; } -export interface ResourceTextEditDto { +export interface IResourceTextEditDto { resource: UriComponents; modelVersionId?: number; edits: modes.TextEdit[]; } -export interface WorkspaceEditDto { - edits: Array; +export interface IWorkspaceEditDto { + edits: Array; // todo@joh reject should go into rename rejectReason?: string; } -export function reviveWorkspaceEditDto(data: WorkspaceEditDto | undefined): modes.WorkspaceEdit { +export function reviveWorkspaceEditDto(data: IWorkspaceEditDto | undefined): modes.WorkspaceEdit { if (data && data.edits) { for (const edit of data.edits) { - if (typeof (edit).resource === 'object') { - (edit).resource = URI.revive((edit).resource); + if (typeof (edit).resource === 'object') { + (edit).resource = URI.revive((edit).resource); } else { - (edit).newUri = URI.revive((edit).newUri); - (edit).oldUri = URI.revive((edit).oldUri); + (edit).newUri = URI.revive((edit).newUri); + (edit).oldUri = URI.revive((edit).oldUri); } } } return data; } -export type CommandDto = ObjectIdentifier & modes.Command; +export type ICommandDto = ObjectIdentifier & modes.Command; -export interface CodeActionDto { +export interface ICodeActionDto { title: string; - edit?: WorkspaceEditDto; + edit?: IWorkspaceEditDto; diagnostics?: IMarkerData[]; - command?: CommandDto; + command?: ICommandDto; kind?: string; isPreferred?: boolean; } -export interface CodeActionListDto { +export interface ICodeActionListDto { cacheId: number; - actions: ReadonlyArray; + actions: ReadonlyArray; } export type CacheId = number; export type ChainedCacheId = [CacheId, CacheId]; -export interface LinksListDto { +export interface ILinksListDto { id?: CacheId; - links: LinkDto[]; + links: ILinkDto[]; } -export interface LinkDto { +export interface ILinkDto { cacheId?: ChainedCacheId; range: IRange; url?: string | UriComponents; tooltip?: string; } -export interface CodeLensListDto { +export interface ICodeLensListDto { cacheId?: number; - lenses: CodeLensDto[]; + lenses: ICodeLensDto[]; } -export interface CodeLensDto { +export interface ICodeLensDto { cacheId?: ChainedCacheId; range: IRange; - command?: CommandDto; + command?: ICommandDto; } -export interface CallHierarchyDto { +export interface ICallHierarchyDto { _id: number; kind: modes.SymbolKind; name: string; @@ -1082,40 +1082,40 @@ export interface CallHierarchyDto { export interface ExtHostLanguageFeaturesShape { $provideDocumentSymbols(handle: number, resource: UriComponents, token: CancellationToken): Promise; - $provideCodeLenses(handle: number, resource: UriComponents, token: CancellationToken): Promise; - $resolveCodeLens(handle: number, symbol: CodeLensDto, token: CancellationToken): Promise; + $provideCodeLenses(handle: number, resource: UriComponents, token: CancellationToken): Promise; + $resolveCodeLens(handle: number, symbol: ICodeLensDto, token: CancellationToken): Promise; $releaseCodeLenses(handle: number, id: number): void; - $provideDefinition(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; - $provideDeclaration(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; - $provideImplementation(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; - $provideTypeDefinition(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; + $provideDefinition(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; + $provideDeclaration(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; + $provideImplementation(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; + $provideTypeDefinition(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; $provideHover(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; $provideDocumentHighlights(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; - $provideReferences(handle: number, resource: UriComponents, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise; - $provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise; + $provideReferences(handle: number, resource: UriComponents, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise; + $provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise; $releaseCodeActions(handle: number, cacheId: number): void; $provideDocumentFormattingEdits(handle: number, resource: UriComponents, options: modes.FormattingOptions, token: CancellationToken): Promise; $provideDocumentRangeFormattingEdits(handle: number, resource: UriComponents, range: IRange, options: modes.FormattingOptions, token: CancellationToken): Promise; $provideOnTypeFormattingEdits(handle: number, resource: UriComponents, position: IPosition, ch: string, options: modes.FormattingOptions, token: CancellationToken): Promise; - $provideWorkspaceSymbols(handle: number, search: string, token: CancellationToken): Promise; - $resolveWorkspaceSymbol(handle: number, symbol: WorkspaceSymbolDto, token: CancellationToken): Promise; + $provideWorkspaceSymbols(handle: number, search: string, token: CancellationToken): Promise; + $resolveWorkspaceSymbol(handle: number, symbol: IWorkspaceSymbolDto, token: CancellationToken): Promise; $releaseWorkspaceSymbols(handle: number, id: number): void; - $provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string, token: CancellationToken): Promise; + $provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string, token: CancellationToken): Promise; $resolveRenameLocation(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; - $provideCompletionItems(handle: number, resource: UriComponents, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise; - $resolveCompletionItem(handle: number, resource: UriComponents, position: IPosition, id: ChainedCacheId, token: CancellationToken): Promise; + $provideCompletionItems(handle: number, resource: UriComponents, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise; + $resolveCompletionItem(handle: number, resource: UriComponents, position: IPosition, id: ChainedCacheId, token: CancellationToken): Promise; $releaseCompletionItems(handle: number, id: number): void; - $provideSignatureHelp(handle: number, resource: UriComponents, position: IPosition, context: modes.SignatureHelpContext, token: CancellationToken): Promise; + $provideSignatureHelp(handle: number, resource: UriComponents, position: IPosition, context: modes.SignatureHelpContext, token: CancellationToken): Promise; $releaseSignatureHelp(handle: number, id: number): void; - $provideDocumentLinks(handle: number, resource: UriComponents, token: CancellationToken): Promise; - $resolveDocumentLink(handle: number, id: ChainedCacheId, token: CancellationToken): Promise; + $provideDocumentLinks(handle: number, resource: UriComponents, token: CancellationToken): Promise; + $resolveDocumentLink(handle: number, id: ChainedCacheId, token: CancellationToken): Promise; $releaseDocumentLinks(handle: number, id: number): void; $provideDocumentColors(handle: number, resource: UriComponents, token: CancellationToken): Promise; $provideColorPresentations(handle: number, resource: UriComponents, colorInfo: IRawColorInfo, token: CancellationToken): Promise; $provideFoldingRanges(handle: number, resource: UriComponents, context: modes.FoldingContext, token: CancellationToken): Promise; $provideSelectionRanges(handle: number, resource: UriComponents, positions: IPosition[], token: CancellationToken): Promise; - $provideCallHierarchyItem(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; - $resolveCallHierarchyItem(handle: number, item: callHierarchy.CallHierarchyItem, direction: callHierarchy.CallHierarchyDirection, token: CancellationToken): Promise<[CallHierarchyDto, modes.Location[]][]>; + $provideCallHierarchyItem(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; + $resolveCallHierarchyItem(handle: number, item: callHierarchy.CallHierarchyItem, direction: callHierarchy.CallHierarchyDirection, token: CancellationToken): Promise<[ICallHierarchyDto, modes.Location[]][]>; } export interface ExtHostQuickOpenShape { @@ -1129,7 +1129,7 @@ export interface ExtHostQuickOpenShape { $onDidHide(sessionId: number): void; } -export interface ShellLaunchConfigDto { +export interface IShellLaunchConfigDto { name?: string; executable?: string; args?: string[] | string; @@ -1162,7 +1162,7 @@ export interface ExtHostTerminalServiceShape { $acceptTerminalTitleChange(id: number, name: string): void; $acceptTerminalDimensions(id: number, cols: number, rows: number): void; $acceptTerminalMaximumDimensions(id: number, cols: number, rows: number): void; - $spawnExtHostProcess(id: number, shellLaunchConfig: ShellLaunchConfigDto, activeWorkspaceRootUri: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void; + $spawnExtHostProcess(id: number, shellLaunchConfig: IShellLaunchConfigDto, activeWorkspaceRootUri: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void; $startExtensionTerminal(id: number, initialDimensions: ITerminalDimensionsDto | undefined): void; $acceptProcessInput(id: number, data: string): void; $acceptProcessResize(id: number, cols: number, rows: number): void; diff --git a/src/vs/workbench/api/common/extHostApiCommands.ts b/src/vs/workbench/api/common/extHostApiCommands.ts index bafedf31454..ff2a106f427 100644 --- a/src/vs/workbench/api/common/extHostApiCommands.ts +++ b/src/vs/workbench/api/common/extHostApiCommands.ts @@ -8,7 +8,7 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import * as vscode from 'vscode'; import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters'; import * as types from 'vs/workbench/api/common/extHostTypes'; -import { IRawColorInfo, WorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol'; +import { IRawColorInfo, IWorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol'; import { ISingleEditOperation } from 'vs/editor/common/model'; import * as modes from 'vs/editor/common/modes'; import * as search from 'vs/workbench/contrib/search/common/search'; @@ -362,7 +362,7 @@ export class ExtHostApiCommands { position: position && typeConverters.Position.from(position), newName }; - return this._commands.executeCommand('_executeDocumentRenameProvider', args).then(value => { + return this._commands.executeCommand('_executeDocumentRenameProvider', args).then(value => { if (!value) { return undefined; } diff --git a/src/vs/workbench/api/common/extHostCommands.ts b/src/vs/workbench/api/common/extHostCommands.ts index 2f429539b4c..6576c56192b 100644 --- a/src/vs/workbench/api/common/extHostCommands.ts +++ b/src/vs/workbench/api/common/extHostCommands.ts @@ -8,7 +8,7 @@ import { ICommandHandlerDescription, ICommandEvent } from 'vs/platform/commands/ import * as extHostTypes from 'vs/workbench/api/common/extHostTypes'; import * as extHostTypeConverter from 'vs/workbench/api/common/extHostTypeConverters'; import { cloneAndChange } from 'vs/base/common/objects'; -import { MainContext, MainThreadCommandsShape, ExtHostCommandsShape, ObjectIdentifier, IMainContext, CommandDto } from './extHost.protocol'; +import { MainContext, MainThreadCommandsShape, ExtHostCommandsShape, ObjectIdentifier, IMainContext, ICommandDto } from './extHost.protocol'; import { isNonEmptyArray } from 'vs/base/common/arrays'; import * as modes from 'vs/editor/common/modes'; import * as vscode from 'vscode'; @@ -228,13 +228,13 @@ export class CommandsConverter { this._commands.registerCommand(true, this._delegatingCommandId, this._executeConvertedCommand, this); } - toInternal(command: vscode.Command | undefined, disposables: DisposableStore): CommandDto | undefined { + toInternal(command: vscode.Command | undefined, disposables: DisposableStore): ICommandDto | undefined { if (!command) { return undefined; } - const result: CommandDto = { + const result: ICommandDto = { $ident: undefined, id: command.command, title: command.title, diff --git a/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts b/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts index 13dd34a001b..ae129051fe8 100644 --- a/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts +++ b/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts @@ -7,7 +7,7 @@ import { Event } from 'vs/base/common/event'; import { URI, UriComponents } from 'vs/base/common/uri'; import { sequence } from 'vs/base/common/async'; import { illegalState } from 'vs/base/common/errors'; -import { ExtHostDocumentSaveParticipantShape, MainThreadTextEditorsShape, ResourceTextEditDto } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostDocumentSaveParticipantShape, MainThreadTextEditorsShape, IResourceTextEditDto } from 'vs/workbench/api/common/extHost.protocol'; import { TextEdit } from 'vs/workbench/api/common/extHostTypes'; import { Range, TextDocumentSaveReason, EndOfLine } from 'vs/workbench/api/common/extHostTypeConverters'; import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments'; @@ -142,7 +142,7 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic }).then(values => { - const resourceEdit: ResourceTextEditDto = { + const resourceEdit: IResourceTextEditDto = { resource: document.uri, edits: [] }; diff --git a/src/vs/workbench/api/common/extHostFileSystemEventService.ts b/src/vs/workbench/api/common/extHostFileSystemEventService.ts index 85f48eff6a9..5ed5945f2f5 100644 --- a/src/vs/workbench/api/common/extHostFileSystemEventService.ts +++ b/src/vs/workbench/api/common/extHostFileSystemEventService.ts @@ -9,7 +9,7 @@ import { IRelativePattern, parse } from 'vs/base/common/glob'; import { URI, UriComponents } from 'vs/base/common/uri'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import * as vscode from 'vscode'; -import { ExtHostFileSystemEventServiceShape, FileSystemEvents, IMainContext, MainContext, ResourceFileEditDto, ResourceTextEditDto, MainThreadTextEditorsShape } from './extHost.protocol'; +import { ExtHostFileSystemEventServiceShape, FileSystemEvents, IMainContext, MainContext, IResourceFileEditDto, IResourceTextEditDto, MainThreadTextEditorsShape } from './extHost.protocol'; import * as typeConverter from './extHostTypeConverters'; import { Disposable, WorkspaceEdit } from './extHostTypes'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; @@ -169,7 +169,7 @@ export class ExtHostFileSystemEventService implements ExtHostFileSystemEventServ } // flatten all WorkspaceEdits collected via waitUntil-call // and apply them in one go. - const allEdits = new Array>(); + const allEdits = new Array>(); for (let edit of edits) { if (edit) { // sparse array let { edits } = typeConverter.WorkspaceEdit.from(edit, this._extHostDocumentsAndEditors); diff --git a/src/vs/workbench/api/common/extHostLanguageFeatures.ts b/src/vs/workbench/api/common/extHostLanguageFeatures.ts index 884618cc457..55c0234ee56 100644 --- a/src/vs/workbench/api/common/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/common/extHostLanguageFeatures.ts @@ -14,7 +14,7 @@ import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments'; import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/common/extHostCommands'; import { ExtHostDiagnostics } from 'vs/workbench/api/common/extHostDiagnostics'; import { asPromise } from 'vs/base/common/async'; -import { MainContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, IRawColorInfo, IMainContext, IdObject, ISerializedRegExp, ISerializedIndentationRule, ISerializedOnEnterRule, ISerializedLanguageConfiguration, WorkspaceSymbolDto, SuggestResultDto, WorkspaceSymbolsDto, CodeActionDto, ISerializedDocumentFilter, WorkspaceEditDto, ISerializedSignatureHelpProviderMetadata, LinkDto, CodeLensDto, SuggestDataDto, LinksListDto, ChainedCacheId, CodeLensListDto, CodeActionListDto, SignatureHelpDto, SignatureHelpContextDto } from './extHost.protocol'; +import { MainContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, IRawColorInfo, IMainContext, IdObject, IRegExpDto, IIndentationRuleDto, IOnEnterRuleDto, ILanguageConfigurationDto, IWorkspaceSymbolDto, ISuggestResultDto, IWorkspaceSymbolsDto, ICodeActionDto, IDocumentFilterDto, IWorkspaceEditDto, ISignatureHelpProviderMetadataDto, ILinkDto, ICodeLensDto, ISuggestDataDto, ILinksListDto, ChainedCacheId, ICodeLensListDto, ICodeActionListDto, ISignatureHelpDto, ISignatureHelpContextDto } from './extHost.protocol'; import { regExpLeadsToEndlessLoop, regExpFlags } from 'vs/base/common/strings'; import { IPosition } from 'vs/editor/common/core/position'; import { IRange, Range as EditorRange } from 'vs/editor/common/core/range'; @@ -111,7 +111,7 @@ class CodeLensAdapter { private readonly _provider: vscode.CodeLensProvider ) { } - provideCodeLenses(resource: URI, token: CancellationToken): Promise { + provideCodeLenses(resource: URI, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); return asPromise(() => this._provider.provideCodeLenses(doc, token)).then(lenses => { @@ -124,7 +124,7 @@ class CodeLensAdapter { const disposables = new DisposableStore(); this._disposables.set(cacheId, disposables); - const result: CodeLensListDto = { + const result: ICodeLensListDto = { cacheId, lenses: [], }; @@ -141,7 +141,7 @@ class CodeLensAdapter { }); } - resolveCodeLens(symbol: CodeLensDto, token: CancellationToken): Promise { + resolveCodeLens(symbol: ICodeLensDto, token: CancellationToken): Promise { const lens = symbol.cacheId && this._cache.get(...symbol.cacheId); if (!lens) { @@ -308,7 +308,7 @@ class ReferenceAdapter { } } -export interface CustomCodeAction extends CodeActionDto { +export interface CustomCodeAction extends ICodeActionDto { _isSynthetic?: boolean; } @@ -327,7 +327,7 @@ class CodeActionAdapter { private readonly _extensionId: ExtensionIdentifier ) { } - provideCodeActions(resource: URI, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise { + provideCodeActions(resource: URI, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); const ran = Selection.isISelection(rangeOrSelection) @@ -391,7 +391,7 @@ class CodeActionAdapter { } } - return { cacheId, actions }; + return { cacheId, actions }; }); } @@ -480,8 +480,8 @@ class NavigateTypeAdapter { this._provider = provider; } - provideWorkspaceSymbols(search: string, token: CancellationToken): Promise { - const result: WorkspaceSymbolsDto = IdObject.mixin({ symbols: [] }); + provideWorkspaceSymbols(search: string, token: CancellationToken): Promise { + const result: IWorkspaceSymbolsDto = IdObject.mixin({ symbols: [] }); return asPromise(() => this._provider.provideWorkspaceSymbols(search, token)).then(value => { if (isNonEmptyArray(value)) { for (const item of value) { @@ -506,7 +506,7 @@ class NavigateTypeAdapter { }); } - resolveWorkspaceSymbol(symbol: WorkspaceSymbolDto, token: CancellationToken): Promise { + resolveWorkspaceSymbol(symbol: IWorkspaceSymbolDto, token: CancellationToken): Promise { if (typeof this._provider.resolveWorkspaceSymbol !== 'function') { return Promise.resolve(symbol); @@ -543,7 +543,7 @@ class RenameAdapter { private readonly _provider: vscode.RenameProvider ) { } - provideRenameEdits(resource: URI, position: IPosition, newName: string, token: CancellationToken): Promise { + provideRenameEdits(resource: URI, position: IPosition, newName: string, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); const pos = typeConvert.Position.to(position); @@ -556,10 +556,10 @@ class RenameAdapter { }, err => { const rejectReason = RenameAdapter._asMessage(err); if (rejectReason) { - return { rejectReason, edits: undefined! }; + return { rejectReason, edits: undefined! }; } else { // generic error - return Promise.reject(err); + return Promise.reject(err); } }); } @@ -633,7 +633,7 @@ class SuggestAdapter { this._provider = provider; } - provideCompletionItems(resource: URI, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise { + provideCompletionItems(resource: URI, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); const pos = typeConvert.Position.to(position); @@ -662,7 +662,7 @@ class SuggestAdapter { const wordRangeBeforePos = (doc.getWordRangeAtPosition(pos) as Range || new Range(pos, pos)) .with({ end: pos }); - const result: SuggestResultDto = { + const result: ISuggestResultDto = { x: pid, b: [], a: typeConvert.Range.from(wordRangeBeforePos), @@ -682,7 +682,7 @@ class SuggestAdapter { }); } - resolveCompletionItem(_resource: URI, position: IPosition, id: ChainedCacheId, token: CancellationToken): Promise { + resolveCompletionItem(_resource: URI, position: IPosition, id: ChainedCacheId, token: CancellationToken): Promise { if (typeof this._provider.resolveCompletionItem !== 'function') { return Promise.resolve(undefined); @@ -710,7 +710,7 @@ class SuggestAdapter { this._cache.delete(id); } - private _convertCompletionItem(item: vscode.CompletionItem, position: vscode.Position, id: ChainedCacheId): SuggestDataDto | undefined { + private _convertCompletionItem(item: vscode.CompletionItem, position: vscode.Position, id: ChainedCacheId): ISuggestDataDto | undefined { if (typeof item.label !== 'string' || item.label.length === 0) { console.warn('INVALID text edit -> must have at least a label'); return undefined; @@ -721,7 +721,7 @@ class SuggestAdapter { throw Error('DisposableStore is missing...'); } - const result: SuggestDataDto = { + const result: ISuggestDataDto = { // x: id, // @@ -777,7 +777,7 @@ class SignatureHelpAdapter { private readonly _provider: vscode.SignatureHelpProvider, ) { } - provideSignatureHelp(resource: URI, position: IPosition, context: SignatureHelpContextDto, token: CancellationToken): Promise { + provideSignatureHelp(resource: URI, position: IPosition, context: ISignatureHelpContextDto, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); const pos = typeConvert.Position.to(position); const vscodeContext = this.reviveContext(context); @@ -791,7 +791,7 @@ class SignatureHelpAdapter { }); } - private reviveContext(context: SignatureHelpContextDto): vscode.SignatureHelpContext { + private reviveContext(context: ISignatureHelpContextDto): vscode.SignatureHelpContext { let activeSignatureHelp: vscode.SignatureHelp | undefined = undefined; if (context.activeSignatureHelp) { const revivedSignatureHelp = typeConvert.SignatureHelp.to(context.activeSignatureHelp); @@ -855,7 +855,7 @@ class LinkProviderAdapter { private readonly _provider: vscode.DocumentLinkProvider ) { } - provideLinks(resource: URI, token: CancellationToken): Promise { + provideLinks(resource: URI, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); return asPromise(() => this._provider.provideDocumentLinks(doc, token)).then(links => { @@ -877,9 +877,9 @@ class LinkProviderAdapter { } else { // cache links for future resolving const pid = this._cache.add(links); - const result: LinksListDto = { links: [], id: pid }; + const result: ILinksListDto = { links: [], id: pid }; for (let i = 0; i < links.length; i++) { - const dto: LinkDto = typeConvert.DocumentLink.from(links[i]); + const dto: ILinkDto = typeConvert.DocumentLink.from(links[i]); dto.cacheId = [pid, i]; result.links.push(dto); } @@ -888,7 +888,7 @@ class LinkProviderAdapter { }); } - resolveLink(id: ChainedCacheId, token: CancellationToken): Promise { + resolveLink(id: ChainedCacheId, token: CancellationToken): Promise { if (typeof this._provider.resolveDocumentLink !== 'function') { return Promise.resolve(undefined); } @@ -1103,11 +1103,11 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { this._logService = logService; } - private _transformDocumentSelector(selector: vscode.DocumentSelector): Array { + private _transformDocumentSelector(selector: vscode.DocumentSelector): Array { return coalesce(asArray(selector).map(sel => this._doTransformDocumentSelector(sel))); } - private _doTransformDocumentSelector(selector: string | vscode.DocumentFilter): ISerializedDocumentFilter | undefined { + private _doTransformDocumentSelector(selector: string | vscode.DocumentFilter): IDocumentFilterDto | undefined { if (typeof selector === 'string') { return { $serialized: true, @@ -1215,11 +1215,11 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return result; } - $provideCodeLenses(handle: number, resource: UriComponents, token: CancellationToken): Promise { + $provideCodeLenses(handle: number, resource: UriComponents, token: CancellationToken): Promise { return this._withAdapter(handle, CodeLensAdapter, adapter => adapter.provideCodeLenses(URI.revive(resource), token), undefined); } - $resolveCodeLens(handle: number, symbol: CodeLensDto, token: CancellationToken): Promise { + $resolveCodeLens(handle: number, symbol: ICodeLensDto, token: CancellationToken): Promise { return this._withAdapter(handle, CodeLensAdapter, adapter => adapter.resolveCodeLens(symbol, token), undefined); } @@ -1314,7 +1314,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { } - $provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise { + $provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise { return this._withAdapter(handle, CodeActionAdapter, adapter => adapter.provideCodeActions(URI.revive(resource), rangeOrSelection, context, token), undefined); } @@ -1362,11 +1362,11 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return this._createDisposable(handle); } - $provideWorkspaceSymbols(handle: number, search: string, token: CancellationToken): Promise { + $provideWorkspaceSymbols(handle: number, search: string, token: CancellationToken): Promise { return this._withAdapter(handle, NavigateTypeAdapter, adapter => adapter.provideWorkspaceSymbols(search, token), { symbols: [] }); } - $resolveWorkspaceSymbol(handle: number, symbol: WorkspaceSymbolDto, token: CancellationToken): Promise { + $resolveWorkspaceSymbol(handle: number, symbol: IWorkspaceSymbolDto, token: CancellationToken): Promise { return this._withAdapter(handle, NavigateTypeAdapter, adapter => adapter.resolveWorkspaceSymbol(symbol, token), undefined); } @@ -1382,7 +1382,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return this._createDisposable(handle); } - $provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string, token: CancellationToken): Promise { + $provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string, token: CancellationToken): Promise { return this._withAdapter(handle, RenameAdapter, adapter => adapter.provideRenameEdits(URI.revive(resource), position, newName, token), undefined); } @@ -1398,11 +1398,11 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return this._createDisposable(handle); } - $provideCompletionItems(handle: number, resource: UriComponents, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise { + $provideCompletionItems(handle: number, resource: UriComponents, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise { return this._withAdapter(handle, SuggestAdapter, adapter => adapter.provideCompletionItems(URI.revive(resource), position, context, token), undefined); } - $resolveCompletionItem(handle: number, resource: UriComponents, position: IPosition, id: ChainedCacheId, token: CancellationToken): Promise { + $resolveCompletionItem(handle: number, resource: UriComponents, position: IPosition, id: ChainedCacheId, token: CancellationToken): Promise { return this._withAdapter(handle, SuggestAdapter, adapter => adapter.resolveCompletionItem(URI.revive(resource), position, id, token), undefined); } @@ -1413,7 +1413,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { // --- parameter hints registerSignatureHelpProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.SignatureHelpProvider, metadataOrTriggerChars: string[] | vscode.SignatureHelpProviderMetadata): vscode.Disposable { - const metadata: ISerializedSignatureHelpProviderMetadata | undefined = Array.isArray(metadataOrTriggerChars) + const metadata: ISignatureHelpProviderMetadataDto | undefined = Array.isArray(metadataOrTriggerChars) ? { triggerCharacters: metadataOrTriggerChars, retriggerCharacters: [] } : metadataOrTriggerChars; @@ -1422,7 +1422,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return this._createDisposable(handle); } - $provideSignatureHelp(handle: number, resource: UriComponents, position: IPosition, context: SignatureHelpContextDto, token: CancellationToken): Promise { + $provideSignatureHelp(handle: number, resource: UriComponents, position: IPosition, context: ISignatureHelpContextDto, token: CancellationToken): Promise { return this._withAdapter(handle, SignatureHelpAdapter, adapter => adapter.provideSignatureHelp(URI.revive(resource), position, context, token), undefined); } @@ -1438,11 +1438,11 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return this._createDisposable(handle); } - $provideDocumentLinks(handle: number, resource: UriComponents, token: CancellationToken): Promise { + $provideDocumentLinks(handle: number, resource: UriComponents, token: CancellationToken): Promise { return this._withAdapter(handle, LinkProviderAdapter, adapter => adapter.provideLinks(URI.revive(resource), token), undefined); } - $resolveDocumentLink(handle: number, id: ChainedCacheId, token: CancellationToken): Promise { + $resolveDocumentLink(handle: number, id: ChainedCacheId, token: CancellationToken): Promise { return this._withAdapter(handle, LinkProviderAdapter, adapter => adapter.resolveLink(id, token), undefined); } @@ -1504,14 +1504,14 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { // --- configuration - private static _serializeRegExp(regExp: RegExp): ISerializedRegExp { + private static _serializeRegExp(regExp: RegExp): IRegExpDto { return { pattern: regExp.source, flags: regExpFlags(regExp), }; } - private static _serializeIndentationRule(indentationRule: vscode.IndentationRule): ISerializedIndentationRule { + private static _serializeIndentationRule(indentationRule: vscode.IndentationRule): IIndentationRuleDto { return { decreaseIndentPattern: ExtHostLanguageFeatures._serializeRegExp(indentationRule.decreaseIndentPattern), increaseIndentPattern: ExtHostLanguageFeatures._serializeRegExp(indentationRule.increaseIndentPattern), @@ -1520,7 +1520,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { }; } - private static _serializeOnEnterRule(onEnterRule: vscode.OnEnterRule): ISerializedOnEnterRule { + private static _serializeOnEnterRule(onEnterRule: vscode.OnEnterRule): IOnEnterRuleDto { return { beforeText: ExtHostLanguageFeatures._serializeRegExp(onEnterRule.beforeText), afterText: onEnterRule.afterText ? ExtHostLanguageFeatures._serializeRegExp(onEnterRule.afterText) : undefined, @@ -1529,7 +1529,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { }; } - private static _serializeOnEnterRules(onEnterRules: vscode.OnEnterRule[]): ISerializedOnEnterRule[] { + private static _serializeOnEnterRules(onEnterRules: vscode.OnEnterRule[]): IOnEnterRuleDto[] { return onEnterRules.map(ExtHostLanguageFeatures._serializeOnEnterRule); } @@ -1549,7 +1549,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { } const handle = this._nextHandle(); - const serializedConfiguration: ISerializedLanguageConfiguration = { + const serializedConfiguration: ILanguageConfigurationDto = { comments: configuration.comments, brackets: configuration.brackets, wordPattern: configuration.wordPattern ? ExtHostLanguageFeatures._serializeRegExp(configuration.wordPattern) : undefined, diff --git a/src/vs/workbench/api/common/extHostSCM.ts b/src/vs/workbench/api/common/extHostSCM.ts index 311981d6f4d..00b3315f6c7 100644 --- a/src/vs/workbench/api/common/extHostSCM.ts +++ b/src/vs/workbench/api/common/extHostSCM.ts @@ -9,7 +9,7 @@ import { debounce } from 'vs/base/common/decorators'; import { DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle'; import { asPromise } from 'vs/base/common/async'; import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; -import { MainContext, MainThreadSCMShape, SCMRawResource, SCMRawResourceSplice, SCMRawResourceSplices, IMainContext, ExtHostSCMShape, CommandDto } from './extHost.protocol'; +import { MainContext, MainThreadSCMShape, SCMRawResource, SCMRawResourceSplice, SCMRawResourceSplices, IMainContext, ExtHostSCMShape, ICommandDto } from './extHost.protocol'; import { sortedDiff } from 'vs/base/common/arrays'; import { comparePaths } from 'vs/base/common/comparers'; import * as vscode from 'vscode'; @@ -445,7 +445,7 @@ class ExtHostSourceControl implements vscode.SourceControl { this._statusBarCommands = statusBarCommands; - const internal = (statusBarCommands || []).map(c => this._commands.converter.toInternal(c, this._statusBarDisposables.value!)) as CommandDto[]; + const internal = (statusBarCommands || []).map(c => this._commands.converter.toInternal(c, this._statusBarDisposables.value!)) as ICommandDto[]; this._proxy.$updateSourceControl(this.handle, { statusBarCommands: internal }); } diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index 39b2cda9188..5da072a265e 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -19,7 +19,7 @@ import { IRange } from 'vs/editor/common/core/range'; import { ISelection } from 'vs/editor/common/core/selection'; import * as htmlContent from 'vs/base/common/htmlContent'; import * as languageSelector from 'vs/editor/common/modes/languageSelector'; -import { WorkspaceEditDto, ResourceTextEditDto, ResourceFileEditDto } from 'vs/workbench/api/common/extHost.protocol'; +import { IWorkspaceEditDto, IResourceTextEditDto, IResourceFileEditDto } from 'vs/workbench/api/common/extHost.protocol'; import { MarkerSeverity, IRelatedInformation, IMarkerData, MarkerTag } from 'vs/platform/markers/common/markers'; import { ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; @@ -455,8 +455,8 @@ export namespace TextEdit { } export namespace WorkspaceEdit { - export function from(value: vscode.WorkspaceEdit, documents?: ExtHostDocumentsAndEditors): WorkspaceEditDto { - const result: WorkspaceEditDto = { + export function from(value: vscode.WorkspaceEdit, documents?: ExtHostDocumentsAndEditors): IWorkspaceEditDto { + const result: IWorkspaceEditDto = { edits: [] }; for (const entry of (value as types.WorkspaceEdit)._allEntries()) { @@ -464,28 +464,28 @@ export namespace WorkspaceEdit { if (Array.isArray(uriOrEdits)) { // text edits const doc = documents && uri ? documents.getDocument(uri) : undefined; - result.edits.push({ resource: uri, modelVersionId: doc && doc.version, edits: uriOrEdits.map(TextEdit.from) }); + result.edits.push({ resource: uri, modelVersionId: doc && doc.version, edits: uriOrEdits.map(TextEdit.from) }); } else { // resource edits - result.edits.push({ oldUri: uri, newUri: uriOrEdits, options: entry[2] }); + result.edits.push({ oldUri: uri, newUri: uriOrEdits, options: entry[2] }); } } return result; } - export function to(value: WorkspaceEditDto) { + export function to(value: IWorkspaceEditDto) { const result = new types.WorkspaceEdit(); for (const edit of value.edits) { - if (Array.isArray((edit).edits)) { + if (Array.isArray((edit).edits)) { result.set( - URI.revive((edit).resource), - (edit).edits.map(TextEdit.to) + URI.revive((edit).resource), + (edit).edits.map(TextEdit.to) ); } else { result.renameFile( - URI.revive((edit).oldUri!), - URI.revive((edit).newUri!), - (edit).options + URI.revive((edit).oldUri!), + URI.revive((edit).newUri!), + (edit).options ); } } diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index a17a9c0622f..f373f4c08ed 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -10,7 +10,7 @@ import { URI, UriComponents } from 'vs/base/common/uri'; import * as platform from 'vs/base/common/platform'; import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { Event, Emitter } from 'vs/base/common/event'; -import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, IMainContext, ShellLaunchConfigDto, IShellDefinitionDto, IShellAndArgsDto, ITerminalDimensionsDto } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, IMainContext, IShellLaunchConfigDto, IShellDefinitionDto, IShellAndArgsDto, ITerminalDimensionsDto } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostConfiguration, ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration'; import { ILogService } from 'vs/platform/log/common/log'; import { EXT_HOST_CREATION_DELAY, IShellLaunchConfig, ITerminalEnvironment, ITerminalChildProcess, ITerminalDimensions } from 'vs/workbench/contrib/terminal/common/terminal'; @@ -551,7 +551,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { this._variableResolver = new ExtHostVariableResolverService(workspaceFolders || [], this._extHostDocumentsAndEditors, configProvider); } - public async $spawnExtHostProcess(id: number, shellLaunchConfigDto: ShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): Promise { + public async $spawnExtHostProcess(id: number, shellLaunchConfigDto: IShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): Promise { const shellLaunchConfig: IShellLaunchConfig = { name: shellLaunchConfigDto.name, executable: shellLaunchConfigDto.executable, diff --git a/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts b/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts index 99724c53a21..d85eae55ebf 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts @@ -7,7 +7,7 @@ import { URI } from 'vs/base/common/uri'; import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { TextDocumentSaveReason, TextEdit, Position, EndOfLine } from 'vs/workbench/api/common/extHostTypes'; -import { MainThreadTextEditorsShape, WorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol'; +import { MainThreadTextEditorsShape, IWorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostDocumentSaveParticipant } from 'vs/workbench/api/common/extHostDocumentSaveParticipant'; import { SingleProxyRPCProtocol } from './testRPCProtocol'; import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles'; @@ -262,9 +262,9 @@ suite('ExtHostDocumentSaveParticipant', () => { test('event delivery, pushEdits sync', () => { - let dto: WorkspaceEditDto; + let dto: IWorkspaceEditDto; const participant = new ExtHostDocumentSaveParticipant(nullLogService, documents, new class extends mock() { - $tryApplyWorkspaceEdit(_edits: WorkspaceEditDto) { + $tryApplyWorkspaceEdit(_edits: IWorkspaceEditDto) { dto = _edits; return Promise.resolve(true); } @@ -286,9 +286,9 @@ suite('ExtHostDocumentSaveParticipant', () => { test('event delivery, concurrent change', () => { - let edits: WorkspaceEditDto; + let edits: IWorkspaceEditDto; const participant = new ExtHostDocumentSaveParticipant(nullLogService, documents, new class extends mock() { - $tryApplyWorkspaceEdit(_edits: WorkspaceEditDto) { + $tryApplyWorkspaceEdit(_edits: IWorkspaceEditDto) { edits = _edits; return Promise.resolve(true); } @@ -323,7 +323,7 @@ suite('ExtHostDocumentSaveParticipant', () => { test('event delivery, two listeners -> two document states', () => { const participant = new ExtHostDocumentSaveParticipant(nullLogService, documents, new class extends mock() { - $tryApplyWorkspaceEdit(dto: WorkspaceEditDto) { + $tryApplyWorkspaceEdit(dto: IWorkspaceEditDto) { for (const edit of dto.edits) { if (!isResourceTextEdit(edit)) { diff --git a/src/vs/workbench/test/electron-browser/api/extHostTextEditors.test.ts b/src/vs/workbench/test/electron-browser/api/extHostTextEditors.test.ts index b168561d77a..a66b5b43b9f 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostTextEditors.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostTextEditors.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as extHostTypes from 'vs/workbench/api/common/extHostTypes'; -import { MainContext, MainThreadTextEditorsShape, WorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol'; +import { MainContext, MainThreadTextEditorsShape, IWorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol'; import { URI } from 'vs/base/common/uri'; import { mock } from 'vs/workbench/test/electron-browser/api/mock'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; @@ -16,14 +16,14 @@ suite('ExtHostTextEditors.applyWorkspaceEdit', () => { const resource = URI.parse('foo:bar'); let editors: ExtHostEditors; - let workspaceResourceEdits: WorkspaceEditDto; + let workspaceResourceEdits: IWorkspaceEditDto; setup(() => { workspaceResourceEdits = null!; let rpcProtocol = new TestRPCProtocol(); rpcProtocol.set(MainContext.MainThreadTextEditors, new class extends mock() { - $tryApplyWorkspaceEdit(_workspaceResourceEdits: WorkspaceEditDto): Promise { + $tryApplyWorkspaceEdit(_workspaceResourceEdits: IWorkspaceEditDto): Promise { workspaceResourceEdits = _workspaceResourceEdits; return Promise.resolve(true); } From b4b5e5a2d83363964b334b9fe9694289fcc03a02 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 5 Aug 2019 16:50:01 +0200 Subject: [PATCH 212/861] fix compilo --- .../api/extHostConfiguration.test.ts | 11 ++-- .../api/extHostWorkspace.test.ts | 55 +++++++++---------- 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts b/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts index 02f4cf4cd98..3104b573b5c 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts @@ -15,7 +15,6 @@ import { IWorkspaceFolder, WorkspaceFolder } from 'vs/platform/workspace/common/ import { ConfigurationTarget, IConfigurationModel } from 'vs/platform/configuration/common/configuration'; import { NullLogService } from 'vs/platform/log/common/log'; import { assign } from 'vs/base/common/objects'; -import { Counter } from 'vs/base/common/numbers'; suite('ExtHostConfiguration', function () { @@ -31,7 +30,7 @@ suite('ExtHostConfiguration', function () { if (!shape) { shape = new class extends mock() { }; } - return new ExtHostConfigProvider(shape, new ExtHostWorkspace(new TestRPCProtocol(), new NullLogService(), new Counter()), createConfigurationData(contents)); + return new ExtHostConfigProvider(shape, new ExtHostWorkspace(new TestRPCProtocol(), new NullLogService()), createConfigurationData(contents)); } function createConfigurationData(contents: any): IConfigurationInitData { @@ -264,7 +263,7 @@ suite('ExtHostConfiguration', function () { test('inspect in no workspace context', function () { const testObject = new ExtHostConfigProvider( new class extends mock() { }, - new ExtHostWorkspace(new TestRPCProtocol(), new NullLogService(), new Counter()), + new ExtHostWorkspace(new TestRPCProtocol(), new NullLogService()), { defaults: new ConfigurationModel({ 'editor': { @@ -304,7 +303,7 @@ suite('ExtHostConfiguration', function () { } }, ['editor.wordWrap']); folders.push([workspaceUri, workspace]); - const extHostWorkspace = new ExtHostWorkspace(new TestRPCProtocol(), new NullLogService(), new Counter()); + const extHostWorkspace = new ExtHostWorkspace(new TestRPCProtocol(), new NullLogService()); extHostWorkspace.$initializeWorkspace({ 'id': 'foo', 'folders': [aWorkspaceFolder(URI.file('foo'), 0)], @@ -379,7 +378,7 @@ suite('ExtHostConfiguration', function () { }, ['editor.wordWrap'])]); folders.push([thirdRoot, new ConfigurationModel({}, [])]); - const extHostWorkspace = new ExtHostWorkspace(new TestRPCProtocol(), new NullLogService(), new Counter()); + const extHostWorkspace = new ExtHostWorkspace(new TestRPCProtocol(), new NullLogService()); extHostWorkspace.$initializeWorkspace({ 'id': 'foo', 'folders': [aWorkspaceFolder(firstRoot, 0), aWorkspaceFolder(secondRoot, 1)], @@ -589,7 +588,7 @@ suite('ExtHostConfiguration', function () { test('configuration change event', (done) => { const workspaceFolder = aWorkspaceFolder(URI.file('folder1'), 0); - const extHostWorkspace = new ExtHostWorkspace(new TestRPCProtocol(), new NullLogService(), new Counter()); + const extHostWorkspace = new ExtHostWorkspace(new TestRPCProtocol(), new NullLogService()); extHostWorkspace.$initializeWorkspace({ 'id': 'foo', 'folders': [workspaceFolder], diff --git a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts index 76040fc8eae..0441b998625 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts @@ -5,7 +5,6 @@ import * as assert from 'assert'; import { CancellationToken } from 'vs/base/common/cancellation'; -import { Counter } from 'vs/base/common/numbers'; import { basename } from 'vs/base/common/path'; import { URI, UriComponents } from 'vs/base/common/uri'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; @@ -18,8 +17,8 @@ import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import { mock } from 'vs/workbench/test/electron-browser/api/mock'; import { TestRPCProtocol } from './testRPCProtocol'; -function createExtHostWorkspace(mainContext: IMainContext, data: IWorkspaceData, logService: ILogService, requestIdProvider: Counter): ExtHostWorkspace { - const result = new ExtHostWorkspace(mainContext, logService, requestIdProvider); +function createExtHostWorkspace(mainContext: IMainContext, data: IWorkspaceData, logService: ILogService): ExtHostWorkspace { + const result = new ExtHostWorkspace(mainContext, logService); result.$initializeWorkspace(data); return result; } @@ -45,7 +44,7 @@ suite('ExtHostWorkspace', function () { test('asRelativePath', () => { - const ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/Applications/NewsWoWBot'), 0)], name: 'Test' }, new NullLogService(), new Counter()); + const ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/Applications/NewsWoWBot'), 0)], name: 'Test' }, new NullLogService()); assertAsRelativePath(ws, '/Coding/Applications/NewsWoWBot/bernd/das/brot', 'bernd/das/brot'); assertAsRelativePath(ws, '/Apps/DartPubCache/hosted/pub.dartlang.org/convert-2.0.1/lib/src/hex.dart', @@ -59,7 +58,7 @@ suite('ExtHostWorkspace', function () { test('asRelativePath, same paths, #11402', function () { const root = '/home/aeschli/workspaces/samples/docker'; const input = '/home/aeschli/workspaces/samples/docker'; - const ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService(), new Counter()); + const ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService()); assertAsRelativePath(ws, input, input); @@ -68,20 +67,20 @@ suite('ExtHostWorkspace', function () { }); test('asRelativePath, no workspace', function () { - const ws = createExtHostWorkspace(new TestRPCProtocol(), null!, new NullLogService(), new Counter()); + const ws = createExtHostWorkspace(new TestRPCProtocol(), null!, new NullLogService()); assertAsRelativePath(ws, '', ''); assertAsRelativePath(ws, '/foo/bar', '/foo/bar'); }); test('asRelativePath, multiple folders', function () { - const ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService(), new Counter()); + const ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService()); assertAsRelativePath(ws, '/Coding/One/file.txt', 'One/file.txt'); assertAsRelativePath(ws, '/Coding/Two/files/out.txt', 'Two/files/out.txt'); assertAsRelativePath(ws, '/Coding/Two2/files/out.txt', '/Coding/Two2/files/out.txt'); }); test('slightly inconsistent behaviour of asRelativePath and getWorkspaceFolder, #31553', function () { - const mrws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService(), new Counter()); + const mrws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService()); assertAsRelativePath(mrws, '/Coding/One/file.txt', 'One/file.txt'); assertAsRelativePath(mrws, '/Coding/One/file.txt', 'One/file.txt', true); @@ -93,7 +92,7 @@ suite('ExtHostWorkspace', function () { assertAsRelativePath(mrws, '/Coding/Two2/files/out.txt', '/Coding/Two2/files/out.txt', true); assertAsRelativePath(mrws, '/Coding/Two2/files/out.txt', '/Coding/Two2/files/out.txt', false); - const srws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0)], name: 'Test' }, new NullLogService(), new Counter()); + const srws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0)], name: 'Test' }, new NullLogService()); assertAsRelativePath(srws, '/Coding/One/file.txt', 'file.txt'); assertAsRelativePath(srws, '/Coding/One/file.txt', 'file.txt', false); assertAsRelativePath(srws, '/Coding/One/file.txt', 'One/file.txt', true); @@ -103,24 +102,24 @@ suite('ExtHostWorkspace', function () { }); test('getPath, legacy', function () { - let ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); + let ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService()); assert.equal(ws.getPath(), undefined); - ws = createExtHostWorkspace(new TestRPCProtocol(), null!, new NullLogService(), new Counter()); + ws = createExtHostWorkspace(new TestRPCProtocol(), null!, new NullLogService()); assert.equal(ws.getPath(), undefined); - ws = createExtHostWorkspace(new TestRPCProtocol(), undefined!, new NullLogService(), new Counter()); + ws = createExtHostWorkspace(new TestRPCProtocol(), undefined!, new NullLogService()); assert.equal(ws.getPath(), undefined); - ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.file('Folder'), 0), aWorkspaceFolderData(URI.file('Another/Folder'), 1)] }, new NullLogService(), new Counter()); + ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.file('Folder'), 0), aWorkspaceFolderData(URI.file('Another/Folder'), 1)] }, new NullLogService()); assert.equal(ws.getPath()!.replace(/\\/g, '/'), '/Folder'); - ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.file('/Folder'), 0)] }, new NullLogService(), new Counter()); + ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.file('/Folder'), 0)] }, new NullLogService()); assert.equal(ws.getPath()!.replace(/\\/g, '/'), '/Folder'); }); test('WorkspaceFolder has name and index', function () { - const ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService(), new Counter()); + const ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', folders: [aWorkspaceFolderData(URI.file('/Coding/One'), 0), aWorkspaceFolderData(URI.file('/Coding/Two'), 1)], name: 'Test' }, new NullLogService()); const [one, two] = ws.getWorkspaceFolders()!; @@ -139,7 +138,7 @@ suite('ExtHostWorkspace', function () { aWorkspaceFolderData(URI.file('/Coding/Two'), 1), aWorkspaceFolderData(URI.file('/Coding/Two/Nested'), 2) ] - }, new NullLogService(), new Counter()); + }, new NullLogService()); let folder = ws.getWorkspaceFolder(URI.file('/foo/bar')); assert.equal(folder, undefined); @@ -179,7 +178,7 @@ suite('ExtHostWorkspace', function () { }); test('Multiroot change event should have a delta, #29641', function (done) { - let ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); + let ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService()); let finished = false; const finish = (error?: any) => { @@ -242,7 +241,7 @@ suite('ExtHostWorkspace', function () { }); test('Multiroot change keeps existing workspaces live', function () { - let ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar'), 0)] }, new NullLogService(), new Counter()); + let ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar'), 0)] }, new NullLogService()); let firstFolder = ws.getWorkspaceFolders()![0]; ws.$acceptWorkspaceData({ id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar2'), 0), aWorkspaceFolderData(URI.parse('foo:bar'), 1, 'renamed')] }); @@ -262,7 +261,7 @@ suite('ExtHostWorkspace', function () { }); test('updateWorkspaceFolders - invalid arguments', function () { - let ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); + let ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService()); assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, null!, null!)); assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, 0, 0)); @@ -271,7 +270,7 @@ suite('ExtHostWorkspace', function () { assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, -1, 0)); assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, -1, -1)); - ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar'), 0)] }, new NullLogService(), new Counter()); + ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [aWorkspaceFolderData(URI.parse('foo:bar'), 0)] }, new NullLogService()); assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, 1, 1)); assert.equal(false, ws.updateWorkspaceFolders(extensionDescriptor, 0, 2)); @@ -293,7 +292,7 @@ suite('ExtHostWorkspace', function () { assertRegistered: undefined! }; - const ws = createExtHostWorkspace(protocol, { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); + const ws = createExtHostWorkspace(protocol, { id: 'foo', name: 'Test', folders: [] }, new NullLogService()); // // Add one folder @@ -526,7 +525,7 @@ suite('ExtHostWorkspace', function () { } }; - let ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService(), new Counter()); + let ws = createExtHostWorkspace(new TestRPCProtocol(), { id: 'foo', name: 'Test', folders: [] }, new NullLogService()); let sub = ws.onDidChangeWorkspace(e => { try { assert.throws(() => { @@ -549,7 +548,7 @@ suite('ExtHostWorkspace', function () { id: 'foo', name: 'Test', folders: [ aWorkspaceFolderData(URI.file('c:/Users/marek/Desktop/vsc_test/'), 0) ] - }, new NullLogService(), new Counter()); + }, new NullLogService()); assert.ok(ws.getWorkspaceFolder(URI.file('c:/Users/marek/Desktop/vsc_test/a.txt'))); assert.ok(ws.getWorkspaceFolder(URI.file('C:/Users/marek/Desktop/vsc_test/b.txt'))); @@ -583,7 +582,7 @@ suite('ExtHostWorkspace', function () { } }); - const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService(), new Counter()); + const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService()); return ws.findFiles('foo', undefined, 10, new ExtensionIdentifier('test')).then(() => { assert(mainThreadCalled, 'mainThreadCalled'); }); @@ -604,7 +603,7 @@ suite('ExtHostWorkspace', function () { } }); - const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService(), new Counter()); + const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService()); return ws.findFiles(new RelativePattern('/other/folder', 'glob/**'), undefined, 10, new ExtensionIdentifier('test')).then(() => { assert(mainThreadCalled, 'mainThreadCalled'); }); @@ -625,7 +624,7 @@ suite('ExtHostWorkspace', function () { } }); - const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService(), new Counter()); + const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService()); return ws.findFiles(new RelativePattern('/other/folder', 'glob/**'), null!, 10, new ExtensionIdentifier('test')).then(() => { assert(mainThreadCalled, 'mainThreadCalled'); }); @@ -643,7 +642,7 @@ suite('ExtHostWorkspace', function () { } }); - const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService(), new Counter()); + const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService()); const token = CancellationToken.Cancelled; return ws.findFiles(new RelativePattern('/other/folder', 'glob/**'), null!, 10, new ExtensionIdentifier('test'), token).then(() => { @@ -664,7 +663,7 @@ suite('ExtHostWorkspace', function () { } }); - const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService(), new Counter()); + const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService()); return ws.findFiles('', new RelativePattern(root, 'glob/**'), 10, new ExtensionIdentifier('test')).then(() => { assert(mainThreadCalled, 'mainThreadCalled'); }); From 5535ee44e39dade6608ec206c34b3ff2be681c30 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 5 Aug 2019 16:59:41 +0200 Subject: [PATCH 213/861] Don't include File schema in web for file picker --- .../dialogs/browser/fileDialogService.ts | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/services/dialogs/browser/fileDialogService.ts b/src/vs/workbench/services/dialogs/browser/fileDialogService.ts index f7d1e60691e..512d28485d8 100644 --- a/src/vs/workbench/services/dialogs/browser/fileDialogService.ts +++ b/src/vs/workbench/services/dialogs/browser/fileDialogService.ts @@ -19,6 +19,7 @@ import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IFileService } from 'vs/platform/files/common/files'; +import { isWeb } from 'vs/base/common/platform'; export class FileDialogService implements IFileDialogService { @@ -90,9 +91,14 @@ export class FileDialogService implements IFileDialogService { return (schema !== Schemas.file) || (setting === true); } - private ensureFileSchema(schema: string): string[] { + private addFileSchemaIfNeeded(schema: string): string[] { + // Include File schema unless the schema is web // Don't allow untitled schema through. - return schema === Schemas.untitled ? [Schemas.file] : (schema !== Schemas.file ? [schema, Schemas.file] : [schema]); + if (isWeb) { + return schema === Schemas.untitled ? [Schemas.file] : [schema]; + } else { + return schema === Schemas.untitled ? [Schemas.file] : (schema !== Schemas.file ? [schema, Schemas.file] : [schema]); + } } async pickFileFolderAndOpen(options: IPickAndOpenOptions): Promise { @@ -104,7 +110,7 @@ export class FileDialogService implements IFileDialogService { if (this.shouldUseSimplified(schema)) { const title = nls.localize('openFileOrFolder.title', 'Open File Or Folder'); - const availableFileSystems = this.ensureFileSchema(schema); // always allow file as well + const availableFileSystems = this.addFileSchemaIfNeeded(schema); const uri = await this.pickRemoteResource({ canSelectFiles: true, canSelectFolders: true, canSelectMany: false, defaultUri: options.defaultUri, title, availableFileSystems }); @@ -130,7 +136,7 @@ export class FileDialogService implements IFileDialogService { if (this.shouldUseSimplified(schema)) { const title = nls.localize('openFile.title', 'Open File'); - const availableFileSystems = this.ensureFileSchema(schema); // always allow file as well + const availableFileSystems = this.addFileSchemaIfNeeded(schema); const uri = await this.pickRemoteResource({ canSelectFiles: true, canSelectFolders: false, canSelectMany: false, defaultUri: options.defaultUri, title, availableFileSystems }); if (uri) { @@ -152,7 +158,7 @@ export class FileDialogService implements IFileDialogService { if (this.shouldUseSimplified(schema)) { const title = nls.localize('openFolder.title', 'Open Folder'); - const availableFileSystems = this.ensureFileSchema(schema); // always allow file as well + const availableFileSystems = this.addFileSchemaIfNeeded(schema); const uri = await this.pickRemoteResource({ canSelectFiles: false, canSelectFolders: true, canSelectMany: false, defaultUri: options.defaultUri, title, availableFileSystems }); if (uri) { @@ -175,7 +181,7 @@ export class FileDialogService implements IFileDialogService { if (this.shouldUseSimplified(schema)) { const title = nls.localize('openWorkspace.title', 'Open Workspace'); const filters: FileFilter[] = [{ name: nls.localize('filterName.workspace', 'Workspace'), extensions: [WORKSPACE_EXTENSION] }]; - const availableFileSystems = this.ensureFileSchema(schema); // always allow file as well + const availableFileSystems = this.addFileSchemaIfNeeded(schema); const uri = await this.pickRemoteResource({ canSelectFiles: true, canSelectFolders: false, canSelectMany: false, defaultUri: options.defaultUri, title, filters, availableFileSystems }); if (uri) { @@ -192,7 +198,7 @@ export class FileDialogService implements IFileDialogService { const schema = this.getFileSystemSchema(options); if (this.shouldUseSimplified(schema)) { if (!options.availableFileSystems) { - options.availableFileSystems = this.ensureFileSchema(schema); // always allow file as well + options.availableFileSystems = this.addFileSchemaIfNeeded(schema); } options.title = nls.localize('saveFileAs.title', 'Save As'); @@ -221,7 +227,7 @@ export class FileDialogService implements IFileDialogService { const schema = this.getFileSystemSchema(options); if (this.shouldUseSimplified(schema)) { if (!options.availableFileSystems) { - options.availableFileSystems = this.ensureFileSchema(schema); // always allow file as well + options.availableFileSystems = this.addFileSchemaIfNeeded(schema); } return this.saveRemoteResource(options); @@ -239,7 +245,7 @@ export class FileDialogService implements IFileDialogService { const schema = this.getFileSystemSchema(options); if (this.shouldUseSimplified(schema)) { if (!options.availableFileSystems) { - options.availableFileSystems = this.ensureFileSchema(schema); // always allow file as well + options.availableFileSystems = this.addFileSchemaIfNeeded(schema); } const uri = await this.pickRemoteResource(options); @@ -301,4 +307,4 @@ function isUntitledWorkspace(path: URI, environmentService: IWorkbenchEnvironmen return resources.isEqualOrParent(path, environmentService.untitledWorkspacesHome); } -registerSingleton(IFileDialogService, FileDialogService, true); \ No newline at end of file +registerSingleton(IFileDialogService, FileDialogService, true); From 122615efeb30d205e11523007b73ca5c2abb136e Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 5 Aug 2019 17:07:58 +0200 Subject: [PATCH 214/861] files - make exists as fast as possible with our current file system provider API --- src/vs/platform/files/common/fileService.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/vs/platform/files/common/fileService.ts b/src/vs/platform/files/common/fileService.ts index 4d9ecebb95e..8a22485eca5 100644 --- a/src/vs/platform/files/common/fileService.ts +++ b/src/vs/platform/files/common/fileService.ts @@ -253,8 +253,12 @@ export class FileService extends Disposable implements IFileService { } async exists(resource: URI): Promise { + const provider = await this.withProvider(resource); + try { - return !!(await this.resolve(resource)); + const stat = await provider.stat(resource); + + return !!stat; } catch (error) { return false; } From 87f2b7682fba16cab3922308a42fcf1000c5a877 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 5 Aug 2019 17:25:51 +0200 Subject: [PATCH 215/861] :polish: prefer to open file in same window if triggered from integrated terminal --- src/vs/code/electron-main/windows.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index 5e50acec4dc..c98f1958018 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -1149,9 +1149,10 @@ export class WindowsManager extends Disposable implements IWindowsMainService { } } - // Linux/Windows: by default we open files in the new window unless triggered via DIALOG or MENU context + // Linux/Windows: by default we open files in the new window unless triggered via DIALOG / MENU context + // or from the integrated terminal where we assume the user prefers to open in the current window else { - if (openConfig.context !== OpenContext.DIALOG && openConfig.context !== OpenContext.MENU) { + if (openConfig.context !== OpenContext.DIALOG && openConfig.context !== OpenContext.MENU && !(openConfig.userEnv && openConfig.userEnv['TERM_PROGRAM'] === 'vscode')) { openFilesInNewWindow = true; } } @@ -2116,4 +2117,4 @@ function resourceFromURIToOpen(u: IURIToOpen): URI { } return u.fileUri; -} \ No newline at end of file +} From f294979c8c08b82d637291ade1e1225dd8ef46e6 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 5 Aug 2019 17:28:01 +0200 Subject: [PATCH 216/861] debt - remove unused simple service --- .../workbench/browser/web.simpleservices.ts | 57 ------------------- 1 file changed, 57 deletions(-) diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 25414d87335..7240412d27a 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -164,63 +164,6 @@ export class SimpleLogService extends ConsoleLogService { } //#endregion -//#region Multi Extension Management - -export class SimpleMultiExtensionsManagementService implements IExtensionManagementService { - - _serviceBrand: any; - - onInstallExtension = Event.None; - onDidInstallExtension = Event.None; - onUninstallExtension = Event.None; - onDidUninstallExtension = Event.None; - - zip(extension: ILocalExtension): Promise { - // @ts-ignore - return Promise.resolve(undefined); - } - - unzip(zipLocation: URI, type: ExtensionType): Promise { - // @ts-ignore - return Promise.resolve(undefined); - } - - install(vsix: URI): Promise { - // @ts-ignore - return Promise.resolve(undefined); - } - - installFromGallery(extension: IGalleryExtension): Promise { - // @ts-ignore - return Promise.resolve(undefined); - } - - uninstall(extension: ILocalExtension, force?: boolean): Promise { - return Promise.resolve(undefined); - } - - reinstallFromGallery(extension: ILocalExtension): Promise { - return Promise.resolve(undefined); - } - - getInstalled(type?: ExtensionType): Promise { - // @ts-ignore - return Promise.resolve(undefined); - } - - getExtensionsReport(): Promise { - // @ts-ignore - return Promise.resolve(undefined); - } - - updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata): Promise { - // @ts-ignore - return Promise.resolve(undefined); - } -} - -//#endregion - //#region Update export class SimpleUpdateService implements IUpdateService { From 6981de9dee7bf98dc1021d6e7b757bedd7499cfa Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 5 Aug 2019 18:00:12 +0200 Subject: [PATCH 217/861] strictPropertyInitialization #78168 --- .../contrib/debug/browser/debugSession.ts | 2 +- .../contrib/debug/browser/debugStatus.ts | 2 +- .../workbench/contrib/debug/browser/repl.ts | 22 +++++++++---------- .../workbench/contrib/debug/common/debug.ts | 2 +- .../contrib/debug/common/debugModel.ts | 6 ++--- .../contrib/files/browser/explorerViewlet.ts | 2 +- .../contrib/files/browser/views/emptyView.ts | 6 ++--- .../files/browser/views/explorerView.ts | 6 ++--- .../files/browser/views/explorerViewer.ts | 2 +- .../files/browser/views/openEditorsView.ts | 22 +++++++++++-------- .../contrib/files/common/explorerModel.ts | 6 ++--- 11 files changed, 41 insertions(+), 37 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugSession.ts b/src/vs/workbench/contrib/debug/browser/debugSession.ts index 16f62f1d7dd..320be3360ce 100644 --- a/src/vs/workbench/contrib/debug/browser/debugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/debugSession.ts @@ -42,7 +42,7 @@ export class DebugSession implements IDebugSession { private sources = new Map(); private threads = new Map(); private rawListeners: IDisposable[] = []; - private fetchThreadsScheduler: RunOnceScheduler; + private fetchThreadsScheduler: RunOnceScheduler | undefined; private repl: ReplModel; private readonly _onDidChangeState = new Emitter(); diff --git a/src/vs/workbench/contrib/debug/browser/debugStatus.ts b/src/vs/workbench/contrib/debug/browser/debugStatus.ts index 1ea94d43674..20f73614519 100644 --- a/src/vs/workbench/contrib/debug/browser/debugStatus.ts +++ b/src/vs/workbench/contrib/debug/browser/debugStatus.ts @@ -13,7 +13,7 @@ import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; export class DebugStatusContribution implements IWorkbenchContribution { - private showInStatusBar: 'never' | 'always' | 'onFirstSessionStart'; + private showInStatusBar!: 'never' | 'always' | 'onFirstSessionStart'; private toDispose: IDisposable[] = []; private entryAccessor: IStatusbarEntryAccessor | undefined; diff --git a/src/vs/workbench/contrib/debug/browser/repl.ts b/src/vs/workbench/contrib/debug/browser/repl.ts index 922de4fe53a..938d2c6477c 100644 --- a/src/vs/workbench/contrib/debug/browser/repl.ts +++ b/src/vs/workbench/contrib/debug/browser/repl.ts @@ -92,18 +92,18 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati private static readonly REPL_INPUT_MAX_HEIGHT = 170; private history: HistoryNavigator; - private tree: WorkbenchAsyncDataTree; - private replDelegate: ReplDelegate; - private container: HTMLElement; - private replInput: CodeEditorWidget; - private replInputContainer: HTMLElement; - private dimension: dom.Dimension; + private tree!: WorkbenchAsyncDataTree; + private replDelegate!: ReplDelegate; + private container!: HTMLElement; + private replInput!: CodeEditorWidget; + private replInputContainer!: HTMLElement; + private dimension!: dom.Dimension; private replInputHeight: number; - private model: ITextModel; - private historyNavigationEnablement: IContextKey; - private scopedInstantiationService: IInstantiationService; - private replElementsChangeListener: IDisposable; - private styleElement: HTMLStyleElement; + private model!: ITextModel; + private historyNavigationEnablement!: IContextKey; + private scopedInstantiationService!: IInstantiationService; + private replElementsChangeListener: IDisposable | undefined; + private styleElement: HTMLStyleElement | undefined; constructor( @IDebugService private readonly debugService: IDebugService, diff --git a/src/vs/workbench/contrib/debug/common/debug.ts b/src/vs/workbench/contrib/debug/common/debug.ts index 1798b2838c6..8fa02439610 100644 --- a/src/vs/workbench/contrib/debug/common/debug.ts +++ b/src/vs/workbench/contrib/debug/common/debug.ts @@ -133,7 +133,7 @@ export function getStateLabel(state: State): string { } } -export class AdapterEndEvent { +export interface AdapterEndEvent { error?: Error; sessionLengthInSeconds: number; emittedStopped: boolean; diff --git a/src/vs/workbench/contrib/debug/common/debugModel.ts b/src/vs/workbench/contrib/debug/common/debugModel.ts index 598c3b95a17..7166ad996a7 100644 --- a/src/vs/workbench/contrib/debug/common/debugModel.ts +++ b/src/vs/workbench/contrib/debug/common/debugModel.ts @@ -94,8 +94,8 @@ export class ExpressionContainer implements IExpressionContainer { // Use chunks to support variable paging #9537 private static readonly BASE_CHUNK_SIZE = 100; - public valueChanged: boolean; - private _value: string; + public valueChanged = false; + private _value: string = ''; protected children?: Promise; constructor( @@ -201,7 +201,7 @@ export class Expression extends ExpressionContainer implements IExpression { static DEFAULT_VALUE = nls.localize('notAvailable', "not available"); public available: boolean; - public type: string; + public type: string | undefined; constructor(public name: string, id = generateUuid()) { super(undefined, 0, id); diff --git a/src/vs/workbench/contrib/files/browser/explorerViewlet.ts b/src/vs/workbench/contrib/files/browser/explorerViewlet.ts index 31cd7cb1006..c3e3a622b58 100644 --- a/src/vs/workbench/contrib/files/browser/explorerViewlet.ts +++ b/src/vs/workbench/contrib/files/browser/explorerViewlet.ts @@ -37,7 +37,7 @@ import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/ export class ExplorerViewletViewsContribution extends Disposable implements IWorkbenchContribution { - private openEditorsVisibleContextKey: IContextKey; + private openEditorsVisibleContextKey!: IContextKey; constructor( @IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService, diff --git a/src/vs/workbench/contrib/files/browser/views/emptyView.ts b/src/vs/workbench/contrib/files/browser/views/emptyView.ts index fddb247aa63..8f097112f00 100644 --- a/src/vs/workbench/contrib/files/browser/views/emptyView.ts +++ b/src/vs/workbench/contrib/files/browser/views/emptyView.ts @@ -32,9 +32,9 @@ export class EmptyView extends ViewletPanel { static readonly ID: string = 'workbench.explorer.emptyView'; static readonly NAME = nls.localize('noWorkspace', "No Folder Opened"); - private button: Button; - private messageElement: HTMLElement; - private titleElement: HTMLElement; + private button!: Button; + private messageElement!: HTMLElement; + private titleElement!: HTMLElement; constructor( options: IViewletViewOptions, diff --git a/src/vs/workbench/contrib/files/browser/views/explorerView.ts b/src/vs/workbench/contrib/files/browser/views/explorerView.ts index 9b464d453c9..f5a52355075 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerView.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerView.ts @@ -55,8 +55,8 @@ export class ExplorerView extends ViewletPanel { static readonly ID: string = 'workbench.explorer.fileView'; static readonly TREE_VIEW_STATE_STORAGE_KEY: string = 'workbench.explorer.treeViewState'; - private tree: WorkbenchAsyncDataTree; - private filter: FilesFilter; + private tree!: WorkbenchAsyncDataTree; + private filter!: FilesFilter; private resourceContext: ResourceContextKey; private folderContext: IContextKey; @@ -66,7 +66,7 @@ export class ExplorerView extends ViewletPanel { // Refresh is needed on the initial explorer open private shouldRefresh = true; - private dragHandler: DelayedDragHandler; + private dragHandler!: DelayedDragHandler; private autoReveal = false; constructor( diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 6543070e81c..bffa827671f 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -440,7 +440,7 @@ export class FileDragAndDrop implements ITreeDragAndDrop { private static readonly CONFIRM_DND_SETTING_KEY = 'explorer.confirmDragAndDrop'; private toDispose: IDisposable[]; - private dropEnabled: boolean; + private dropEnabled = false; constructor( @INotificationService private notificationService: INotificationService, diff --git a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts index 893ea55f5be..1f570dfa7ce 100644 --- a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts +++ b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts @@ -51,16 +51,16 @@ export class OpenEditorsView extends ViewletPanel { static readonly ID = 'workbench.explorer.openEditorsView'; static NAME = nls.localize({ key: 'openEditors', comment: ['Open is an adjective'] }, "Open Editors"); - private dirtyCountElement: HTMLElement; + private dirtyCountElement!: HTMLElement; private listRefreshScheduler: RunOnceScheduler; private structuralRefreshDelay: number; - private list: WorkbenchList; - private listLabels: ResourceLabels; - private contributedContextMenu: IMenu; - private needsRefresh: boolean; - private resourceContext: ResourceContextKey; - private groupFocusedContext: IContextKey; - private dirtyEditorFocusedContext: IContextKey; + private list!: WorkbenchList; + private listLabels: ResourceLabels | undefined; + private contributedContextMenu!: IMenu; + private needsRefresh = false; + private resourceContext!: ResourceContextKey; + private groupFocusedContext!: IContextKey; + private dirtyEditorFocusedContext!: IContextKey; constructor( options: IViewletViewOptions, @@ -466,9 +466,13 @@ interface IEditorGroupTemplateData { } class OpenEditorActionRunner extends ActionRunner { - public editor: OpenEditor; + public editor: OpenEditor | undefined; run(action: IAction, context?: any): Promise { + if (!this.editor) { + return Promise.resolve(); + } + return super.run(action, { groupId: this.editor.groupId, editorIndex: this.editor.editorIndex }); } } diff --git a/src/vs/workbench/contrib/files/common/explorerModel.ts b/src/vs/workbench/contrib/files/common/explorerModel.ts index 85c08590a5d..aefd67e415d 100644 --- a/src/vs/workbench/contrib/files/common/explorerModel.ts +++ b/src/vs/workbench/contrib/files/common/explorerModel.ts @@ -19,7 +19,7 @@ import { IExplorerService } from 'vs/workbench/contrib/files/common/files'; export class ExplorerModel implements IDisposable { - private _roots: ExplorerItem[]; + private _roots!: ExplorerItem[]; private _listener: IDisposable; private _onDidChangeRoots = new Emitter(); @@ -75,7 +75,7 @@ export class ExplorerModel implements IDisposable { export class ExplorerItem { private _isDirectoryResolved: boolean; - public isError: boolean; + public isError = false; constructor( public resource: URI, @@ -367,4 +367,4 @@ export class NewExplorerItem extends ExplorerItem { constructor(parent: ExplorerItem, isDirectory: boolean) { super(URI.file(''), parent, isDirectory); } -} \ No newline at end of file +} From 8efcc47e180ca2b8da04b54e98831911eacd7454 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Mon, 5 Aug 2019 09:05:11 -0700 Subject: [PATCH 218/861] strictPropertyInitialization, #78168 --- .../code/electron-browser/issue/issueReporterMain.ts | 8 ++++---- src/vs/editor/common/modes.ts | 4 ++-- src/vs/platform/issue/electron-main/issueService.ts | 8 ++++---- src/vs/workbench/api/browser/mainThreadComments.ts | 12 ++++++------ src/vs/workbench/api/common/extHost.protocol.ts | 2 +- src/vs/workbench/api/common/extHostComments.ts | 6 +++--- .../contrib/comments/browser/reactionsAction.ts | 5 ++--- 7 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/vs/code/electron-browser/issue/issueReporterMain.ts b/src/vs/code/electron-browser/issue/issueReporterMain.ts index 2302d162f34..e6ee71c50f0 100644 --- a/src/vs/code/electron-browser/issue/issueReporterMain.ts +++ b/src/vs/code/electron-browser/issue/issueReporterMain.ts @@ -64,9 +64,9 @@ export function startup(configuration: IssueReporterConfiguration) { } export class IssueReporter extends Disposable { - private environmentService: IEnvironmentService; - private telemetryService: ITelemetryService; - private logService: ILogService; + private environmentService!: IEnvironmentService; + private telemetryService!: ITelemetryService; + private logService!: ILogService; private readonly issueReporterModel: IssueReporterModel; private numberOfSearchResultsDisplayed = 0; private receivedSystemInfo = false; @@ -74,7 +74,7 @@ export class IssueReporter extends Disposable { private shouldQueueSearch = false; private hasBeenSubmitted = false; - private readonly previewButton: Button; + private readonly previewButton!: Button; constructor(configuration: IssueReporterConfiguration) { super(); diff --git a/src/vs/editor/common/modes.ts b/src/vs/editor/common/modes.ts index fa05b9b968c..7480fccf86b 100644 --- a/src/vs/editor/common/modes.ts +++ b/src/vs/editor/common/modes.ts @@ -1288,7 +1288,7 @@ export interface CommentThread { threadId: string; resource: string | null; range: IRange; - label: string; + label: string | undefined; contextValue: string | undefined; comments: Comment[] | undefined; onDidChangeComments: Event; @@ -1296,7 +1296,7 @@ export interface CommentThread { input?: CommentInput; onDidChangeInput: Event; onDidChangeRange: Event; - onDidChangeLabel: Event; + onDidChangeLabel: Event; onDidChangeCollasibleState: Event; isDisposed: boolean; } diff --git a/src/vs/platform/issue/electron-main/issueService.ts b/src/vs/platform/issue/electron-main/issueService.ts index 97c788209ed..48b0293e933 100644 --- a/src/vs/platform/issue/electron-main/issueService.ts +++ b/src/vs/platform/issue/electron-main/issueService.ts @@ -21,10 +21,10 @@ const DEFAULT_BACKGROUND_COLOR = '#1E1E1E'; export class IssueService implements IIssueService { _serviceBrand: any; - _issueWindow: BrowserWindow | null; - _issueParentWindow: BrowserWindow | null; - _processExplorerWindow: BrowserWindow | null; - _processExplorerParentWindow: BrowserWindow | null; + _issueWindow: BrowserWindow | null = null; + _issueParentWindow: BrowserWindow | null = null; + _processExplorerWindow: BrowserWindow | null = null; + _processExplorerParentWindow: BrowserWindow | null = null; constructor( private machineId: string, diff --git a/src/vs/workbench/api/browser/mainThreadComments.ts b/src/vs/workbench/api/browser/mainThreadComments.ts index 2580f438473..b7af867d10c 100644 --- a/src/vs/workbench/api/browser/mainThreadComments.ts +++ b/src/vs/workbench/api/browser/mainThreadComments.ts @@ -35,13 +35,13 @@ export class MainThreadCommentThread implements modes.CommentThread { private _onDidChangeInput = new Emitter(); get onDidChangeInput(): Event { return this._onDidChangeInput.event; } - private _label: string; + private _label: string | undefined; - get label(): string { + get label(): string | undefined { return this._label; } - set label(label: string) { + set label(label: string | undefined) { this._label = label; this._onDidChangeLabel.fire(this._label); } @@ -56,8 +56,8 @@ export class MainThreadCommentThread implements modes.CommentThread { this._contextValue = context; } - private _onDidChangeLabel = new Emitter(); - readonly onDidChangeLabel: Event = this._onDidChangeLabel.event; + private _onDidChangeLabel = new Emitter(); + readonly onDidChangeLabel: Event = this._onDidChangeLabel.event; private _comments: modes.Comment[] | undefined; @@ -348,7 +348,7 @@ export class MainThreadComments extends Disposable implements MainThreadComments private _activeCommentThread?: MainThreadCommentThread; private readonly _activeCommentThreadDisposables = this._register(new DisposableStore()); - private _openPanelListener: IDisposable | null; + private _openPanelListener: IDisposable | null = null; constructor( diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index ea98e0fec0e..5db8a6658a9 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -132,7 +132,7 @@ export interface MainThreadCommentsShape extends IDisposable { $unregisterCommentController(handle: number): void; $updateCommentControllerFeatures(handle: number, features: CommentProviderFeatures): void; $createCommentThread(handle: number, commentThreadHandle: number, threadId: string, resource: UriComponents, range: IRange, extensionId: ExtensionIdentifier): modes.CommentThread | undefined; - $updateCommentThread(handle: number, commentThreadHandle: number, threadId: string, resource: UriComponents, range: IRange, label: string, contextValue: string | undefined, comments: modes.Comment[], collapseState: modes.CommentThreadCollapsibleState): void; + $updateCommentThread(handle: number, commentThreadHandle: number, threadId: string, resource: UriComponents, range: IRange, label: string | undefined, contextValue: string | undefined, comments: modes.Comment[], collapseState: modes.CommentThreadCollapsibleState): void; $deleteCommentThread(handle: number, commentThreadHandle: number): void; $onDidCommentThreadsChange(handle: number, event: modes.CommentThreadChangedEvent): void; } diff --git a/src/vs/workbench/api/common/extHostComments.ts b/src/vs/workbench/api/common/extHostComments.ts index b71643ba369..b4057f98164 100644 --- a/src/vs/workbench/api/common/extHostComments.ts +++ b/src/vs/workbench/api/common/extHostComments.ts @@ -253,13 +253,13 @@ export class ExtHostCommentThread implements vscode.CommentThread { return this._range; } - private _label: string; + private _label: string | undefined; - get label(): string { + get label(): string | undefined { return this._label; } - set label(label: string) { + set label(label: string | undefined) { this._label = label; this._onDidUpdateCommentThread.fire(); } diff --git a/src/vs/workbench/contrib/comments/browser/reactionsAction.ts b/src/vs/workbench/contrib/comments/browser/reactionsAction.ts index c14030dab80..a06e6ce4017 100644 --- a/src/vs/workbench/contrib/comments/browser/reactionsAction.ts +++ b/src/vs/workbench/contrib/comments/browser/reactionsAction.ts @@ -11,11 +11,10 @@ import { URI, UriComponents } from 'vs/base/common/uri'; export class ToggleReactionsAction extends Action { static readonly ID = 'toolbar.toggle.pickReactions'; - private _menuActions: IAction[]; + private _menuActions: IAction[] = []; private toggleDropdownMenu: () => void; constructor(toggleDropdownMenu: () => void, title?: string) { - title = title || nls.localize('pickReactions', "Pick Reactions..."); - super(ToggleReactionsAction.ID, title, 'toggle-reactions', true); + super(ToggleReactionsAction.ID, title || nls.localize('pickReactions', "Pick Reactions..."), 'toggle-reactions', true); this.toggleDropdownMenu = toggleDropdownMenu; } run(): Promise { From 6e498530cc95080ab907d5048b712ce5e8972425 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 5 Aug 2019 18:32:11 +0200 Subject: [PATCH 219/861] :up: native-is-elevated@0.3.0 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index cd2ed9a3334..8e938a9f02b 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "jschardet": "1.6.0", "keytar": "^4.11.0", "minimist": "1.2.0", - "native-is-elevated": "^0.2.1", + "native-is-elevated": "0.3.0", "native-keymap": "2.0.0", "native-watchdog": "1.0.0", "node-pty": "0.9.0-beta19", diff --git a/yarn.lock b/yarn.lock index 6697594e961..6267a879280 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5982,10 +5982,10 @@ napi-build-utils@^1.0.1: resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.1.tgz#1381a0f92c39d66bf19852e7873432fc2123e508" integrity sha512-boQj1WFgQH3v4clhu3mTNfP+vOBxorDlE8EKiMjUlLG3C4qAESnn9AxIOkFgTR2c9LtzNjPrjS60cT27ZKBhaA== -native-is-elevated@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/native-is-elevated/-/native-is-elevated-0.2.1.tgz#70a2123a8575b9f624a3ef465d98cb74ae017385" - integrity sha1-cKISOoV1ufYko+9GXZjLdK4Bc4U= +native-is-elevated@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/native-is-elevated/-/native-is-elevated-0.3.0.tgz#6c5d8f57daeec129abd03b5606a55e56e4337423" + integrity sha512-QJgU7vaCZ199PSEC4LAmwtGfqwGaz8a51YDeze3DPiRzcOq25LIQpxCbBWunIu+csMMHFsDuyO2OVfeSD4ioHQ== native-keymap@2.0.0: version "2.0.0" From 77665ca7ef52c3259c7403611a513ccede13b248 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 5 Aug 2019 07:53:17 -0700 Subject: [PATCH 220/861] More strict prop init --- .../contrib/terminal/browser/terminalPanel.ts | 53 +++++++++---------- .../browser/terminalProcessManager.ts | 9 ++-- .../terminal/browser/terminalService.ts | 4 +- .../contrib/terminal/browser/terminalTab.ts | 21 ++++---- .../terminal/browser/terminalWidgetManager.ts | 2 +- .../terminal/common/terminalService.ts | 2 +- .../contrib/terminal/node/terminalProcess.ts | 4 +- 7 files changed, 47 insertions(+), 48 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts b/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts index c79e4eedcb0..cf725f2f8d0 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts @@ -29,14 +29,14 @@ const FIND_FOCUS_CLASS = 'find-focused'; export class TerminalPanel extends Panel { - private _actions: IAction[]; - private _copyContextMenuAction: IAction; - private _contextMenuActions: IAction[]; + private _actions: IAction[] | undefined; + private _copyContextMenuAction: IAction | undefined; + private _contextMenuActions: IAction[] | undefined; private _cancelContextMenu: boolean = false; - private _fontStyleElement: HTMLElement; - private _parentDomElement: HTMLElement; - private _terminalContainer: HTMLElement; - private _findWidget: TerminalFindWidget; + private _fontStyleElement: HTMLElement | undefined; + private _parentDomElement: HTMLElement | undefined; + private _terminalContainer: HTMLElement | undefined; + private _findWidget: TerminalFindWidget | undefined; constructor( @IConfigurationService private readonly _configurationService: IConfigurationService, @@ -61,14 +61,13 @@ export class TerminalPanel extends Panel { dom.addClass(this._terminalContainer, 'terminal-outer-container'); this._findWidget = this._instantiationService.createInstance(TerminalFindWidget, this._terminalService.getFindState()); - this._findWidget.focusTracker.onDidFocus(() => this._terminalContainer.classList.add(FIND_FOCUS_CLASS)); - this._findWidget.focusTracker.onDidBlur(() => this._terminalContainer.classList.remove(FIND_FOCUS_CLASS)); + this._findWidget.focusTracker.onDidFocus(() => this._terminalContainer!.classList.add(FIND_FOCUS_CLASS)); this._parentDomElement.appendChild(this._fontStyleElement); this._parentDomElement.appendChild(this._terminalContainer); this._parentDomElement.appendChild(this._findWidget.getDomNode()); - this._attachEventListeners(); + this._attachEventListeners(this._parentDomElement, this._terminalContainer); this._terminalService.setContainers(this.getContainer(), this._terminalContainer); @@ -137,7 +136,7 @@ export class TerminalPanel extends Panel { } private _getContextMenuActions(): IAction[] { - if (!this._contextMenuActions) { + if (!this._contextMenuActions || !this._copyContextMenuAction) { this._copyContextMenuAction = this._instantiationService.createInstance(CopyTerminalSelectionAction, CopyTerminalSelectionAction.ID, CopyTerminalSelectionAction.SHORT_LABEL); this._contextMenuActions = [ this._instantiationService.createInstance(CreateNewTerminalAction, CreateNewTerminalAction.ID, CreateNewTerminalAction.SHORT_LABEL), @@ -179,31 +178,31 @@ export class TerminalPanel extends Panel { public focusFindWidget() { const activeInstance = this._terminalService.getActiveInstance(); if (activeInstance && activeInstance.hasSelection() && activeInstance.selection!.indexOf('\n') === -1) { - this._findWidget.reveal(activeInstance.selection); + this._findWidget!.reveal(activeInstance.selection); } else { - this._findWidget.reveal(); + this._findWidget!.reveal(); } } public hideFindWidget() { - this._findWidget.hide(); + this._findWidget!.hide(); } public showFindWidget() { const activeInstance = this._terminalService.getActiveInstance(); if (activeInstance && activeInstance.hasSelection() && activeInstance.selection!.indexOf('\n') === -1) { - this._findWidget.show(activeInstance.selection); + this._findWidget!.show(activeInstance.selection); } else { - this._findWidget.show(); + this._findWidget!.show(); } } public getFindWidget(): TerminalFindWidget { - return this._findWidget; + return this._findWidget!; } - private _attachEventListeners(): void { - this._register(dom.addDisposableListener(this._parentDomElement, 'mousedown', async (event: MouseEvent) => { + private _attachEventListeners(parentDomElement: HTMLElement, terminalContainer: HTMLElement): void { + this._register(dom.addDisposableListener(parentDomElement, 'mousedown', async (event: MouseEvent) => { if (this._terminalService.terminalInstances.length === 0) { return; } @@ -240,7 +239,7 @@ export class TerminalPanel extends Panel { } } })); - this._register(dom.addDisposableListener(this._parentDomElement, 'mouseup', async (event: MouseEvent) => { + this._register(dom.addDisposableListener(parentDomElement, 'mouseup', async (event: MouseEvent) => { if (this._configurationService.getValue('terminal.integrated.copyOnSelection')) { if (this._terminalService.terminalInstances.length === 0) { return; @@ -254,7 +253,7 @@ export class TerminalPanel extends Panel { } } })); - this._register(dom.addDisposableListener(this._parentDomElement, 'contextmenu', (event: MouseEvent) => { + this._register(dom.addDisposableListener(parentDomElement, 'contextmenu', (event: MouseEvent) => { if (!this._cancelContextMenu) { const standardEvent = new StandardMouseEvent(event); const anchor: { x: number, y: number } = { x: standardEvent.posx, y: standardEvent.posy }; @@ -269,19 +268,19 @@ export class TerminalPanel extends Panel { this._cancelContextMenu = false; })); this._register(dom.addDisposableListener(document, 'keydown', (event: KeyboardEvent) => { - this._terminalContainer.classList.toggle('alt-active', !!event.altKey); + terminalContainer.classList.toggle('alt-active', !!event.altKey); })); this._register(dom.addDisposableListener(document, 'keyup', (event: KeyboardEvent) => { - this._terminalContainer.classList.toggle('alt-active', !!event.altKey); + terminalContainer.classList.toggle('alt-active', !!event.altKey); })); - this._register(dom.addDisposableListener(this._parentDomElement, 'keyup', (event: KeyboardEvent) => { + this._register(dom.addDisposableListener(parentDomElement, 'keyup', (event: KeyboardEvent) => { if (event.keyCode === 27) { // Keep terminal open on escape event.stopPropagation(); } })); - this._register(dom.addDisposableListener(this._parentDomElement, dom.EventType.DROP, async (e: DragEvent) => { - if (e.target === this._parentDomElement || dom.isAncestor(e.target as HTMLElement, this._parentDomElement)) { + this._register(dom.addDisposableListener(parentDomElement, dom.EventType.DROP, async (e: DragEvent) => { + if (e.target === this._parentDomElement || dom.isAncestor(e.target as HTMLElement, parentDomElement)) { if (!e.dataTransfer) { return; } @@ -319,7 +318,7 @@ export class TerminalPanel extends Panel { } private _updateFont(): void { - if (this._terminalService.terminalInstances.length === 0) { + if (this._terminalService.terminalInstances.length === 0 || !this._parentDomElement) { return; } // TODO: Can we support ligatures? diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index 9684a8830f3..29e4aa6fbfc 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -54,9 +54,8 @@ export class TerminalProcessManager implements ITerminalProcessManager { private _processType: ProcessType = ProcessType.Process; private _preLaunchInputQueue: string[] = []; private _latency: number = -1; - private _latencyRequest: Promise; private _latencyLastMeasured: number = 0; - private _initialCwd: string; + private _initialCwd: string | undefined; private readonly _onProcessReady = new Emitter(); public get onProcessReady(): Event { return this._onProcessReady.event; } @@ -259,7 +258,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { } public getInitialCwd(): Promise { - return Promise.resolve(this._initialCwd); + return Promise.resolve(this._initialCwd ? this._initialCwd : ''); } public getCwd(): Promise { @@ -275,8 +274,8 @@ export class TerminalProcessManager implements ITerminalProcessManager { return Promise.resolve(0); } if (this._latencyLastMeasured === 0 || this._latencyLastMeasured + LATENCY_MEASURING_INTERVAL < Date.now()) { - this._latencyRequest = this._process.getLatency(); - this._latency = await this._latencyRequest; + const latencyRequest = this._process.getLatency(); + this._latency = await latencyRequest; this._latencyLastMeasured = Date.now(); } return Promise.resolve(this._latency); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 9ca71e3d27b..4f584f6d13a 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -137,7 +137,7 @@ export class TerminalService extends CommonTerminalService implements ITerminalS public setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void { this._configHelper.panelContainer = panelContainer; this._terminalContainer = terminalContainer; - this._terminalTabs.forEach(tab => tab.attachToElement(this._terminalContainer)); + this._terminalTabs.forEach(tab => tab.attachToElement(terminalContainer)); } public hidePanel(): void { @@ -146,4 +146,4 @@ export class TerminalService extends CommonTerminalService implements ITerminalS this._layoutService.setPanelHidden(true); } } -} \ No newline at end of file +} diff --git a/src/vs/workbench/contrib/terminal/browser/terminalTab.ts b/src/vs/workbench/contrib/terminal/browser/terminalTab.ts index e00296853ff..aefb287ded3 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalTab.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalTab.ts @@ -18,7 +18,7 @@ const TERMINAL_MIN_USEFUL_SIZE = 250; class SplitPaneContainer extends Disposable { private _height: number; private _width: number; - private _splitView: SplitView; + private _splitView!: SplitView; private readonly _splitViewDisposables = this._register(new DisposableStore()); private _children: SplitPane[] = []; @@ -177,7 +177,6 @@ class SplitPane implements IView { public maximumSize: number = Number.MAX_VALUE; public orientation: Orientation | undefined; - protected _size: number; private _onDidChange: Event = Event.None; public get onDidChange(): Event { return this._onDidChange; } @@ -195,15 +194,14 @@ class SplitPane implements IView { public layout(size: number): void { // Only layout when both sizes are known - this._size = size; - if (!this._size || !this.orthogonalSize) { + if (!size || !this.orthogonalSize) { return; } if (this.orientation === Orientation.VERTICAL) { - this.instance.layout({ width: this.orthogonalSize, height: this._size }); + this.instance.layout({ width: this.orthogonalSize, height: size }); } else { - this.instance.layout({ width: this._size, height: this.orthogonalSize }); + this.instance.layout({ width: size, height: this.orthogonalSize }); } } @@ -215,7 +213,7 @@ class SplitPane implements IView { export class TerminalTab extends Disposable implements ITerminalTab { private _terminalInstances: ITerminalInstance[] = []; private _splitPaneContainer: SplitPaneContainer | undefined; - private _tabElement: HTMLElement | null; + private _tabElement: HTMLElement | undefined; private _panelPosition: Position = Position.BOTTOM; private _activeInstanceIndex: number; @@ -230,7 +228,7 @@ export class TerminalTab extends Disposable implements ITerminalTab { constructor( terminalFocusContextKey: IContextKey, configHelper: ITerminalConfigHelper, - private _container: HTMLElement, + private _container: HTMLElement | undefined, shellLaunchConfigOrInstance: IShellLaunchConfig | ITerminalInstance, @ITerminalService private readonly _terminalService: ITerminalService, @IWorkbenchLayoutService private readonly _layoutService: IWorkbenchLayoutService, @@ -259,9 +257,9 @@ export class TerminalTab extends Disposable implements ITerminalTab { public dispose(): void { super.dispose(); - if (this._tabElement) { + if (this._container && this._tabElement) { this._container.removeChild(this._tabElement); - this._tabElement = null; + this._tabElement = undefined; } this._terminalInstances = []; this._onInstancesChanged.fire(); @@ -380,6 +378,9 @@ export class TerminalTab extends Disposable implements ITerminalTab { configHelper: ITerminalConfigHelper, shellLaunchConfig: IShellLaunchConfig ): ITerminalInstance | undefined { + if (!this._container) { + throw new Error('Cannot split terminal that has not been attached'); + } const newTerminalSize = ((this._panelPosition === Position.BOTTOM ? this._container.clientWidth : this._container.clientHeight) / (this._terminalInstances.length + 1)); if (newTerminalSize < TERMINAL_MIN_USEFUL_SIZE) { return undefined; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalWidgetManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalWidgetManager.ts index 8c9efe0314f..ce9ed466a98 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalWidgetManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalWidgetManager.ts @@ -11,7 +11,7 @@ export class TerminalWidgetManager implements IDisposable { private _container: HTMLElement | undefined; private _xtermViewport: HTMLElement | undefined; - private _messageWidget: MessageWidget; + private _messageWidget: MessageWidget | undefined; private readonly _messageListeners = new DisposableStore(); constructor( diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index 8bf6a5bfa5b..e88af8ffc03 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -35,7 +35,7 @@ export abstract class TerminalService implements ITerminalService { protected _isShuttingDown: boolean; protected _terminalFocusContextKey: IContextKey; protected _findWidgetVisible: IContextKey; - protected _terminalContainer: HTMLElement; + protected _terminalContainer: HTMLElement | undefined; protected _terminalTabs: ITerminalTab[] = []; protected _backgroundedTerminalInstances: ITerminalInstance[] = []; protected get _terminalInstances(): ITerminalInstance[] { diff --git a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts index 8b61a562d8d..74d4598d6f5 100644 --- a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts +++ b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts @@ -23,7 +23,7 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable { private _closeTimeout: any; private _ptyProcess: pty.IPty | undefined; private _currentTitle: string = ''; - private _processStartupComplete: Promise; + private _processStartupComplete: Promise | undefined; private _isDisposed: boolean = false; private _titleInterval: NodeJS.Timer | null = null; private _initialCwd: string; @@ -172,7 +172,7 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable { private _kill(): void { // Wait to kill to process until the start up code has run. This prevents us from firing a process exit before a // process start. - this._processStartupComplete.then(() => { + this._processStartupComplete!.then(() => { if (this._isDisposed) { return; } From 9e8b6fb9063e8e812462ade345566cd8a456ebe5 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 5 Aug 2019 09:59:25 -0700 Subject: [PATCH 221/861] Make terminalInstance._xterm | undefined --- .../terminal/browser/terminalInstance.ts | 192 +++++++++++------- .../terminal/browser/terminalLinkHandler.ts | 4 +- 2 files changed, 118 insertions(+), 78 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index a645388dfe4..e8cb9f09efe 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -181,9 +181,9 @@ export class TerminalInstance implements ITerminalInstance { private _isVisible: boolean; private _isDisposed: boolean; private _skipTerminalCommands: string[]; - private _title: string; - private _wrapperElement: HTMLDivElement; - private _xterm: XTermTerminal; + private _title: string = ''; + private _wrapperElement: HTMLDivElement | undefined; + private _xterm: XTermTerminal | undefined; private _xtermSearch: SearchAddon | undefined; private _xtermElement: HTMLDivElement; private _terminalHasTextContextKey: IContextKey; @@ -192,7 +192,7 @@ export class TerminalInstance implements ITerminalInstance { private _rows: number; private _dimensionsOverride: ITerminalDimensions | undefined; private _windowsShellHelper: IWindowsShellHelper | undefined; - private _xtermReadyPromise: Promise; + private _xtermReadyPromise: Promise; private _titleReadyPromise: Promise; private _titleReadyComplete: (title: string) => any; @@ -455,11 +455,11 @@ export class TerminalInstance implements ITerminalInstance { /** * Create xterm.js instance and attach data listeners. */ - protected async _createXterm(): Promise { + protected async _createXterm(): Promise { const Terminal = await this._getXtermConstructor(); const font = this._configHelper.getFont(undefined, true); const config = this._configHelper.config; - this._xterm = new Terminal({ + const xterm = new Terminal({ scrollback: config.scrollback, theme: this._getXtermTheme(), drawBoldTextInBrightColors: config.drawBoldTextInBrightColors, @@ -476,10 +476,11 @@ export class TerminalInstance implements ITerminalInstance { // TODO: Guess whether to use canvas or dom better rendererType: config.rendererType === 'auto' ? 'canvas' : config.rendererType }); + this._xterm = xterm; this.updateAccessibilitySupport(); this._terminalInstanceService.getXtermSearchConstructor().then(Addon => { this._xtermSearch = new Addon(); - this._xterm.loadAddon(this._xtermSearch); + xterm.loadAddon(this._xtermSearch); }); if (this._shellLaunchConfig.initialText) { this._xterm.writeln(this._shellLaunchConfig.initialText); @@ -501,11 +502,11 @@ export class TerminalInstance implements ITerminalInstance { return; } if (this._processManager.os === platform.OperatingSystem.Windows) { - this._xterm.setOption('windowsMode', true); + xterm.setOption('windowsMode', true); // Force line data to be sent when the cursor is moved, the main purpose for // this is because ConPTY will often not do a line feed but instead move the // cursor, in which case we still want to send the current line's data to tasks. - this._xterm.addCsiHandler('H', () => { + xterm.addCsiHandler('H', () => { this._onCursorMove(); return false; }); @@ -522,7 +523,9 @@ export class TerminalInstance implements ITerminalInstance { } this._commandTracker = new TerminalCommandTracker(this._xterm); - this._disposables.add(this._themeService.onThemeChange(theme => this._updateTheme(theme))); + this._disposables.add(this._themeService.onThemeChange(theme => this._updateTheme(xterm, theme))); + + return xterm; } private _isScreenReaderOptimized(): boolean { @@ -562,7 +565,7 @@ export class TerminalInstance implements ITerminalInstance { } public _attachToElement(container: HTMLElement): void { - this._xtermReadyPromise.then(() => { + this._xtermReadyPromise.then(xterm => { if (this._wrapperElement) { throw new Error('The terminal instance has already been attached to a container'); } @@ -575,9 +578,9 @@ export class TerminalInstance implements ITerminalInstance { // Attach the xterm object to the DOM, exposing it to the smoke tests (this._wrapperElement).xterm = this._xterm; - this._xterm.open(this._xtermElement); - this._xterm.textarea.addEventListener('focus', () => this._onFocus.fire(this)); - this._xterm.attachCustomKeyEventHandler((event: KeyboardEvent): boolean => { + xterm.open(this._xtermElement); + xterm.textarea.addEventListener('focus', () => this._onFocus.fire(this)); + xterm.attachCustomKeyEventHandler((event: KeyboardEvent): boolean => { // Disable all input if the terminal is exiting if (this._isExiting) { return false; @@ -604,7 +607,7 @@ export class TerminalInstance implements ITerminalInstance { return true; }); - this._disposables.add(dom.addDisposableListener(this._xterm.element, 'mousedown', () => { + this._disposables.add(dom.addDisposableListener(xterm.element, 'mousedown', () => { // We need to listen to the mouseup event on the document since the user may release // the mouse button anywhere outside of _xterm.element. const listener = dom.addDisposableListener(document, 'mouseup', () => { @@ -616,13 +619,13 @@ export class TerminalInstance implements ITerminalInstance { })); // xterm.js currently drops selection on keyup as we need to handle this case. - this._disposables.add(dom.addDisposableListener(this._xterm.element, 'keyup', () => { + this._disposables.add(dom.addDisposableListener(xterm.element, 'keyup', () => { // Wait until keyup has propagated through the DOM before evaluating // the new selection state. setTimeout(() => this._refreshSelectionContextKey(), 0); })); - const xtermHelper: HTMLElement = this._xterm.element.querySelector('.xterm-helpers'); + const xtermHelper: HTMLElement = xterm.element.querySelector('.xterm-helpers'); const focusTrap: HTMLElement = document.createElement('div'); focusTrap.setAttribute('tabindex', '0'); dom.addClass(focusTrap, 'focus-trap'); @@ -634,20 +637,20 @@ export class TerminalInstance implements ITerminalInstance { const hidePanelElement = currentElement.querySelector('.hide-panel-action'); hidePanelElement.focus(); })); - xtermHelper.insertBefore(focusTrap, this._xterm.textarea); + xtermHelper.insertBefore(focusTrap, xterm.textarea); - this._disposables.add(dom.addDisposableListener(this._xterm.textarea, 'focus', () => { + this._disposables.add(dom.addDisposableListener(xterm.textarea, 'focus', () => { this._terminalFocusContextKey.set(true); this._onFocused.fire(this); })); - this._disposables.add(dom.addDisposableListener(this._xterm.textarea, 'blur', () => { + this._disposables.add(dom.addDisposableListener(xterm.textarea, 'blur', () => { this._terminalFocusContextKey.reset(); this._refreshSelectionContextKey(); })); - this._disposables.add(dom.addDisposableListener(this._xterm.element, 'focus', () => { + this._disposables.add(dom.addDisposableListener(xterm.element, 'focus', () => { this._terminalFocusContextKey.set(true); })); - this._disposables.add(dom.addDisposableListener(this._xterm.element, 'blur', () => { + this._disposables.add(dom.addDisposableListener(xterm.element, 'blur', () => { this._terminalFocusContextKey.reset(); this._refreshSelectionContextKey(); })); @@ -672,8 +675,8 @@ export class TerminalInstance implements ITerminalInstance { // If IShellLaunchConfig.waitOnExit was true and the process finished before the terminal // panel was initialized. - if (this._xterm.getOption('disableStdin')) { - this._attachPressAnyKeyToCloseListener(); + if (xterm.getOption('disableStdin')) { + this._attachPressAnyKeyToCloseListener(xterm); } const neverMeasureRenderTime = this._storageService.getBoolean(NEVER_MEASURE_RENDER_TIME_STORAGE_KEY, StorageScope.GLOBAL, false); @@ -683,9 +686,10 @@ export class TerminalInstance implements ITerminalInstance { }); } - private _measureRenderTime(): void { + private async _measureRenderTime(): Promise { + const xterm = await this._xtermReadyPromise; const frameTimes: number[] = []; - const textRenderLayer = this._xterm._core._renderService._renderer._renderLayers[0]; + const textRenderLayer = xterm._core._renderService._renderer._renderLayers[0]; const originalOnGridChanged = textRenderLayer.onGridChanged; const evaluateCanvasRenderer = () => { @@ -734,30 +738,37 @@ export class TerminalInstance implements ITerminalInstance { } public deregisterLinkMatcher(linkMatcherId: number): void { - this._xterm.deregisterLinkMatcher(linkMatcherId); + this._xtermReadyPromise.then(xterm => xterm.deregisterLinkMatcher(linkMatcherId)); } public hasSelection(): boolean { - return this._xterm && this._xterm.hasSelection(); + return this._xterm ? this._xterm.hasSelection() : false; } public async copySelection(): Promise { + const xterm = await this._xtermReadyPromise; if (this.hasSelection()) { - await this._clipboardService.writeText(this._xterm.getSelection()); + await this._clipboardService.writeText(xterm.getSelection()); } else { this._notificationService.warn(nls.localize('terminal.integrated.copySelection.noSelection', 'The terminal has no selection to copy')); } } public get selection(): string | undefined { - return this.hasSelection() ? this._xterm.getSelection() : undefined; + return this._xterm && this.hasSelection() ? this._xterm.getSelection() : undefined; } public clearSelection(): void { + if (!this._xterm) { + return; + } this._xterm.clearSelection(); } public selectAll(): void { + if (!this._xterm) { + return; + } // Focus here to ensure the terminal context key is set this._xterm.focus(); this._xterm.selectAll(); @@ -778,6 +789,9 @@ export class TerminalInstance implements ITerminalInstance { } public notifyFindWidgetFocusChanged(isFocused: boolean): void { + if (!this._xterm) { + return; + } const terminalFocused = !isFocused && (document.activeElement === this._xterm.textarea || document.activeElement === this._xterm.element); this._terminalFocusContextKey.set(terminalFocused); } @@ -840,12 +854,16 @@ export class TerminalInstance implements ITerminalInstance { } public forceRedraw(): void { + if (!this._xterm) { + return; + } if (this._configHelper.config.experimentalRefreshOnResume) { if (this._xterm.getOption('rendererType') !== 'dom') { this._xterm.setOption('rendererType', 'dom'); // Do this asynchronously to clear our the texture atlas as all terminals will not // be using canvas - setTimeout(() => this._xterm.setOption('rendererType', 'canvas'), 0); + const xterm = this._xterm; + setTimeout(() => xterm.setOption('rendererType', 'canvas'), 0); } } this._xterm.refresh(0, this._xterm.rows - 1); @@ -870,6 +888,9 @@ export class TerminalInstance implements ITerminalInstance { } public async paste(): Promise { + if (!this._xterm) { + return; + } this.focus(); this._xterm._core._coreService.triggerDataEvent(await this._clipboardService.readText(), true); } @@ -936,31 +957,45 @@ export class TerminalInstance implements ITerminalInstance { } public scrollDownLine(): void { - this._xterm.scrollLines(1); + if (this._xterm) { + this._xterm.scrollLines(1); + } } public scrollDownPage(): void { - this._xterm.scrollPages(1); + if (this._xterm) { + this._xterm.scrollPages(1); + } } public scrollToBottom(): void { - this._xterm.scrollToBottom(); + if (this._xterm) { + this._xterm.scrollToBottom(); + } } public scrollUpLine(): void { - this._xterm.scrollLines(-1); + if (this._xterm) { + this._xterm.scrollLines(-1); + } } public scrollUpPage(): void { - this._xterm.scrollPages(-1); + if (this._xterm) { + this._xterm.scrollPages(-1); + } } public scrollToTop(): void { - this._xterm.scrollToTop(); + if (this._xterm) { + this._xterm.scrollToTop(); + } } public clear(): void { - this._xterm.clear(); + if (this._xterm) { + this._xterm.clear(); + } } private _refreshSelectionContextKey() { @@ -990,9 +1025,9 @@ export class TerminalInstance implements ITerminalInstance { if (this._processManager!.remoteAuthority) { return; } - this._xtermReadyPromise.then(() => { + this._xtermReadyPromise.then(xterm => { if (!this._isDisposed && this._processManager && this._processManager.shellProcessId) { - this._windowsShellHelper = this._terminalInstanceService.createWindowsShellHelper(this._processManager.shellProcessId, this, this._xterm); + this._windowsShellHelper = this._terminalInstanceService.createWindowsShellHelper(this._processManager.shellProcessId, this, xterm); } }); }); @@ -1066,20 +1101,22 @@ export class TerminalInstance implements ITerminalInstance { // Only trigger wait on exit when the exit was *not* triggered by the // user (via the `workbench.action.terminal.kill` command). if (this._shellLaunchConfig.waitOnExit && (!this._processManager || this._processManager.processState !== ProcessState.KILLED_BY_USER)) { - if (exitCodeMessage) { - this._xterm.writeln(exitCodeMessage); - } - if (typeof this._shellLaunchConfig.waitOnExit === 'string') { - let message = this._shellLaunchConfig.waitOnExit; - // Bold the message and add an extra new line to make it stand out from the rest of the output - message = `\r\n\x1b[1m${message}\x1b[0m`; - this._xterm.writeln(message); - } - // Disable all input if the terminal is exiting and listen for next keypress - this._xterm.setOption('disableStdin', true); - if (this._xterm.textarea) { - this._attachPressAnyKeyToCloseListener(); - } + this._xtermReadyPromise.then(xterm => { + if (exitCodeMessage) { + xterm.writeln(exitCodeMessage); + } + if (typeof this._shellLaunchConfig.waitOnExit === 'string') { + let message = this._shellLaunchConfig.waitOnExit; + // Bold the message and add an extra new line to make it stand out from the rest of the output + message = `\r\n\x1b[1m${message}\x1b[0m`; + xterm.writeln(message); + } + // Disable all input if the terminal is exiting and listen for next keypress + xterm.setOption('disableStdin', true); + if (xterm.textarea) { + this._attachPressAnyKeyToCloseListener(xterm); + } + }); } else { this.dispose(); if (exitCodeMessage) { @@ -1098,9 +1135,9 @@ export class TerminalInstance implements ITerminalInstance { this._onExit.fire(exitCode || 0); } - private _attachPressAnyKeyToCloseListener() { + private _attachPressAnyKeyToCloseListener(xterm: XTermTerminal) { if (!this._pressAnyKeyToCloseListener) { - this._pressAnyKeyToCloseListener = dom.addDisposableListener(this._xterm.textarea, 'keypress', (event: KeyboardEvent) => { + this._pressAnyKeyToCloseListener = dom.addDisposableListener(xterm.textarea, 'keypress', (event: KeyboardEvent) => { if (this._pressAnyKeyToCloseListener) { this._pressAnyKeyToCloseListener.dispose(); this._pressAnyKeyToCloseListener = undefined; @@ -1124,19 +1161,20 @@ export class TerminalInstance implements ITerminalInstance { this._processManager = undefined; } - // Ensure new processes' output starts at start of new line - this._xterm.write('\n\x1b[G'); + if (this._xterm) { + // Ensure new processes' output starts at start of new line + this._xterm.write('\n\x1b[G'); - // Print initialText if specified - if (shell.initialText) { - this._xterm.writeln(shell.initialText); - } + // Print initialText if specified + if (shell.initialText) { + this._xterm.writeln(shell.initialText); + } - const oldTitle = this._title; - // Clean up waitOnExit state - if (this._isExiting && this._shellLaunchConfig.waitOnExit) { - this._xterm.setOption('disableStdin', false); - this._isExiting = false; + // Clean up waitOnExit state + if (this._isExiting && this._shellLaunchConfig.waitOnExit) { + this._xterm.setOption('disableStdin', false); + this._isExiting = false; + } } // Set the new shell launch config @@ -1144,6 +1182,7 @@ export class TerminalInstance implements ITerminalInstance { // Launch the process unless this is only a renderer. // In the renderer only cases, we still need to set the title correctly. + const oldTitle = this._title; if (!this._shellLaunchConfig.isRendererOnly) { this._createProcess(); } else if (this._shellLaunchConfig.name) { @@ -1171,7 +1210,7 @@ export class TerminalInstance implements ITerminalInstance { } private _onLineFeed(): void { - const buffer = this._xterm.buffer; + const buffer = this._xterm!.buffer; const newLine = buffer.getLine(buffer.baseY + buffer.cursorY); if (newLine && !newLine.isWrapped) { this._sendLineData(buffer, buffer.baseY + buffer.cursorY - 1); @@ -1179,7 +1218,7 @@ export class TerminalInstance implements ITerminalInstance { } private _onCursorMove(): void { - const buffer = this._xterm.buffer; + const buffer = this._xterm!.buffer; this._sendLineData(buffer, buffer.baseY + buffer.cursorY); } @@ -1234,14 +1273,14 @@ export class TerminalInstance implements ITerminalInstance { const isEnabled = this._isScreenReaderOptimized(); if (isEnabled) { this._navigationModeAddon = new NavigationModeAddon(this._terminalA11yTreeFocusContextKey); - this._xterm.loadAddon(this._navigationModeAddon); + this._xterm!.loadAddon(this._navigationModeAddon); } else { if (this._navigationModeAddon) { this._navigationModeAddon.dispose(); this._navigationModeAddon = undefined; } } - this._xterm.setOption('screenReaderMode', isEnabled); + this._xterm!.setOption('screenReaderMode', isEnabled); } private _setCursorBlink(blink: boolean): void { @@ -1440,13 +1479,14 @@ export class TerminalInstance implements ITerminalInstance { }; } - private _updateTheme(theme?: ITheme): void { - this._xterm.setOption('theme', this._getXtermTheme(theme)); + private _updateTheme(xterm: XTermTerminal, theme?: ITheme): void { + xterm.setOption('theme', this._getXtermTheme(theme)); } - public toggleEscapeSequenceLogging(): void { - const isDebug = this._xterm.getOption('logLevel') === 'debug'; - this._xterm.setOption('logLevel', isDebug ? 'info' : 'debug'); + public async toggleEscapeSequenceLogging(): Promise { + const xterm = await this._xtermReadyPromise; + const isDebug = xterm.getOption('logLevel') === 'debug'; + xterm.setOption('logLevel', isDebug ? 'info' : 'debug'); } public getInitialCwd(): Promise { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts b/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts index 1313dabefa6..938ab02e434 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts @@ -68,8 +68,8 @@ interface IPath { export class TerminalLinkHandler { private readonly _hoverDisposables = new DisposableStore(); private _mouseMoveDisposable: IDisposable; - private _widgetManager: TerminalWidgetManager; - private _processCwd: string; + private _widgetManager: TerminalWidgetManager | undefined; + private _processCwd: string | undefined; private _gitDiffPreImagePattern: RegExp; private _gitDiffPostImagePattern: RegExp; private readonly _tooltipCallback: (event: MouseEvent, uri: string) => boolean | void; From 1155cdf6b321d20efb6069075cc60e11c20fff86 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Mon, 5 Aug 2019 10:35:36 -0700 Subject: [PATCH 222/861] Fix #62143. Indentation guess may not be too eager with alignment. --- .../editor/common/model/indentationGuesser.ts | 15 ++++++- .../test/common/model/textModel.test.ts | 40 +++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/common/model/indentationGuesser.ts b/src/vs/editor/common/model/indentationGuesser.ts index 709e6ddd741..b1790f97bdb 100644 --- a/src/vs/editor/common/model/indentationGuesser.ts +++ b/src/vs/editor/common/model/indentationGuesser.ts @@ -158,8 +158,19 @@ export function guessIndentation(source: ITextBuffer, defaultTabSize: number, de spacesDiff(previousLineText, previousLineIndentation, currentLineText, currentLineIndentation, tmp); if (tmp.looksLikeAlignment) { - // skip this line entirely - continue; + // if defaultInsertSpaces === true && the spaces count == tabSize, we may want to count it as valid indentation + // + // - item1 + // - item2 + // + // otherwise skip this line entirely + // + // const a = 1, + // b = 2; + + if (!(defaultInsertSpaces && defaultTabSize === tmp.spacesDiff)) { + continue; + } } let currentSpacesDiff = tmp.spacesDiff; diff --git a/src/vs/editor/test/common/model/textModel.test.ts b/src/vs/editor/test/common/model/textModel.test.ts index 812edc45468..0771acc14ae 100644 --- a/src/vs/editor/test/common/model/textModel.test.ts +++ b/src/vs/editor/test/common/model/textModel.test.ts @@ -608,6 +608,46 @@ suite('Editor Model - TextModel', () => { ]); }); + test('issue #62143: Broken indentation detection', () => { + // works before the fix + assertGuess(true, 2, [ + 'x', + 'x', + ' x', + ' x' + ]); + + // works before the fix + assertGuess(true, 2, [ + 'x', + ' - item2', + ' - item3' + ]); + + // works before the fix + testGuessIndentation(true, 2, true, 2, [ + 'x x', + ' x', + ' x', + ]); + + // fails before the fix + // empty space inline breaks the indentation guess + testGuessIndentation(true, 2, true, 2, [ + 'x x', + ' x', + ' x', + ' x' + ]); + + testGuessIndentation(true, 2, true, 2, [ + '', + '- item1', + ' - item2', + ' - item3' + ]); + }); + test('validatePosition', () => { let m = TextModel.createFromString('line one\nline two'); From 9e68f21d4d2ae13fd17e048fdbfa3d66a965dce5 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 5 Aug 2019 20:10:58 +0200 Subject: [PATCH 223/861] debt - a bit of strictPropertyInitialization (#78168) --- src/vs/base/browser/ui/dropdown/dropdown.ts | 8 +- .../clipboard/browser/clipboardService.ts | 4 +- .../electron-main/historyMainService.ts | 4 +- .../electron-browser/mainProcessService.ts | 4 +- .../electron-browser/sharedProcessService.ts | 4 +- .../issue/electron-browser/issueService.ts | 4 +- .../launch/electron-main/launchService.ts | 4 +- .../lifecycle/browser/lifecycleService.ts | 4 +- .../lifecycle/common/lifecycleService.ts | 4 +- .../electron-browser/lifecycleService.ts | 2 +- .../lifecycle/electron-main/lifecycleMain.ts | 2 +- .../electron-browser/menubarService.ts | 2 +- .../product/browser/productService.ts | 4 +- .../platform/product/node/productService.ts | 4 +- src/vs/platform/sign/browser/signService.ts | 2 +- .../storage/browser/storageService.ts | 2 +- .../storage/node/storageMainService.ts | 2 +- .../platform/storage/node/storageService.ts | 2 +- .../update/electron-browser/updateService.ts | 2 +- src/vs/workbench/browser/layout.ts | 2 +- .../parts/activitybar/activitybarPart.ts | 4 +- .../browser/parts/editor/editorPart.ts | 2 +- .../browser/parts/panel/panelPart.ts | 2 +- .../browser/parts/quickinput/quickInput.ts | 2 +- .../parts/quickopen/quickOpenController.ts | 4 +- .../browser/parts/sidebar/sidebarPart.ts | 4 +- .../browser/parts/statusbar/statusbarPart.ts | 2 +- .../browser/parts/titlebar/titlebarPart.ts | 4 +- src/vs/workbench/browser/parts/views/views.ts | 2 +- src/vs/workbench/browser/web.main.ts | 12 ++- src/vs/workbench/browser/workbench.ts | 2 +- .../backup/common/backupModelTracker.ts | 10 +-- .../debug/browser/debugHelperService.ts | 4 +- .../debug/browser/statusbarColorProvider.ts | 2 +- .../browser/editors/fileEditorTracker.ts | 2 +- .../files/browser/editors/textFileEditor.ts | 2 +- .../contrib/files/common/dirtyFilesTracker.ts | 16 ++-- .../quickopen/browser/gotoSymbolHandler.ts | 2 +- .../contrib/search/browser/openFileHandler.ts | 6 +- .../search/browser/openSymbolHandler.ts | 2 +- src/vs/workbench/electron-browser/main.ts | 17 ++--- .../backup/common/backupFileService.ts | 18 ++--- .../services/editor/browser/editorService.ts | 8 +- .../editor/test/browser/editorService.test.ts | 4 +- .../environment/browser/environmentService.ts | 3 +- .../services/history/browser/history.ts | 8 +- .../mode/common/workbenchModeService.ts | 4 +- .../common/notificationService.ts | 4 +- .../progress/browser/editorProgressService.ts | 2 +- .../progress/browser/progressService.ts | 2 +- .../progress/test/progressIndicator.test.ts | 10 +-- .../common/textFileEditorModelManager.ts | 73 +++++++++---------- .../textfile/common/textFileService.ts | 12 +-- .../common/textResourcePropertiesService.ts | 4 +- .../services/textfile/common/textfiles.ts | 4 +- .../services/textfile/node/textFileService.ts | 4 +- .../textfile/test/textFileService.io.test.ts | 2 +- .../textfile/test/textFileService.test.ts | 2 +- .../untitled/common/untitledEditorService.ts | 4 +- .../workspaceEditingService.ts | 4 +- src/vs/workbench/test/browser/part.test.ts | 8 +- 61 files changed, 176 insertions(+), 173 deletions(-) diff --git a/src/vs/base/browser/ui/dropdown/dropdown.ts b/src/vs/base/browser/ui/dropdown/dropdown.ts index 1f9217cc9dd..7c984ea2163 100644 --- a/src/vs/base/browser/ui/dropdown/dropdown.ts +++ b/src/vs/base/browser/ui/dropdown/dropdown.ts @@ -29,7 +29,7 @@ export class BaseDropdown extends ActionRunner { private boxContainer?: HTMLElement; private _label?: HTMLElement; private contents?: HTMLElement; - private visible: boolean; + private visible: boolean | undefined; constructor(container: HTMLElement, options: IBaseDropdownOptions) { super(); @@ -109,7 +109,7 @@ export class BaseDropdown extends ActionRunner { } isVisible(): boolean { - return this.visible; + return !!this.visible; } protected onEvent(e: Event, activeElement: HTMLElement): void { @@ -272,7 +272,7 @@ export class DropdownMenu extends BaseDropdown { export class DropdownMenuActionViewItem extends BaseActionViewItem { private menuActionsOrProvider: any; - private dropdownMenu: DropdownMenu; + private dropdownMenu: DropdownMenu | undefined; private contextMenuProvider: IContextMenuProvider; private actionViewItemProvider?: IActionViewItemProvider; private keybindings?: (action: IAction) => ResolvedKeybinding | undefined; @@ -281,7 +281,7 @@ export class DropdownMenuActionViewItem extends BaseActionViewItem { constructor(action: IAction, menuActions: ReadonlyArray, contextMenuProvider: IContextMenuProvider, actionViewItemProvider: IActionViewItemProvider | undefined, actionRunner: IActionRunner, keybindings: ((action: IAction) => ResolvedKeybinding | undefined) | undefined, clazz: string | undefined, anchorAlignmentProvider?: () => AnchorAlignment); constructor(action: IAction, actionProvider: IActionProvider, contextMenuProvider: IContextMenuProvider, actionViewItemProvider: IActionViewItemProvider | undefined, actionRunner: IActionRunner, keybindings: ((action: IAction) => ResolvedKeybinding) | undefined, clazz: string | undefined, anchorAlignmentProvider?: () => AnchorAlignment); - constructor(action: IAction, menuActionsOrProvider: any, contextMenuProvider: IContextMenuProvider, actionViewItemProvider: IActionViewItemProvider | undefined, actionRunner: IActionRunner, keybindings: ((action: IAction) => ResolvedKeybinding | undefined) | undefined, clazz: string | undefined, anchorAlignmentProvider?: () => AnchorAlignment) { + constructor(action: IAction, menuActionsOrProvider: ReadonlyArray | IActionProvider, contextMenuProvider: IContextMenuProvider, actionViewItemProvider: IActionViewItemProvider | undefined, actionRunner: IActionRunner, keybindings: ((action: IAction) => ResolvedKeybinding | undefined) | undefined, clazz: string | undefined, anchorAlignmentProvider?: () => AnchorAlignment) { super(null, action); this.menuActionsOrProvider = menuActionsOrProvider; diff --git a/src/vs/platform/clipboard/browser/clipboardService.ts b/src/vs/platform/clipboard/browser/clipboardService.ts index 9502c4bdc97..8ea9e8e026d 100644 --- a/src/vs/platform/clipboard/browser/clipboardService.ts +++ b/src/vs/platform/clipboard/browser/clipboardService.ts @@ -10,7 +10,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio export class BrowserClipboardService implements IClipboardService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private _internalResourcesClipboard: URI[] | undefined; @@ -46,4 +46,4 @@ export class BrowserClipboardService implements IClipboardService { } } -registerSingleton(IClipboardService, BrowserClipboardService, true); \ No newline at end of file +registerSingleton(IClipboardService, BrowserClipboardService, true); diff --git a/src/vs/platform/history/electron-main/historyMainService.ts b/src/vs/platform/history/electron-main/historyMainService.ts index 6447b2c65e1..01e9cd3f4d8 100644 --- a/src/vs/platform/history/electron-main/historyMainService.ts +++ b/src/vs/platform/history/electron-main/historyMainService.ts @@ -40,7 +40,7 @@ export class HistoryMainService implements IHistoryMainService { private static readonly recentlyOpenedStorageKey = 'openedPathsList'; - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private _onRecentlyOpenedChange = new Emitter(); readonly onRecentlyOpenedChange: CommonEvent = this._onRecentlyOpenedChange.event; @@ -387,4 +387,4 @@ function indexOfFolder(arr: IRecent[], folderURI: ISingleFolderWorkspaceIdentifi function indexOfFile(arr: IRecentFile[], fileURI: URI): number { return arrays.firstIndex(arr, f => areResourcesEqual(f.fileUri, fileURI)); -} \ No newline at end of file +} diff --git a/src/vs/platform/ipc/electron-browser/mainProcessService.ts b/src/vs/platform/ipc/electron-browser/mainProcessService.ts index 31ac99261c6..e2f756cc803 100644 --- a/src/vs/platform/ipc/electron-browser/mainProcessService.ts +++ b/src/vs/platform/ipc/electron-browser/mainProcessService.ts @@ -21,7 +21,7 @@ export interface IMainProcessService { export class MainProcessService extends Disposable implements IMainProcessService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private mainProcessConnection: Client; @@ -40,4 +40,4 @@ export class MainProcessService extends Disposable implements IMainProcessServic registerChannel(channelName: string, channel: IServerChannel): void { this.mainProcessConnection.registerChannel(channelName, channel); } -} \ No newline at end of file +} diff --git a/src/vs/platform/ipc/electron-browser/sharedProcessService.ts b/src/vs/platform/ipc/electron-browser/sharedProcessService.ts index 399aa628cc6..f01e3f0b5de 100644 --- a/src/vs/platform/ipc/electron-browser/sharedProcessService.ts +++ b/src/vs/platform/ipc/electron-browser/sharedProcessService.ts @@ -23,7 +23,7 @@ export interface ISharedProcessService { export class SharedProcessService implements ISharedProcessService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private withSharedProcessConnection: Promise>; @@ -43,4 +43,4 @@ export class SharedProcessService implements ISharedProcessService { registerChannel(channelName: string, channel: IServerChannel): void { this.withSharedProcessConnection.then(connection => connection.registerChannel(channelName, channel)); } -} \ No newline at end of file +} diff --git a/src/vs/platform/issue/electron-browser/issueService.ts b/src/vs/platform/issue/electron-browser/issueService.ts index e9d287e7628..29ea55b6044 100644 --- a/src/vs/platform/issue/electron-browser/issueService.ts +++ b/src/vs/platform/issue/electron-browser/issueService.ts @@ -10,7 +10,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio export class IssueService implements IIssueService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private channel: IChannel; @@ -29,4 +29,4 @@ export class IssueService implements IIssueService { getSystemStatus(): Promise { return this.channel.call('getSystemStatus'); } -} \ No newline at end of file +} diff --git a/src/vs/platform/launch/electron-main/launchService.ts b/src/vs/platform/launch/electron-main/launchService.ts index 626a376d04b..95e56eae4da 100644 --- a/src/vs/platform/launch/electron-main/launchService.ts +++ b/src/vs/platform/launch/electron-main/launchService.ts @@ -94,7 +94,7 @@ export class LaunchChannel implements IServerChannel { export class LaunchChannelClient implements ILaunchService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; constructor(private channel: IChannel) { } @@ -121,7 +121,7 @@ export class LaunchChannelClient implements ILaunchService { export class LaunchService implements ILaunchService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; constructor( @ILogService private readonly logService: ILogService, diff --git a/src/vs/platform/lifecycle/browser/lifecycleService.ts b/src/vs/platform/lifecycle/browser/lifecycleService.ts index f5e4c4c3f3c..9a85a58262e 100644 --- a/src/vs/platform/lifecycle/browser/lifecycleService.ts +++ b/src/vs/platform/lifecycle/browser/lifecycleService.ts @@ -11,7 +11,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio export class BrowserLifecycleService extends AbstractLifecycleService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; constructor( @ILogService readonly logService: ILogService @@ -56,4 +56,4 @@ export class BrowserLifecycleService extends AbstractLifecycleService { return null; } -} \ No newline at end of file +} diff --git a/src/vs/platform/lifecycle/common/lifecycleService.ts b/src/vs/platform/lifecycle/common/lifecycleService.ts index 2225c04ca99..326a1b371b9 100644 --- a/src/vs/platform/lifecycle/common/lifecycleService.ts +++ b/src/vs/platform/lifecycle/common/lifecycleService.ts @@ -13,7 +13,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio export abstract class AbstractLifecycleService extends Disposable implements ILifecycleService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; protected readonly _onBeforeShutdown = this._register(new Emitter()); readonly onBeforeShutdown: Event = this._onBeforeShutdown.event; @@ -72,4 +72,4 @@ export abstract class AbstractLifecycleService extends Disposable implements ILi await barrier.wait(); } -} \ No newline at end of file +} diff --git a/src/vs/platform/lifecycle/electron-browser/lifecycleService.ts b/src/vs/platform/lifecycle/electron-browser/lifecycleService.ts index b4896df9ffe..7e4fd29a3a6 100644 --- a/src/vs/platform/lifecycle/electron-browser/lifecycleService.ts +++ b/src/vs/platform/lifecycle/electron-browser/lifecycleService.ts @@ -18,7 +18,7 @@ export class LifecycleService extends AbstractLifecycleService { private static readonly LAST_SHUTDOWN_REASON_KEY = 'lifecyle.lastShutdownReason'; - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private shutdownReason: ShutdownReason; diff --git a/src/vs/platform/lifecycle/electron-main/lifecycleMain.ts b/src/vs/platform/lifecycle/electron-main/lifecycleMain.ts index 058efdc2500..c44298bc61e 100644 --- a/src/vs/platform/lifecycle/electron-main/lifecycleMain.ts +++ b/src/vs/platform/lifecycle/electron-main/lifecycleMain.ts @@ -131,7 +131,7 @@ export const enum LifecycleMainPhase { export class LifecycleService extends Disposable implements ILifecycleService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private static readonly QUIT_FROM_RESTART_MARKER = 'quit.from.restart'; // use a marker to find out if the session was restarted diff --git a/src/vs/platform/menubar/electron-browser/menubarService.ts b/src/vs/platform/menubar/electron-browser/menubarService.ts index 7a288b3d348..794d65de6a7 100644 --- a/src/vs/platform/menubar/electron-browser/menubarService.ts +++ b/src/vs/platform/menubar/electron-browser/menubarService.ts @@ -10,7 +10,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio export class MenubarService implements IMenubarService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private channel: IChannel; diff --git a/src/vs/platform/product/browser/productService.ts b/src/vs/platform/product/browser/productService.ts index fbdf03fd3e4..34ad8bb76b5 100644 --- a/src/vs/platform/product/browser/productService.ts +++ b/src/vs/platform/product/browser/productService.ts @@ -15,7 +15,7 @@ export class ProductService implements IProductService { this.productConfiguration = element ? JSON.parse(element.getAttribute('data-settings')!) : null; } - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; get version(): string { return '1.35.0'; } @@ -46,4 +46,4 @@ export class ProductService implements IProductService { get extensionAllowedBadgeProviders(): readonly string[] | undefined { return this.productConfiguration ? this.productConfiguration.extensionAllowedBadgeProviders : undefined; } get aiConfig() { return this.productConfiguration ? this.productConfiguration.aiConfig : undefined; } -} \ No newline at end of file +} diff --git a/src/vs/platform/product/node/productService.ts b/src/vs/platform/product/node/productService.ts index 4b98ff65d0f..ba9c84a551d 100644 --- a/src/vs/platform/product/node/productService.ts +++ b/src/vs/platform/product/node/productService.ts @@ -10,7 +10,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio export class ProductService implements IProductService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; get version(): string { return pkg.version; } @@ -39,4 +39,4 @@ export class ProductService implements IProductService { get extensionKeywords(): { [extension: string]: readonly string[]; } | undefined { return product.extensionKeywords; } get extensionAllowedBadgeProviders(): readonly string[] | undefined { return product.extensionAllowedBadgeProviders; } -} \ No newline at end of file +} diff --git a/src/vs/platform/sign/browser/signService.ts b/src/vs/platform/sign/browser/signService.ts index d142447abbd..75951fab3dc 100644 --- a/src/vs/platform/sign/browser/signService.ts +++ b/src/vs/platform/sign/browser/signService.ts @@ -8,7 +8,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio export class SignService implements ISignService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private readonly _tkn: string | null; diff --git a/src/vs/platform/storage/browser/storageService.ts b/src/vs/platform/storage/browser/storageService.ts index 7e18f2ba09d..d7e7be28dd7 100644 --- a/src/vs/platform/storage/browser/storageService.ts +++ b/src/vs/platform/storage/browser/storageService.ts @@ -17,7 +17,7 @@ import { runWhenIdle } from 'vs/base/common/async'; export class BrowserStorageService extends Disposable implements IStorageService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private readonly _onDidChangeStorage: Emitter = this._register(new Emitter()); readonly onDidChangeStorage: Event = this._onDidChangeStorage.event; diff --git a/src/vs/platform/storage/node/storageMainService.ts b/src/vs/platform/storage/node/storageMainService.ts index 8c76782626a..d1f06b6ecb2 100644 --- a/src/vs/platform/storage/node/storageMainService.ts +++ b/src/vs/platform/storage/node/storageMainService.ts @@ -75,7 +75,7 @@ export interface IStorageChangeEvent { export class StorageMainService extends Disposable implements IStorageMainService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private static STORAGE_NAME = 'state.vscdb'; diff --git a/src/vs/platform/storage/node/storageService.ts b/src/vs/platform/storage/node/storageService.ts index caff11a3483..8598b895448 100644 --- a/src/vs/platform/storage/node/storageService.ts +++ b/src/vs/platform/storage/node/storageService.ts @@ -19,7 +19,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio export class StorageService extends Disposable implements IStorageService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private static WORKSPACE_STORAGE_NAME = 'state.vscdb'; private static WORKSPACE_META_NAME = 'workspace.json'; diff --git a/src/vs/platform/update/electron-browser/updateService.ts b/src/vs/platform/update/electron-browser/updateService.ts index 952c39cdbed..bd8fa6cc185 100644 --- a/src/vs/platform/update/electron-browser/updateService.ts +++ b/src/vs/platform/update/electron-browser/updateService.ts @@ -11,7 +11,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio export class UpdateService implements IUpdateService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private _onStateChange = new Emitter(); readonly onStateChange: Event = this._onStateChange.event; diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 54c94f6cdce..9ddefc89b44 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -62,7 +62,7 @@ enum Storage { export abstract class Layout extends Disposable implements IWorkbenchLayoutService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private readonly _onTitleBarVisibilityChange: Emitter = this._register(new Emitter()); readonly onTitleBarVisibilityChange: Event = this._onTitleBarVisibilityChange.event; diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts index c8ce2bc031f..f2d8631a6c3 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts @@ -48,7 +48,7 @@ interface ICachedViewlet { export class ActivitybarPart extends Part implements IActivityBarService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private static readonly ACTION_HEIGHT = 48; private static readonly PINNED_VIEWLETS = 'workbench.activity.pinnedViewlets'; @@ -508,4 +508,4 @@ export class ActivitybarPart extends Part implements IActivityBarService { } } -registerSingleton(IActivityBarService, ActivitybarPart); \ No newline at end of file +registerSingleton(IActivityBarService, ActivitybarPart); diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index 3d456d54ecc..0d0ac0c7231 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -82,7 +82,7 @@ class GridWidgetView implements IView { export class EditorPart extends Part implements IEditorGroupsService, IEditorGroupsAccessor { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private static readonly EDITOR_PART_UI_STATE_STORAGE_KEY = 'editorpart.state'; private static readonly EDITOR_PART_CENTERED_VIEW_STORAGE_KEY = 'editorpart.centeredview'; diff --git a/src/vs/workbench/browser/parts/panel/panelPart.ts b/src/vs/workbench/browser/parts/panel/panelPart.ts index 1189df45c45..b36f3294394 100644 --- a/src/vs/workbench/browser/parts/panel/panelPart.ts +++ b/src/vs/workbench/browser/parts/panel/panelPart.ts @@ -48,7 +48,7 @@ export class PanelPart extends CompositePart implements IPanelService { private static readonly PINNED_PANELS = 'workbench.panel.pinnedPanels'; private static readonly MIN_COMPOSITE_BAR_WIDTH = 50; - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; //#region IView diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.ts b/src/vs/workbench/browser/parts/quickinput/quickInput.ts index 08e3ff9a240..437bd45dfc6 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.ts @@ -880,7 +880,7 @@ class InputBox extends QuickInput implements IInputBox { export class QuickInputService extends Component implements IQuickInputService { - public _serviceBrand: ServiceIdentifier; + public _serviceBrand!: ServiceIdentifier; private static readonly ID = 'workbench.component.quickinput'; private static readonly MAX_WIDTH = 600; // Max total width of quick open widget diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index f31bd9d480e..feaa519ab1b 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -61,7 +61,7 @@ export class QuickOpenController extends Component implements IQuickOpenService private static readonly MAX_SHORT_RESPONSE_TIME = 500; private static readonly ID = 'workbench.component.quickopen'; - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private readonly _onShow: Emitter = this._register(new Emitter()); readonly onShow: Event = this._onShow.event; @@ -861,4 +861,4 @@ export class RemoveFromEditorHistoryAction extends Action { } } -registerSingleton(IQuickOpenService, QuickOpenController, true); \ No newline at end of file +registerSingleton(IQuickOpenService, QuickOpenController, true); diff --git a/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts b/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts index 8b50a07b662..b2a2c74ca93 100644 --- a/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts +++ b/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts @@ -34,7 +34,7 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export class SidebarPart extends CompositePart implements IViewletService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; static readonly activeViewletSettingsKey = 'workbench.sidebar.activeviewletid'; @@ -79,7 +79,7 @@ export class SidebarPart extends CompositePart implements IViewletServi private viewletRegistry: ViewletRegistry; private sideBarFocusContextKey: IContextKey; private activeViewletContextKey: IContextKey; - private blockOpeningViewlet: boolean; + private blockOpeningViewlet = false; constructor( @INotificationService notificationService: INotificationService, diff --git a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts index 089cbd3003e..6813f378920 100644 --- a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts +++ b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts @@ -323,7 +323,7 @@ class HideStatusbarEntryAction extends Action { export class StatusbarPart extends Part implements IStatusbarService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; //#region IView diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index f6b0a6849f9..66bf29cdd22 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -58,7 +58,7 @@ export class TitlebarPart extends Part implements ITitleService { private _onMenubarVisibilityChange = this._register(new Emitter()); readonly onMenubarVisibilityChange: Event = this._onMenubarVisibilityChange.event; - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private title: HTMLElement; private dragRegion: HTMLElement; @@ -639,4 +639,4 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { } }); -registerSingleton(ITitleService, TitlebarPart); \ No newline at end of file +registerSingleton(ITitleService, TitlebarPart); diff --git a/src/vs/workbench/browser/parts/views/views.ts b/src/vs/workbench/browser/parts/views/views.ts index 0cd0c4bb50b..2983c109250 100644 --- a/src/vs/workbench/browser/parts/views/views.ts +++ b/src/vs/workbench/browser/parts/views/views.ts @@ -626,7 +626,7 @@ export class PersistentContributableViewsModel extends ContributableViewsModel { export class ViewsService extends Disposable implements IViewsService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private readonly viewDescriptorCollections: Map; private readonly viewDisposable: Map; diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index ede771a03ee..875a529f4ed 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -46,8 +46,6 @@ import { InMemoryUserDataProvider } from 'vs/workbench/services/userData/common/ class CodeRendererMain extends Disposable { - private workbench: Workbench; - constructor( private readonly domElement: HTMLElement, private readonly configuration: IWorkbenchConstructionOptions @@ -65,24 +63,24 @@ class CodeRendererMain extends Disposable { this.restoreBaseTheme(); // Create Workbench - this.workbench = new Workbench( + const workbench = new Workbench( this.domElement, services.serviceCollection, services.logService ); // Layout - this._register(addDisposableListener(window, EventType.RESIZE, () => this.workbench.layout())); + this._register(addDisposableListener(window, EventType.RESIZE, () => workbench.layout())); // Workbench Lifecycle - this._register(this.workbench.onShutdown(() => this.dispose())); - this._register(this.workbench.onWillShutdown(() => { + this._register(workbench.onShutdown(() => this.dispose())); + this._register(workbench.onWillShutdown(() => { services.storageService.close(); this.saveBaseTheme(); })); // Startup - this.workbench.startup(); + workbench.startup(); } private restoreBaseTheme(): void { diff --git a/src/vs/workbench/browser/workbench.ts b/src/vs/workbench/browser/workbench.ts index aa5a918fc23..c5757dd5423 100644 --- a/src/vs/workbench/browser/workbench.ts +++ b/src/vs/workbench/browser/workbench.ts @@ -238,7 +238,7 @@ export class Workbench extends Layout { this._register(storageService.onWillSaveState(e => this.storeFontInfo(e, storageService))); } - private fontAliasing: 'default' | 'antialiased' | 'none' | 'auto'; + private fontAliasing: 'default' | 'antialiased' | 'none' | 'auto' | undefined; private setFontAliasing(configurationService: IConfigurationService) { const aliasing = configurationService.getValue<'default' | 'antialiased' | 'none' | 'auto'>('workbench.fontAliasing'); if (this.fontAliasing === aliasing) { diff --git a/src/vs/workbench/contrib/backup/common/backupModelTracker.ts b/src/vs/workbench/contrib/backup/common/backupModelTracker.ts index 854d26b935c..3ac6bb520d5 100644 --- a/src/vs/workbench/contrib/backup/common/backupModelTracker.ts +++ b/src/vs/workbench/contrib/backup/common/backupModelTracker.ts @@ -16,7 +16,7 @@ const AUTO_SAVE_AFTER_DELAY_DISABLED_TIME = CONTENT_CHANGE_EVENT_BUFFER_DELAY + export class BackupModelTracker extends Disposable implements IWorkbenchContribution { - private configuredAutoSaveAfterDelay: boolean; + private configuredAutoSaveAfterDelay = false; constructor( @IBackupFileService private readonly backupFileService: IBackupFileService, @@ -47,11 +47,11 @@ export class BackupModelTracker extends Disposable implements IWorkbenchContribu private onConfigurationChange(configuration: IFilesConfiguration): void { if (!configuration || !configuration.files) { this.configuredAutoSaveAfterDelay = false; + return; } - this.configuredAutoSaveAfterDelay = - (configuration.files.autoSave === AutoSaveConfiguration.AFTER_DELAY && - configuration.files.autoSaveDelay <= AUTO_SAVE_AFTER_DELAY_DISABLED_TIME); + + this.configuredAutoSaveAfterDelay = (configuration.files.autoSave === AutoSaveConfiguration.AFTER_DELAY && configuration.files.autoSaveDelay <= AUTO_SAVE_AFTER_DELAY_DISABLED_TIME); } private onTextFileModelChanged(event: TextFileModelChangeEvent): void { @@ -81,4 +81,4 @@ export class BackupModelTracker extends Disposable implements IWorkbenchContribu private discardBackup(resource: Uri): void { this.backupFileService.discardResourceBackup(resource); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/contrib/debug/browser/debugHelperService.ts b/src/vs/workbench/contrib/debug/browser/debugHelperService.ts index 37d46f87b45..a0616866a48 100644 --- a/src/vs/workbench/contrib/debug/browser/debugHelperService.ts +++ b/src/vs/workbench/contrib/debug/browser/debugHelperService.ts @@ -11,11 +11,11 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export class BrowserDebugHelperService implements IDebugHelperService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; createTelemetryService(configurationService: IConfigurationService, args: string[]): TelemetryService | undefined { return undefined; } } -registerSingleton(IDebugHelperService, BrowserDebugHelperService); \ No newline at end of file +registerSingleton(IDebugHelperService, BrowserDebugHelperService); diff --git a/src/vs/workbench/contrib/debug/browser/statusbarColorProvider.ts b/src/vs/workbench/contrib/debug/browser/statusbarColorProvider.ts index b2926f0be76..1819f552ec3 100644 --- a/src/vs/workbench/contrib/debug/browser/statusbarColorProvider.ts +++ b/src/vs/workbench/contrib/debug/browser/statusbarColorProvider.ts @@ -34,7 +34,7 @@ export const STATUS_BAR_DEBUGGING_BORDER = registerColor('statusBar.debuggingBor }, localize('statusBarDebuggingBorder', "Status bar border color separating to the sidebar and editor when a program is being debugged. The status bar is shown in the bottom of the window")); export class StatusBarColorProvider extends Themable implements IWorkbenchContribution { - private styleElement: HTMLStyleElement; + private styleElement: HTMLStyleElement | undefined; constructor( @IThemeService themeService: IThemeService, diff --git a/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts b/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts index c04d6638e87..76c18cda35c 100644 --- a/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts +++ b/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts @@ -30,7 +30,7 @@ import { withNullAsUndefined } from 'vs/base/common/types'; export class FileEditorTracker extends Disposable implements IWorkbenchContribution { - private closeOnFileDelete: boolean; + private closeOnFileDelete: boolean | undefined; private modelLoadQueue = new ResourceQueue(); private activeOutOfWorkspaceWatchers = new ResourceMap(); diff --git a/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts b/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts index 1021cb40834..c52724a2e64 100644 --- a/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts +++ b/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts @@ -40,7 +40,7 @@ export class TextFileEditor extends BaseTextEditor { static readonly ID = TEXT_FILE_EDITOR_ID; - private restoreViewState: boolean; + private restoreViewState: boolean | undefined; private readonly groupListener = this._register(new MutableDisposable()); constructor( diff --git a/src/vs/workbench/contrib/files/common/dirtyFilesTracker.ts b/src/vs/workbench/contrib/files/common/dirtyFilesTracker.ts index 49ef8b18505..20c46e13777 100644 --- a/src/vs/workbench/contrib/files/common/dirtyFilesTracker.ts +++ b/src/vs/workbench/contrib/files/common/dirtyFilesTracker.ts @@ -19,7 +19,7 @@ import { IEditorService, ACTIVE_GROUP } from 'vs/workbench/services/editor/commo export class DirtyFilesTracker extends Disposable implements IWorkbenchContribution { private isDocumentedEdited: boolean; - private lastDirtyCount: number; + private lastKnownDirtyCount: number | undefined; private readonly badgeHandle = this._register(new MutableDisposable()); constructor( @@ -50,6 +50,10 @@ export class DirtyFilesTracker extends Disposable implements IWorkbenchContribut this.lifecycleService.onShutdown(this.dispose, this); } + private get hasDirtyCount(): boolean { + return typeof this.lastKnownDirtyCount === 'number' && this.lastKnownDirtyCount > 0; + } + private onUntitledDidChangeDirty(resource: URI): void { const gotDirty = this.untitledEditorService.isDirty(resource); @@ -57,7 +61,7 @@ export class DirtyFilesTracker extends Disposable implements IWorkbenchContribut this.updateDocumentEdited(); } - if (gotDirty || this.lastDirtyCount > 0) { + if (gotDirty || this.hasDirtyCount) { this.updateActivityBadge(); } } @@ -100,7 +104,7 @@ export class DirtyFilesTracker extends Disposable implements IWorkbenchContribut this.updateDocumentEdited(); } - if (this.lastDirtyCount > 0) { + if (this.hasDirtyCount) { this.updateActivityBadge(); } } @@ -118,15 +122,17 @@ export class DirtyFilesTracker extends Disposable implements IWorkbenchContribut this.updateDocumentEdited(); } - if (this.lastDirtyCount > 0) { + if (this.hasDirtyCount) { this.updateActivityBadge(); } } private updateActivityBadge(): void { const dirtyCount = this.textFileService.getDirty().length; - this.lastDirtyCount = dirtyCount; + this.lastKnownDirtyCount = dirtyCount; + this.badgeHandle.clear(); + if (dirtyCount > 0) { this.badgeHandle.value = this.activityService.showActivity(VIEWLET_ID, new NumberBadge(dirtyCount, num => num === 1 ? nls.localize('dirtyFile', "1 unsaved file") : nls.localize('dirtyFiles', "{0} unsaved files", dirtyCount)), 'explorer-viewlet-label'); } diff --git a/src/vs/workbench/contrib/quickopen/browser/gotoSymbolHandler.ts b/src/vs/workbench/contrib/quickopen/browser/gotoSymbolHandler.ts index ed5f3203846..eef3c303d6c 100644 --- a/src/vs/workbench/contrib/quickopen/browser/gotoSymbolHandler.ts +++ b/src/vs/workbench/contrib/quickopen/browser/gotoSymbolHandler.ts @@ -366,7 +366,7 @@ export class GotoSymbolHandler extends QuickOpenHandler { static readonly ID = 'workbench.picker.filesymbols'; private rangeHighlightDecorationId?: IEditorLineDecoration; - private lastKnownEditorViewState: IEditorViewState | null; + private lastKnownEditorViewState: IEditorViewState | null = null; private cachedOutlineRequest?: Promise; private pendingOutlineRequest?: CancellationTokenSource; diff --git a/src/vs/workbench/contrib/search/browser/openFileHandler.ts b/src/vs/workbench/contrib/search/browser/openFileHandler.ts index 495381f6beb..39d390233dd 100644 --- a/src/vs/workbench/contrib/search/browser/openFileHandler.ts +++ b/src/vs/workbench/contrib/search/browser/openFileHandler.ts @@ -44,7 +44,7 @@ export class FileQuickOpenModel extends QuickOpenModel { } export class FileEntry extends EditorQuickOpenEntry { - private range: IRange | null; + private range: IRange | null = null; constructor( private resource: URI, @@ -112,7 +112,7 @@ export interface IOpenFileOptions { } export class OpenFileHandler extends QuickOpenHandler { - private options: IOpenFileOptions; + private options: IOpenFileOptions | undefined; private queryBuilder: QueryBuilder; private cacheState: CacheState; @@ -277,7 +277,7 @@ export class CacheState { private query: IFileQuery; private loadingPhase = LoadingPhase.Created; - private promise: Promise; + private promise: Promise | undefined; constructor(cacheQuery: (cacheKey: string) => IFileQuery, private doLoad: (query: IFileQuery) => Promise, private doDispose: (cacheKey: string) => Promise, private previous: CacheState | null) { this.query = cacheQuery(this._cacheKey); diff --git a/src/vs/workbench/contrib/search/browser/openSymbolHandler.ts b/src/vs/workbench/contrib/search/browser/openSymbolHandler.ts index 207662ab1ae..4a0a138d83b 100644 --- a/src/vs/workbench/contrib/search/browser/openSymbolHandler.ts +++ b/src/vs/workbench/contrib/search/browser/openSymbolHandler.ts @@ -27,7 +27,7 @@ import { Schemas } from 'vs/base/common/network'; import { IOpenerService } from 'vs/platform/opener/common/opener'; class SymbolEntry extends EditorQuickOpenEntry { - private bearingResolve: Promise; + private bearingResolve: Promise | undefined; constructor( private bearing: IWorkspaceSymbol, diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts index 61c920df264..82769037076 100644 --- a/src/vs/workbench/electron-browser/main.ts +++ b/src/vs/workbench/electron-browser/main.ts @@ -54,7 +54,6 @@ import { basename } from 'vs/base/common/resources'; class CodeRendererMain extends Disposable { - private workbench: Workbench; private readonly environmentService: WorkbenchEnvironmentService; constructor(configuration: IWindowConfiguration) { @@ -116,17 +115,17 @@ class CodeRendererMain extends Disposable { mark('willStartWorkbench'); // Create Workbench - this.workbench = new Workbench(document.body, services.serviceCollection, services.logService); + const workbench = new Workbench(document.body, services.serviceCollection, services.logService); // Layout - this._register(addDisposableListener(window, EventType.RESIZE, e => this.onWindowResize(e, true))); + this._register(addDisposableListener(window, EventType.RESIZE, e => this.onWindowResize(e, true, workbench))); // Workbench Lifecycle - this._register(this.workbench.onShutdown(() => this.dispose())); - this._register(this.workbench.onWillShutdown(event => event.join(services.storageService.close()))); + this._register(workbench.onShutdown(() => this.dispose())); + this._register(workbench.onWillShutdown(event => event.join(services.storageService.close()))); // Startup - const instantiationService = this.workbench.startup(); + const instantiationService = workbench.startup(); // Window this._register(instantiationService.createInstance(ElectronWindow)); @@ -145,7 +144,7 @@ class CodeRendererMain extends Disposable { services.logService.trace('workbench configuration', JSON.stringify(this.environmentService.configuration)); } - private onWindowResize(e: Event, retry: boolean): void { + private onWindowResize(e: Event, retry: boolean, workbench: Workbench): void { if (e.target === window) { if (window.document && window.document.body && window.document.body.clientWidth === 0) { // TODO@Ben this is an electron issue on macOS when simple fullscreen is enabled @@ -154,12 +153,12 @@ class CodeRendererMain extends Disposable { // call at the next animation frame once, in the hope that the dimensions are // proper then. if (retry) { - scheduleAtNextAnimationFrame(() => this.onWindowResize(e, false)); + scheduleAtNextAnimationFrame(() => this.onWindowResize(e, false, workbench)); } return; } - this.workbench.layout(); + workbench.layout(); } } diff --git a/src/vs/workbench/services/backup/common/backupFileService.ts b/src/vs/workbench/services/backup/common/backupFileService.ts index 3193fee9594..04394b745b0 100644 --- a/src/vs/workbench/services/backup/common/backupFileService.ts +++ b/src/vs/workbench/services/backup/common/backupFileService.ts @@ -106,7 +106,7 @@ export class BackupFilesModel implements IBackupFilesModel { export class BackupFileService implements IBackupFileService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private impl: IBackupFileService; @@ -177,15 +177,15 @@ class BackupFileServiceImpl implements IBackupFileService { private static readonly PREAMBLE_META_SEPARATOR = ' '; // using a character that is know to be escaped in a URI as separator private static readonly PREAMBLE_MAX_LENGTH = 10000; - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; - private backupWorkspacePath: URI; + private backupWorkspacePath!: URI; private isShuttingDown: boolean; private ioOperationQueues: ResourceQueue; // queue IO operations to ensure write order - private ready: Promise; - private model: IBackupFilesModel; + private ready!: Promise; + private model!: IBackupFilesModel; constructor( backupWorkspaceResource: URI, @@ -201,10 +201,10 @@ class BackupFileServiceImpl implements IBackupFileService { initialize(backupWorkspaceResource: URI): void { this.backupWorkspacePath = backupWorkspaceResource; - this.ready = this.init(); + this.ready = this.doInitialize(); } - private init(): Promise { + private doInitialize(): Promise { this.model = new BackupFilesModel(this.fileService); return this.model.resolve(this.backupWorkspacePath); @@ -380,7 +380,7 @@ class BackupFileServiceImpl implements IBackupFileService { export class InMemoryBackupFileService implements IBackupFileService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private backups: Map = new Map(); @@ -440,4 +440,4 @@ export class InMemoryBackupFileService implements IBackupFileService { toBackupResource(resource: URI): URI { return URI.file(join(resource.scheme, this.hashPath(resource))); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/services/editor/browser/editorService.ts b/src/vs/workbench/services/editor/browser/editorService.ts index 96f36a7053a..3bd6b03f963 100644 --- a/src/vs/workbench/services/editor/browser/editorService.ts +++ b/src/vs/workbench/services/editor/browser/editorService.ts @@ -33,7 +33,7 @@ type ICachedEditorInput = ResourceEditorInput | IFileEditorInput | DataUriEditor export class EditorService extends Disposable implements EditorServiceImpl { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private static CACHE: ResourceMap = new ResourceMap(); @@ -56,8 +56,8 @@ export class EditorService extends Disposable implements EditorServiceImpl { private fileInputFactory: IFileInputFactory; private openEditorHandlers: IOpenEditorOverrideHandler[] = []; - private lastActiveEditor: IEditorInput | null; - private lastActiveGroupId: GroupIdentifier; + private lastActiveEditor: IEditorInput | null = null; + private lastActiveGroupId: GroupIdentifier | null = null; constructor( @IEditorGroupsService private readonly editorGroupService: IEditorGroupsService, @@ -627,7 +627,7 @@ export interface IEditorOpenHandler { * method by providing a IEditorOpenHandler. */ export class DelegatingEditorService extends EditorService { - private editorOpenHandler: IEditorOpenHandler; + private editorOpenHandler: IEditorOpenHandler | undefined; constructor( @IEditorGroupsService editorGroupService: IEditorGroupsService, diff --git a/src/vs/workbench/services/editor/test/browser/editorService.test.ts b/src/vs/workbench/services/editor/test/browser/editorService.test.ts index 913a95d4aa1..712b8f922b4 100644 --- a/src/vs/workbench/services/editor/test/browser/editorService.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorService.test.ts @@ -49,8 +49,8 @@ export class TestEditorControl extends BaseEditor { } export class TestEditorInput extends EditorInput implements IFileEditorInput { - public gotDisposed: boolean; - private fails: boolean; + public gotDisposed = false; + private fails = false; constructor(private resource: URI) { super(); } getTypeId() { return 'testEditorInputForEditorService'; } diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts index 73e8b7c1d11..d6c619eae10 100644 --- a/src/vs/workbench/services/environment/browser/environmentService.ts +++ b/src/vs/workbench/services/environment/browser/environmentService.ts @@ -65,7 +65,8 @@ export interface IBrowserWindowConfiguration { } export class BrowserWorkbenchEnvironmentService implements IEnvironmentService { - _serviceBrand: ServiceIdentifier; + + _serviceBrand!: ServiceIdentifier; readonly configuration: IWindowConfiguration = new BrowserWindowConfiguration(); diff --git a/src/vs/workbench/services/history/browser/history.ts b/src/vs/workbench/services/history/browser/history.ts index 91e3136b50e..9ae41e07977 100644 --- a/src/vs/workbench/services/history/browser/history.ts +++ b/src/vs/workbench/services/history/browser/history.ts @@ -99,7 +99,7 @@ interface IRecentlyClosedFile { export class HistoryService extends Disposable implements IHistoryService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private static readonly STORAGE_KEY = 'history.entries'; private static readonly MAX_HISTORY_ITEMS = 200; @@ -115,10 +115,10 @@ export class HistoryService extends Disposable implements IHistoryService { private stack: IStackEntry[]; private index: number; private lastIndex: number; - private navigatingInStack: boolean; - private currentTextEditorState: TextEditorState | null; + private navigatingInStack = false; + private currentTextEditorState: TextEditorState | null = null; - private lastEditLocation: IStackEntry; + private lastEditLocation: IStackEntry | undefined; private history: Array; private recentlyClosedFiles: IRecentlyClosedFile[]; diff --git a/src/vs/workbench/services/mode/common/workbenchModeService.ts b/src/vs/workbench/services/mode/common/workbenchModeService.ts index 61d28dced34..0813403571a 100644 --- a/src/vs/workbench/services/mode/common/workbenchModeService.ts +++ b/src/vs/workbench/services/mode/common/workbenchModeService.ts @@ -94,7 +94,7 @@ export const languagesExtPoint: IExtensionPoint = export class WorkbenchModeServiceImpl extends ModeServiceImpl { private _configurationService: IConfigurationService; private _extensionService: IExtensionService; - private _onReadyPromise: Promise; + private _onReadyPromise: Promise | undefined; constructor( @IExtensionService extensionService: IExtensionService, @@ -232,4 +232,4 @@ function isValidLanguageExtensionPoint(value: IRawLanguageExtensionPoint, collec return true; } -registerSingleton(IModeService, WorkbenchModeServiceImpl); \ No newline at end of file +registerSingleton(IModeService, WorkbenchModeServiceImpl); diff --git a/src/vs/workbench/services/notification/common/notificationService.ts b/src/vs/workbench/services/notification/common/notificationService.ts index 78280e20a22..5db9ec24347 100644 --- a/src/vs/workbench/services/notification/common/notificationService.ts +++ b/src/vs/workbench/services/notification/common/notificationService.ts @@ -13,7 +13,7 @@ import { IAction } from 'vs/base/common/actions'; export class NotificationService extends Disposable implements INotificationService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private _model: INotificationsModel = this._register(new NotificationsModel()); @@ -108,4 +108,4 @@ export class NotificationService extends Disposable implements INotificationServ } } -registerSingleton(INotificationService, NotificationService, true); \ No newline at end of file +registerSingleton(INotificationService, NotificationService, true); diff --git a/src/vs/workbench/services/progress/browser/editorProgressService.ts b/src/vs/workbench/services/progress/browser/editorProgressService.ts index 7ea3daae18e..73ecabab26a 100644 --- a/src/vs/workbench/services/progress/browser/editorProgressService.ts +++ b/src/vs/workbench/services/progress/browser/editorProgressService.ts @@ -9,5 +9,5 @@ import { ProgressBarIndicator } from 'vs/workbench/services/progress/browser/pro export class EditorProgressService extends ProgressBarIndicator { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; } diff --git a/src/vs/workbench/services/progress/browser/progressService.ts b/src/vs/workbench/services/progress/browser/progressService.ts index d7bb38745a1..465920cd05d 100644 --- a/src/vs/workbench/services/progress/browser/progressService.ts +++ b/src/vs/workbench/services/progress/browser/progressService.ts @@ -28,7 +28,7 @@ import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; export class ProgressService extends Disposable implements IProgressService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private readonly stack: [IProgressOptions, Progress][] = []; private readonly globalStatusEntry = this._register(new MutableDisposable()); diff --git a/src/vs/workbench/services/progress/test/progressIndicator.test.ts b/src/vs/workbench/services/progress/test/progressIndicator.test.ts index a8d2b740d0b..b548da65af9 100644 --- a/src/vs/workbench/services/progress/test/progressIndicator.test.ts +++ b/src/vs/workbench/services/progress/test/progressIndicator.test.ts @@ -28,7 +28,7 @@ class TestViewlet implements IViewlet { } class TestCompositeScope extends CompositeScope { - isActive: boolean; + isActive: boolean = false; constructor(viewletService: IViewletService, panelService: IPanelService, scopeId: string) { super(viewletService, panelService, scopeId); @@ -39,10 +39,10 @@ class TestCompositeScope extends CompositeScope { } class TestProgressBar { - fTotal: number; - fWorked: number; - fInfinite: boolean; - fDone: boolean; + fTotal: number = 0; + fWorked: number = 0; + fInfinite: boolean = false; + fDone: boolean = false; constructor() { } diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts b/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts index 8afe2d46768..13f60f4629b 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts @@ -38,10 +38,41 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE private readonly _onModelOrphanedChanged: Emitter = this._register(new Emitter()); readonly onModelOrphanedChanged: Event = this._onModelOrphanedChanged.event; - private _onModelsDirtyEvent: Event; - private _onModelsSaveError: Event; - private _onModelsSaved: Event; - private _onModelsReverted: Event; + private _onModelsDirty!: Event; + get onModelsDirty(): Event { + if (!this._onModelsDirty) { + this._onModelsDirty = this.debounce(this.onModelDirty); + } + + return this._onModelsDirty; + } + + private _onModelsSaveError!: Event; + get onModelsSaveError(): Event { + if (!this._onModelsSaveError) { + this._onModelsSaveError = this.debounce(this.onModelSaveError); + } + + return this._onModelsSaveError; + } + + private _onModelsSaved!: Event; + get onModelsSaved(): Event { + if (!this._onModelsSaved) { + this._onModelsSaved = this.debounce(this.onModelSaved); + } + + return this._onModelsSaved; + } + + private _onModelsReverted!: Event; + get onModelsReverted(): Event { + if (!this._onModelsReverted) { + this._onModelsReverted = this.debounce(this.onModelReverted); + } + + return this._onModelsReverted; + } private mapResourceToDisposeListener: ResourceMap; private mapResourceToStateChangeListener: ResourceMap; @@ -70,38 +101,6 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE this.lifecycleService.onShutdown(this.dispose, this); } - get onModelsDirty(): Event { - if (!this._onModelsDirtyEvent) { - this._onModelsDirtyEvent = this.debounce(this.onModelDirty); - } - - return this._onModelsDirtyEvent; - } - - get onModelsSaveError(): Event { - if (!this._onModelsSaveError) { - this._onModelsSaveError = this.debounce(this.onModelSaveError); - } - - return this._onModelsSaveError; - } - - get onModelsSaved(): Event { - if (!this._onModelsSaved) { - this._onModelsSaved = this.debounce(this.onModelSaved); - } - - return this._onModelsSaved; - } - - get onModelsReverted(): Event { - if (!this._onModelsReverted) { - this._onModelsReverted = this.debounce(this.onModelReverted); - } - - return this._onModelsReverted; - } - private debounce(event: Event): Event { return Event.debounce(event, (prev: TextFileModelChangeEvent[], cur: TextFileModelChangeEvent) => { if (!prev) { @@ -327,4 +326,4 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE this.clear(); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/services/textfile/common/textFileService.ts b/src/vs/workbench/services/textfile/common/textFileService.ts index 905933d6b34..a061414b910 100644 --- a/src/vs/workbench/services/textfile/common/textFileService.ts +++ b/src/vs/workbench/services/textfile/common/textFileService.ts @@ -46,7 +46,7 @@ import { PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry'; */ export abstract class TextFileService extends Disposable implements ITextFileService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private readonly _onAutoSaveConfigurationChange: Emitter = this._register(new Emitter()); readonly onAutoSaveConfigurationChange: Event = this._onAutoSaveConfigurationChange.event; @@ -64,9 +64,9 @@ export abstract class TextFileService extends Disposable implements ITextFileSer private currentFilesAssociationConfig: { [key: string]: string; }; private configuredAutoSaveDelay?: number; - private configuredAutoSaveOnFocusChange: boolean; - private configuredAutoSaveOnWindowChange: boolean; - private configuredHotExit: string; + private configuredAutoSaveOnFocusChange: boolean | undefined; + private configuredAutoSaveOnWindowChange: boolean | undefined; + private configuredHotExit: string | undefined; private autoSaveContext: IContextKey; constructor( @@ -1011,8 +1011,8 @@ export abstract class TextFileService extends Disposable implements ITextFileSer getAutoSaveConfiguration(): IAutoSaveConfiguration { return { autoSaveDelay: this.configuredAutoSaveDelay && this.configuredAutoSaveDelay > 0 ? this.configuredAutoSaveDelay : undefined, - autoSaveFocusChange: this.configuredAutoSaveOnFocusChange, - autoSaveApplicationChange: this.configuredAutoSaveOnWindowChange + autoSaveFocusChange: !!this.configuredAutoSaveOnFocusChange, + autoSaveApplicationChange: !!this.configuredAutoSaveOnWindowChange }; } diff --git a/src/vs/workbench/services/textfile/common/textResourcePropertiesService.ts b/src/vs/workbench/services/textfile/common/textResourcePropertiesService.ts index ce097d6fdf5..653da4a83c4 100644 --- a/src/vs/workbench/services/textfile/common/textResourcePropertiesService.ts +++ b/src/vs/workbench/services/textfile/common/textResourcePropertiesService.ts @@ -17,7 +17,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio export class TextResourcePropertiesService implements ITextResourcePropertiesService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private remoteEnvironment: IRemoteAgentEnvironment | null = null; @@ -55,4 +55,4 @@ export class TextResourcePropertiesService implements ITextResourcePropertiesSer } } -registerSingleton(ITextResourcePropertiesService, TextResourcePropertiesService, true); \ No newline at end of file +registerSingleton(ITextResourcePropertiesService, TextResourcePropertiesService, true); diff --git a/src/vs/workbench/services/textfile/common/textfiles.ts b/src/vs/workbench/services/textfile/common/textfiles.ts index 1cbf25a56ef..5438af0f575 100644 --- a/src/vs/workbench/services/textfile/common/textfiles.ts +++ b/src/vs/workbench/services/textfile/common/textfiles.ts @@ -522,7 +522,7 @@ export function stringToSnapshot(value: string): ITextSnapshot { } export class TextSnapshotReadable implements VSBufferReadable { - private preambleHandled: boolean; + private preambleHandled = false; constructor(private snapshot: ITextSnapshot, private preamble?: string) { } @@ -805,4 +805,4 @@ export const SUPPORTED_ENCODINGS: { [encoding: string]: { labelLong: string; lab labelShort: 'CP 850', order: 47 } -}; \ No newline at end of file +}; diff --git a/src/vs/workbench/services/textfile/node/textFileService.ts b/src/vs/workbench/services/textfile/node/textFileService.ts index 3db51b4e10f..29d0d542efe 100644 --- a/src/vs/workbench/services/textfile/node/textFileService.ts +++ b/src/vs/workbench/services/textfile/node/textFileService.ts @@ -30,7 +30,7 @@ import { ITextSnapshot } from 'vs/editor/common/model'; export class NodeTextFileService extends TextFileService { - private _encoding: EncodingOracle; + private _encoding!: EncodingOracle; get encoding(): EncodingOracle { if (!this._encoding) { this._encoding = this._register(this.instantiationService.createInstance(EncodingOracle)); @@ -505,4 +505,4 @@ export class EncodingOracle extends Disposable implements IResourceEncodings { } } -registerSingleton(ITextFileService, NodeTextFileService); \ No newline at end of file +registerSingleton(ITextFileService, NodeTextFileService); diff --git a/src/vs/workbench/services/textfile/test/textFileService.io.test.ts b/src/vs/workbench/services/textfile/test/textFileService.io.test.ts index 586639b4e8e..6bbdf0e42e1 100644 --- a/src/vs/workbench/services/textfile/test/textFileService.io.test.ts +++ b/src/vs/workbench/services/textfile/test/textFileService.io.test.ts @@ -49,7 +49,7 @@ class ServiceAccessor { class TestNodeTextFileService extends NodeTextFileService { - private _testEncoding: TestEncodingOracle; + private _testEncoding: TestEncodingOracle | undefined; get encoding(): TestEncodingOracle { if (!this._testEncoding) { this._testEncoding = this._register(this.instantiationService.createInstance(TestEncodingOracle)); diff --git a/src/vs/workbench/services/textfile/test/textFileService.test.ts b/src/vs/workbench/services/textfile/test/textFileService.test.ts index ce5dd5dd772..30079948c80 100644 --- a/src/vs/workbench/services/textfile/test/textFileService.test.ts +++ b/src/vs/workbench/services/textfile/test/textFileService.test.ts @@ -37,7 +37,7 @@ class ServiceAccessor { class BeforeShutdownEventImpl implements BeforeShutdownEvent { - public value: boolean | Promise; + public value: boolean | Promise | undefined; public reason = ShutdownReason.CLOSE; veto(value: boolean | Promise): void { diff --git a/src/vs/workbench/services/untitled/common/untitledEditorService.ts b/src/vs/workbench/services/untitled/common/untitledEditorService.ts index ad0498407ff..3571e4f6c0a 100644 --- a/src/vs/workbench/services/untitled/common/untitledEditorService.ts +++ b/src/vs/workbench/services/untitled/common/untitledEditorService.ts @@ -112,7 +112,7 @@ export interface IUntitledEditorService { export class UntitledEditorService extends Disposable implements IUntitledEditorService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private mapResourceToInput = new ResourceMap(); private mapResourceToAssociatedFilePath = new ResourceMap(); @@ -284,4 +284,4 @@ export class UntitledEditorService extends Disposable implements IUntitledEditor } } -registerSingleton(IUntitledEditorService, UntitledEditorService, true); \ No newline at end of file +registerSingleton(IUntitledEditorService, UntitledEditorService, true); diff --git a/src/vs/workbench/services/workspace/electron-browser/workspaceEditingService.ts b/src/vs/workbench/services/workspace/electron-browser/workspaceEditingService.ts index 500f4761c45..ee955429c1f 100644 --- a/src/vs/workbench/services/workspace/electron-browser/workspaceEditingService.ts +++ b/src/vs/workbench/services/workspace/electron-browser/workspaceEditingService.ts @@ -36,7 +36,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio export class WorkspaceEditingService implements IWorkspaceEditingService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; constructor( @IJSONEditingService private readonly jsonEditingService: IJSONEditingService, @@ -448,4 +448,4 @@ export class WorkspaceEditingService implements IWorkspaceEditingService { } } -registerSingleton(IWorkspaceEditingService, WorkspaceEditingService, true); \ No newline at end of file +registerSingleton(IWorkspaceEditingService, WorkspaceEditingService, true); diff --git a/src/vs/workbench/test/browser/part.test.ts b/src/vs/workbench/test/browser/part.test.ts index ed151b3aced..e0cefdd51c8 100644 --- a/src/vs/workbench/test/browser/part.test.ts +++ b/src/vs/workbench/test/browser/part.test.ts @@ -13,10 +13,10 @@ import { StorageScope } from 'vs/platform/storage/common/storage'; class SimplePart extends Part { - minimumWidth: number; - maximumWidth: number; - minimumHeight: number; - maximumHeight: number; + minimumWidth: number = 50; + maximumWidth: number = 50; + minimumHeight: number = 50; + maximumHeight: number = 50; layout(width: number, height: number): void { throw new Error('Method not implemented.'); From 0fb4ce799e2b9fc70bf377444add287e1e70c29c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 5 Aug 2019 11:12:18 -0700 Subject: [PATCH 224/861] Clean up --- .../contrib/terminal/browser/terminalInstance.ts | 8 ++++---- .../workbench/contrib/terminal/browser/terminalPanel.ts | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index e8cb9f09efe..c11888713b2 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -182,7 +182,7 @@ export class TerminalInstance implements ITerminalInstance { private _isDisposed: boolean; private _skipTerminalCommands: string[]; private _title: string = ''; - private _wrapperElement: HTMLDivElement | undefined; + private _wrapperElement: (HTMLElement & { xterm?: XTermTerminal }) | undefined; private _xterm: XTermTerminal | undefined; private _xtermSearch: SearchAddon | undefined; private _xtermElement: HTMLDivElement; @@ -576,7 +576,7 @@ export class TerminalInstance implements ITerminalInstance { this._xtermElement = document.createElement('div'); // Attach the xterm object to the DOM, exposing it to the smoke tests - (this._wrapperElement).xterm = this._xterm; + this._wrapperElement.xterm = this._xterm; xterm.open(this._xtermElement); xterm.textarea.addEventListener('focus', () => this._onFocus.fire(this)); @@ -809,8 +809,8 @@ export class TerminalInstance implements ITerminalInstance { this._hadFocusOnExit = dom.hasClass(this._xterm.element, 'focus'); } if (this._wrapperElement) { - if ((this._wrapperElement).xterm) { - (this._wrapperElement).xterm = null; + if (this._wrapperElement.xterm) { + this._wrapperElement.xterm = undefined; } if (this._wrapperElement.parentElement) { this._container.removeChild(this._wrapperElement); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts b/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts index cf725f2f8d0..77d6388d0ef 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts @@ -314,7 +314,9 @@ export class TerminalPanel extends Panel { theme = this.themeService.getTheme(); } - this._findWidget.updateTheme(theme); + if (this._findWidget) { + this._findWidget.updateTheme(theme); + } } private _updateFont(): void { From 60079e01b44b6350c4b8eeabc5c0e6d74f22a797 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 5 Aug 2019 20:17:08 +0200 Subject: [PATCH 225/861] :up: vscode-windows-registry@1.0.2 --- package.json | 2 +- yarn.lock | 15 ++++----------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 8e938a9f02b..f2d6e909082 100644 --- a/package.json +++ b/package.json @@ -153,7 +153,7 @@ }, "optionalDependencies": { "vscode-windows-ca-certs": "0.1.0", - "vscode-windows-registry": "1.0.1", + "vscode-windows-registry": "1.0.2", "windows-foreground-love": "0.2.0", "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" diff --git a/yarn.lock b/yarn.lock index 6267a879280..c0b3855173d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5950,11 +5950,6 @@ nan@2.14.0, nan@^2.0.0, nan@^2.13.2, nan@^2.14.0: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== -nan@^2.12.1: - version "2.12.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552" - integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw== - nan@^2.9.2: version "2.10.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" @@ -9605,12 +9600,10 @@ vscode-windows-ca-certs@0.1.0: dependencies: node-addon-api "1.6.2" -vscode-windows-registry@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/vscode-windows-registry/-/vscode-windows-registry-1.0.1.tgz#bc9f765563eb6dc1c9ad9a41f9eaacc84dfadc7c" - integrity sha512-q0aKXi9Py1OBdmXIJJFeJBzpPJMMUxMJNBU9FysWIXEwJyMQGEVevKzM2J3Qz/cHSc5LVqibmoUWzZ7g+97qRg== - dependencies: - nan "^2.12.1" +vscode-windows-registry@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/vscode-windows-registry/-/vscode-windows-registry-1.0.2.tgz#b863e704a6a69c50b3098a55fbddbe595b0c124a" + integrity sha512-/CLLvuOSM2Vme2z6aNyB+4Omd7hDxpf4Thrt8ImxnXeQtxzel2bClJpFQvQqK/s4oaXlkBKS7LqVLeZM+uSVIA== vso-node-api@6.1.2-preview: version "6.1.2-preview" From ce2f7de6015aaf6798825db36cc18aeca5fd91ea Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 5 Aug 2019 11:31:13 -0700 Subject: [PATCH 226/861] Make TerminalCommandTracker an xterm addon --- .../commandTrackerAddon.ts} | 141 ++++++++++-------- .../terminal/browser/terminalInstance.ts | 11 +- .../contrib/terminal/common/terminal.ts | 4 +- .../terminalCommandTracker.test.ts | 9 +- 4 files changed, 94 insertions(+), 71 deletions(-) rename src/vs/workbench/contrib/terminal/browser/{terminalCommandTracker.ts => addons/commandTrackerAddon.ts} (56%) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalCommandTracker.ts b/src/vs/workbench/contrib/terminal/browser/addons/commandTrackerAddon.ts similarity index 56% rename from src/vs/workbench/contrib/terminal/browser/terminalCommandTracker.ts rename to src/vs/workbench/contrib/terminal/browser/addons/commandTrackerAddon.ts index 77822137bcd..3c4069967ba 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalCommandTracker.ts +++ b/src/vs/workbench/contrib/terminal/browser/addons/commandTrackerAddon.ts @@ -3,9 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Terminal, IMarker } from 'xterm'; -import { ITerminalCommandTracker } from 'vs/workbench/contrib/terminal/common/terminal'; -import { IDisposable } from 'vs/base/common/lifecycle'; +import { Terminal, IMarker, ITerminalAddon } from 'xterm'; +import { ICommandTracker } from 'vs/workbench/contrib/terminal/common/terminal'; /** * The minimum size of the prompt in which to assume the line is a command. @@ -22,15 +21,15 @@ export const enum ScrollPosition { Middle } -export class TerminalCommandTracker implements ITerminalCommandTracker, IDisposable { +export class CommandTrackerAddon implements ICommandTracker, ITerminalAddon { private _currentMarker: IMarker | Boundary = Boundary.Bottom; private _selectionStart: IMarker | Boundary | null = null; private _isDisposable: boolean = false; + private _terminal: Terminal | undefined; - constructor( - private _xterm: Terminal - ) { - this._xterm.onKey(e => this._onKey(e.key)); + public activate(terminal: Terminal): void { + this._terminal = terminal; + terminal.onKey(e => this._onKey(e.key)); } public dispose(): void { @@ -48,116 +47,138 @@ export class TerminalCommandTracker implements ITerminalCommandTracker, IDisposa } private _onEnter(): void { - if (this._xterm.buffer.cursorX >= MINIMUM_PROMPT_LENGTH) { - this._xterm.addMarker(0); + if (!this._terminal) { + return; + } + if (this._terminal.buffer.cursorX >= MINIMUM_PROMPT_LENGTH) { + this._terminal.addMarker(0); } } public scrollToPreviousCommand(scrollPosition: ScrollPosition = ScrollPosition.Top, retainSelection: boolean = false): void { + if (!this._terminal) { + return; + } if (!retainSelection) { this._selectionStart = null; } let markerIndex; if (this._currentMarker === Boundary.Bottom) { - markerIndex = this._xterm.markers.length - 1; + markerIndex = this._terminal.markers.length - 1; } else if (this._currentMarker === Boundary.Top) { markerIndex = -1; } else if (this._isDisposable) { - markerIndex = this._findPreviousCommand(); + markerIndex = this._findPreviousCommand(this._terminal); this._currentMarker.dispose(); this._isDisposable = false; } else { - markerIndex = this._xterm.markers.indexOf(this._currentMarker) - 1; + markerIndex = this._terminal.markers.indexOf(this._currentMarker) - 1; } if (markerIndex < 0) { this._currentMarker = Boundary.Top; - this._xterm.scrollToTop(); + this._terminal.scrollToTop(); return; } - this._currentMarker = this._xterm.markers[markerIndex]; + this._currentMarker = this._terminal.markers[markerIndex]; this._scrollToMarker(this._currentMarker, scrollPosition); } public scrollToNextCommand(scrollPosition: ScrollPosition = ScrollPosition.Top, retainSelection: boolean = false): void { + if (!this._terminal) { + return; + } if (!retainSelection) { this._selectionStart = null; } let markerIndex; if (this._currentMarker === Boundary.Bottom) { - markerIndex = this._xterm.markers.length; + markerIndex = this._terminal.markers.length; } else if (this._currentMarker === Boundary.Top) { markerIndex = 0; } else if (this._isDisposable) { - markerIndex = this._findNextCommand(); + markerIndex = this._findNextCommand(this._terminal); this._currentMarker.dispose(); this._isDisposable = false; } else { - markerIndex = this._xterm.markers.indexOf(this._currentMarker) + 1; + markerIndex = this._terminal.markers.indexOf(this._currentMarker) + 1; } - if (markerIndex >= this._xterm.markers.length) { + if (markerIndex >= this._terminal.markers.length) { this._currentMarker = Boundary.Bottom; - this._xterm.scrollToBottom(); + this._terminal.scrollToBottom(); return; } - this._currentMarker = this._xterm.markers[markerIndex]; + this._currentMarker = this._terminal.markers[markerIndex]; this._scrollToMarker(this._currentMarker, scrollPosition); } private _scrollToMarker(marker: IMarker, position: ScrollPosition): void { + if (!this._terminal) { + return; + } let line = marker.line; if (position === ScrollPosition.Middle) { - line = Math.max(line - Math.floor(this._xterm.rows / 2), 0); + line = Math.max(line - Math.floor(this._terminal.rows / 2), 0); } - this._xterm.scrollToLine(line); + this._terminal.scrollToLine(line); } public selectToPreviousCommand(): void { + if (!this._terminal) { + return; + } if (this._selectionStart === null) { this._selectionStart = this._currentMarker; } this.scrollToPreviousCommand(ScrollPosition.Middle, true); - this._selectLines(this._currentMarker, this._selectionStart); + this._selectLines(this._terminal, this._currentMarker, this._selectionStart); } public selectToNextCommand(): void { + if (!this._terminal) { + return; + } if (this._selectionStart === null) { this._selectionStart = this._currentMarker; } this.scrollToNextCommand(ScrollPosition.Middle, true); - this._selectLines(this._currentMarker, this._selectionStart); + this._selectLines(this._terminal, this._currentMarker, this._selectionStart); } public selectToPreviousLine(): void { + if (!this._terminal) { + return; + } if (this._selectionStart === null) { this._selectionStart = this._currentMarker; } - - this.scrollToPreviousLine(ScrollPosition.Middle, true); - this._selectLines(this._currentMarker, this._selectionStart); + this.scrollToPreviousLine(this._terminal, ScrollPosition.Middle, true); + this._selectLines(this._terminal, this._currentMarker, this._selectionStart); } public selectToNextLine(): void { + if (!this._terminal) { + return; + } if (this._selectionStart === null) { this._selectionStart = this._currentMarker; } - - this.scrollToNextLine(ScrollPosition.Middle, true); - this._selectLines(this._currentMarker, this._selectionStart); + this.scrollToNextLine(this._terminal, ScrollPosition.Middle, true); + this._selectLines(this._terminal, this._currentMarker, this._selectionStart); } - private _selectLines(start: IMarker | Boundary, end: IMarker | Boundary | null): void { + private _selectLines(xterm: Terminal, start: IMarker | Boundary, end: IMarker | Boundary | null): void { if (end === null) { end = Boundary.Bottom; } - let startLine = this._getLine(start); - let endLine = this._getLine(end); + let startLine = this._getLine(xterm, start); + let endLine = this._getLine(xterm, end); if (startLine > endLine) { const temp = startLine; @@ -169,13 +190,13 @@ export class TerminalCommandTracker implements ITerminalCommandTracker, IDisposa // command in the selection for the current command endLine -= 1; - this._xterm.selectLines(startLine, endLine); + xterm.selectLines(startLine, endLine); } - private _getLine(marker: IMarker | Boundary): number { + private _getLine(xterm: Terminal, marker: IMarker | Boundary): number { // Use the _second last_ row as the last row is likely the prompt if (marker === Boundary.Bottom) { - return this._xterm.buffer.baseY + this._xterm.rows - 1; + return xterm.buffer.baseY + xterm.rows - 1; } if (marker === Boundary.Top) { @@ -185,74 +206,74 @@ export class TerminalCommandTracker implements ITerminalCommandTracker, IDisposa return marker.line; } - public scrollToPreviousLine(scrollPosition: ScrollPosition = ScrollPosition.Top, retainSelection: boolean = false): void { + public scrollToPreviousLine(xterm: Terminal, scrollPosition: ScrollPosition = ScrollPosition.Top, retainSelection: boolean = false): void { if (!retainSelection) { this._selectionStart = null; } if (this._currentMarker === Boundary.Top) { - this._xterm.scrollToTop(); + xterm.scrollToTop(); return; } if (this._currentMarker === Boundary.Bottom) { - this._currentMarker = this._xterm.addMarker(this._getOffset() - 1); + this._currentMarker = xterm.addMarker(this._getOffset(xterm) - 1); } else { - const offset = this._getOffset(); + const offset = this._getOffset(xterm); if (this._isDisposable) { this._currentMarker.dispose(); } - this._currentMarker = this._xterm.addMarker(offset - 1); + this._currentMarker = xterm.addMarker(offset - 1); } this._isDisposable = true; this._scrollToMarker(this._currentMarker, scrollPosition); } - public scrollToNextLine(scrollPosition: ScrollPosition = ScrollPosition.Top, retainSelection: boolean = false): void { + public scrollToNextLine(xterm: Terminal, scrollPosition: ScrollPosition = ScrollPosition.Top, retainSelection: boolean = false): void { if (!retainSelection) { this._selectionStart = null; } if (this._currentMarker === Boundary.Bottom) { - this._xterm.scrollToBottom(); + xterm.scrollToBottom(); return; } if (this._currentMarker === Boundary.Top) { - this._currentMarker = this._xterm.addMarker(this._getOffset() + 1); + this._currentMarker = xterm.addMarker(this._getOffset(xterm) + 1); } else { - const offset = this._getOffset(); + const offset = this._getOffset(xterm); if (this._isDisposable) { this._currentMarker.dispose(); } - this._currentMarker = this._xterm.addMarker(offset + 1); + this._currentMarker = xterm.addMarker(offset + 1); } this._isDisposable = true; this._scrollToMarker(this._currentMarker, scrollPosition); } - private _getOffset(): number { + private _getOffset(xterm: Terminal): number { if (this._currentMarker === Boundary.Bottom) { return 0; } else if (this._currentMarker === Boundary.Top) { - return 0 - (this._xterm.buffer.baseY + this._xterm.buffer.cursorY); + return 0 - (xterm.buffer.baseY + xterm.buffer.cursorY); } else { - let offset = this._getLine(this._currentMarker); - offset -= this._xterm.buffer.baseY + this._xterm.buffer.cursorY; + let offset = this._getLine(xterm, this._currentMarker); + offset -= xterm.buffer.baseY + xterm.buffer.cursorY; return offset; } } - private _findPreviousCommand(): number { + private _findPreviousCommand(xterm: Terminal): number { if (this._currentMarker === Boundary.Top) { return 0; } else if (this._currentMarker === Boundary.Bottom) { - return this._xterm.markers.length - 1; + return xterm.markers.length - 1; } let i; - for (i = this._xterm.markers.length - 1; i >= 0; i--) { - if (this._xterm.markers[i].line < this._currentMarker.line) { + for (i = xterm.markers.length - 1; i >= 0; i--) { + if (xterm.markers[i].line < this._currentMarker.line) { return i; } } @@ -260,20 +281,20 @@ export class TerminalCommandTracker implements ITerminalCommandTracker, IDisposa return -1; } - private _findNextCommand(): number { + private _findNextCommand(xterm: Terminal): number { if (this._currentMarker === Boundary.Top) { return 0; } else if (this._currentMarker === Boundary.Bottom) { - return this._xterm.markers.length - 1; + return xterm.markers.length - 1; } let i; - for (i = 0; i < this._xterm.markers.length; i++) { - if (this._xterm.markers[i].line > this._currentMarker.line) { + for (i = 0; i < xterm.markers.length; i++) { + if (xterm.markers[i].line > this._currentMarker.line) { return i; } } - return this._xterm.markers.length; + return xterm.markers.length; } } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index c11888713b2..94be500ddde 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -30,13 +30,13 @@ import { ansiColorIdentifiers, TERMINAL_BACKGROUND_COLOR, TERMINAL_CURSOR_BACKGR import { TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/terminalCommands'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; import { TerminalLinkHandler } from 'vs/workbench/contrib/terminal/browser/terminalLinkHandler'; -import { TerminalCommandTracker } from 'vs/workbench/contrib/terminal/browser/terminalCommandTracker'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalProcessManager } from 'vs/workbench/contrib/terminal/browser/terminalProcessManager'; import { Terminal as XTermTerminal, IBuffer, ITerminalAddon } from 'xterm'; import { SearchAddon, ISearchOptions } from 'xterm-addon-search'; +import { CommandTrackerAddon } from 'vs/workbench/contrib/terminal/browser/addons/commandTrackerAddon'; import { NavigationModeAddon } from 'vs/workbench/contrib/terminal/browser/addons/navigationModeAddon'; // How long in milliseconds should an average frame take to render for a notification to appear @@ -201,7 +201,7 @@ export class TerminalInstance implements ITerminalInstance { private _widgetManager: TerminalWidgetManager; private _linkHandler: TerminalLinkHandler; - private _commandTracker: TerminalCommandTracker; + private _commandTrackerAddon: CommandTrackerAddon; private _navigationModeAddon: INavigationMode & ITerminalAddon | undefined; public disableLayout: boolean; @@ -229,7 +229,7 @@ export class TerminalInstance implements ITerminalInstance { public get hadFocusOnExit(): boolean { return this._hadFocusOnExit; } public get isTitleSetByProcess(): boolean { return !!this._messageTitleDisposable; } public get shellLaunchConfig(): IShellLaunchConfig { return this._shellLaunchConfig; } - public get commandTracker(): TerminalCommandTracker { return this._commandTracker; } + public get commandTracker(): CommandTrackerAddon { return this._commandTrackerAddon; } public get navigationMode(): INavigationMode | undefined { return this._navigationModeAddon; } private readonly _onExit = new Emitter(); @@ -522,7 +522,8 @@ export class TerminalInstance implements ITerminalInstance { this._xterm.onData(data => this._sendRendererInput(data)); } - this._commandTracker = new TerminalCommandTracker(this._xterm); + this._commandTrackerAddon = new CommandTrackerAddon(); + this._xterm.loadAddon(this._commandTrackerAddon); this._disposables.add(this._themeService.onThemeChange(theme => this._updateTheme(xterm, theme))); return xterm; @@ -802,7 +803,7 @@ export class TerminalInstance implements ITerminalInstance { lifecycle.dispose(this._windowsShellHelper); this._windowsShellHelper = undefined; this._linkHandler = lifecycle.dispose(this._linkHandler); - this._commandTracker = lifecycle.dispose(this._commandTracker); + this._commandTrackerAddon = lifecycle.dispose(this._commandTrackerAddon); this._widgetManager = lifecycle.dispose(this._widgetManager); if (this._xterm && this._xterm.element) { diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index ae7b445e9f8..3e16d10bb5a 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -483,7 +483,7 @@ export interface ITerminalInstance { * An object that tracks when commands are run and enables navigating and selecting between * them. */ - readonly commandTracker: ITerminalCommandTracker; + readonly commandTracker: ICommandTracker; readonly navigationMode: INavigationMode | undefined; @@ -671,7 +671,7 @@ export interface ITerminalInstance { getCwd(): Promise; } -export interface ITerminalCommandTracker { +export interface ICommandTracker { scrollToPreviousCommand(): void; scrollToNextCommand(): void; selectToPreviousCommand(): void; diff --git a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalCommandTracker.test.ts b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalCommandTracker.test.ts index 6216173e3a2..2c74cd54682 100644 --- a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalCommandTracker.test.ts +++ b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalCommandTracker.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import { Terminal, TerminalCore } from 'xterm'; -import { TerminalCommandTracker } from 'vs/workbench/contrib/terminal/browser/terminalCommandTracker'; +import { CommandTrackerAddon } from 'vs/workbench/contrib/terminal/browser/addons/commandTrackerAddon'; import { isWindows } from 'vs/base/common/platform'; interface TestTerminalCore extends TerminalCore { @@ -28,7 +28,7 @@ const COLS = 10; suite('Workbench - TerminalCommandTracker', () => { let xterm: TestTerminal; - let commandTracker: TerminalCommandTracker; + let commandTracker: CommandTrackerAddon; setup(() => { xterm = (new Terminal({ @@ -39,7 +39,8 @@ suite('Workbench - TerminalCommandTracker', () => { for (let i = 0; i < ROWS - 1; i++) { syncWrite(xterm, `${i}\n`); } - commandTracker = new TerminalCommandTracker(xterm); + commandTracker = new CommandTrackerAddon(); + xterm.loadAddon(commandTracker); }); suite('Command tracking', () => { @@ -151,4 +152,4 @@ suite('Workbench - TerminalCommandTracker', () => { assert.equal(xterm.getSelection(), isWindows ? '0\r\n1\r\n2' : '0\n1\n2'); }); }); -}); \ No newline at end of file +}); From fcaf9637e4e04d2468ab272d4b0a2f814867d2a3 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 5 Aug 2019 11:48:49 -0700 Subject: [PATCH 227/861] Remove terminallinkhandler dependence on terminalservice --- .../contrib/terminal/browser/terminalInstance.ts | 4 ++-- .../terminal/browser/terminalLinkHandler.ts | 15 +++++---------- .../electron-browser/terminalLinkHandler.test.ts | 14 +++++++------- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 94be500ddde..4a76d9422f5 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -511,10 +511,10 @@ export class TerminalInstance implements ITerminalInstance { return false; }); } - this._linkHandler = this._instantiationService.createInstance(TerminalLinkHandler, this._xterm, this._processManager); + this._linkHandler = this._instantiationService.createInstance(TerminalLinkHandler, this._xterm, this._processManager, this._configHelper); }); } else if (this.shellLaunchConfig.isRendererOnly) { - this._linkHandler = this._instantiationService.createInstance(TerminalLinkHandler, this._xterm, undefined); + this._linkHandler = this._instantiationService.createInstance(TerminalLinkHandler, this._xterm, undefined, this._configHelper); } // Register listener to trigger the onInput ext API if the terminal is a renderer only diff --git a/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts b/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts index 938ab02e434..ccfa0c6258c 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts @@ -9,11 +9,11 @@ import { dispose, IDisposable, DisposableStore } from 'vs/base/common/lifecycle' import { IOpenerService } from 'vs/platform/opener/common/opener'; import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/terminalWidgetManager'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { ITerminalService, ITerminalProcessManager } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalProcessManager, ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal'; import { ITextEditorSelection } from 'vs/platform/editor/common/editor'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IFileService } from 'vs/platform/files/common/files'; -import { ILinkMatcherOptions } from 'xterm'; +import { Terminal, ILinkMatcherOptions } from 'xterm'; import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts'; import { posix, win32 } from 'vs/base/common/path'; import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; @@ -76,12 +76,12 @@ export class TerminalLinkHandler { private readonly _leaveCallback: () => void; constructor( - private _xterm: any, + private _xterm: Terminal, private readonly _processManager: ITerminalProcessManager | undefined, + private readonly _configHelper: ITerminalConfigHelper, @IOpenerService private readonly _openerService: IOpenerService, @IEditorService private readonly _editorService: IEditorService, @IConfigurationService private readonly _configurationService: IConfigurationService, - @ITerminalService private readonly _terminalService: ITerminalService, @ITerminalInstanceService private readonly _terminalInstanceService: ITerminalInstanceService, @IFileService private readonly _fileService: IFileService ) { @@ -94,7 +94,7 @@ export class TerminalLinkHandler { if (!this._widgetManager) { return; } - if (this._terminalService && this._terminalService.configHelper.config.rendererType === 'dom') { + if (this._configHelper.config.rendererType === 'dom') { const target = (e.target as HTMLElement); this._widgetManager.showMessage(target.offsetLeft, target.offsetTop, this._getLinkHoverString()); } else { @@ -183,8 +183,6 @@ export class TerminalLinkHandler { } public dispose(): void { - this._xterm = null; - this._hoverDisposables.dispose(); this._mouseMoveDisposable = dispose(this._mouseMoveDisposable); } @@ -195,9 +193,6 @@ export class TerminalLinkHandler { event.preventDefault(); // Require correct modifier on click if (!this._isLinkActivationModifierDown(event)) { - // If the modifier is not pressed, the terminal should be - // focused if it's not already - this._terminalService.getActiveInstance()!.focus(true); return false; } return handler(uri); diff --git a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts index 5cbeb9a7ba0..1aeea762f4f 100644 --- a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts +++ b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts @@ -65,7 +65,7 @@ interface LinkFormatInfo { suite('Workbench - TerminalLinkHandler', () => { suite('localLinkRegex', () => { test('Windows', () => { - const terminalLinkHandler = new TestTerminalLinkHandler(new TestXterm(), { + const terminalLinkHandler = new TestTerminalLinkHandler(new TestXterm() as any, { os: OperatingSystem.Windows, userHome: '' } as any, null!, null!, null!, null!, new MockTerminalInstanceService(), null!); @@ -141,7 +141,7 @@ suite('Workbench - TerminalLinkHandler', () => { }); test('Linux', () => { - const terminalLinkHandler = new TestTerminalLinkHandler(new TestXterm(), { + const terminalLinkHandler = new TestTerminalLinkHandler(new TestXterm() as any, { os: OperatingSystem.Linux, userHome: '' } as any, null!, null!, null!, null!, new MockTerminalInstanceService(), null!); @@ -209,7 +209,7 @@ suite('Workbench - TerminalLinkHandler', () => { suite('preprocessPath', () => { test('Windows', () => { - const linkHandler = new TestTerminalLinkHandler(new TestXterm(), { + const linkHandler = new TestTerminalLinkHandler(new TestXterm() as any, { os: OperatingSystem.Windows, userHome: 'C:\\Users\\Me' } as any, null!, null!, null!, null!, new MockTerminalInstanceService(), null!); @@ -222,7 +222,7 @@ suite('Workbench - TerminalLinkHandler', () => { assert.equal(linkHandler.preprocessPath('C:\\absolute\\path\\file5'), 'C:\\absolute\\path\\file5'); }); test('Windows - spaces', () => { - const linkHandler = new TestTerminalLinkHandler(new TestXterm(), { + const linkHandler = new TestTerminalLinkHandler(new TestXterm() as any, { os: OperatingSystem.Windows, userHome: 'C:\\Users\\M e' } as any, null!, null!, null!, null!, new MockTerminalInstanceService(), null!); @@ -236,7 +236,7 @@ suite('Workbench - TerminalLinkHandler', () => { }); test('Linux', () => { - const linkHandler = new TestTerminalLinkHandler(new TestXterm(), { + const linkHandler = new TestTerminalLinkHandler(new TestXterm() as any, { os: OperatingSystem.Linux, userHome: '/home/me' } as any, null!, null!, null!, null!, new MockTerminalInstanceService(), null!); @@ -249,7 +249,7 @@ suite('Workbench - TerminalLinkHandler', () => { }); test('No Workspace', () => { - const linkHandler = new TestTerminalLinkHandler(new TestXterm(), { + const linkHandler = new TestTerminalLinkHandler(new TestXterm() as any, { os: OperatingSystem.Linux, userHome: '/home/me' } as any, null!, null!, null!, null!, new MockTerminalInstanceService(), null!); @@ -263,7 +263,7 @@ suite('Workbench - TerminalLinkHandler', () => { test('gitDiffLinkRegex', () => { // The platform is irrelevant because the links generated by Git are the same format regardless of platform - const linkHandler = new TestTerminalLinkHandler(new TestXterm(), { + const linkHandler = new TestTerminalLinkHandler(new TestXterm() as any, { os: OperatingSystem.Linux, userHome: '' } as any, null!, null!, null!, null!, new MockTerminalInstanceService(), null!); From 25fe9803871fda2727b1d7b276e8f072711b2d0b Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 5 Aug 2019 14:31:15 -0700 Subject: [PATCH 228/861] Remove terminal renderers Part of #69865 --- .../src/singlefolder-tests/terminal.test.ts | 74 +-------- src/vs/vscode.proposed.d.ts | 155 ++---------------- .../api/browser/mainThreadTerminalService.ts | 48 ------ .../workbench/api/common/extHost.protocol.ts | 8 - src/vs/workbench/api/common/extHostTypes.ts | 8 +- src/vs/workbench/api/node/extHost.api.impl.ts | 3 - src/vs/workbench/api/node/extHostTask.ts | 4 +- .../api/node/extHostTerminalService.ts | 151 +---------------- .../tasks/browser/terminalTaskSystem.ts | 15 +- .../terminal/browser/terminalInstance.ts | 121 ++++---------- .../contrib/terminal/common/terminal.ts | 26 --- .../terminal/common/terminalService.ts | 4 - 12 files changed, 75 insertions(+), 542 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts index dc281a06fd5..2aa3d25adf4 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { window, Terminal, Pseudoterminal, EventEmitter, TerminalDimensions, workspace, ConfigurationTarget } from 'vscode'; +import { window, Pseudoterminal, EventEmitter, TerminalDimensions, workspace, ConfigurationTarget } from 'vscode'; import { doesNotThrow, equal, ok } from 'assert'; suite('window namespace tests', () => { @@ -81,24 +81,6 @@ suite('window namespace tests', () => { }); const terminal = window.createTerminal('b'); }); - - test('Terminal.sendText should fire Terminal.onInput', (done) => { - const reg1 = window.onDidOpenTerminal(terminal => { - reg1.dispose(); - const reg2 = renderer.onDidAcceptInput(data => { - equal(data, 'bar'); - reg2.dispose(); - const reg3 = window.onDidCloseTerminal(() => { - reg3.dispose(); - done(); - }); - terminal.dispose(); - }); - terminal.sendText('bar', false); - }); - const renderer = window.createTerminalRenderer('foo'); - }); - // test('onDidChangeActiveTerminal should fire when new terminals are created', (done) => { // const reg1 = window.onDidChangeActiveTerminal((active: Terminal | undefined) => { // equal(active, terminal); @@ -201,59 +183,7 @@ suite('window namespace tests', () => { }); }); - suite('Terminal renderers (deprecated)', () => { - test('should fire onDidOpenTerminal and onDidCloseTerminal from createTerminalRenderer terminal', (done) => { - const reg1 = window.onDidOpenTerminal(term => { - equal(term.name, 'c'); - reg1.dispose(); - const reg2 = window.onDidCloseTerminal(() => { - reg2.dispose(); - done(); - }); - term.dispose(); - }); - window.createTerminalRenderer('c'); - }); - - test('should get maximum dimensions set when shown', (done) => { - let terminal: Terminal; - const reg1 = window.onDidOpenTerminal(term => { - reg1.dispose(); - term.show(); - terminal = term; - }); - const renderer = window.createTerminalRenderer('foo'); - const reg2 = renderer.onDidChangeMaximumDimensions(dimensions => { - ok(dimensions.columns > 0); - ok(dimensions.rows > 0); - reg2.dispose(); - const reg3 = window.onDidCloseTerminal(() => { - reg3.dispose(); - done(); - }); - terminal.dispose(); - }); - }); - - test('should fire Terminal.onData on write', (done) => { - const reg1 = window.onDidOpenTerminal(terminal => { - reg1.dispose(); - const reg2 = terminal.onDidWriteData(data => { - equal(data, 'bar'); - reg2.dispose(); - const reg3 = window.onDidCloseTerminal(() => { - reg3.dispose(); - done(); - }); - terminal.dispose(); - }); - renderer.write('bar'); - }); - const renderer = window.createTerminalRenderer('foo'); - }); - }); - - suite('Virtual process terminals', () => { + suite('Extension pty terminals', () => { test('should fire onDidOpenTerminal and onDidCloseTerminal', (done) => { const reg1 = window.onDidOpenTerminal(term => { equal(term.name, 'c'); diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index f18ceb8bb17..3a1ed0907ed 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -787,142 +787,6 @@ declare module 'vscode' { runInBackground?: boolean; } - /** - * Represents the dimensions of a terminal. - */ - export interface TerminalDimensions { - /** - * The number of columns in the terminal. - */ - readonly columns: number; - - /** - * The number of rows in the terminal. - */ - readonly rows: number; - } - - /** - * Represents a terminal without a process where all interaction and output in the terminal is - * controlled by an extension. This is similar to an output window but has the same VT sequence - * compatibility as the regular terminal. - * - * Note that an instance of [Terminal](#Terminal) will be created when a TerminalRenderer is - * created with all its APIs available for use by extensions. When using the Terminal object - * of a TerminalRenderer it acts just like normal only the extension that created the - * TerminalRenderer essentially acts as a process. For example when an - * [Terminal.onDidWriteData](#Terminal.onDidWriteData) listener is registered, that will fire - * when [TerminalRenderer.write](#TerminalRenderer.write) is called. Similarly when - * [Terminal.sendText](#Terminal.sendText) is triggered that will fire the - * [TerminalRenderer.onDidAcceptInput](#TerminalRenderer.onDidAcceptInput) event. - * - * @deprecated Use [ExtensionTerminalOptions](#ExtensionTerminalOptions) instead. - * - * **Example:** Create a terminal renderer, show it and write hello world in red - * ```typescript - * const renderer = window.createTerminalRenderer('foo'); - * renderer.terminal.then(t => t.show()); - * renderer.write('\x1b[31mHello world\x1b[0m'); - * ``` - */ - export interface TerminalRenderer { - /** - * The name of the terminal, this will appear in the terminal selector. - * @deprecated Use [ExtensionTerminalOptions](#ExtensionTerminalOptions) instead. - */ - name: string; - - /** - * The dimensions of the terminal, the rows and columns of the terminal can only be set to - * a value smaller than the maximum value, if this is undefined the terminal will auto fit - * to the maximum value [maximumDimensions](TerminalRenderer.maximumDimensions). - * - * @deprecated Use [ExtensionTerminalOptions](#ExtensionTerminalOptions) instead. - * - * **Example:** Override the dimensions of a TerminalRenderer to 20 columns and 10 rows - * ```typescript - * terminalRenderer.dimensions = { - * cols: 20, - * rows: 10 - * }; - * ``` - */ - dimensions: TerminalDimensions | undefined; - - /** - * The maximum dimensions of the terminal, this will be undefined immediately after a - * terminal renderer is created and also until the terminal becomes visible in the UI. - * Listen to [onDidChangeMaximumDimensions](TerminalRenderer.onDidChangeMaximumDimensions) - * to get notified when this value changes. - * - * @deprecated Use [ExtensionTerminalOptions](#ExtensionTerminalOptions) instead. - */ - readonly maximumDimensions: TerminalDimensions | undefined; - - /** - * The corresponding [Terminal](#Terminal) for this TerminalRenderer. - * - * @deprecated Use [ExtensionTerminalOptions](#ExtensionTerminalOptions) instead. - */ - readonly terminal: Terminal; - - /** - * Write text to the terminal. Unlike [Terminal.sendText](#Terminal.sendText) which sends - * text to the underlying _process_, this will write the text to the terminal itself. - * - * @param text The text to write. - * @deprecated Use [ExtensionTerminalOptions](#ExtensionTerminalOptions) instead. - * - * **Example:** Write red text to the terminal - * ```typescript - * terminalRenderer.write('\x1b[31mHello world\x1b[0m'); - * ``` - * - * **Example:** Move the cursor to the 10th row and 20th column and write an asterisk - * ```typescript - * terminalRenderer.write('\x1b[10;20H*'); - * ``` - */ - write(text: string): void; - - /** - * An event which fires on keystrokes in the terminal or when an extension calls - * [Terminal.sendText](#Terminal.sendText). Keystrokes are converted into their - * corresponding VT sequence representation. - * - * @deprecated Use [ExtensionTerminalOptions](#ExtensionTerminalOptions) instead. - * - * **Example:** Simulate interaction with the terminal from an outside extension or a - * workbench command such as `workbench.action.terminal.runSelectedText` - * ```typescript - * const terminalRenderer = window.createTerminalRenderer('test'); - * terminalRenderer.onDidAcceptInput(data => { - * console.log(data); // 'Hello world' - * }); - * terminalRenderer.terminal.sendText('Hello world'); - * ``` - */ - readonly onDidAcceptInput: Event; - - /** - * An event which fires when the [maximum dimensions](#TerminalRenderer.maximumDimensions) of - * the terminal renderer change. - * - * @deprecated Use [ExtensionTerminalOptions](#ExtensionTerminalOptions) instead. - */ - readonly onDidChangeMaximumDimensions: Event; - } - - export namespace window { - /** - * Create a [TerminalRenderer](#TerminalRenderer). - * - * @param name The name of the terminal renderer, this shows up in the terminal selector. - * @deprecated Use [ExtensionTerminalOptions](#ExtensionTerminalOptions) instead. - */ - export function createTerminalRenderer(name: string): TerminalRenderer; - } - //#endregion //#region Extension terminals @@ -954,6 +818,21 @@ declare module 'vscode' { pty: Pseudoterminal; } + /** + * Represents the dimensions of a terminal. + */ + export interface TerminalDimensions { + /** + * The number of columns in the terminal. + */ + readonly columns: number; + + /** + * The number of rows in the terminal. + */ + readonly rows: number; + } + /** * Defines the interface of a terminal pty, enabling extensions to control a terminal. */ @@ -1169,7 +1048,7 @@ declare module 'vscode' { /** * @param callback The callback that will be called when the extension callback task is executed. */ - constructor(callback: (terminalRenderer: TerminalRenderer, cancellationToken: CancellationToken, thisArg?: any) => Thenable); + constructor(callback: (terminalRenderer: any, cancellationToken: CancellationToken, thisArg?: any) => Thenable); /** * The callback used to execute the task. @@ -1177,7 +1056,7 @@ declare module 'vscode' { * @param cancellationToken Cancellation used to signal a cancel request to the executing task. * @returns The callback should return '0' for success and a non-zero value for failure. */ - callback: (terminalRenderer: TerminalRenderer, cancellationToken: CancellationToken, thisArg?: any) => Thenable; + callback: (terminalRenderer: any, cancellationToken: CancellationToken, thisArg?: any) => Thenable; } /** diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index fcb1f70bfb6..ae5f3288551 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -21,7 +21,6 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape private readonly _terminalProcesses = new Map>(); private readonly _terminalProcessesReady = new Map void>(); private readonly _terminalOnDidWriteDataListeners = new Map(); - private readonly _terminalOnDidAcceptInputListeners = new Map(); constructor( extHostContext: IExtHostContext, @@ -100,11 +99,6 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape }); } - public $createTerminalRenderer(name: string): Promise { - const instance = this._terminalService.createTerminalRenderer(name); - return Promise.resolve(instance.id); - } - public $show(terminalId: number, preserveFocus: boolean): void { const terminalInstance = this._terminalService.getInstanceFromId(terminalId); if (terminalInstance) { @@ -127,44 +121,6 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape } } - public $terminalRendererWrite(terminalId: number, text: string): void { - const terminalInstance = this._terminalService.getInstanceFromId(terminalId); - if (terminalInstance && terminalInstance.shellLaunchConfig.isRendererOnly) { - terminalInstance.write(text); - } - } - - public $terminalRendererSetName(terminalId: number, name: string): void { - const terminalInstance = this._terminalService.getInstanceFromId(terminalId); - if (terminalInstance && terminalInstance.shellLaunchConfig.isRendererOnly) { - terminalInstance.setTitle(name, false); - } - } - - public $terminalRendererSetDimensions(terminalId: number, dimensions: ITerminalDimensions): void { - const terminalInstance = this._terminalService.getInstanceFromId(terminalId); - if (terminalInstance && terminalInstance.shellLaunchConfig.isRendererOnly) { - terminalInstance.setDimensions(dimensions); - } - } - - public $terminalRendererRegisterOnInputListener(terminalId: number): void { - const terminalInstance = this._terminalService.getInstanceFromId(terminalId); - if (!terminalInstance) { - return; - } - - // Listener already registered - if (this._terminalOnDidAcceptInputListeners.has(terminalId)) { - return; - } - - // Register - const listener = terminalInstance.onRendererInput(data => this._onTerminalRendererInput(terminalId, data)); - this._terminalOnDidAcceptInputListeners.set(terminalId, listener); - terminalInstance.addDisposable(listener); - } - public $sendText(terminalId: number, text: string, addNewLine: boolean): void { const terminalInstance = this._terminalService.getInstanceFromId(terminalId); if (terminalInstance) { @@ -207,10 +163,6 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape this._proxy.$acceptWorkspacePermissionsChanged(isAllowed); } - private _onTerminalRendererInput(terminalId: number, data: string): void { - this._proxy.$acceptTerminalRendererInput(terminalId, data); - } - private _onTerminalDisposed(terminalInstance: ITerminalInstance): void { this._proxy.$acceptTerminalClosed(terminalInstance.id); } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 5db8a6658a9..01a1733917a 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -395,7 +395,6 @@ export interface TerminalLaunchConfig { export interface MainThreadTerminalServiceShape extends IDisposable { $createTerminal(config: TerminalLaunchConfig): Promise<{ id: number, name: string }>; - $createTerminalRenderer(name: string): Promise; $dispose(terminalId: number): void; $hide(terminalId: number): void; $sendText(terminalId: number, text: string, addNewLine: boolean): void; @@ -411,12 +410,6 @@ export interface MainThreadTerminalServiceShape extends IDisposable { $sendProcessCwd(terminalId: number, initialCwd: string): void; $sendOverrideDimensions(terminalId: number, dimensions: ITerminalDimensions | undefined): void; $sendResolvedLaunchConfig(terminalId: number, shellLaunchConfig: IShellLaunchConfig): void; - - // Renderer - $terminalRendererSetName(terminalId: number, name: string): void; - $terminalRendererSetDimensions(terminalId: number, dimensions: ITerminalDimensions): void; - $terminalRendererWrite(terminalId: number, text: string): void; - $terminalRendererRegisterOnInputListener(terminalId: number): void; } export interface TransferQuickPickItems extends quickInput.IQuickPickItem { @@ -1158,7 +1151,6 @@ export interface ExtHostTerminalServiceShape { $acceptActiveTerminalChanged(id: number | null): void; $acceptTerminalProcessId(id: number, processId: number): void; $acceptTerminalProcessData(id: number, data: string): void; - $acceptTerminalRendererInput(id: number, data: string): void; $acceptTerminalTitleChange(id: number, name: string): void; $acceptTerminalDimensions(id: number, cols: number, rows: number): void; $acceptTerminalMaximumDimensions(id: number, cols: number, rows: number): void; diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index 0a0ce14f00e..7cd821ea564 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -1754,9 +1754,9 @@ export enum TaskScope { } export class CustomExecution implements vscode.CustomExecution { - private _callback: (args: vscode.TerminalRenderer, cancellationToken: vscode.CancellationToken) => Thenable; + private _callback: (args: any, cancellationToken: vscode.CancellationToken) => Thenable; - constructor(callback: (args: vscode.TerminalRenderer, cancellationToken: vscode.CancellationToken) => Thenable) { + constructor(callback: (args: any, cancellationToken: vscode.CancellationToken) => Thenable) { this._callback = callback; } @@ -1764,11 +1764,11 @@ export class CustomExecution implements vscode.CustomExecution { return 'customExecution' + generateUuid(); } - public set callback(value: (args: vscode.TerminalRenderer, cancellationToken: vscode.CancellationToken) => Thenable) { + public set callback(value: (args: any, cancellationToken: vscode.CancellationToken) => Thenable) { this._callback = value; } - public get callback(): (args: vscode.TerminalRenderer, cancellationToken: vscode.CancellationToken) => Thenable { + public get callback(): (args: any, cancellationToken: vscode.CancellationToken) => Thenable { return this._callback; } } diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index f4df88c11ba..b08841be25d 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -539,9 +539,6 @@ export function createApiFactory( } return extHostTerminalService.createTerminal(nameOrOptions, shellPath, shellArgs); }, - createTerminalRenderer(name: string): vscode.TerminalRenderer { - return extHostTerminalService.createTerminalRenderer(name); - }, registerTreeDataProvider(viewId: string, treeDataProvider: vscode.TreeDataProvider): vscode.Disposable { return extHostTreeViews.registerTreeDataProvider(viewId, treeDataProvider, extension); }, diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index 5c6a6a2c2f3..f9ebaec4b50 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -435,7 +435,7 @@ class CustomExecutionData implements IDisposable { } this.terminal = callbackTerminals[0]; - const terminalRenderer: vscode.TerminalRenderer = await this.terminalService.resolveTerminalRenderer(terminalId); + const terminalRenderer: any = await this.terminalService.resolveTerminalRenderer(terminalId); // If we don't have the maximum dimensions yet, then we need to wait for them (but not indefinitely). // Custom executions will expect the dimensions to be set properly before they are launched. @@ -450,7 +450,7 @@ class CustomExecutionData implements IDisposable { let dimensionsRegistration: IDisposable | undefined; const dimensionsPromise: Promise = new Promise((resolve) => { - dimensionsRegistration = terminalRenderer.onDidChangeMaximumDimensions((newDimensions) => { + dimensionsRegistration = terminalRenderer.onDidChangeMaximumDimensions(() => { resolve(); }); }); diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 4462de7b458..7081ccfac8b 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -24,8 +24,6 @@ import { getSystemShell, detectAvailableShells } from 'vs/workbench/contrib/term import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; import { IDisposable } from 'vs/base/common/lifecycle'; -const RENDERER_NO_PROCESS_ID = -1; - export class BaseExtHostTerminal { public _id: number | undefined; protected _idPromise: Promise; @@ -100,17 +98,10 @@ export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Termi constructor( proxy: MainThreadTerminalServiceShape, private _name?: string, - id?: number, - pid?: number + id?: number ) { super(proxy, id); - this._pidPromise = new Promise(c => { - if (pid === RENDERER_NO_PROCESS_ID) { - c(undefined); - } else { - this._pidPromiseComplete = c; - } - }); + this._pidPromise = new Promise(c => this._pidPromiseComplete = c); } public async create( @@ -201,92 +192,11 @@ export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Termi } } -export class ExtHostTerminalRenderer extends BaseExtHostTerminal implements vscode.TerminalRenderer { - public get name(): string { return this._name; } - public set name(newName: string) { - this._name = newName; - this._checkDisposed(); - this._queueApiRequest(this._proxy.$terminalRendererSetName, [this._name]); - } - - private readonly _onInput = new Emitter(); - public get onDidAcceptInput(): Event { - this._checkDisposed(); - this._queueApiRequest(this._proxy.$terminalRendererRegisterOnInputListener, [this._id]); - // Tell the main side to start sending data if it's not already - // this._proxy.$terminalRendererRegisterOnDataListener(this._id); - return this._onInput && this._onInput.event; - } - - private _dimensions: vscode.TerminalDimensions | undefined; - public get dimensions(): vscode.TerminalDimensions | undefined { return this._dimensions; } - public set dimensions(dimensions: vscode.TerminalDimensions | undefined) { - this._checkDisposed(); - this._dimensions = dimensions; - this._queueApiRequest(this._proxy.$terminalRendererSetDimensions, [dimensions]); - } - - private _maximumDimensions: vscode.TerminalDimensions | undefined; - public get maximumDimensions(): vscode.TerminalDimensions | undefined { - if (!this._maximumDimensions) { - return undefined; - } - return { - rows: this._maximumDimensions.rows, - columns: this._maximumDimensions.columns - }; - } - - private readonly _onDidChangeMaximumDimensions: Emitter = new Emitter(); - public get onDidChangeMaximumDimensions(): Event { - return this._onDidChangeMaximumDimensions && this._onDidChangeMaximumDimensions.event; - } - - public get terminal(): ExtHostTerminal { - return this._terminal; - } - - constructor( - proxy: MainThreadTerminalServiceShape, - private _name: string, - private _terminal: ExtHostTerminal, - id?: number - ) { - super(proxy, id); - - if (!id) { - this._proxy.$createTerminalRenderer(this._name).then(id => { - this._runQueuedRequests(id); - (this._terminal)._runQueuedRequests(id); - }); - } - } - - public write(data: string): void { - this._checkDisposed(); - this._queueApiRequest(this._proxy.$terminalRendererWrite, [data]); - } - - public _fireOnInput(data: string): void { - this._onInput.fire(data); - } - - public _setMaximumDimensions(columns: number, rows: number): void { - if (this._maximumDimensions && this._maximumDimensions.columns === columns && this._maximumDimensions.rows === rows) { - return; - } - const newValue = { columns, rows }; - this._maximumDimensions = newValue; - this._onDidChangeMaximumDimensions.fire(newValue); - } -} - export class ExtHostTerminalService implements ExtHostTerminalServiceShape { private _proxy: MainThreadTerminalServiceShape; private _activeTerminal: ExtHostTerminal | undefined; private _terminals: ExtHostTerminal[] = []; private _terminalProcesses: { [id: number]: ITerminalChildProcess } = {}; - private _terminalRenderers: ExtHostTerminalRenderer[] = []; private _getTerminalPromises: { [id: number]: Promise } = {}; private _variableResolver: ExtHostVariableResolverService | undefined; private _lastActiveWorkspace: IWorkspaceFolder | undefined; @@ -350,17 +260,6 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { this._setupExtHostProcessListeners(id, p); } - public createTerminalRenderer(name: string): vscode.TerminalRenderer { - const terminal = new ExtHostTerminal(this._proxy, name); - terminal._setProcessId(undefined); - this._terminals.push(terminal); - - const renderer = new ExtHostTerminalRenderer(this._proxy, name, terminal); - this._terminalRenderers.push(renderer); - - return renderer; - } - public getDefaultShell(configProvider: ExtHostConfigProvider): string { const fetchSetting = (key: string) => { const setting = configProvider @@ -391,22 +290,9 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed, this._lastActiveWorkspace, this._variableResolver, this._logService); } - public async resolveTerminalRenderer(id: number): Promise { - // Check to see if the extension host already knows about this terminal. - for (const terminalRenderer of this._terminalRenderers) { - if (terminalRenderer._id === id) { - return terminalRenderer; - } - } - - const terminal = this._getTerminalById(id); - if (!terminal) { - throw new Error(`Cannot resolve terminal renderer for terminal id ${id}`); - } - const renderer = new ExtHostTerminalRenderer(this._proxy, terminal.name, terminal, terminal._id); - this._terminalRenderers.push(renderer); - - return renderer; + // TODO: Remove when CustomExecution is removed + public async resolveTerminalRenderer(id: number): Promise { + throw new Error('TerminalRenderers are no longer supported'); } public $acceptActiveTerminalChanged(id: number | null): void { @@ -454,22 +340,6 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { // Virtual processes only - when virtual process resize fires it means that the // terminal's maximum dimensions changed this._terminalProcesses[id].resize(cols, rows); - } else { - // Terminal renderer - this._getTerminalByIdEventually(id).then(() => { - // When a terminal's dimensions change, a renderer's _maximum_ dimensions change - const renderer = this._getTerminalRendererById(id); - if (renderer) { - renderer._setMaximumDimensions(cols, rows); - } - }); - } - } - - public $acceptTerminalRendererInput(id: number, data: string): void { - const renderer = this._getTerminalRendererById(id); - if (renderer) { - renderer._fireOnInput(data); } } @@ -496,8 +366,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return; } - const renderer = this._getTerminalRendererById(id); - const terminal = new ExtHostTerminal(this._proxy, name, id, renderer ? RENDERER_NO_PROCESS_ID : undefined); + const terminal = new ExtHostTerminal(this._proxy, name, id); this._terminals.push(terminal); this._onDidOpenTerminal.fire(terminal); } @@ -739,16 +608,12 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return this._getTerminalObjectById(this._terminals, id); } - private _getTerminalRendererById(id: number): ExtHostTerminalRenderer | null { - return this._getTerminalObjectById(this._terminalRenderers, id); - } - - private _getTerminalObjectById(array: T[], id: number): T | null { + private _getTerminalObjectById(array: T[], id: number): T | null { const index = this._getTerminalObjectIndexById(array, id); return index !== null ? array[index] : null; } - private _getTerminalObjectIndexById(array: T[], id: number): number | null { + private _getTerminalObjectIndexById(array: T[], id: number): number | null { let index: number | null = null; array.some((item, i) => { const thisId = item._id; diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index efef7a28135..6bccee3e09f 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -285,7 +285,7 @@ export class TerminalTaskSystem implements ITaskSystem { } return new Promise((resolve) => { - activeTerminal.terminal.rendererExit(result); + // activeTerminal.terminal.rendererExit(result); resolve(); }); } @@ -918,12 +918,13 @@ export class TerminalTaskSystem implements ITaskSystem { let launchConfigs: IShellLaunchConfig | undefined; if (task.command.runtime === RuntimeType.CustomExecution) { - this.currentTask.shellLaunchConfig = launchConfigs = { - isRendererOnly: true, - waitOnExit, - name: this.createTerminalName(task, workspaceFolder), - initialText: task.command.presentation && task.command.presentation.echo ? `\x1b[1m> Executing task: ${task._label} <\x1b[0m\n` : undefined - }; + throw new Error('CustomExecution is no longer supported'); + // this.currentTask.shellLaunchConfig = launchConfigs = { + // isRendererOnly: true, + // waitOnExit, + // name: this.createTerminalName(task, workspaceFolder), + // initialText: task.command.presentation && task.command.presentation.echo ? `\x1b[1m> Executing task: ${task._label} <\x1b[0m\n` : undefined + // }; } else if (task.command.runtime === RuntimeType.CustomExecution2) { this.currentTask.shellLaunchConfig = launchConfigs = { isExtensionTerminal: true, diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 4a76d9422f5..17d404a2f87 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -172,7 +172,7 @@ export class TerminalInstance implements ITerminalInstance { private static _lastKnownGridDimensions: IGridDimensions | undefined; private static _idCounter = 1; - private _processManager: ITerminalProcessManager | undefined; + private _processManager: ITerminalProcessManager; private _pressAnyKeyToCloseListener: lifecycle.IDisposable | undefined; private _id: number; @@ -246,8 +246,6 @@ export class TerminalInstance implements ITerminalInstance { public get onData(): Event { return this._onData.event; } private readonly _onLineData = new Emitter(); public get onLineData(): Event { return this._onLineData.event; } - private readonly _onRendererInput = new Emitter(); - public get onRendererInput(): Event { return this._onRendererInput.event; } private readonly _onRequestExtHostProcess = new Emitter(); public get onRequestExtHostProcess(): Event { return this._onRequestExtHostProcess.event; } private readonly _onDimensionsChanged = new Emitter(); @@ -293,11 +291,7 @@ export class TerminalInstance implements ITerminalInstance { this._logService.trace(`terminalInstance#ctor (id: ${this.id})`, this._shellLaunchConfig); this._initDimensions(); - if (!this.shellLaunchConfig.isRendererOnly) { - this._createProcess(); - } else { - this.setTitle(this._shellLaunchConfig.name, false); - } + this._createProcess(); this._xtermReadyPromise = this._createXterm(); this._xtermReadyPromise.then(() => { @@ -488,39 +482,30 @@ export class TerminalInstance implements ITerminalInstance { this._xterm.onLineFeed(() => this._onLineFeed()); this._xterm.onKey(e => this._onKey(e.key, e.domEvent)); - if (this._processManager) { - this._processManager.onProcessData(data => this._onProcessData(data)); - this._xterm.onData(data => this._processManager!.write(data)); - // TODO: How does the cwd work on detached processes? - this.processReady.then(async () => { - this._linkHandler.processCwd = await this._processManager!.getInitialCwd(); - }); - // Init winpty compat and link handler after process creation as they rely on the - // underlying process OS - this._processManager.onProcessReady(() => { - if (!this._processManager) { - return; - } - if (this._processManager.os === platform.OperatingSystem.Windows) { - xterm.setOption('windowsMode', true); - // Force line data to be sent when the cursor is moved, the main purpose for - // this is because ConPTY will often not do a line feed but instead move the - // cursor, in which case we still want to send the current line's data to tasks. - xterm.addCsiHandler('H', () => { - this._onCursorMove(); - return false; - }); - } - this._linkHandler = this._instantiationService.createInstance(TerminalLinkHandler, this._xterm, this._processManager, this._configHelper); - }); - } else if (this.shellLaunchConfig.isRendererOnly) { - this._linkHandler = this._instantiationService.createInstance(TerminalLinkHandler, this._xterm, undefined, this._configHelper); - } - - // Register listener to trigger the onInput ext API if the terminal is a renderer only - if (this._shellLaunchConfig.isRendererOnly) { - this._xterm.onData(data => this._sendRendererInput(data)); - } + this._processManager.onProcessData(data => this._onProcessData(data)); + this._xterm.onData(data => this._processManager!.write(data)); + // TODO: How does the cwd work on detached processes? + this.processReady.then(async () => { + this._linkHandler.processCwd = await this._processManager!.getInitialCwd(); + }); + // Init winpty compat and link handler after process creation as they rely on the + // underlying process OS + this._processManager.onProcessReady(() => { + if (!this._processManager) { + return; + } + if (this._processManager.os === platform.OperatingSystem.Windows) { + xterm.setOption('windowsMode', true); + // Force line data to be sent when the cursor is moved, the main purpose for + // this is because ConPTY will often not do a line feed but instead move the + // cursor, in which case we still want to send the current line's data to tasks. + xterm.addCsiHandler('H', () => { + this._onCursorMove(); + return false; + }); + } + this._linkHandler = this._instantiationService.createInstance(TerminalLinkHandler, this._xterm, this._processManager, this._configHelper); + }); this._commandTrackerAddon = new CommandTrackerAddon(); this._xterm.loadAddon(this._commandTrackerAddon); @@ -659,13 +644,8 @@ export class TerminalInstance implements ITerminalInstance { this._wrapperElement.appendChild(this._xtermElement); this._container.appendChild(this._wrapperElement); - if (this._processManager) { - this._widgetManager = new TerminalWidgetManager(this._wrapperElement); - this._processManager.onProcessReady(() => this._linkHandler.setWidgetManager(this._widgetManager)); - } else if (this._shellLaunchConfig.isRendererOnly) { - this._widgetManager = new TerminalWidgetManager(this._wrapperElement); - this._linkHandler.setWidgetManager(this._widgetManager); - } + this._widgetManager = new TerminalWidgetManager(this._wrapperElement); + this._processManager.onProcessReady(() => this._linkHandler.setWidgetManager(this._widgetManager)); const computedStyle = window.getComputedStyle(this._container); const width = parseInt(computedStyle.getPropertyValue('width').replace('px', ''), 10); @@ -844,16 +824,6 @@ export class TerminalInstance implements ITerminalInstance { this._disposables.dispose(); } - public rendererExit(exitCode: number): void { - // The use of this API is for cases where there is no backing process behind a terminal - // instance (e.g. a custom execution task). - if (!this.shellLaunchConfig.isRendererOnly) { - throw new Error('rendererExit is only expected to be called on a renderer only terminal'); - } - - return this._onProcessExit(exitCode); - } - public forceRedraw(): void { if (!this._xterm) { return; @@ -902,10 +872,6 @@ export class TerminalInstance implements ITerminalInstance { return; } this._xterm.write(text); - if (this._shellLaunchConfig.isRendererOnly) { - // Fire onData API in the extension host - this._onData.fire(text); - } }); } @@ -916,16 +882,11 @@ export class TerminalInstance implements ITerminalInstance { text += '\r'; } - if (this._shellLaunchConfig.isRendererOnly) { - // If the terminal is a renderer only, fire the onInput ext API - this._sendRendererInput(text); - } else { - // If the terminal has a process, send it to the process - if (this._processManager) { - this._processManager.ptyProcessReady.then(() => { - this._processManager!.write(text); - }); - } + // If the terminal has a process, send it to the process + if (this._processManager) { + this._processManager.ptyProcessReady.then(() => { + this._processManager!.write(text); + }); } } @@ -1159,7 +1120,6 @@ export class TerminalInstance implements ITerminalInstance { // Kill and clear up the process, making the process manager ready for a new process if (this._processManager) { this._processManager.dispose(); - this._processManager = undefined; } if (this._xterm) { @@ -1184,11 +1144,7 @@ export class TerminalInstance implements ITerminalInstance { // Launch the process unless this is only a renderer. // In the renderer only cases, we still need to set the title correctly. const oldTitle = this._title; - if (!this._shellLaunchConfig.isRendererOnly) { - this._createProcess(); - } else if (this._shellLaunchConfig.name) { - this.setTitle(this._shellLaunchConfig.name, false); - } + this._createProcess(); if (oldTitle !== this._title) { this.setTitle(this._title, true); @@ -1201,15 +1157,6 @@ export class TerminalInstance implements ITerminalInstance { } } - private _sendRendererInput(input: string): void { - if (this._processManager) { - throw new Error('onRendererInput attempted to be used on a regular terminal'); - } - - // For terminal renderers onData fires on keystrokes and when sendText is called. - this._onRendererInput.fire(input); - } - private _onLineFeed(): void { const buffer = this._xterm!.buffer; const newLine = buffer.getLine(buffer.baseY + buffer.cursorY); diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 3e16d10bb5a..6c2b7627191 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -187,11 +187,6 @@ export interface IShellLaunchConfig { */ initialText?: string; - /** - * @deprecated use `isExtensionTerminal` - */ - isRendererOnly?: boolean; - /** * Whether an extension is controlling the terminal via a `vscode.Pseudoterminal`. */ @@ -244,12 +239,6 @@ export interface ITerminalService { */ createTerminal(shell?: IShellLaunchConfig): ITerminalInstance; - /** - * Creates a terminal renderer. - * @param name The name of the terminal. - */ - createTerminalRenderer(name: string): ITerminalInstance; - /** * Creates a raw terminal instance, this should not be used outside of the terminal part. */ @@ -422,13 +411,6 @@ export interface ITerminalInstance { */ onData: Event; - /** - * Attach a listener to the "renderer" input event, this event fires for terminal renderers on - * keystrokes and when the Terminal.sendText extension API is used. - * @param listener The listener function. - */ - onRendererInput: Event; - /** * Attach a listener to listen for new lines added to this terminal instance. * @@ -497,14 +479,6 @@ export interface ITerminalInstance { */ dispose(immediate?: boolean): void; - /** - * Indicates that a consumer of a renderer only terminal is finished with it. - * - * @param exitCode The exit code of the terminal. Zero indicates success, non-zero indicates - * failure. - */ - rendererExit(exitCode: number): void; - /** * Forces the terminal to redraw its viewport. */ diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index e88af8ffc03..a9595156654 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -126,10 +126,6 @@ export abstract class TerminalService implements ITerminalService { public abstract createInstance(terminalFocusContextKey: IContextKey, configHelper: ITerminalConfigHelper, container: HTMLElement, shellLaunchConfig: IShellLaunchConfig): ITerminalInstance; public abstract setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void; - public createTerminalRenderer(name: string): ITerminalInstance { - return this.createTerminal({ name, isRendererOnly: true }); - } - public getActiveOrCreateInstance(wasNewTerminalAction?: boolean): ITerminalInstance { const activeInstance = this.getActiveInstance(); return activeInstance ? activeInstance : this.createTerminal(undefined, wasNewTerminalAction); From 0eed3275f6ff1d6e5b2da250274137e328f14add Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 5 Aug 2019 15:03:31 -0700 Subject: [PATCH 229/861] Some clean up --- .../src/singlefolder-tests/terminal.test.ts | 28 ++++++++++++++- src/vs/vscode.proposed.d.ts | 34 +++++++++---------- .../api/node/extHostTerminalService.ts | 10 ++---- 3 files changed, 47 insertions(+), 25 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts index 2aa3d25adf4..9ecfbf61859 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts @@ -229,7 +229,7 @@ suite('window namespace tests', () => { const terminal = window.createTerminal({ name: 'foo', pty }); }); - test('should fire provide dimensions on start as the terminal has been shown', (done) => { + test('should not provide dimensions on start as the terminal has not been shown yet', (done) => { const reg1 = window.onDidOpenTerminal(term => { equal(terminal, term); reg1.dispose(); @@ -237,6 +237,32 @@ suite('window namespace tests', () => { const pty: Pseudoterminal = { onDidWrite: new EventEmitter().event, open: (dimensions) => { + equal(dimensions, undefined); + const reg3 = window.onDidCloseTerminal(() => { + reg3.dispose(); + done(); + }); + // Show a terminal and wait a brief period before dispose, this will cause + // the panel to init it's dimenisons and be provided to following terminals. + // The following test depends on this. + terminal.show(); + setTimeout(() => terminal.dispose(), 200); + }, + close: () => {} + }; + const terminal = window.createTerminal({ name: 'foo', pty }); + }); + + test('should provide dimensions on start as the terminal has been shown', (done) => { + const reg1 = window.onDidOpenTerminal(term => { + equal(terminal, term); + reg1.dispose(); + }); + const pty: Pseudoterminal = { + onDidWrite: new EventEmitter().event, + open: (dimensions) => { + // This test depends on Terminal.show being called some time before such + // that the panel dimensions are initialized and cached. ok(dimensions!.columns > 0); ok(dimensions!.rows > 0); const reg3 = window.onDidCloseTerminal(() => { diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 3a1ed0907ed..5b39ce4dcbb 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -787,13 +787,28 @@ declare module 'vscode' { runInBackground?: boolean; } + /** + * Represents the dimensions of a terminal. + */ + export interface TerminalDimensions { + /** + * The number of columns in the terminal. + */ + readonly columns: number; + + /** + * The number of rows in the terminal. + */ + readonly rows: number; + } + //#endregion //#region Extension terminals export namespace window { /** - * Creates a [Terminal](#Terminal) where an extension controls the teerminal. + * Creates a [Terminal](#Terminal) where an extension controls the terminal. * * @param options An [ExtensionTerminalOptions](#ExtensionTerminalOptions) object describing * the characteristics of the new terminal. @@ -818,21 +833,6 @@ declare module 'vscode' { pty: Pseudoterminal; } - /** - * Represents the dimensions of a terminal. - */ - export interface TerminalDimensions { - /** - * The number of columns in the terminal. - */ - readonly columns: number; - - /** - * The number of rows in the terminal. - */ - readonly rows: number; - } - /** * Defines the interface of a terminal pty, enabling extensions to control a terminal. */ @@ -1064,7 +1064,7 @@ declare module 'vscode' { */ export class CustomExecution2 { /** - * @param process The [Pseudotrminal](#Pseudoterminal) to be used by the task to display output. + * @param process The [Pseudoterminal](#Pseudoterminal) to be used by the task to display output. * @param callback The callback that will be called when the task is started by a user. */ constructor(callback: (thisArg?: any) => Thenable); diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 7081ccfac8b..a0bdd8ecc05 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -337,7 +337,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { public $acceptTerminalMaximumDimensions(id: number, cols: number, rows: number): void { if (this._terminalProcesses[id]) { - // Virtual processes only - when virtual process resize fires it means that the + // Extension pty terminal only - when virtual process resize fires it means that the // terminal's maximum dimensions changed this._terminalProcesses[id].resize(cols, rows); } @@ -674,9 +674,7 @@ class ExtHostPseudoterminal implements ITerminalChildProcess { } shutdown(): void { - if (this._pty.close) { - this._pty.close(); - } + this._pty.close(); } input(data: string): void { @@ -718,9 +716,7 @@ class ExtHostPseudoterminal implements ITerminalChildProcess { this._pty.onDidOverrideDimensions(e => this._onProcessOverrideDimensions.fire(e ? { cols: e.columns, rows: e.rows } : e)); } - if (this._pty.open) { - this._pty.open(initialDimensions); - } + this._pty.open(initialDimensions ? initialDimensions : undefined); } } From c783f4996c88861c5b8138cfee4d20953b297c68 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 5 Aug 2019 15:10:21 -0700 Subject: [PATCH 230/861] Remove TerminalOptions.runInBackground Fixes #76121 --- src/vs/vscode.proposed.d.ts | 12 ------------ src/vs/workbench/api/node/extHost.api.impl.ts | 4 +--- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index f18ceb8bb17..db42ea4b01a 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -775,18 +775,6 @@ declare module 'vscode' { readonly onDidWriteData: Event; } - - export interface TerminalOptions { - /** - * When enabled the terminal will run the process as normal but not be surfaced to the user - * until `Terminal.show` is called. The typical usage for this is when you need to run - * something that may need interactivity but only want to tell the user about it when - * interaction is needed. Note that the terminals will still be exposed to all extensions - * as normal. - */ - runInBackground?: boolean; - } - /** * Represents the dimensions of a terminal. */ diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index f4df88c11ba..3c4e7ee8a66 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -532,10 +532,8 @@ export function createApiFactory( if (typeof nameOrOptions === 'object') { if ('pty' in nameOrOptions) { return extHostTerminalService.createExtensionTerminal(nameOrOptions); - } else { - nameOrOptions.hideFromUser = nameOrOptions.hideFromUser || (nameOrOptions.runInBackground && extension.enableProposedApi); - return extHostTerminalService.createTerminalFromOptions(nameOrOptions); } + return extHostTerminalService.createTerminalFromOptions(nameOrOptions); } return extHostTerminalService.createTerminal(nameOrOptions, shellPath, shellArgs); }, From 8785c87b456fd481e7df39f7197f68aa36513d06 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 5 Aug 2019 15:16:35 -0700 Subject: [PATCH 231/861] Remove checks for process manager existence in terminal instance --- .../terminal/browser/terminalInstance.ts | 56 +++++-------------- 1 file changed, 14 insertions(+), 42 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 17d404a2f87..ca4d3207848 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -483,17 +483,14 @@ export class TerminalInstance implements ITerminalInstance { this._xterm.onKey(e => this._onKey(e.key, e.domEvent)); this._processManager.onProcessData(data => this._onProcessData(data)); - this._xterm.onData(data => this._processManager!.write(data)); + this._xterm.onData(data => this._processManager.write(data)); // TODO: How does the cwd work on detached processes? this.processReady.then(async () => { - this._linkHandler.processCwd = await this._processManager!.getInitialCwd(); + this._linkHandler.processCwd = await this._processManager.getInitialCwd(); }); // Init winpty compat and link handler after process creation as they rely on the // underlying process OS this._processManager.onProcessReady(() => { - if (!this._processManager) { - return; - } if (this._processManager.os === platform.OperatingSystem.Windows) { xterm.setOption('windowsMode', true); // Force line data to be sent when the cursor is moved, the main purpose for @@ -808,14 +805,7 @@ export class TerminalInstance implements ITerminalInstance { this._pressAnyKeyToCloseListener = undefined; } - if (this._processManager) { - this._processManager.dispose(immediate); - } else { - // In cases where there is no associated process (for example executing an extension callback task) - // consumers still expect on onExit event to be fired. An example of this is terminating the extension callback - // task. - this._onExit.fire(0); - } + this._processManager.dispose(immediate); if (!this._isDisposed) { this._isDisposed = true; @@ -882,12 +872,8 @@ export class TerminalInstance implements ITerminalInstance { text += '\r'; } - // If the terminal has a process, send it to the process - if (this._processManager) { - this._processManager.ptyProcessReady.then(() => { - this._processManager!.write(text); - }); - } + // Send it to the process + this._processManager.ptyProcessReady.then(() => this._processManager.write(text)); } public setVisible(visible: boolean): void { @@ -984,7 +970,7 @@ export class TerminalInstance implements ITerminalInstance { if (platform.isWindows) { this._processManager.ptyProcessReady.then(() => { - if (this._processManager!.remoteAuthority) { + if (this._processManager.remoteAuthority) { return; } this._xtermReadyPromise.then(xterm => { @@ -998,7 +984,7 @@ export class TerminalInstance implements ITerminalInstance { // Create the process asynchronously to allow the terminal's container // to be created so dimensions are accurate setTimeout(() => { - this._processManager!.createProcess(this._shellLaunchConfig, this._cols, this._rows, this._isScreenReaderOptimized()); + this._processManager.createProcess(this._shellLaunchConfig, this._cols, this._rows, this._isScreenReaderOptimized()); }, 0); } @@ -1036,7 +1022,7 @@ export class TerminalInstance implements ITerminalInstance { exitCodeMessage = nls.localize('terminal.integrated.exitedWithInvalidPathDirectory', 'The terminal shell path "{0}" is a directory', this._shellLaunchConfig.executable); } else if (exitCode === SHELL_CWD_INVALID_EXIT_CODE && this._shellLaunchConfig.cwd) { exitCodeMessage = nls.localize('terminal.integrated.exitedWithInvalidCWD', 'The terminal shell CWD "{0}" does not exist', this._shellLaunchConfig.cwd.toString()); - } else if (this._processManager && this._processManager.processState === ProcessState.KILLED_DURING_LAUNCH) { + } else if (this._processManager.processState === ProcessState.KILLED_DURING_LAUNCH) { let args = ''; if (typeof this._shellLaunchConfig.args === 'string') { args = ` ${this._shellLaunchConfig.args}`; @@ -1058,11 +1044,11 @@ export class TerminalInstance implements ITerminalInstance { } } - this._logService.debug(`Terminal process exit (id: ${this.id})${this._processManager ? ' state ' + this._processManager.processState : ''}`); + this._logService.debug(`Terminal process exit (id: ${this.id}) state ${this._processManager.processState}`); // Only trigger wait on exit when the exit was *not* triggered by the // user (via the `workbench.action.terminal.kill` command). - if (this._shellLaunchConfig.waitOnExit && (!this._processManager || this._processManager.processState !== ProcessState.KILLED_BY_USER)) { + if (this._shellLaunchConfig.waitOnExit && this._processManager.processState !== ProcessState.KILLED_BY_USER) { this._xtermReadyPromise.then(xterm => { if (exitCodeMessage) { xterm.writeln(exitCodeMessage); @@ -1082,7 +1068,7 @@ export class TerminalInstance implements ITerminalInstance { } else { this.dispose(); if (exitCodeMessage) { - if (this._processManager && this._processManager.processState === ProcessState.KILLED_DURING_LAUNCH) { + if (this._processManager.processState === ProcessState.KILLED_DURING_LAUNCH) { this._notificationService.error(exitCodeMessage); } else { if (this._configHelper.config.showExitAlert) { @@ -1118,9 +1104,7 @@ export class TerminalInstance implements ITerminalInstance { } // Kill and clear up the process, making the process manager ready for a new process - if (this._processManager) { - this._processManager.dispose(); - } + this._processManager.dispose(); if (this._xterm) { // Ensure new processes' output starts at start of new line @@ -1150,11 +1134,7 @@ export class TerminalInstance implements ITerminalInstance { this.setTitle(this._title, true); } - if (this._processManager) { - // The "!" operator is required here because _processManager is set to undefiend earlier - // and TS does not know that createProcess sets it. - this._processManager!.onProcessData(data => this._onProcessData(data)); - } + this._processManager.onProcessData(data => this._onProcessData(data)); } private _onLineFeed(): void { @@ -1339,9 +1319,7 @@ export class TerminalInstance implements ITerminalInstance { } } - if (this._processManager) { - this._processManager.ptyProcessReady.then(() => this._processManager!.setDimensions(cols, rows)); - } + this._processManager.ptyProcessReady.then(() => this._processManager.setDimensions(cols, rows)); } public setTitle(title: string | undefined, eventFromProcess: boolean): void { @@ -1438,16 +1416,10 @@ export class TerminalInstance implements ITerminalInstance { } public getInitialCwd(): Promise { - if (!this._processManager) { - return Promise.resolve(''); - } return this._processManager.getInitialCwd(); } public getCwd(): Promise { - if (!this._processManager) { - return Promise.resolve(''); - } return this._processManager.getCwd(); } } From c17bb3e4b3282553f6e313bdfe946668e5fd4f7f Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Mon, 5 Aug 2019 15:38:36 -0700 Subject: [PATCH 232/861] Re #69955. Adopt new tree in comments panel. --- .../api/browser/mainThreadComments.ts | 3 +- .../contrib/comments/browser/commentsPanel.ts | 41 ++-- .../comments/browser/commentsTreeViewer.ts | 192 ++++++++++-------- 3 files changed, 127 insertions(+), 109 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadComments.ts b/src/vs/workbench/api/browser/mainThreadComments.ts index b7af867d10c..bbd29b585a2 100644 --- a/src/vs/workbench/api/browser/mainThreadComments.ts +++ b/src/vs/workbench/api/browser/mainThreadComments.ts @@ -16,9 +16,10 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { Extensions as PanelExtensions, PanelDescriptor, PanelRegistry } from 'vs/workbench/browser/panel'; import { ICommentInfo, ICommentService } from 'vs/workbench/contrib/comments/browser/commentService'; -import { CommentsPanel, COMMENTS_PANEL_ID, COMMENTS_PANEL_TITLE } from 'vs/workbench/contrib/comments/browser/commentsPanel'; +import { CommentsPanel } from 'vs/workbench/contrib/comments/browser/commentsPanel'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { CommentProviderFeatures, ExtHostCommentsShape, ExtHostContext, IExtHostContext, MainContext, MainThreadCommentsShape } from '../common/extHost.protocol'; +import { COMMENTS_PANEL_ID, COMMENTS_PANEL_TITLE } from 'vs/workbench/contrib/comments/browser/commentsTreeViewer'; export class MainThreadCommentThread implements modes.CommentThread { diff --git a/src/vs/workbench/contrib/comments/browser/commentsPanel.ts b/src/vs/workbench/contrib/comments/browser/commentsPanel.ts index 27440e3e996..5f0e33758a4 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsPanel.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsPanel.ts @@ -4,34 +4,31 @@ *--------------------------------------------------------------------------------------------*/ import 'vs/css!./media/panel'; +import * as nls from 'vs/nls'; import * as dom from 'vs/base/browser/dom'; -import { IAction } from 'vs/base/common/actions'; -import { Event } from 'vs/base/common/event'; -import { CollapseAllAction, DefaultAccessibilityProvider, DefaultController, DefaultDragAndDrop } from 'vs/base/parts/tree/browser/treeDefaults'; +import { IAction, Action } from 'vs/base/common/actions'; +import { CollapseAllAction } from 'vs/base/browser/ui/tree/treeDefaults'; import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { TreeResourceNavigator, WorkbenchTree } from 'vs/platform/list/browser/listService'; +import { TreeResourceNavigator2 } from 'vs/platform/list/browser/listService'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { Panel } from 'vs/workbench/browser/panel'; import { CommentNode, CommentsModel, ResourceWithCommentThreads, ICommentThreadChangedEvent } from 'vs/workbench/contrib/comments/common/commentModel'; import { ReviewController } from 'vs/workbench/contrib/comments/browser/commentsEditorContribution'; -import { CommentsDataFilter, CommentsDataSource, CommentsModelRenderer } from 'vs/workbench/contrib/comments/browser/commentsTreeViewer'; import { ICommentService, IWorkspaceCommentThreadsEvent } from 'vs/workbench/contrib/comments/browser/commentService'; import { IEditorService, ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { textLinkForeground, textLinkActiveForeground, focusBorder, textPreformatForeground } from 'vs/platform/theme/common/colorRegistry'; -import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { ResourceLabels } from 'vs/workbench/browser/labels'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; +import { CommentsList, COMMENTS_PANEL_ID, COMMENTS_PANEL_TITLE } from 'vs/workbench/contrib/comments/browser/commentsTreeViewer'; -export const COMMENTS_PANEL_ID = 'workbench.panel.comments'; -export const COMMENTS_PANEL_TITLE = 'Comments'; export class CommentsPanel extends Panel { private treeLabels: ResourceLabels; - private tree: WorkbenchTree; + private tree: CommentsList; private treeContainer: HTMLElement; private messageBoxContainer: HTMLElement; private messageBox: HTMLElement; @@ -42,7 +39,6 @@ export class CommentsPanel extends Panel { @IInstantiationService private readonly instantiationService: IInstantiationService, @ICommentService private readonly commentService: ICommentService, @IEditorService private readonly editorService: IEditorService, - @IOpenerService private readonly openerService: IOpenerService, @ITelemetryService telemetryService: ITelemetryService, @IThemeService themeService: IThemeService, @IStorageService storageService: IStorageService @@ -113,7 +109,7 @@ export class CommentsPanel extends Panel { public getActions(): IAction[] { if (!this.collapseAllAction) { - this.collapseAllAction = this.instantiationService.createInstance(CollapseAllAction, this.tree, this.commentsModel.hasCommentThreads()); + this.collapseAllAction = new Action('vs.tree.collapse', nls.localize('collapseAll', "Collapse All"), 'monaco-tree-action collapse-all', true, () => this.tree ? new CollapseAllAction(this.tree, true).run() : Promise.resolve()); this._register(this.collapseAllAction); } @@ -141,22 +137,11 @@ export class CommentsPanel extends Panel { private createTree(): void { this.treeLabels = this._register(this.instantiationService.createInstance(ResourceLabels, this)); + this.tree = this._register(this.instantiationService.createInstance(CommentsList, this.treeLabels, this.treeContainer)); - this.tree = this._register(this.instantiationService.createInstance(WorkbenchTree, this.treeContainer, { - dataSource: new CommentsDataSource(), - renderer: new CommentsModelRenderer(this.treeLabels, this.openerService), - accessibilityProvider: new DefaultAccessibilityProvider, - controller: new DefaultController(), - dnd: new DefaultDragAndDrop(), - filter: new CommentsDataFilter() - }, { - twistiePixels: 20, - ariaLabel: COMMENTS_PANEL_TITLE - })); - - const commentsNavigator = this._register(new TreeResourceNavigator(this.tree, { openOnFocus: true })); - this._register(Event.debounce(commentsNavigator.openResource, (last, event) => event, 100, true)(options => { - this.openFile(options.element, options.editorOptions.pinned, options.editorOptions.preserveFocus, options.sideBySide); + const commentsNavigator = this._register(new TreeResourceNavigator2(this.tree, { openOnFocus: true })); + this._register(commentsNavigator.onDidOpenResource(e => { + this.openFile(e.element, e.editorOptions.pinned, e.editorOptions.preserveFocus, e.sideBySide); })); } @@ -213,7 +198,7 @@ export class CommentsPanel extends Panel { this.collapseAllAction.enabled = this.commentsModel.hasCommentThreads(); dom.toggleClass(this.treeContainer, 'hidden', !this.commentsModel.hasCommentThreads()); - this.tree.refresh().then(() => { + this.tree.updateChildren().then(() => { this.renderMessage(); }, (e) => { console.log(e); @@ -243,4 +228,4 @@ CommandsRegistry.registerCommand({ panelService.openPanel(COMMENTS_PANEL_ID, true); } } -}); \ No newline at end of file +}); diff --git a/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts b/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts index 090ffa54650..7ab435e96ca 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts @@ -9,30 +9,28 @@ import { renderMarkdown } from 'vs/base/browser/htmlContentRenderer'; import { onUnexpectedError } from 'vs/base/common/errors'; import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; -import { IDataSource, IFilter, IRenderer as ITreeRenderer, ITree } from 'vs/base/parts/tree/browser/tree'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IResourceLabel, ResourceLabels } from 'vs/workbench/browser/labels'; import { CommentNode, CommentsModel, ResourceWithCommentThreads } from 'vs/workbench/contrib/comments/common/commentModel'; +import { IAsyncDataSource, ITreeNode } from 'vs/base/browser/ui/tree/tree'; +import { IListVirtualDelegate, IListRenderer } from 'vs/base/browser/ui/list/list'; +import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { WorkbenchAsyncDataTree, IListService } from 'vs/platform/list/browser/listService'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -export class CommentsDataSource implements IDataSource { - public getId(tree: ITree, element: any): string { - if (element instanceof CommentsModel) { - return 'root'; - } - if (element instanceof ResourceWithCommentThreads) { - return `${element.owner}-${element.id}`; - } - if (element instanceof CommentNode) { - return `${element.owner}-${element.resource.toString()}-${element.threadId}-${element.comment.uniqueIdInThread}` + (element.isRoot ? '-root' : ''); - } - return ''; - } +export const COMMENTS_PANEL_ID = 'workbench.panel.comments'; +export const COMMENTS_PANEL_TITLE = 'Comments'; - public hasChildren(tree: ITree, element: any): boolean { +export class CommentsAsyncDataSource implements IAsyncDataSource { + hasChildren(element: any): boolean { return element instanceof CommentsModel || element instanceof ResourceWithCommentThreads || (element instanceof CommentNode && !!element.replies.length); } - public getChildren(tree: ITree, element: any): Promise { + getChildren(element: any): any[] | Promise { if (element instanceof CommentsModel) { return Promise.resolve(element.resourceCommentThreads); } @@ -44,14 +42,6 @@ export class CommentsDataSource implements IDataSource { } return Promise.resolve([]); } - - public getParent(tree: ITree, element: any): Promise { - return Promise.resolve(undefined); - } - - public shouldAutoexpand(tree: ITree, element: any): boolean { - return true; - } } interface IResourceTemplateData { @@ -65,61 +55,36 @@ interface ICommentThreadTemplateData { disposables: IDisposable[]; } -export class CommentsModelRenderer implements ITreeRenderer { +export class CommentsModelVirualDelegate implements IListVirtualDelegate { private static RESOURCE_ID = 'resource-with-comments'; private static COMMENT_ID = 'comment-node'; - constructor( - private labels: ResourceLabels, - @IOpenerService private readonly openerService: IOpenerService - ) { - } - public getHeight(tree: ITree, element: any): number { + getHeight(element: any): number { return 22; } - public getTemplateId(tree: ITree, element: any): string { + public getTemplateId(element: any): string { if (element instanceof ResourceWithCommentThreads) { - return CommentsModelRenderer.RESOURCE_ID; + return CommentsModelVirualDelegate.RESOURCE_ID; } if (element instanceof CommentNode) { - return CommentsModelRenderer.COMMENT_ID; + return CommentsModelVirualDelegate.COMMENT_ID; } return ''; } +} - public renderTemplate(ITree: ITree, templateId: string, container: HTMLElement): any { - switch (templateId) { - case CommentsModelRenderer.RESOURCE_ID: - return this.renderResourceTemplate(container); - case CommentsModelRenderer.COMMENT_ID: - return this.renderCommentTemplate(container); - } +export class ResourceWithCommentsRenderer implements IListRenderer, IResourceTemplateData> { + templateId: string = 'resource-with-comments'; + + constructor( + private labels: ResourceLabels + ) { } - public disposeTemplate(tree: ITree, templateId: string, templateData: any): void { - switch (templateId) { - case CommentsModelRenderer.RESOURCE_ID: - (templateData).resourceLabel.dispose(); - break; - case CommentsModelRenderer.COMMENT_ID: - (templateData).disposables.forEach(disposeable => disposeable.dispose()); - break; - } - } - - public renderElement(tree: ITree, element: any, templateId: string, templateData: any): void { - switch (templateId) { - case CommentsModelRenderer.RESOURCE_ID: - return this.renderResourceElement(tree, element, templateData); - case CommentsModelRenderer.COMMENT_ID: - return this.renderCommentElement(tree, element, templateData); - } - } - - private renderResourceTemplate(container: HTMLElement): IResourceTemplateData { + renderTemplate(container: HTMLElement) { const data = Object.create(null); const labelContainer = dom.append(container, dom.$('.resource-container')); data.resourceLabel = this.labels.create(labelContainer); @@ -127,7 +92,23 @@ export class CommentsModelRenderer implements ITreeRenderer { return data; } - private renderCommentTemplate(container: HTMLElement): ICommentThreadTemplateData { + renderElement(node: ITreeNode, index: number, templateData: IResourceTemplateData, height: number | undefined): void { + templateData.resourceLabel.setFile(node.element.resource); + } + + disposeTemplate(templateData: IResourceTemplateData): void { + templateData.resourceLabel.dispose(); + } +} + +export class CommentNodeRenderer implements IListRenderer, ICommentThreadTemplateData> { + templateId: string = 'comment-node'; + + constructor( + @IOpenerService private readonly openerService: IOpenerService + ) { } + + renderTemplate(container: HTMLElement) { const data = Object.create(null); const labelContainer = dom.append(container, dom.$('.comment-container')); data.userName = dom.append(labelContainer, dom.$('.user')); @@ -137,16 +118,12 @@ export class CommentsModelRenderer implements ITreeRenderer { return data; } - private renderResourceElement(tree: ITree, element: ResourceWithCommentThreads, templateData: IResourceTemplateData) { - templateData.resourceLabel.setFile(element.resource); - } - - private renderCommentElement(tree: ITree, element: CommentNode, templateData: ICommentThreadTemplateData) { - templateData.userName.textContent = element.comment.userName; + renderElement(node: ITreeNode, index: number, templateData: ICommentThreadTemplateData, height: number | undefined): void { + templateData.userName.textContent = node.element.comment.userName; templateData.commentText.innerHTML = ''; const disposables = new DisposableStore(); templateData.disposables.push(disposables); - const renderedComment = renderMarkdown(element.comment.body, { + const renderedComment = renderMarkdown(node.element.comment.body, { inline: true, actionHandler: { callback: (content) => { @@ -171,16 +148,71 @@ export class CommentsModelRenderer implements ITreeRenderer { templateData.commentText.appendChild(renderedComment); } -} -export class CommentsDataFilter implements IFilter { - public isVisible(tree: ITree, element: any): boolean { - if (element instanceof CommentsModel) { - return element.resourceCommentThreads.length > 0; - } - if (element instanceof ResourceWithCommentThreads) { - return element.commentThreads.length > 0; - } - return true; + disposeTemplate(templateData: ICommentThreadTemplateData): void { + templateData.disposables.forEach(disposeable => disposeable.dispose()); + } +} + +export class CommentsList extends WorkbenchAsyncDataTree { + constructor( + labels: ResourceLabels, + container: HTMLElement, + @IContextKeyService contextKeyService: IContextKeyService, + @IListService listService: IListService, + @IThemeService themeService: IThemeService, + @IInstantiationService instantiationService: IInstantiationService, + @IConfigurationService configurationService: IConfigurationService, + @IKeybindingService keybindingService: IKeybindingService, + @IAccessibilityService accessibilityService: IAccessibilityService + ) { + const delegate = new CommentsModelVirualDelegate(); + const dataSource = new CommentsAsyncDataSource(); + + const renderers = [ + instantiationService.createInstance(ResourceWithCommentsRenderer, labels), + instantiationService.createInstance(CommentNodeRenderer) + ]; + + super( + container, + delegate, + renderers, + dataSource, + { + ariaLabel: COMMENTS_PANEL_TITLE, + keyboardSupport: true, + identityProvider: { + getId: (element: any) => { + if (element instanceof CommentsModel) { + return 'root'; + } + if (element instanceof ResourceWithCommentThreads) { + return `${element.owner}-${element.id}`; + } + if (element instanceof CommentNode) { + return `${element.owner}-${element.resource.toString()}-${element.threadId}-${element.comment.uniqueIdInThread}` + (element.isRoot ? '-root' : ''); + } + return ''; + } + }, + expandOnlyOnTwistieClick: (element: any) => { + if (element instanceof CommentsModel || element instanceof ResourceWithCommentThreads) { + return false; + } + + return true; + }, + collapseByDefault: () => { + return false; + } + }, + contextKeyService, + listService, + themeService, + configurationService, + keybindingService, + accessibilityService + ); } } From 1e08f99c4a9b15ebfab9cab68ffac72c3b99466a Mon Sep 17 00:00:00 2001 From: DiamondYuan Date: Tue, 6 Aug 2019 10:25:17 +0800 Subject: [PATCH 233/861] chore: fix typo --- src/vs/platform/storage/node/storageService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/storage/node/storageService.ts b/src/vs/platform/storage/node/storageService.ts index 8598b895448..ca09cbc9cc9 100644 --- a/src/vs/platform/storage/node/storageService.ts +++ b/src/vs/platform/storage/node/storageService.ts @@ -81,7 +81,7 @@ export class StorageService extends Disposable implements IStorageService { const useInMemoryStorage = !!this.environmentService.extensionTestsLocationURI; // no storage during extension tests! - // Create workspace storage and initalize + // Create workspace storage and initialize mark('willInitWorkspaceStorage'); try { await this.createWorkspaceStorage(useInMemoryStorage ? SQLiteStorageDatabase.IN_MEMORY_PATH : join(result.path, StorageService.WORKSPACE_STORAGE_NAME), result.wasCreated ? StorageHint.STORAGE_DOES_NOT_EXIST : undefined).init(); From a7159768f57673ea9bdfa77263d20f31b2844705 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 6 Aug 2019 07:20:05 +0200 Subject: [PATCH 234/861] fix tests --- .../test/electron-browser/configurationService.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts b/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts index e59d6ad40d8..b6e9d5d09fa 100644 --- a/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts @@ -106,6 +106,8 @@ suite('WorkspaceContextService - Folder', () => { workspaceResource = folderDir; const environmentService = new TestEnvironmentService(URI.file(parentDir)); const fileService = new FileService(new NullLogService()); + const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService()); + fileService.registerProvider(Schemas.file, diskFileSystemProvider); fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, environmentService.backupHome, new DiskFileSystemProvider(new NullLogService()), environmentService)); workspaceContextService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, new RemoteAgentService({}, environmentService, new RemoteAuthorityResolverService(), new SignService(undefined))); return (workspaceContextService).initialize(convertToWorkspacePayload(URI.file(folderDir))); From f48eb3f992c4562c9dcfaf4e7d2c4ac34a225ffb Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 6 Aug 2019 08:31:14 +0200 Subject: [PATCH 235/861] test ci From c2b7f61b9efecd8007107eb3bb54aadc68d2ab9d Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 6 Aug 2019 08:35:19 +0200 Subject: [PATCH 236/861] disable auto ci --- build/azure-pipelines/product-build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index ad437466dac..c6a1790c027 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -128,6 +128,8 @@ jobs: steps: - template: sync-mooncake.yml +trigger: none + schedules: - cron: "0 5 * * Mon-Fri" displayName: Mon-Fri at 7:00 From 9bd90d3807e0ae12d2f501108e6b4189fb8c1720 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 6 Aug 2019 08:40:14 +0200 Subject: [PATCH 237/861] test ci again From 2bf257c0c5bd49c149714294a28177f32fa5382b Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 6 Aug 2019 09:59:09 +0200 Subject: [PATCH 238/861] Implement resolveTask for typescript tasks Fixes #76521 --- .../src/extension.ts | 6 +- .../src/features/task.ts | 126 +++++++++--------- 2 files changed, 68 insertions(+), 64 deletions(-) diff --git a/extensions/typescript-language-features/src/extension.ts b/extensions/typescript-language-features/src/extension.ts index a4ec5f1bc0e..ffa61f231f1 100644 --- a/extensions/typescript-language-features/src/extension.ts +++ b/extensions/typescript-language-features/src/extension.ts @@ -7,7 +7,6 @@ import * as vscode from 'vscode'; import { Api, getExtensionApi } from './api'; import { registerCommands } from './commands/index'; import { LanguageConfigurationManager } from './features/languageConfiguration'; -import TypeScriptTaskProviderManager from './features/task'; import TypeScriptServiceClientHost from './typeScriptServiceClientHost'; import { flatten } from './utils/arrays'; import * as electron from './utils/electron'; @@ -21,6 +20,7 @@ import ManagedFileContextManager from './utils/managedFileContext'; import { PluginManager } from './utils/plugins'; import * as ProjectStatus from './utils/projectStatus'; import { Surveyor } from './utils/surveyor'; +import TscTaskProvider from './features/task'; export function activate( context: vscode.ExtensionContext @@ -39,7 +39,7 @@ export function activate( }); registerCommands(commandManager, lazyClientHost, pluginManager); - context.subscriptions.push(new TypeScriptTaskProviderManager(lazyClientHost.map(x => x.serviceClient))); + context.subscriptions.push(vscode.workspace.registerTaskProvider('typescript', new TscTaskProvider(lazyClientHost.map(x => x.serviceClient)))); context.subscriptions.push(new LanguageConfigurationManager()); import('./features/tsconfig').then(module => { @@ -134,4 +134,4 @@ function isSupportedDocument( export function deactivate() { rimraf.sync(electron.getInstanceDir()); -} \ No newline at end of file +} diff --git a/extensions/typescript-language-features/src/features/task.ts b/extensions/typescript-language-features/src/features/task.ts index d9fa6f783d8..e47ee6d7fdc 100644 --- a/extensions/typescript-language-features/src/features/task.ts +++ b/extensions/typescript-language-features/src/features/task.ts @@ -12,8 +12,6 @@ import { ITypeScriptServiceClient } from '../typescriptService'; import { Lazy } from '../utils/lazy'; import { isImplicitProjectConfigFile } from '../utils/tsconfig'; import TsConfigProvider, { TSConfig } from '../utils/tsconfigProvider'; -import { Disposable } from '../utils/dispose'; - const localize = nls.loadMessageBundle(); @@ -36,7 +34,7 @@ interface TypeScriptTaskDefinition extends vscode.TaskDefinition { /** * Provides tasks for building `tsconfig.json` files in a project. */ -class TscTaskProvider implements vscode.TaskProvider { +export default class TscTaskProvider implements vscode.TaskProvider { private autoDetect: AutoDetect = 'on'; private readonly tsconfigProvider: TsConfigProvider; private readonly disposables: vscode.Disposable[] = []; @@ -56,7 +54,7 @@ class TscTaskProvider implements vscode.TaskProvider { public async provideTasks(token: vscode.CancellationToken): Promise { const folders = vscode.workspace.workspaceFolders; - if (!folders || !folders.length) { + if ((this.autoDetect === 'off') || !folders || !folders.length) { return []; } @@ -71,12 +69,29 @@ class TscTaskProvider implements vscode.TaskProvider { return tasks; } - public resolveTask(_task: vscode.Task): vscode.Task | undefined { + public async resolveTask(_task: vscode.Task): Promise { const definition = _task.definition; const badTsconfig = /\\tsconfig.*\.json/; if (badTsconfig.exec(definition.tsconfig) !== null) { // Warn that the task has the wrong slash type vscode.window.showWarningMessage(localize('badTsConfig', "Typescript Task in tasks.json contains \"\\\\\". Typescript tasks tsconfig must use \"/\"")); + return undefined; + } + + const typescriptTask = (_task.definition).tsconfig; + if (typescriptTask) { + if (_task.scope === undefined || _task.scope === vscode.TaskScope.Global || _task.scope === vscode.TaskScope.Workspace) { + // scope is required to be a WorkspaceFolder for resolveTask + return undefined; + } + const kind: TypeScriptTaskDefinition = (_task.definition); + const tsconfigUri: vscode.Uri = _task.scope.uri.with({ path: _task.scope.uri.path + '/' + kind.tsconfig }); + const tsconfig: TSConfig = { + path: tsconfigUri.fsPath, + posixPath: tsconfigUri.path, + workspaceFolder: _task.scope + }; + return this.getTasksForProjectAndDefinition(tsconfig, kind); } return undefined; } @@ -179,6 +194,32 @@ class TscTaskProvider implements vscode.TaskProvider { return undefined; } + private getBuildTask(workspaceFolder: vscode.WorkspaceFolder | undefined, label: string, command: string, args: string[], buildTaskidentifier: TypeScriptTaskDefinition): vscode.Task { + const buildTask = new vscode.Task( + buildTaskidentifier, + workspaceFolder || vscode.TaskScope.Workspace, + localize('buildTscLabel', 'build - {0}', label), + 'tsc', + new vscode.ShellExecution(command, args), + '$tsc'); + buildTask.group = vscode.TaskGroup.Build; + buildTask.isBackground = false; + return buildTask; + } + + private getWatchTask(workspaceFolder: vscode.WorkspaceFolder | undefined, label: string, command: string, args: string[], watchTaskidentifier: TypeScriptTaskDefinition) { + const watchTask = new vscode.Task( + watchTaskidentifier, + workspaceFolder || vscode.TaskScope.Workspace, + localize('buildAndWatchTscLabel', 'watch - {0}', label), + 'tsc', + new vscode.ShellExecution(command, [...args, '--watch']), + '$tsc-watch'); + watchTask.group = vscode.TaskGroup.Build; + watchTask.isBackground = true; + return watchTask; + } + private async getTasksForProject(project: TSConfig): Promise { const command = await TscTaskProvider.getCommand(project); const args = await this.getBuildShellArgs(project); @@ -187,36 +228,33 @@ class TscTaskProvider implements vscode.TaskProvider { const tasks: vscode.Task[] = []; if (this.autoDetect === 'build' || this.autoDetect === 'on') { - const buildTaskidentifier: TypeScriptTaskDefinition = { type: 'typescript', tsconfig: label }; - const buildTask = new vscode.Task( - buildTaskidentifier, - project.workspaceFolder || vscode.TaskScope.Workspace, - localize('buildTscLabel', 'build - {0}', label), - 'tsc', - new vscode.ShellExecution(command, args), - '$tsc'); - buildTask.group = vscode.TaskGroup.Build; - buildTask.isBackground = false; - tasks.push(buildTask); + tasks.push(this.getBuildTask(project.workspaceFolder, label, command, args, { type: 'typescript', tsconfig: label })); } if (this.autoDetect === 'watch' || this.autoDetect === 'on') { - const watchTaskidentifier: TypeScriptTaskDefinition = { type: 'typescript', tsconfig: label, option: 'watch' }; - const watchTask = new vscode.Task( - watchTaskidentifier, - project.workspaceFolder || vscode.TaskScope.Workspace, - localize('buildAndWatchTscLabel', 'watch - {0}', label), - 'tsc', - new vscode.ShellExecution(command, [...args, '--watch']), - '$tsc-watch'); - watchTask.group = vscode.TaskGroup.Build; - watchTask.isBackground = true; - tasks.push(watchTask); + + tasks.push(this.getWatchTask(project.workspaceFolder, label, command, args, { type: 'typescript', tsconfig: label, option: 'watch' })); } return tasks; } + private async getTasksForProjectAndDefinition(project: TSConfig, definition: TypeScriptTaskDefinition): Promise { + const command = await TscTaskProvider.getCommand(project); + const args = await this.getBuildShellArgs(project); + const label = this.getLabelForTasks(project); + + let task: vscode.Task | undefined; + + if (definition.option === undefined) { + task = this.getBuildTask(project.workspaceFolder, label, command, args, definition); + } else if (definition.option === 'watch') { + task = this.getWatchTask(project.workspaceFolder, label, command, args, definition); + } + + return task; + } + private getBuildShellArgs(project: TSConfig): Promise> { const defaultArgs = ['-p', project.path]; return new Promise>((resolve) => { @@ -252,37 +290,3 @@ class TscTaskProvider implements vscode.TaskProvider { this.autoDetect = typeof type === 'undefined' ? 'on' : type; } } - -/** - * Manages registrations of TypeScript task providers with VS Code. - */ -export default class TypeScriptTaskProviderManager extends Disposable { - private taskProviderSub: vscode.Disposable | undefined = undefined; - - constructor( - private readonly client: Lazy - ) { - super(); - vscode.workspace.onDidChangeConfiguration(this.onConfigurationChanged, this, this._disposables); - this.onConfigurationChanged(); - } - - dispose() { - super.dispose(); - - if (this.taskProviderSub) { - this.taskProviderSub.dispose(); - this.taskProviderSub = undefined; - } - } - - private onConfigurationChanged() { - const autoDetect = vscode.workspace.getConfiguration('typescript.tsc').get('autoDetect'); - if (this.taskProviderSub && autoDetect === 'off') { - this.taskProviderSub.dispose(); - this.taskProviderSub = undefined; - } else if (!this.taskProviderSub && autoDetect !== 'off') { - this.taskProviderSub = vscode.workspace.registerTaskProvider('typescript', new TscTaskProvider(this.client)); - } - } -} From c77d1d2e24452da3e645bce6b13073524974d074 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 6 Aug 2019 10:13:53 +0200 Subject: [PATCH 239/861] strictPropertyInitialization #78168 --- .../contrib/debug/browser/breakpointWidget.ts | 104 +++++++++--------- .../contrib/debug/browser/breakpointsView.ts | 4 +- .../contrib/debug/browser/callStackView.ts | 16 +-- .../debug/browser/debugActionViewItems.ts | 22 ++-- .../contrib/debug/browser/debugViewlet.ts | 8 +- .../contrib/debug/node/debugAdapter.ts | 10 +- .../contrib/debug/test/common/mockDebug.ts | 8 +- .../contrib/output/browser/outputActions.ts | 6 +- .../contrib/output/browser/outputPanel.ts | 6 +- .../contrib/output/browser/outputServices.ts | 6 +- .../configurationResolverService.test.ts | 2 +- 11 files changed, 96 insertions(+), 96 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/breakpointWidget.ts b/src/vs/workbench/contrib/debug/browser/breakpointWidget.ts index 7200bad0a0a..136afbbf63d 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointWidget.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointWidget.ts @@ -45,10 +45,10 @@ export interface IPrivateBreakpointWidgetService { const DECORATION_KEY = 'breakpointwidgetdecoration'; export class BreakpointWidget extends ZoneWidget implements IPrivateBreakpointWidgetService { - public _serviceBrand: any; + _serviceBrand: any; - private selectContainer: HTMLElement; - private input: IActiveCodeEditor; + private selectContainer!: HTMLElement; + private input!: IActiveCodeEditor; private toDispose: lifecycle.IDisposable[]; private conditionInput = ''; private hitCountInput = ''; @@ -130,12 +130,12 @@ export class BreakpointWidget extends ZoneWidget implements IPrivateBreakpointWi } } - public show(rangeOrPos: IRange | IPosition, heightInLines: number) { + show(rangeOrPos: IRange | IPosition, heightInLines: number) { const lineNum = this.input.getModel().getLineCount(); super.show(rangeOrPos, lineNum + 1); } - public fitHeightToContent() { + fitHeightToContent() { const lineNum = this.input.getModel().getLineCount(); this._relayout(lineNum + 1); } @@ -165,50 +165,6 @@ export class BreakpointWidget extends ZoneWidget implements IPrivateBreakpointWi setTimeout(() => this.input.focus(), 150); } - public close(success: boolean): void { - if (success) { - // if there is already a breakpoint on this location - remove it. - - let condition = this.breakpoint && this.breakpoint.condition; - let hitCondition = this.breakpoint && this.breakpoint.hitCondition; - let logMessage = this.breakpoint && this.breakpoint.logMessage; - this.rememberInput(); - - if (this.conditionInput || this.context === Context.CONDITION) { - condition = this.conditionInput; - } - if (this.hitCountInput || this.context === Context.HIT_COUNT) { - hitCondition = this.hitCountInput; - } - if (this.logMessageInput || this.context === Context.LOG_MESSAGE) { - logMessage = this.logMessageInput; - } - - if (this.breakpoint) { - const data = new Map(); - data.set(this.breakpoint.getId(), { - condition, - hitCondition, - logMessage - }); - this.debugService.updateBreakpoints(this.breakpoint.uri, data, false).then(undefined, onUnexpectedError); - } else { - const model = this.editor.getModel(); - if (model) { - this.debugService.addBreakpoints(model.uri, [{ - lineNumber: this.lineNumber, - enabled: true, - condition, - hitCondition, - logMessage - }], `breakpointWidget`); - } - } - } - - this.dispose(); - } - protected _doLayout(heightInPixel: number, widthInPixel: number): void { this.input.layout({ height: heightInPixel, width: widthInPixel - 113 }); } @@ -305,7 +261,51 @@ export class BreakpointWidget extends ZoneWidget implements IPrivateBreakpointWi return false; } - public dispose(): void { + close(success: boolean): void { + if (success) { + // if there is already a breakpoint on this location - remove it. + + let condition = this.breakpoint && this.breakpoint.condition; + let hitCondition = this.breakpoint && this.breakpoint.hitCondition; + let logMessage = this.breakpoint && this.breakpoint.logMessage; + this.rememberInput(); + + if (this.conditionInput || this.context === Context.CONDITION) { + condition = this.conditionInput; + } + if (this.hitCountInput || this.context === Context.HIT_COUNT) { + hitCondition = this.hitCountInput; + } + if (this.logMessageInput || this.context === Context.LOG_MESSAGE) { + logMessage = this.logMessageInput; + } + + if (this.breakpoint) { + const data = new Map(); + data.set(this.breakpoint.getId(), { + condition, + hitCondition, + logMessage + }); + this.debugService.updateBreakpoints(this.breakpoint.uri, data, false).then(undefined, onUnexpectedError); + } else { + const model = this.editor.getModel(); + if (model) { + this.debugService.addBreakpoints(model.uri, [{ + lineNumber: this.lineNumber, + enabled: true, + condition, + hitCondition, + logMessage + }], `breakpointWidget`); + } + } + } + + this.dispose(); + } + + dispose(): void { super.dispose(); this.input.dispose(); lifecycle.dispose(this.toDispose); @@ -327,7 +327,7 @@ class AcceptBreakpointWidgetInputAction extends EditorCommand { }); } - public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor): void { + runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor): void { accessor.get(IPrivateBreakpointWidgetService).close(true); } } @@ -347,7 +347,7 @@ class CloseBreakpointWidgetCommand extends EditorCommand { }); } - public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void { + runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void { const debugContribution = editor.getContribution(EDITOR_CONTRIBUTION_ID); if (debugContribution) { // if focus is in outer editor we need to use the debug contribution to close diff --git a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts index 87094b93ebc..72de87a6f1c 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts @@ -45,8 +45,8 @@ function createCheckbox(): HTMLInputElement { export class BreakpointsView extends ViewletPanel { private static readonly MAX_VISIBLE_FILES = 9; - private list: WorkbenchList; - private needsRefresh: boolean; + private list!: WorkbenchList; + private needsRefresh = false; constructor( options: IViewletViewOptions, diff --git a/src/vs/workbench/contrib/debug/browser/callStackView.ts b/src/vs/workbench/contrib/debug/browser/callStackView.ts index 142460a504c..93a7a5ed2bd 100644 --- a/src/vs/workbench/contrib/debug/browser/callStackView.ts +++ b/src/vs/workbench/contrib/debug/browser/callStackView.ts @@ -37,15 +37,15 @@ type CallStackItem = IStackFrame | IThread | IDebugSession | string | ThreadAndS export class CallStackView extends ViewletPanel { - private pauseMessage: HTMLSpanElement; - private pauseMessageLabel: HTMLSpanElement; + private pauseMessage!: HTMLSpanElement; + private pauseMessageLabel!: HTMLSpanElement; private onCallStackChangeScheduler: RunOnceScheduler; - private needsRefresh: boolean; - private ignoreSelectionChangedEvent: boolean; - private ignoreFocusStackFrameEvent: boolean; + private needsRefresh = false; + private ignoreSelectionChangedEvent = false; + private ignoreFocusStackFrameEvent = false; private callStackItemType: IContextKey; - private dataSource: CallStackDataSource; - private tree: WorkbenchAsyncDataTree; + private dataSource!: CallStackDataSource; + private tree!: WorkbenchAsyncDataTree; private contributedContextMenu: IMenu; private parentSessionToExpand = new Set(); @@ -584,7 +584,7 @@ function isDeemphasized(frame: IStackFrame): boolean { } class CallStackDataSource implements IAsyncDataSource { - deemphasizedStackFramesToShow: IStackFrame[]; + deemphasizedStackFramesToShow: IStackFrame[] = []; constructor(private debugService: IDebugService) { } diff --git a/src/vs/workbench/contrib/debug/browser/debugActionViewItems.ts b/src/vs/workbench/contrib/debug/browser/debugActionViewItems.ts index 0e160e29040..8e4b12fde6c 100644 --- a/src/vs/workbench/contrib/debug/browser/debugActionViewItems.ts +++ b/src/vs/workbench/contrib/debug/browser/debugActionViewItems.ts @@ -27,13 +27,13 @@ export class StartDebugActionViewItem implements IActionViewItem { private static readonly SEPARATOR = '─────────'; - public actionRunner: IActionRunner; - private container: HTMLElement; - private start: HTMLElement; + actionRunner!: IActionRunner; + private container!: HTMLElement; + private start!: HTMLElement; private selectBox: SelectBox; - private options: { label: string, handler?: (() => boolean) }[]; + private options: { label: string, handler?: (() => boolean) }[] = []; private toDispose: IDisposable[]; - private selected: number; + private selected = 0; constructor( private context: any, @@ -66,7 +66,7 @@ export class StartDebugActionViewItem implements IActionViewItem { })); } - public render(container: HTMLElement): void { + render(container: HTMLElement): void { this.container = container; dom.addClass(container, 'start-debug-action-item'); this.start = dom.append(container, $('.icon')); @@ -129,15 +129,15 @@ export class StartDebugActionViewItem implements IActionViewItem { this.updateOptions(); } - public setActionContext(context: any): void { + setActionContext(context: any): void { this.context = context; } - public isEnabled(): boolean { + isEnabled(): boolean { return true; } - public focus(fromRight?: boolean): void { + focus(fromRight?: boolean): void { if (fromRight) { this.selectBox.focus(); } else { @@ -145,11 +145,11 @@ export class StartDebugActionViewItem implements IActionViewItem { } } - public blur(): void { + blur(): void { this.container.blur(); } - public dispose(): void { + dispose(): void { this.toDispose = dispose(this.toDispose); } diff --git a/src/vs/workbench/contrib/debug/browser/debugViewlet.ts b/src/vs/workbench/contrib/debug/browser/debugViewlet.ts index c4bf84c04a0..10681dbeda0 100644 --- a/src/vs/workbench/contrib/debug/browser/debugViewlet.ts +++ b/src/vs/workbench/contrib/debug/browser/debugViewlet.ts @@ -36,12 +36,12 @@ import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; export class DebugViewlet extends ViewContainerViewlet { - private startDebugActionViewItem: StartDebugActionViewItem; + private startDebugActionViewItem: StartDebugActionViewItem | undefined; private progressResolve: (() => void) | undefined; - private breakpointView: ViewletPanel; + private breakpointView: ViewletPanel | undefined; private panelListeners = new Map(); - private debugToolBarMenu: IMenu; - private disposeOnTitleUpdate: IDisposable; + private debugToolBarMenu: IMenu | undefined; + private disposeOnTitleUpdate: IDisposable | undefined; constructor( @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, diff --git a/src/vs/workbench/contrib/debug/node/debugAdapter.ts b/src/vs/workbench/contrib/debug/node/debugAdapter.ts index 360a27a9329..3a8e1feb93a 100644 --- a/src/vs/workbench/contrib/debug/node/debugAdapter.ts +++ b/src/vs/workbench/contrib/debug/node/debugAdapter.ts @@ -27,9 +27,9 @@ export abstract class StreamDebugAdapter extends AbstractDebugAdapter { private static readonly HEADER_LINESEPARATOR = /\r?\n/; // allow for non-RFC 2822 conforming line separators private static readonly HEADER_FIELDSEPARATOR = /: */; - private outputStream: stream.Writable; - private rawData: Buffer; - private contentLength: number; + private outputStream!: stream.Writable; + private rawData = Buffer.allocUnsafe(0); + private contentLength = -1; constructor() { super(); @@ -145,7 +145,7 @@ export class SocketDebugAdapter extends StreamDebugAdapter { */ export class ExecutableDebugAdapter extends StreamDebugAdapter { - private serverProcess: cp.ChildProcess; + private serverProcess: cp.ChildProcess | undefined; constructor(private adapterExecutable: IDebugAdapterExecutable, private debugType: string, private readonly outputService?: IOutputService) { super(); @@ -266,7 +266,7 @@ export class ExecutableDebugAdapter extends StreamDebugAdapter { // processes. Therefore we use TASKKILL.EXE if (platform.isWindows) { return new Promise((c, e) => { - const killer = cp.exec(`taskkill /F /T /PID ${this.serverProcess.pid}`, function (err, stdout, stderr) { + const killer = cp.exec(`taskkill /F /T /PID ${this.serverProcess!.pid}`, function (err, stdout, stderr) { if (err) { return e(err); } diff --git a/src/vs/workbench/contrib/debug/test/common/mockDebug.ts b/src/vs/workbench/contrib/debug/test/common/mockDebug.ts index bae3cd2b832..19aae90891d 100644 --- a/src/vs/workbench/contrib/debug/test/common/mockDebug.ts +++ b/src/vs/workbench/contrib/debug/test/common/mockDebug.ts @@ -155,7 +155,7 @@ export class MockSession implements IDebugSession { configuration: IConfig = { type: 'mock', name: 'mock', request: 'launch' }; unresolvedConfiguration: IConfig = { type: 'mock', name: 'mock', request: 'launch' }; state = State.Stopped; - root: IWorkspaceFolder; + root!: IWorkspaceFolder; capabilities: DebugProtocol.Capabilities = {}; getId(): string { @@ -301,9 +301,9 @@ export class MockSession implements IDebugSession { export class MockRawSession { - capabilities: DebugProtocol.Capabilities; - disconnected: boolean; - sessionLengthInSeconds: number; + capabilities: DebugProtocol.Capabilities = {}; + disconnected = false; + sessionLengthInSeconds: number = 0; public readyForBreakpoints = true; public emittedStopped = true; diff --git a/src/vs/workbench/contrib/output/browser/outputActions.ts b/src/vs/workbench/contrib/output/browser/outputActions.ts index e99147c8079..561891fc62e 100644 --- a/src/vs/workbench/contrib/output/browser/outputActions.ts +++ b/src/vs/workbench/contrib/output/browser/outputActions.ts @@ -122,8 +122,8 @@ export class SwitchOutputActionViewItem extends SelectActionViewItem { private static readonly SEPARATOR = '─────────'; - private outputChannels: IOutputChannelDescriptor[]; - private logChannels: IOutputChannelDescriptor[]; + private outputChannels: IOutputChannelDescriptor[] = []; + private logChannels: IOutputChannelDescriptor[] = []; constructor( action: IAction, @@ -267,4 +267,4 @@ export class OpenOutputLogFileAction extends Action { return undefined; }); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/contrib/output/browser/outputPanel.ts b/src/vs/workbench/contrib/output/browser/outputPanel.ts index 09365d68550..b63f819dcf6 100644 --- a/src/vs/workbench/contrib/output/browser/outputPanel.ts +++ b/src/vs/workbench/contrib/output/browser/outputPanel.ts @@ -29,9 +29,9 @@ import { IWindowService } from 'vs/platform/windows/common/windows'; import { CursorChangeReason } from 'vs/editor/common/controller/cursorEvents'; export class OutputPanel extends AbstractTextResourceEditor { - private actions: IAction[]; + private actions: IAction[] | undefined; private scopedInstantiationService: IInstantiationService; - private _focus: boolean; + private _focus = false; constructor( @ITelemetryService telemetryService: ITelemetryService, @@ -155,7 +155,7 @@ export class OutputPanel extends AbstractTextResourceEditor { } const model = codeEditor.getModel(); - if (model) { + if (model && this.actions) { const newPositionLine = e.position.lineNumber; const lastLine = model.getLineCount(); const newLockState = lastLine !== newPositionLine; diff --git a/src/vs/workbench/contrib/output/browser/outputServices.ts b/src/vs/workbench/contrib/output/browser/outputServices.ts index 695b84e3c23..13d736f2db0 100644 --- a/src/vs/workbench/contrib/output/browser/outputServices.ts +++ b/src/vs/workbench/contrib/output/browser/outputServices.ts @@ -71,7 +71,7 @@ export class OutputService extends Disposable implements IOutputService, ITextMo private readonly _onActiveOutputChannel = this._register(new Emitter()); readonly onActiveOutputChannel: Event = this._onActiveOutputChannel.event; - private _outputPanel: OutputPanel; + private _outputPanel: OutputPanel | undefined; constructor( @IStorageService private readonly storageService: IStorageService, @@ -224,7 +224,7 @@ export class OutputService extends Disposable implements IOutputService, ITextMo CONTEXT_ACTIVE_LOG_OUTPUT.bindTo(this.contextKeyService).set(!!channel.outputChannelDescriptor.file && channel.outputChannelDescriptor.log); return this._outputPanel.setInput(this.createInput(channel), EditorOptions.create({ preserveFocus }), CancellationToken.None) .then(() => { - if (!preserveFocus) { + if (!preserveFocus && this._outputPanel) { this._outputPanel.focus(); } }); @@ -291,4 +291,4 @@ export class LogContentProvider { } return channelModel; } -} \ No newline at end of file +} diff --git a/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts b/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts index 5b9f44514e9..dd668c74f6d 100644 --- a/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts +++ b/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts @@ -555,7 +555,7 @@ class MockQuickInputService implements IQuickInputService { return Promise.resolve(options ? 'resolved' + options.prompt : 'resolved'); } - backButton: IQuickInputButton; + backButton!: IQuickInputButton; createQuickPick(): IQuickPick { throw new Error('not implemented.'); From b2450ce9450001a1ce1a48d16e045b27edd0fc17 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 6 Aug 2019 10:16:55 +0200 Subject: [PATCH 240/861] :lipstick: --- .../services/extensions/node/extensionHostMain.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/services/extensions/node/extensionHostMain.ts b/src/vs/workbench/services/extensions/node/extensionHostMain.ts index b5913991608..6cf41ef0492 100644 --- a/src/vs/workbench/services/extensions/node/extensionHostMain.ts +++ b/src/vs/workbench/services/extensions/node/extensionHostMain.ts @@ -40,7 +40,7 @@ export class ExtensionHostMain { private _isTerminating: boolean; private readonly _hostUtils: IHostUtils; private readonly _extensionService: ExtHostExtensionService; - private readonly disposables = new DisposableStore(); + private readonly _disposables = new DisposableStore(); constructor( protocol: IMessagePassingProtocol, @@ -55,14 +55,14 @@ export class ExtensionHostMain { const rpcProtocol = new RPCProtocol(protocol, null, uriTransformer); // ensure URIs are transformed and revived - initData = this.transform(initData, rpcProtocol); + initData = ExtensionHostMain._transform(initData, rpcProtocol); // allow to patch console consolePatchFn(rpcProtocol.getProxy(MainContext.MainThreadConsole)); // services const extHostLogService = new ExtHostLogService(logServiceFn(initData), initData.logsLocation.fsPath); - this.disposables.add(extHostLogService); + this._disposables.add(extHostLogService); const extHostWorkspace = new ExtHostWorkspace(rpcProtocol, extHostLogService, withNullAsUndefined(initData.workspace)); @@ -122,7 +122,7 @@ export class ExtensionHostMain { } this._isTerminating = true; - this.disposables.dispose(); + this._disposables.dispose(); errors.setUnexpectedErrorHandler((err) => { // TODO: write to log once we have one @@ -136,7 +136,7 @@ export class ExtensionHostMain { }, 1000); } - private transform(initData: IInitData, rpcProtocol: RPCProtocol): IInitData { + private static _transform(initData: IInitData, rpcProtocol: RPCProtocol): IInitData { initData.extensions.forEach((ext) => (ext).extensionLocation = URI.revive(rpcProtocol.transformIncomingURIs(ext.extensionLocation))); initData.environment.appRoot = URI.revive(rpcProtocol.transformIncomingURIs(initData.environment.appRoot)); initData.environment.appSettingsHome = URI.revive(rpcProtocol.transformIncomingURIs(initData.environment.appSettingsHome)); From 78b0c662cf9c32b3cf0ef7334402d250ea74bcb5 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 6 Aug 2019 10:22:10 +0200 Subject: [PATCH 241/861] files - lazy trie --- src/vs/platform/files/common/fileService.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/vs/platform/files/common/fileService.ts b/src/vs/platform/files/common/fileService.ts index 8a22485eca5..34a6974e03c 100644 --- a/src/vs/platform/files/common/fileService.ts +++ b/src/vs/platform/files/common/fileService.ts @@ -164,21 +164,25 @@ export class FileService extends Disposable implements IFileService { private async doResolveFile(resource: URI, options?: IResolveFileOptions): Promise { const provider = await this.withProvider(resource); - // leverage a trie to check for recursive resolving const resolveTo = options && options.resolveTo; - const trie = TernarySearchTree.forPaths(); - trie.set(resource.toString(), true); - if (isNonEmptyArray(resolveTo)) { - resolveTo.forEach(uri => trie.set(uri.toString(), true)); - } - const resolveSingleChildDescendants = !!(options && options.resolveSingleChildDescendants); const resolveMetadata = !!(options && options.resolveMetadata); const stat = await provider.stat(resource); + let trie: TernarySearchTree | undefined; + return this.toFileStat(provider, resource, stat, undefined, resolveMetadata, (stat, siblings) => { + // lazy trie to check for recursive resolving + if (!trie) { + trie = TernarySearchTree.forPaths(); + trie.set(resource.toString(), true); + if (isNonEmptyArray(resolveTo)) { + resolveTo.forEach(uri => trie!.set(uri.toString(), true)); + } + } + // check for recursive resolving if (Boolean(trie.findSuperstr(stat.resource.toString()) || trie.get(stat.resource.toString()))) { return true; From bb0e9fd5670ac52276d6682929a3bf8d52da0e4e Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 6 Aug 2019 10:27:00 +0200 Subject: [PATCH 242/861] keyboard - disable failing tests (#78544) --- .../services/keybinding/test/browserKeyboardMapper.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/services/keybinding/test/browserKeyboardMapper.test.ts b/src/vs/workbench/services/keybinding/test/browserKeyboardMapper.test.ts index cbc20c36579..e6f8b9b4d97 100644 --- a/src/vs/workbench/services/keybinding/test/browserKeyboardMapper.test.ts +++ b/src/vs/workbench/services/keybinding/test/browserKeyboardMapper.test.ts @@ -40,12 +40,12 @@ suite('keyboard layout loader', () => { let commandService = instantiationService.stub(ICommandService, {}); let instance = new TestKeyboardMapperFactory(notitifcationService, storageService, commandService); - test('load default US keyboard layout', () => { + test.skip('load default US keyboard layout', () => { assert.notEqual(instance.activeKeyboardLayout, null); assert.equal(instance.activeKeyboardLayout!.isUSStandard, true); }); - test('isKeyMappingActive', () => { + test.skip('isKeyMappingActive', () => { assert.equal(instance.isKeyMappingActive({ KeyA: { value: 'a', From 31cd6aea845f3c5ea5d526211bfbd73c474451d3 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 6 Aug 2019 10:50:20 +0200 Subject: [PATCH 243/861] strictPropertyInitialization #78168 --- .../browser/debugConfigurationManager.ts | 2 +- .../debug/browser/debugEditorContribution.ts | 14 +++++++---- .../debug/browser/debugEditorModelManager.ts | 2 +- .../contrib/debug/browser/debugHover.ts | 19 ++++++++------- .../contrib/debug/browser/debugQuickOpen.ts | 2 +- .../contrib/debug/browser/debugService.ts | 2 +- .../contrib/debug/browser/debugToolBar.ts | 7 +++--- .../debug/browser/loadedScriptsView.ts | 18 +++++++-------- .../contrib/debug/browser/rawDebugSession.ts | 23 +++++++------------ .../contrib/debug/browser/variablesView.ts | 4 ++-- .../debug/browser/watchExpressionsView.ts | 4 ++-- .../debug/common/abstractDebugAdapter.ts | 6 ++--- 12 files changed, 49 insertions(+), 54 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts b/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts index df8a68cbc67..6ace957453c 100644 --- a/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts +++ b/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts @@ -44,7 +44,7 @@ const DEBUG_SELECTED_ROOT = 'debug.selectedroot'; export class ConfigurationManager implements IConfigurationManager { private debuggers: Debugger[]; private breakpointModeIdsSet = new Set(); - private launches: ILaunch[]; + private launches!: ILaunch[]; private selectedName: string | undefined; private selectedLaunch: ILaunch | undefined; private toDispose: IDisposable[]; diff --git a/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts b/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts index 1b6dbbb7d5f..2074a14ab74 100644 --- a/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts +++ b/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts @@ -57,8 +57,8 @@ export class DebugEditorContribution implements IDebugEditorContribution { private toDispose: lifecycle.IDisposable[]; private hoverWidget: DebugHoverWidget; - private nonDebugHoverPosition: Position; - private hoverRange: Range; + private nonDebugHoverPosition: Position | undefined; + private hoverRange: Range | null = null; private mouseDown = false; private breakpointHintDecoration: string[]; @@ -68,7 +68,7 @@ export class DebugEditorContribution implements IDebugEditorContribution { private exceptionWidget: ExceptionWidget | undefined; - private configurationWidget: FloatingClickWidget; + private configurationWidget: FloatingClickWidget | undefined; constructor( private editor: ICodeEditor, @@ -377,7 +377,11 @@ export class DebugEditorContribution implements IDebugEditorContribution { @memoize private get showHoverScheduler(): RunOnceScheduler { - const scheduler = new RunOnceScheduler(() => this.showHover(this.hoverRange, false), HOVER_DELAY); + const scheduler = new RunOnceScheduler(() => { + if (this.hoverRange) { + this.showHover(this.hoverRange, false); + } + }, HOVER_DELAY); this.toDispose.push(scheduler); return scheduler; @@ -398,7 +402,7 @@ export class DebugEditorContribution implements IDebugEditorContribution { @memoize private get provideNonDebugHoverScheduler(): RunOnceScheduler { const scheduler = new RunOnceScheduler(() => { - if (this.editor.hasModel()) { + if (this.editor.hasModel() && this.nonDebugHoverPosition) { getHover(this.editor.getModel(), this.nonDebugHoverPosition, CancellationToken.None); } }, HOVER_DELAY); diff --git a/src/vs/workbench/contrib/debug/browser/debugEditorModelManager.ts b/src/vs/workbench/contrib/debug/browser/debugEditorModelManager.ts index 9a4cdf0bb6e..84dd90e7056 100644 --- a/src/vs/workbench/contrib/debug/browser/debugEditorModelManager.ts +++ b/src/vs/workbench/contrib/debug/browser/debugEditorModelManager.ts @@ -36,7 +36,7 @@ export class DebugEditorModelManager implements IWorkbenchContribution { static readonly STICKINESS = TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges; private modelDataMap: Map; private toDispose: lifecycle.IDisposable[]; - private ignoreDecorationsChangedEvent: boolean; + private ignoreDecorationsChangedEvent = false; constructor( @IModelService private readonly modelService: IModelService, diff --git a/src/vs/workbench/contrib/debug/browser/debugHover.ts b/src/vs/workbench/contrib/debug/browser/debugHover.ts index 37e81c80c52..f06919be1d9 100644 --- a/src/vs/workbench/contrib/debug/browser/debugHover.ts +++ b/src/vs/workbench/contrib/debug/browser/debugHover.ts @@ -41,17 +41,16 @@ export class DebugHoverWidget implements IContentWidget { allowEditorOverflow = true; private _isVisible: boolean; - private domNode: HTMLElement; - private tree: AsyncDataTree; + private domNode!: HTMLElement; + private tree!: AsyncDataTree; private showAtPosition: Position | null; private highlightDecorations: string[]; - private complexValueContainer: HTMLElement; - private complexValueTitle: HTMLElement; - private valueContainer: HTMLElement; - private treeContainer: HTMLElement; + private complexValueContainer!: HTMLElement; + private complexValueTitle!: HTMLElement; + private valueContainer!: HTMLElement; + private treeContainer!: HTMLElement; private toDispose: lifecycle.IDisposable[]; - private scrollbar: DomScrollableElement; - private dataSource: DebugHoverDataSource; + private scrollbar!: DomScrollableElement; constructor( private editor: ICodeEditor, @@ -72,10 +71,10 @@ export class DebugHoverWidget implements IContentWidget { this.complexValueTitle = dom.append(this.complexValueContainer, $('.title')); this.treeContainer = dom.append(this.complexValueContainer, $('.debug-hover-tree')); this.treeContainer.setAttribute('role', 'tree'); - this.dataSource = new DebugHoverDataSource(); + const dataSource = new DebugHoverDataSource(); this.tree = this.instantiationService.createInstance(WorkbenchAsyncDataTree, this.treeContainer, new DebugHoverDelegate(), [this.instantiationService.createInstance(VariablesRenderer)], - this.dataSource, { + dataSource, { ariaLabel: nls.localize('treeAriaLabel', "Debug Hover"), accessibilityProvider: new DebugHoverAccessibilityProvider(), mouseSupport: false, diff --git a/src/vs/workbench/contrib/debug/browser/debugQuickOpen.ts b/src/vs/workbench/contrib/debug/browser/debugQuickOpen.ts index d75f5a9b0df..64a399d212f 100644 --- a/src/vs/workbench/contrib/debug/browser/debugQuickOpen.ts +++ b/src/vs/workbench/contrib/debug/browser/debugQuickOpen.ts @@ -77,7 +77,7 @@ export class DebugQuickOpenHandler extends QuickOpenHandler { public static readonly ID = 'workbench.picker.launch'; - private autoFocusIndex: number; + private autoFocusIndex: number | undefined; constructor( @IDebugService private readonly debugService: IDebugService, diff --git a/src/vs/workbench/contrib/debug/browser/debugService.ts b/src/vs/workbench/contrib/debug/browser/debugService.ts index 1ae35d5a248..da261aa0032 100644 --- a/src/vs/workbench/contrib/debug/browser/debugService.ts +++ b/src/vs/workbench/contrib/debug/browser/debugService.ts @@ -87,7 +87,7 @@ export class DebugService implements IDebugService { private inDebugMode: IContextKey; private breakpointsToSendOnResourceSaved: Set; private initializing = false; - private previousState: State; + private previousState: State | undefined; constructor( @IStorageService private readonly storageService: IStorageService, diff --git a/src/vs/workbench/contrib/debug/browser/debugToolBar.ts b/src/vs/workbench/contrib/debug/browser/debugToolBar.ts index dc603f4eedb..5146eac7f78 100644 --- a/src/vs/workbench/contrib/debug/browser/debugToolBar.ts +++ b/src/vs/workbench/contrib/debug/browser/debugToolBar.ts @@ -55,10 +55,10 @@ export class DebugToolBar extends Themable implements IWorkbenchContribution { private activeActions: IAction[]; private updateScheduler: RunOnceScheduler; private debugToolBarMenu: IMenu; - private disposeOnUpdate: IDisposable; + private disposeOnUpdate: IDisposable | undefined; - private isVisible: boolean; - private isBuilt: boolean; + private isVisible = false; + private isBuilt = false; constructor( @INotificationService private readonly notificationService: INotificationService, @@ -126,7 +126,6 @@ export class DebugToolBar extends Themable implements IWorkbenchContribution { this.registerListeners(); this.hide(); - this.isBuilt = false; } private registerListeners(): void { diff --git a/src/vs/workbench/contrib/debug/browser/loadedScriptsView.ts b/src/vs/workbench/contrib/debug/browser/loadedScriptsView.ts index 70a962e46ec..6a70b78319b 100644 --- a/src/vs/workbench/contrib/debug/browser/loadedScriptsView.ts +++ b/src/vs/workbench/contrib/debug/browser/loadedScriptsView.ts @@ -46,7 +46,7 @@ class BaseTreeItem { private _showedMoreThanOne: boolean; private _children = new Map(); - private _source: Source; + private _source: Source | undefined; constructor(private _parent: BaseTreeItem | undefined, private _label: string) { this._showedMoreThanOne = false; @@ -184,7 +184,7 @@ class BaseTreeItem { } // skips intermediate single-child nodes - getSource(): Source { + getSource(): Source | undefined { const child = this.oneChild(); if (child) { return child.getSource(); @@ -381,13 +381,13 @@ class SessionTreeItem extends BaseTreeItem { export class LoadedScriptsView extends ViewletPanel { - private treeContainer: HTMLElement; + private treeContainer!: HTMLElement; private loadedScriptsItemType: IContextKey; - private tree: WorkbenchAsyncDataTree; - private treeLabels: ResourceLabels; - private changeScheduler: RunOnceScheduler; - private treeNeedsRefreshOnVisible: boolean; - private filter: LoadedScriptsFilter; + private tree!: WorkbenchAsyncDataTree; + private treeLabels!: ResourceLabels; + private changeScheduler!: RunOnceScheduler; + private treeNeedsRefreshOnVisible = false; + private filter!: LoadedScriptsFilter; constructor( options: IViewletViewOptions, @@ -635,7 +635,7 @@ class LoadedSciptsAccessibilityProvider implements IAccessibilityProvider { - private filterText: string; + private filterText: string | undefined; setFilter(filterText: string) { this.filterText = filterText; diff --git a/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts b/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts index a0f2120b920..39bb171c4ec 100644 --- a/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts @@ -37,19 +37,19 @@ interface ILaunchVSCodeArguments { */ export class RawDebugSession { - private allThreadsContinued: boolean; - private _readyForBreakpoints: boolean; + private allThreadsContinued = true; + private _readyForBreakpoints = false; private _capabilities: DebugProtocol.Capabilities; // shutdown - private debugAdapterStopped: boolean; - private inShutdown: boolean; - private terminated: boolean; - private firedAdapterExitEvent: boolean; + private debugAdapterStopped = false; + private inShutdown = false; + private terminated = false; + private firedAdapterExitEvent = false; // telemetry - private startTime: number; - private didReceiveStoppedEvent: boolean; + private startTime = 0; + private didReceiveStoppedEvent = false; // DAP events private readonly _onDidInitialize: Emitter; @@ -78,13 +78,6 @@ export class RawDebugSession { ) { this.debugAdapter = debugAdapter; this._capabilities = Object.create(null); - this._readyForBreakpoints = false; - this.inShutdown = false; - this.debugAdapterStopped = false; - this.firedAdapterExitEvent = false; - this.didReceiveStoppedEvent = false; - - this.allThreadsContinued = true; this._onDidInitialize = new Emitter(); this._onDidStop = new Emitter(); diff --git a/src/vs/workbench/contrib/debug/browser/variablesView.ts b/src/vs/workbench/contrib/debug/browser/variablesView.ts index 71559c50d3c..45eb8037c71 100644 --- a/src/vs/workbench/contrib/debug/browser/variablesView.ts +++ b/src/vs/workbench/contrib/debug/browser/variablesView.ts @@ -39,8 +39,8 @@ export const variableSetEmitter = new Emitter(); export class VariablesView extends ViewletPanel { private onFocusStackFrameScheduler: RunOnceScheduler; - private needsRefresh: boolean; - private tree: WorkbenchAsyncDataTree; + private needsRefresh = false; + private tree!: WorkbenchAsyncDataTree; private savedViewState: IAsyncDataTreeViewState | undefined; constructor( diff --git a/src/vs/workbench/contrib/debug/browser/watchExpressionsView.ts b/src/vs/workbench/contrib/debug/browser/watchExpressionsView.ts index 7b0430d2504..ecc9524f016 100644 --- a/src/vs/workbench/contrib/debug/browser/watchExpressionsView.ts +++ b/src/vs/workbench/contrib/debug/browser/watchExpressionsView.ts @@ -36,8 +36,8 @@ const MAX_VALUE_RENDER_LENGTH_IN_VIEWLET = 1024; export class WatchExpressionsView extends ViewletPanel { private onWatchExpressionsUpdatedScheduler: RunOnceScheduler; - private needsRefresh: boolean; - private tree: WorkbenchAsyncDataTree; + private needsRefresh = false; + private tree!: WorkbenchAsyncDataTree; constructor( options: IViewletViewOptions, diff --git a/src/vs/workbench/contrib/debug/common/abstractDebugAdapter.ts b/src/vs/workbench/contrib/debug/common/abstractDebugAdapter.ts index 17dfdf746ad..74d087e06b7 100644 --- a/src/vs/workbench/contrib/debug/common/abstractDebugAdapter.ts +++ b/src/vs/workbench/contrib/debug/common/abstractDebugAdapter.ts @@ -14,9 +14,9 @@ export abstract class AbstractDebugAdapter implements IDebugAdapter { private sequence: number; private pendingRequests = new Map void>(); - private requestCallback: (request: DebugProtocol.Request) => void; - private eventCallback: (request: DebugProtocol.Event) => void; - private messageCallback: (message: DebugProtocol.ProtocolMessage) => void; + private requestCallback: ((request: DebugProtocol.Request) => void) | undefined; + private eventCallback: ((request: DebugProtocol.Event) => void) | undefined; + private messageCallback: ((message: DebugProtocol.ProtocolMessage) => void) | undefined; protected readonly _onError: Emitter; protected readonly _onExit: Emitter; From 6ac91118fa021b38d7a3543160ac8ec6d3c571da Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 6 Aug 2019 11:06:10 +0200 Subject: [PATCH 244/861] strictPropertyInitialization #78168 --- .../browser/ui/selectBox/selectBoxCustom.ts | 28 +++++++++---------- .../workbench/browser/parts/compositeBar.ts | 10 +++---- .../browser/parts/compositeBarActions.ts | 24 ++++++++-------- .../browser/parts/panel/panelPart.ts | 8 +++--- src/vs/workbench/browser/viewlet.ts | 2 +- .../output/common/outputChannelModel.ts | 6 ++-- 6 files changed, 40 insertions(+), 38 deletions(-) diff --git a/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts b/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts index f26942d54e9..134c64bbef4 100644 --- a/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts +++ b/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts @@ -89,21 +89,21 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi private _isVisible: boolean; private selectBoxOptions: ISelectBoxOptions; private selectElement: HTMLSelectElement; - private options: ISelectOptionItem[]; + private options: ISelectOptionItem[] = []; private selected: number; private readonly _onDidSelect: Emitter; private styles: ISelectBoxStyles; - private listRenderer: SelectListRenderer; - private contextViewProvider: IContextViewProvider; - private selectDropDownContainer: HTMLElement; - private styleElement: HTMLStyleElement; - private selectList: List; - private selectDropDownListContainer: HTMLElement; - private widthControlElement: HTMLElement; - private _currentSelection: number; - private _dropDownPosition: AnchorPosition; + private listRenderer!: SelectListRenderer; + private contextViewProvider!: IContextViewProvider; + private selectDropDownContainer!: HTMLElement; + private styleElement!: HTMLStyleElement; + private selectList!: List; + private selectDropDownListContainer!: HTMLElement; + private widthControlElement!: HTMLElement; + private _currentSelection = 0; + private _dropDownPosition!: AnchorPosition; private _hasDetails: boolean = false; - private selectionDetailsPane: HTMLElement; + private selectionDetailsPane!: HTMLElement; private _skipLayout: boolean = false; private _sticky: boolean = false; // for dev purposes only @@ -241,7 +241,7 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi } public setOptions(options: ISelectOptionItem[], selected?: number): void { - if (!this.options || !arrays.equals(this.options, options)) { + if (!arrays.equals(this.options, options)) { this.options = options; this.selectElement.options.length = 0; this._hasDetails = false; @@ -266,7 +266,7 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi // Mirror options in drop-down // Populate select list for non-native select mode - if (this.selectList && !!this.options) { + if (this.selectList) { this.selectList.splice(0, this.selectList.length, this.options); } } @@ -689,7 +689,7 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi private setWidthControlElement(container: HTMLElement): number { let elementWidth = 0; - if (container && !!this.options) { + if (container) { let longest = 0; let longestLength = 0; diff --git a/src/vs/workbench/browser/parts/compositeBar.ts b/src/vs/workbench/browser/parts/compositeBar.ts index 69f53744b05..7a39fce8178 100644 --- a/src/vs/workbench/browser/parts/compositeBar.ts +++ b/src/vs/workbench/browser/parts/compositeBar.ts @@ -46,10 +46,10 @@ export interface ICompositeBarOptions { export class CompositeBar extends Widget implements ICompositeBar { - private dimension: Dimension; + private dimension: Dimension | undefined; - private compositeSwitcherBar: ActionBar; - private compositeOverflowAction: CompositeOverflowActivityAction | null; + private compositeSwitcherBar!: ActionBar; + private compositeOverflowAction: CompositeOverflowActivityAction | undefined; private compositeOverflowActionViewItem: CompositeOverflowActivityActionViewItem | undefined; private model: CompositeBarModel; @@ -343,7 +343,7 @@ export class CompositeBar extends Widget implements ICompositeBar { this.compositeSwitcherBar.pull(this.compositeSwitcherBar.length() - 1); this.compositeOverflowAction.dispose(); - this.compositeOverflowAction = null; + this.compositeOverflowAction = undefined; if (this.compositeOverflowActionViewItem) { this.compositeOverflowActionViewItem.dispose(); @@ -460,7 +460,7 @@ interface ICompositeBarModelItem extends ICompositeBarItem { class CompositeBarModel { - private _items: ICompositeBarModelItem[]; + private _items: ICompositeBarModelItem[] = []; private readonly options: ICompositeBarOptions; activeItem?: ICompositeBarModelItem; diff --git a/src/vs/workbench/browser/parts/compositeBarActions.ts b/src/vs/workbench/browser/parts/compositeBarActions.ts index d3445a9bbb6..d93d9aec8b7 100644 --- a/src/vs/workbench/browser/parts/compositeBarActions.ts +++ b/src/vs/workbench/browser/parts/compositeBarActions.ts @@ -124,12 +124,12 @@ export interface IActivityActionViewItemOptions extends IBaseActionViewItemOptio } export class ActivityActionViewItem extends BaseActionViewItem { - protected container: HTMLElement; - protected label: HTMLElement; - protected badge: HTMLElement; - protected options: IActivityActionViewItemOptions; + protected container!: HTMLElement; + protected label!: HTMLElement; + protected badge!: HTMLElement; + protected options!: IActivityActionViewItemOptions; - private badgeContent: HTMLElement; + private badgeContent: HTMLElement | undefined; private readonly badgeDisposable = this._register(new MutableDisposable()); private mouseUpTimeout: any; @@ -347,7 +347,7 @@ export class CompositeOverflowActivityAction extends ActivityAction { } export class CompositeOverflowActivityActionViewItem extends ActivityActionViewItem { - private actions: Action[]; + private actions: Action[] | undefined; constructor( action: ActivityAction, @@ -371,8 +371,8 @@ export class CompositeOverflowActivityActionViewItem extends ActivityActionViewI this.contextMenuService.showContextMenu({ getAnchor: () => this.element!, - getActions: () => this.actions, - onHide: () => dispose(this.actions) + getActions: () => this.actions!, + onHide: () => dispose(this.actions!) }); } @@ -402,7 +402,9 @@ export class CompositeOverflowActivityActionViewItem extends ActivityActionViewI dispose(): void { super.dispose(); - this.actions = dispose(this.actions); + if (this.actions) { + this.actions = dispose(this.actions); + } } } @@ -431,7 +433,7 @@ export class CompositeActionViewItem extends ActivityActionViewItem { private static manageExtensionAction: ManageExtensionAction; - private compositeActivity: IActivity | null; + private compositeActivity: IActivity | undefined; private compositeTransfer: LocalSelectionTransfer; constructor( @@ -454,7 +456,7 @@ export class CompositeActionViewItem extends ActivityActionViewItem { CompositeActionViewItem.manageExtensionAction = instantiationService.createInstance(ManageExtensionAction); } - this._register(compositeActivityAction.onDidChangeActivity(() => { this.compositeActivity = null; this.updateActivity(); }, this)); + this._register(compositeActivityAction.onDidChangeActivity(() => { this.compositeActivity = undefined; this.updateActivity(); }, this)); } protected get activity(): IActivity { diff --git a/src/vs/workbench/browser/parts/panel/panelPart.ts b/src/vs/workbench/browser/parts/panel/panelPart.ts index b36f3294394..b864241fdea 100644 --- a/src/vs/workbench/browser/parts/panel/panelPart.ts +++ b/src/vs/workbench/browser/parts/panel/panelPart.ts @@ -83,8 +83,8 @@ export class PanelPart extends CompositePart implements IPanelService { private compositeBar: CompositeBar; private compositeActions: Map = new Map(); - private blockOpeningPanel: boolean; - private _contentDimension: Dimension; + private blockOpeningPanel = false; + private _contentDimension: Dimension | undefined; constructor( @INotificationService notificationService: INotificationService, @@ -367,7 +367,7 @@ export class PanelPart extends CompositePart implements IPanelService { private onDidStorageChange(e: IWorkspaceStorageChangeEvent): void { if (e.key === PanelPart.PINNED_PANELS && e.scope === StorageScope.GLOBAL && this.cachedPanelsValue !== this.getStoredCachedPanelsValue() /* This checks if current window changed the value or not */) { - this._cachedPanelsValue = null; + this._cachedPanelsValue = undefined; const newCompositeItems: ICompositeBarItem[] = []; const compositeItems = this.compositeBar.getCompositeBarItems(); const cachedPanels = this.getCachedPanels(); @@ -422,7 +422,7 @@ export class PanelPart extends CompositePart implements IPanelService { return cachedPanels; } - private _cachedPanelsValue: string | null; + private _cachedPanelsValue: string | undefined; private get cachedPanelsValue(): string { if (!this._cachedPanelsValue) { this._cachedPanelsValue = this.getStoredCachedPanelsValue(); diff --git a/src/vs/workbench/browser/viewlet.ts b/src/vs/workbench/browser/viewlet.ts index befbcf39cf6..368e56b41c7 100644 --- a/src/vs/workbench/browser/viewlet.ts +++ b/src/vs/workbench/browser/viewlet.ts @@ -76,7 +76,7 @@ export const Extensions = { }; export class ViewletRegistry extends CompositeRegistry { - private defaultViewletId: string; + private defaultViewletId!: string; /** * Registers a viewlet to the platform. diff --git a/src/vs/workbench/services/output/common/outputChannelModel.ts b/src/vs/workbench/services/output/common/outputChannelModel.ts index be87bf1aecc..f92624f44e8 100644 --- a/src/vs/workbench/services/output/common/outputChannelModel.ts +++ b/src/vs/workbench/services/output/common/outputChannelModel.ts @@ -58,7 +58,7 @@ export abstract class AbstractFileOutputChannelModel extends Disposable implemen readonly onDispose: Event = this._onDispose.event; protected modelUpdater: RunOnceScheduler; - protected model: ITextModel | null; + protected model: ITextModel | null = null; protected startOffset: number = 0; protected endOffset: number = 0; @@ -288,7 +288,7 @@ export class BufferredOutputChannel extends Disposable implements IOutputChannel readonly onDispose: Event = this._onDispose.event; private modelUpdater: RunOnceScheduler; - private model: ITextModel | null; + private model: ITextModel | null = null; private readonly bufferredContent: BufferedContent; private lastReadId: number | undefined = undefined; @@ -414,4 +414,4 @@ class BufferedContent { return { value, id }; } } -} \ No newline at end of file +} From c223ba6f80b66b1bad90dbd7b8f5079d8ef372e8 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 6 Aug 2019 11:18:04 +0200 Subject: [PATCH 245/861] files - properly emit errors (#78364) --- src/vs/workbench/services/textfile/node/textFileService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/textfile/node/textFileService.ts b/src/vs/workbench/services/textfile/node/textFileService.ts index 29d0d542efe..93c43cd1fef 100644 --- a/src/vs/workbench/services/textfile/node/textFileService.ts +++ b/src/vs/workbench/services/textfile/node/textFileService.ts @@ -137,7 +137,7 @@ export class NodeTextFileService extends TextFileService { }); // Error - stream.on('error', error => this.emit(error)); + stream.on('error', error => this.emit('error', error)); } // ensure the stream is flowing From 6b070857d1c66e938cd05ac04eaa3754d20ceab3 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 6 Aug 2019 12:48:33 +0200 Subject: [PATCH 246/861] SignService: No need to cache the import fixes #78186 --- src/vs/platform/sign/node/signService.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/vs/platform/sign/node/signService.ts b/src/vs/platform/sign/node/signService.ts index b33e5e25be1..cf5a0703ea8 100644 --- a/src/vs/platform/sign/node/signService.ts +++ b/src/vs/platform/sign/node/signService.ts @@ -4,14 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import { ISignService } from 'vs/platform/sign/common/sign'; -import { memoize } from 'vs/base/common/decorators'; export class SignService implements ISignService { _serviceBrand: any; - // Cache the 'vsda' import, because when the same missing module is imported multiple times, - // the ones after the first will not throw an error. And this will break the contract of the sign method. - @memoize private vsda(): Promise { return import('vsda'); } @@ -29,4 +25,4 @@ export class SignService implements ISignService { return value; } -} \ No newline at end of file +} From a98faa44543cd9625f83b6dd83825acccd799c4e Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 6 Aug 2019 13:48:37 +0200 Subject: [PATCH 247/861] Remove CustomExecution Fixes #78540 --- src/vs/vscode.proposed.d.ts | 22 +-- .../workbench/api/browser/mainThreadTask.ts | 30 +-- src/vs/workbench/api/common/extHostTypes.ts | 34 +--- src/vs/workbench/api/common/shared/tasks.ts | 8 +- src/vs/workbench/api/node/extHost.api.impl.ts | 1 - src/vs/workbench/api/node/extHostTask.ts | 181 +----------------- .../api/node/extHostTerminalService.ts | 5 - .../tasks/browser/terminalTaskSystem.ts | 33 +--- .../workbench/contrib/tasks/common/tasks.ts | 9 +- .../contrib/tasks/node/processTaskSystem.ts | 4 +- 10 files changed, 34 insertions(+), 293 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index ce6c93482ca..f78b6392341 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1029,24 +1029,6 @@ declare module 'vscode' { //#endregion //#region CustomExecution - /** - * Class used to execute an extension callback as a task. - */ - export class CustomExecution { - /** - * @param callback The callback that will be called when the extension callback task is executed. - */ - constructor(callback: (terminalRenderer: any, cancellationToken: CancellationToken, thisArg?: any) => Thenable); - - /** - * The callback used to execute the task. - * @param terminalRenderer Used by the task to render output and receive input. - * @param cancellationToken Cancellation used to signal a cancel request to the executing task. - * @returns The callback should return '0' for success and a non-zero value for failure. - */ - callback: (terminalRenderer: any, cancellationToken: CancellationToken, thisArg?: any) => Thenable; - } - /** * Class used to execute an extension callback as a task. */ @@ -1081,12 +1063,12 @@ declare module 'vscode' { * or '$eslint'. Problem matchers can be contributed by an extension using * the `problemMatchers` extension point. */ - constructor(taskDefinition: TaskDefinition, scope: WorkspaceFolder | TaskScope.Global | TaskScope.Workspace, name: string, source: string, execution?: ProcessExecution | ShellExecution | CustomExecution | CustomExecution2, problemMatchers?: string | string[]); + constructor(taskDefinition: TaskDefinition, scope: WorkspaceFolder | TaskScope.Global | TaskScope.Workspace, name: string, source: string, execution?: ProcessExecution | ShellExecution | CustomExecution2, problemMatchers?: string | string[]); /** * The task's execution engine */ - execution2?: ProcessExecution | ShellExecution | CustomExecution | CustomExecution2; + execution2?: ProcessExecution | ShellExecution | CustomExecution2; } //#endregion diff --git a/src/vs/workbench/api/browser/mainThreadTask.ts b/src/vs/workbench/api/browser/mainThreadTask.ts index 3e022e13cab..7934efb088b 100644 --- a/src/vs/workbench/api/browser/mainThreadTask.ts +++ b/src/vs/workbench/api/browser/mainThreadTask.ts @@ -29,7 +29,7 @@ import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { ExtHostContext, MainThreadTaskShape, ExtHostTaskShape, MainContext, IExtHostContext } from 'vs/workbench/api/common/extHost.protocol'; import { TaskDefinitionDTO, TaskExecutionDTO, ProcessExecutionOptionsDTO, TaskPresentationOptionsDTO, - ProcessExecutionDTO, ShellExecutionDTO, ShellExecutionOptionsDTO, CustomExecutionDTO, CustomExecution2DTO, TaskDTO, TaskSourceDTO, TaskHandleDTO, TaskFilterDTO, TaskProcessStartedDTO, TaskProcessEndedDTO, TaskSystemInfoDTO, + ProcessExecutionDTO, ShellExecutionDTO, ShellExecutionOptionsDTO, CustomExecution2DTO, TaskDTO, TaskSourceDTO, TaskHandleDTO, TaskFilterDTO, TaskProcessStartedDTO, TaskProcessEndedDTO, TaskSystemInfoDTO, RunOptionsDTO } from 'vs/workbench/api/common/shared/tasks'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; @@ -131,7 +131,7 @@ namespace ProcessExecutionOptionsDTO { } namespace ProcessExecutionDTO { - export function is(value: ShellExecutionDTO | ProcessExecutionDTO | CustomExecutionDTO | CustomExecution2DTO): value is ProcessExecutionDTO { + export function is(value: ShellExecutionDTO | ProcessExecutionDTO | CustomExecution2DTO): value is ProcessExecutionDTO { const candidate = value as ProcessExecutionDTO; return candidate && !!candidate.process; } @@ -199,7 +199,7 @@ namespace ShellExecutionOptionsDTO { } namespace ShellExecutionDTO { - export function is(value: ShellExecutionDTO | ProcessExecutionDTO | CustomExecutionDTO | CustomExecution2DTO): value is ShellExecutionDTO { + export function is(value: ShellExecutionDTO | ProcessExecutionDTO | CustomExecution2DTO): value is ShellExecutionDTO { const candidate = value as ShellExecutionDTO; return candidate && (!!candidate.commandLine || !!candidate.command); } @@ -230,28 +230,8 @@ namespace ShellExecutionDTO { } } -namespace CustomExecutionDTO { - export function is(value: ShellExecutionDTO | ProcessExecutionDTO | CustomExecutionDTO | CustomExecution2DTO): value is CustomExecutionDTO { - const candidate = value as CustomExecutionDTO; - return candidate && candidate.customExecution === 'customExecution'; - } - - export function from(value: CommandConfiguration): CustomExecutionDTO { - return { - customExecution: 'customExecution' - }; - } - - export function to(value: CustomExecutionDTO): CommandConfiguration { - return { - runtime: RuntimeType.CustomExecution, - presentation: undefined - }; - } -} - namespace CustomExecution2DTO { - export function is(value: ShellExecutionDTO | ProcessExecutionDTO | CustomExecutionDTO | CustomExecution2DTO): value is CustomExecution2DTO { + export function is(value: ShellExecutionDTO | ProcessExecutionDTO | CustomExecution2DTO): value is CustomExecution2DTO { const candidate = value as CustomExecution2DTO; return candidate && candidate.customExecution === 'customExecution2'; } @@ -371,8 +351,6 @@ namespace TaskDTO { command = ShellExecutionDTO.to(task.execution); } else if (ProcessExecutionDTO.is(task.execution)) { command = ProcessExecutionDTO.to(task.execution); - } else if (CustomExecutionDTO.is(task.execution)) { - command = CustomExecutionDTO.to(task.execution); } else if (CustomExecution2DTO.is(task.execution)) { command = CustomExecution2DTO.to(task.execution); } diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index 7cd821ea564..9ad1d38f66e 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -1753,26 +1753,6 @@ export enum TaskScope { Workspace = 2 } -export class CustomExecution implements vscode.CustomExecution { - private _callback: (args: any, cancellationToken: vscode.CancellationToken) => Thenable; - - constructor(callback: (args: any, cancellationToken: vscode.CancellationToken) => Thenable) { - this._callback = callback; - } - - public computeId(): string { - return 'customExecution' + generateUuid(); - } - - public set callback(value: (args: any, cancellationToken: vscode.CancellationToken) => Thenable) { - this._callback = value; - } - - public get callback(): (args: any, cancellationToken: vscode.CancellationToken) => Thenable { - return this._callback; - } -} - export class CustomExecution2 implements vscode.CustomExecution2 { private _callback: () => Thenable; constructor(callback: () => Thenable) { @@ -1804,7 +1784,7 @@ export class Task implements vscode.Task2 { private _definition: vscode.TaskDefinition; private _scope: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder | undefined; private _name: string; - private _execution: ProcessExecution | ShellExecution | CustomExecution | CustomExecution2 | undefined; + private _execution: ProcessExecution | ShellExecution | CustomExecution2 | undefined; private _problemMatchers: string[]; private _hasDefinedMatchers: boolean; private _isBackground: boolean; @@ -1813,8 +1793,8 @@ export class Task implements vscode.Task2 { private _presentationOptions: vscode.TaskPresentationOptions; private _runOptions: vscode.RunOptions; - constructor(definition: vscode.TaskDefinition, name: string, source: string, execution?: ProcessExecution | ShellExecution | CustomExecution | CustomExecution2, problemMatchers?: string | string[]); - constructor(definition: vscode.TaskDefinition, scope: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder, name: string, source: string, execution?: ProcessExecution | ShellExecution | CustomExecution | CustomExecution2, problemMatchers?: string | string[]); + constructor(definition: vscode.TaskDefinition, name: string, source: string, execution?: ProcessExecution | ShellExecution | CustomExecution2, problemMatchers?: string | string[]); + constructor(definition: vscode.TaskDefinition, scope: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder, name: string, source: string, execution?: ProcessExecution | ShellExecution | CustomExecution2, 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; let problemMatchers: string | string[]; @@ -1879,7 +1859,7 @@ export class Task implements vscode.Task2 { type: Task.ShellType, id: this._execution.computeId() }; - } else if (this._execution instanceof CustomExecution) { + } else if (this._execution instanceof CustomExecution2) { this._definition = { type: Task.ExtensionCallbackType, id: this._execution.computeId() @@ -1926,18 +1906,18 @@ export class Task implements vscode.Task2 { } get execution(): ProcessExecution | ShellExecution | undefined { - return ((this._execution instanceof CustomExecution) || (this._execution instanceof CustomExecution2)) ? undefined : this._execution; + return (this._execution instanceof CustomExecution2) ? undefined : this._execution; } set execution(value: ProcessExecution | ShellExecution | undefined) { this.execution2 = value; } - get execution2(): ProcessExecution | ShellExecution | CustomExecution | CustomExecution2 | undefined { + get execution2(): ProcessExecution | ShellExecution | CustomExecution2 | undefined { return this._execution; } - set execution2(value: ProcessExecution | ShellExecution | CustomExecution | CustomExecution2 | undefined) { + set execution2(value: ProcessExecution | ShellExecution | CustomExecution2 | undefined) { if (value === null) { value = undefined; } diff --git a/src/vs/workbench/api/common/shared/tasks.ts b/src/vs/workbench/api/common/shared/tasks.ts index a27f90777d3..b8fab0b5a02 100644 --- a/src/vs/workbench/api/common/shared/tasks.ts +++ b/src/vs/workbench/api/common/shared/tasks.ts @@ -66,10 +66,6 @@ export interface ShellExecutionDTO { options?: ShellExecutionOptionsDTO; } -export interface CustomExecutionDTO { - customExecution: 'customExecution'; -} - export interface CustomExecution2DTO { customExecution: 'customExecution2'; } @@ -88,7 +84,7 @@ export interface TaskHandleDTO { export interface TaskDTO { _id: string; name?: string; - execution: ProcessExecutionDTO | ShellExecutionDTO | CustomExecutionDTO | CustomExecution2DTO | undefined; + execution: ProcessExecutionDTO | ShellExecutionDTO | CustomExecution2DTO | undefined; definition: TaskDefinitionDTO; isBackground?: boolean; source: TaskSourceDTO; @@ -129,4 +125,4 @@ export interface TaskSystemInfoDTO { scheme: string; authority: string; platform: string; -} \ No newline at end of file +} diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 1d7028491d0..e2bd21dfcf4 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -842,7 +842,6 @@ export function createApiFactory( EventEmitter: Emitter, ExtensionExecutionContext: extHostTypes.ExtensionExecutionContext, ExtensionKind: extHostTypes.ExtensionKind, - CustomExecution: extHostTypes.CustomExecution, CustomExecution2: extHostTypes.CustomExecution2, FileChangeType: extHostTypes.FileChangeType, FileSystemError: extHostTypes.FileSystemError, diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index f9ebaec4b50..6655e30153e 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -21,17 +21,15 @@ import { TaskDefinitionDTO, TaskExecutionDTO, TaskPresentationOptionsDTO, ProcessExecutionOptionsDTO, ProcessExecutionDTO, ShellExecutionOptionsDTO, ShellExecutionDTO, - CustomExecutionDTO, CustomExecution2DTO, TaskDTO, TaskHandleDTO, TaskFilterDTO, TaskProcessStartedDTO, TaskProcessEndedDTO, TaskSystemInfoDTO, TaskSetDTO } from '../common/shared/tasks'; import { ExtHostVariableResolverService } from 'vs/workbench/api/node/extHostDebugService'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { ExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; -import { ExtHostTerminalService, ExtHostTerminal } from 'vs/workbench/api/node/extHostTerminalService'; +import { ExtHostTerminalService } from 'vs/workbench/api/node/extHostTerminalService'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; -import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; -import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { CancellationToken } from 'vs/base/common/cancellation'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; namespace TaskDefinitionDTO { @@ -80,7 +78,7 @@ namespace ProcessExecutionOptionsDTO { } namespace ProcessExecutionDTO { - export function is(value: ShellExecutionDTO | ProcessExecutionDTO | CustomExecutionDTO | CustomExecution2DTO | undefined): value is ProcessExecutionDTO { + export function is(value: ShellExecutionDTO | ProcessExecutionDTO | CustomExecution2DTO | undefined): value is ProcessExecutionDTO { if (value) { const candidate = value as ProcessExecutionDTO; return candidate && !!candidate.process; @@ -125,7 +123,7 @@ namespace ShellExecutionOptionsDTO { } namespace ShellExecutionDTO { - export function is(value: ShellExecutionDTO | ProcessExecutionDTO | CustomExecutionDTO | CustomExecution2DTO | undefined): value is ShellExecutionDTO { + export function is(value: ShellExecutionDTO | ProcessExecutionDTO | CustomExecution2DTO | undefined): value is ShellExecutionDTO { if (value) { const candidate = value as ShellExecutionDTO; return candidate && (!!candidate.commandLine || !!candidate.command); @@ -162,25 +160,8 @@ namespace ShellExecutionDTO { } } -namespace CustomExecutionDTO { - export function is(value: ShellExecutionDTO | ProcessExecutionDTO | CustomExecutionDTO | CustomExecution2DTO | undefined): value is CustomExecutionDTO { - if (value) { - let candidate = value as CustomExecutionDTO; - return candidate && candidate.customExecution === 'customExecution'; - } else { - return false; - } - } - - export function from(value: vscode.CustomExecution): CustomExecutionDTO { - return { - customExecution: 'customExecution' - }; - } -} - namespace CustomExecution2DTO { - export function is(value: ShellExecutionDTO | ProcessExecutionDTO | CustomExecutionDTO | CustomExecution2DTO | undefined): value is CustomExecution2DTO { + export function is(value: ShellExecutionDTO | ProcessExecutionDTO | CustomExecution2DTO | undefined): value is CustomExecution2DTO { if (value) { let candidate = value as CustomExecution2DTO; return candidate && candidate.customExecution === 'customExecution2'; @@ -229,13 +210,11 @@ namespace TaskDTO { if (value === undefined || value === null) { return undefined; } - let execution: ShellExecutionDTO | ProcessExecutionDTO | CustomExecutionDTO | CustomExecution2DTO | undefined; + let execution: ShellExecutionDTO | ProcessExecutionDTO | CustomExecution2DTO | undefined; if (value.execution instanceof types.ProcessExecution) { execution = ProcessExecutionDTO.from(value.execution); } else if (value.execution instanceof types.ShellExecution) { execution = ShellExecutionDTO.from(value.execution); - } else if ((value).execution2 && (value).execution2 instanceof types.CustomExecution) { - execution = CustomExecutionDTO.from((value).execution2); } else if ((value).execution2 && (value).execution2 instanceof types.CustomExecution2) { execution = CustomExecution2DTO.from((value).execution2); } @@ -373,110 +352,6 @@ interface HandlerData { extension: IExtensionDescription; } -class CustomExecutionData implements IDisposable { - private static waitForDimensionsTimeoutInMs: number = 5000; - private _cancellationSource?: CancellationTokenSource; - private readonly _onTaskExecutionComplete: Emitter = new Emitter(); - private readonly _disposables = new DisposableStore(); - private terminal?: vscode.Terminal; - private terminalId?: number; - public result: number | undefined; - - constructor( - private readonly customExecution: vscode.CustomExecution, - private readonly terminalService: ExtHostTerminalService) { - } - - public dispose(): void { - this._cancellationSource = undefined; - this._disposables.dispose(); - } - - public get onTaskExecutionComplete(): Event { - return this._onTaskExecutionComplete.event; - } - - private onDidCloseTerminal(terminal: vscode.Terminal): void { - if ((this.terminal === terminal) && this._cancellationSource) { - this._cancellationSource.cancel(); - } - } - - private onDidOpenTerminal(terminal: vscode.Terminal): void { - if (!(terminal instanceof ExtHostTerminal)) { - throw new Error('How could this not be a extension host terminal?'); - } - - if (this.terminalId && terminal._id === this.terminalId) { - this.startCallback(this.terminalId); - } - } - - public async startCallback(terminalId: number): Promise { - this.terminalId = terminalId; - - // If we have already started the extension task callback, then - // do not start it again. - // It is completely valid for multiple terminals to be opened - // before the one for our task. - if (this._cancellationSource) { - return undefined; - } - - const callbackTerminals: vscode.Terminal[] = this.terminalService.terminals.filter((terminal) => terminal._id === terminalId); - - if (!callbackTerminals || callbackTerminals.length === 0) { - this._disposables.add(this.terminalService.onDidOpenTerminal(this.onDidOpenTerminal.bind(this))); - return; - } - - if (callbackTerminals.length !== 1) { - throw new Error(`Expected to only have one terminal at this point`); - } - - this.terminal = callbackTerminals[0]; - const terminalRenderer: any = await this.terminalService.resolveTerminalRenderer(terminalId); - - // If we don't have the maximum dimensions yet, then we need to wait for them (but not indefinitely). - // Custom executions will expect the dimensions to be set properly before they are launched. - // BUT, due to the API contract VSCode has for terminals and dimensions, they are still responsible for - // handling cases where they are not set. - if (!terminalRenderer.maximumDimensions) { - const dimensionTimeout: Promise = new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, CustomExecutionData.waitForDimensionsTimeoutInMs); - }); - - let dimensionsRegistration: IDisposable | undefined; - const dimensionsPromise: Promise = new Promise((resolve) => { - dimensionsRegistration = terminalRenderer.onDidChangeMaximumDimensions(() => { - resolve(); - }); - }); - - await Promise.race([dimensionTimeout, dimensionsPromise]); - if (dimensionsRegistration) { - dimensionsRegistration.dispose(); - } - } - - this._cancellationSource = new CancellationTokenSource(); - this._disposables.add(this._cancellationSource); - - this._disposables.add(this.terminalService.onDidCloseTerminal(this.onDidCloseTerminal.bind(this))); - - // Regardless of how the task completes, we are done with this custom execution task. - this.customExecution.callback(terminalRenderer, this._cancellationSource.token).then( - (success) => { - this.result = success; - this._onTaskExecutionComplete.fire(this); - }, (rejected) => { - this._onTaskExecutionComplete.fire(this); - }); - } -} - export class ExtHostTask implements ExtHostTaskShape { private _proxy: MainThreadTaskShape; @@ -487,8 +362,6 @@ export class ExtHostTask implements ExtHostTaskShape { private _handleCounter: number; private _handlers: Map; private _taskExecutions: Map; - private _providedCustomExecutions: Map; - private _activeCustomExecutions: Map; private _providedCustomExecutions2: Map; private _activeCustomExecutions2: Map; @@ -512,8 +385,6 @@ export class ExtHostTask implements ExtHostTaskShape { this._handleCounter = 0; this._handlers = new Map(); this._taskExecutions = new Map(); - this._providedCustomExecutions = new Map(); - this._activeCustomExecutions = new Map(); this._providedCustomExecutions2 = new Map(); this._activeCustomExecutions2 = new Map(); } @@ -591,25 +462,6 @@ export class ExtHostTask implements ExtHostTaskShape { await this._terminalService.attachPtyToTerminal(terminalId, await execution2.callback()); } - // Once a terminal is spun up for the custom execution task this event will be fired. - // At that point, we need to actually start the callback, but - // only if it hasn't already begun. - const extensionCallback: CustomExecutionData | undefined = this._providedCustomExecutions.get(execution.id); - if (extensionCallback) { - if (this._activeCustomExecutions.get(execution.id) !== undefined) { - throw new Error('We should not be trying to start the same custom task executions twice.'); - } - - this._activeCustomExecutions.set(execution.id, extensionCallback); - - const taskExecutionComplete: IDisposable = extensionCallback.onTaskExecutionComplete(() => { - this.customExecutionComplete(execution); - taskExecutionComplete.dispose(); - }); - - extensionCallback.startCallback(terminalId); - } - this._onDidExecuteTask.fire({ execution: await this.getTaskExecution(execution) }); @@ -665,7 +517,6 @@ export class ExtHostTask implements ExtHostTaskShape { // For custom execution tasks, we need to store the execution objects locally // since we obviously cannot send callback functions through the proxy. // So, clear out any existing ones. - this._providedCustomExecutions.clear(); this._providedCustomExecutions2.clear(); // Set up a list of task ID promises that we can wait on @@ -689,14 +540,11 @@ export class ExtHostTask implements ExtHostTaskShape { if (taskDTO) { taskDTOs.push(taskDTO); - if (CustomExecutionDTO.is(taskDTO.execution)) { + if (CustomExecution2DTO.is(taskDTO.execution)) { // The ID is calculated on the main thread task side, so, let's call into it here. // We need the task id's pre-computed for custom task executions because when OnDidStartTask // is invoked, we have to be able to map it back to our data. - taskIdPromises.push(this.addCustomExecution(taskDTO, task)); - } else if (CustomExecution2DTO.is(taskDTO.execution)) { taskIdPromises.push(this.addCustomExecution2(taskDTO, task)); - } } } @@ -745,10 +593,6 @@ export class ExtHostTask implements ExtHostTaskShape { throw new Error('Unexpected: The resolved task definition must be the same object as the original task definition. The task definition cannot be changed.'); } - if (CustomExecutionDTO.is(resolvedTaskDTO.execution)) { - await this.addCustomExecution(resolvedTaskDTO, resolvedTask); - } - if (CustomExecution2DTO.is(resolvedTaskDTO.execution)) { await this.addCustomExecution2(resolvedTaskDTO, resolvedTask); } @@ -801,11 +645,6 @@ export class ExtHostTask implements ExtHostTaskShape { return this._handleCounter++; } - private async addCustomExecution(taskDTO: TaskDTO, task: vscode.Task2): Promise { - const taskId = await this._proxy.$createTaskId(taskDTO); - this._providedCustomExecutions.set(taskId, new CustomExecutionData((task).execution2, this._terminalService)); - } - private async addCustomExecution2(taskDTO: TaskDTO, task: vscode.Task2): Promise { const taskId = await this._proxy.$createTaskId(taskDTO); this._providedCustomExecutions2.set(taskId, (task).execution2); @@ -834,12 +673,6 @@ export class ExtHostTask implements ExtHostTaskShape { } private customExecutionComplete(execution: TaskExecutionDTO): void { - const extensionCallback: CustomExecutionData | undefined = this._activeCustomExecutions.get(execution.id); - if (extensionCallback) { - this._activeCustomExecutions.delete(execution.id); - this._proxy.$customExecutionComplete(execution.id, extensionCallback.result); - extensionCallback.dispose(); - } const extensionCallback2: vscode.CustomExecution2 | undefined = this._activeCustomExecutions2.get(execution.id); if (extensionCallback2) { this._activeCustomExecutions2.delete(execution.id); diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index a0bdd8ecc05..d8334b47d4d 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -290,11 +290,6 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed, this._lastActiveWorkspace, this._variableResolver, this._logService); } - // TODO: Remove when CustomExecution is removed - public async resolveTerminalRenderer(id: number): Promise { - throw new Error('TerminalRenderers are no longer supported'); - } - public $acceptActiveTerminalChanged(id: number | null): void { const original = this._activeTerminal; if (id === null) { diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index 6bccee3e09f..2559188da9e 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -472,7 +472,7 @@ export class TerminalTaskSystem implements ITaskSystem { const resolvedVariables = this.resolveVariablesFromSet(systemInfo, workspaceFolder, task, variables); return resolvedVariables.then((resolvedVariables) => { - const isCustomExecution = (task.command.runtime === RuntimeType.CustomExecution) || (task.command.runtime === RuntimeType.CustomExecution2); + const isCustomExecution = (task.command.runtime === RuntimeType.CustomExecution2); if (resolvedVariables && (task.command !== undefined) && task.command.runtime && (isCustomExecution || (task.command.name !== undefined))) { this.currentTask.resolvedVariables = resolvedVariables; return this.executeInTerminal(task, trigger, new VariableResolver(workspaceFolder, systemInfo, resolvedVariables.variables, this.configurationResolverService), workspaceFolder); @@ -556,9 +556,7 @@ export class TerminalTaskSystem implements ITaskSystem { let processStartedSignaled = false; terminal.processReady.then(() => { if (!processStartedSignaled) { - if (task.command.runtime !== RuntimeType.CustomExecution) { - this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.ProcessStarted, task, terminal!.processId!)); - } + this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.ProcessStarted, task, terminal!.processId!)); processStartedSignaled = true; } }, (_error) => { @@ -608,9 +606,7 @@ export class TerminalTaskSystem implements ITaskSystem { processStartedSignaled = true; } - if (task.command.runtime !== RuntimeType.CustomExecution) { - this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.ProcessEnded, task, exitCode)); - } + this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.ProcessEnded, task, exitCode)); for (let i = 0; i < eventCounter; i++) { let event = TaskEvent.create(TaskEventKind.Inactive, task); @@ -635,9 +631,7 @@ export class TerminalTaskSystem implements ITaskSystem { let processStartedSignaled = false; terminal.processReady.then(() => { if (!processStartedSignaled) { - if (task.command.runtime !== RuntimeType.CustomExecution) { - this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.ProcessStarted, task, terminal!.processId!)); - } + this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.ProcessStarted, task, terminal!.processId!)); processStartedSignaled = true; } }, (_error) => { @@ -690,9 +684,8 @@ export class TerminalTaskSystem implements ITaskSystem { this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.ProcessStarted, task, terminal.processId!)); processStartedSignaled = true; } - if (task.command.runtime !== RuntimeType.CustomExecution) { - this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.ProcessEnded, task, exitCode)); - } + + this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.ProcessEnded, task, exitCode)); this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.Inactive, task)); this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.End, task)); resolve({ exitCode }); @@ -845,7 +838,7 @@ export class TerminalTaskSystem implements ITaskSystem { } } } else { - let commandExecutable = ((task.command.runtime !== RuntimeType.CustomExecution) && (task.command.runtime !== RuntimeType.CustomExecution2)) ? CommandString.value(command) : undefined; + let commandExecutable = (task.command.runtime !== RuntimeType.CustomExecution2) ? CommandString.value(command) : undefined; let executable = !isShellCommand ? this.resolveVariable(variableResolver, '${' + TerminalTaskSystem.ProcessVarName + '}') : commandExecutable; @@ -917,15 +910,7 @@ export class TerminalTaskSystem implements ITaskSystem { let args: CommandString[] | undefined; let launchConfigs: IShellLaunchConfig | undefined; - if (task.command.runtime === RuntimeType.CustomExecution) { - throw new Error('CustomExecution is no longer supported'); - // this.currentTask.shellLaunchConfig = launchConfigs = { - // isRendererOnly: true, - // waitOnExit, - // name: this.createTerminalName(task, workspaceFolder), - // initialText: task.command.presentation && task.command.presentation.echo ? `\x1b[1m> Executing task: ${task._label} <\x1b[0m\n` : undefined - // }; - } else if (task.command.runtime === RuntimeType.CustomExecution2) { + if (task.command.runtime === RuntimeType.CustomExecution2) { this.currentTask.shellLaunchConfig = launchConfigs = { isExtensionTerminal: true, waitOnExit, @@ -1146,7 +1131,7 @@ export class TerminalTaskSystem implements ITaskSystem { private collectCommandVariables(variables: Set, command: CommandConfiguration, task: CustomTask | ContributedTask): void { // The custom execution should have everything it needs already as it provided // the callback. - if ((command.runtime === RuntimeType.CustomExecution) || (command.runtime === RuntimeType.CustomExecution2)) { + if (command.runtime === RuntimeType.CustomExecution2) { return; } diff --git a/src/vs/workbench/contrib/tasks/common/tasks.ts b/src/vs/workbench/contrib/tasks/common/tasks.ts index decd333ab72..46593df22be 100644 --- a/src/vs/workbench/contrib/tasks/common/tasks.ts +++ b/src/vs/workbench/contrib/tasks/common/tasks.ts @@ -273,8 +273,7 @@ export namespace PresentationOptions { export enum RuntimeType { Shell = 1, Process = 2, - CustomExecution = 3, - CustomExecution2 = 4 + CustomExecution2 = 3 } export namespace RuntimeType { @@ -284,8 +283,6 @@ export namespace RuntimeType { return RuntimeType.Shell; case 'process': return RuntimeType.Process; - case 'customExecution': - return RuntimeType.CustomExecution; case 'customExecution2': return RuntimeType.CustomExecution2; default: @@ -663,10 +660,6 @@ export class CustomTask extends CommonTask { type = 'process'; break; - case RuntimeType.CustomExecution: - type = 'customExecution'; - break; - case RuntimeType.CustomExecution2: type = 'customExecution2'; break; diff --git a/src/vs/workbench/contrib/tasks/node/processTaskSystem.ts b/src/vs/workbench/contrib/tasks/node/processTaskSystem.ts index 972b7ec3374..8110db9d80c 100644 --- a/src/vs/workbench/contrib/tasks/node/processTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/node/processTaskSystem.ts @@ -280,7 +280,7 @@ export class ProcessTaskSystem implements ITaskSystem { this.childProcessEnded(); watchingProblemMatcher.done(); watchingProblemMatcher.dispose(); - if (processStartedSignaled && task.command.runtime !== RuntimeType.CustomExecution) { + if (processStartedSignaled) { this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.ProcessEnded, task, success.cmdCode!)); } toDispose = dispose(toDispose!); @@ -336,7 +336,7 @@ export class ProcessTaskSystem implements ITaskSystem { startStopProblemMatcher.done(); startStopProblemMatcher.dispose(); this.checkTerminated(task, success); - if (processStartedSignaled && task.command.runtime !== RuntimeType.CustomExecution) { + if (processStartedSignaled) { this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.ProcessEnded, task, success.cmdCode!)); } this._onDidStateChange.fire(inactiveEvent); From 3bbbad38c1e9d1dc1889db3c86b206d8a12cd467 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 6 Aug 2019 13:53:34 +0200 Subject: [PATCH 248/861] :lipstick: --- extensions/git/src/commands.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index da1a1bc107b..34652fa9bff 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -450,10 +450,7 @@ export class CommandCenter { return; } - const match = /git\s+clone\s+(.*)/.exec(url); - if (match) { - url = match[1]; - } + url = url.replace(/^\s*git\s+clone\s+/, ''); const config = workspace.getConfiguration('git'); let defaultCloneDirectory = config.get('defaultCloneDirectory') || os.homedir(); From b93c4fa3b5f667545b30e48a1e70c9853e60b600 Mon Sep 17 00:00:00 2001 From: Darrien Singleton Date: Tue, 6 Aug 2019 09:22:17 -0400 Subject: [PATCH 249/861] new branch --- extensions/git/src/commands.ts | 7 +++++++ extensions/git/src/git.ts | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 2cf349dca39..20843b21ada 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -353,6 +353,8 @@ export class CommandCenter { switch (resource.type) { case Status.INDEX_MODIFIED: case Status.INDEX_RENAMED: + case Status.UNTRACKED: + case Status.INDEX_ADDED: return this.getURI(resource.original, 'HEAD'); case Status.MODIFIED: @@ -414,6 +416,7 @@ export class CommandCenter { switch (resource.type) { case Status.INDEX_MODIFIED: case Status.INDEX_RENAMED: + case Status.INDEX_ADDED: return `${basename} (Index)`; case Status.MODIFIED: @@ -426,6 +429,10 @@ export class CommandCenter { case Status.DELETED_BY_THEM: return `${basename} (Ours)`; + + case Status.UNTRACKED: + + return `${basename} (Untracked)`; } return ''; diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 145ddaac49d..ee7be7864db 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -1116,15 +1116,17 @@ export class Repository { } let mode: string; + let add: string = ''; try { const details = await this.getObjectDetails('HEAD', path); mode = details.mode; } catch (err) { mode = '100644'; + add = '--add'; } - await this.run(['update-index', '--cacheinfo', mode, hash, path]); + await this.run(['update-index', add, '--cacheinfo', mode, hash, path]); } async checkout(treeish: string, paths: string[], opts: { track?: boolean } = Object.create(null)): Promise { From fef6ca7c6d1d33e53b881fb73505bf818af8dcae Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 6 Aug 2019 15:09:14 +0200 Subject: [PATCH 250/861] adopt new loader for #78542 --- src/vs/loader.js | 68 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/src/vs/loader.js b/src/vs/loader.js index 8445bbeff3f..a222ee64009 100644 --- a/src/vs/loader.js +++ b/src/vs/loader.js @@ -709,8 +709,11 @@ var AMDLoader; var recorder = moduleManager.getRecorder(); var cachedDataPath = that._getCachedDataPath(nodeCachedData, filename); var options = { filename: filename }; + var hashData; try { - options.cachedData = that._fs.readFileSync(cachedDataPath); + var data = that._fs.readFileSync(cachedDataPath); + hashData = data.slice(0, 16); + options.cachedData = data.slice(16); recorder.record(60 /* CachedDataFound */, cachedDataPath); } catch (_e) { @@ -724,7 +727,8 @@ var AMDLoader; var args = [this.exports, require, this, filename, dirname, process, _commonjsGlobal, Buffer]; var result = compileWrapper.apply(this.exports, args); // cached data aftermath - setTimeout(function () { return that._handleCachedData(script, cachedDataPath, !options.cachedData, moduleManager); }, Math.ceil(moduleManager.getConfig().getOptionsLiteral().nodeCachedData.writeDelay * Math.random())); + that._handleCachedData(script, scriptSource, cachedDataPath, !options.cachedData, moduleManager); + that._verifyCachedData(script, scriptSource, cachedDataPath, hashData); return result; }; }; @@ -755,7 +759,7 @@ var AMDLoader; var vmScriptPathOrUri_1 = this._getElectronRendererScriptPathOrUri(normalizedScriptSrc_1); var wantsCachedData_1 = Boolean(opts.nodeCachedData); var cachedDataPath_1 = wantsCachedData_1 ? this._getCachedDataPath(opts.nodeCachedData, scriptSrc) : undefined; - this._readSourceAndCachedData(normalizedScriptSrc_1, cachedDataPath_1, recorder, function (err, data, cachedData) { + this._readSourceAndCachedData(normalizedScriptSrc_1, cachedDataPath_1, recorder, function (err, data, cachedData, hashData) { if (err) { errorback(err); return; @@ -770,7 +774,8 @@ var AMDLoader; scriptSource = nodeInstrumenter(scriptSource, normalizedScriptSrc_1); var scriptOpts = { filename: vmScriptPathOrUri_1, cachedData: cachedData }; var script = _this._createAndEvalScript(moduleManager, scriptSource, scriptOpts, callback, errorback); - _this._handleCachedData(script, cachedDataPath_1, wantsCachedData_1 && !cachedData, moduleManager); + _this._handleCachedData(script, scriptSource, cachedDataPath_1, wantsCachedData_1 && !cachedData, moduleManager); + _this._verifyCachedData(script, scriptSource, cachedDataPath_1, hashData); }); } }; @@ -815,13 +820,13 @@ var AMDLoader; var basename = this._path.basename(filename).replace(/\.js$/, ''); return this._path.join(config.path, basename + "-" + hash + ".code"); }; - NodeScriptLoader.prototype._handleCachedData = function (script, cachedDataPath, createCachedData, moduleManager) { + NodeScriptLoader.prototype._handleCachedData = function (script, scriptSource, cachedDataPath, createCachedData, moduleManager) { var _this = this; if (script.cachedDataRejected) { // cached data got rejected -> delete and re-create this._fs.unlink(cachedDataPath, function (err) { moduleManager.getRecorder().record(62 /* CachedDataRejected */, cachedDataPath); - _this._createAndWriteCachedData(script, cachedDataPath, moduleManager); + _this._createAndWriteCachedData(script, scriptSource, cachedDataPath, moduleManager); if (err) { moduleManager.getConfig().onError(err); } @@ -829,22 +834,29 @@ var AMDLoader; } else if (createCachedData) { // no cached data, but wanted - this._createAndWriteCachedData(script, cachedDataPath, moduleManager); + this._createAndWriteCachedData(script, scriptSource, cachedDataPath, moduleManager); } }; - NodeScriptLoader.prototype._createAndWriteCachedData = function (script, cachedDataPath, moduleManager) { + // Cached data format: | SOURCE_HASH | V8_CACHED_DATA | + // -SOURCE_HASH is the md5 hash of the JS source (always 16 bytes) + // -V8_CACHED_DATA is what v8 produces + NodeScriptLoader.prototype._createAndWriteCachedData = function (script, scriptSource, cachedDataPath, moduleManager) { var _this = this; var timeout = Math.ceil(moduleManager.getConfig().getOptionsLiteral().nodeCachedData.writeDelay * (1 + Math.random())); var lastSize = -1; var iteration = 0; + var hashData = undefined; var createLoop = function () { setTimeout(function () { + if (!hashData) { + hashData = _this._crypto.createHash('md5').update(scriptSource, 'utf8').digest(); + } var cachedData = script.createCachedData(); if (cachedData.length === 0 || cachedData.length === lastSize || iteration >= 5) { return; } lastSize = cachedData.length; - _this._fs.writeFile(cachedDataPath, cachedData, function (err) { + _this._fs.writeFile(cachedDataPath, Buffer.concat([hashData, cachedData]), function (err) { if (err) { moduleManager.getConfig().onError(err); } @@ -865,15 +877,16 @@ var AMDLoader; } else { // cached data case: read both files in parallel - var source_1; - var cachedData_1; + var source_1 = undefined; + var cachedData_1 = undefined; + var hashData_1 = undefined; var steps_1 = 2; var step_1 = function (err) { if (err) { callback(err); } else if (--steps_1 === 0) { - callback(undefined, source_1, cachedData_1); + callback(undefined, source_1, cachedData_1, hashData_1); } }; this._fs.readFile(sourcePath, { encoding: 'utf8' }, function (err, data) { @@ -881,12 +894,39 @@ var AMDLoader; step_1(err); }); this._fs.readFile(cachedDataPath, function (err, data) { - cachedData_1 = data && data.length > 0 ? data : undefined; + if (!err && data && data.length > 0) { + hashData_1 = data.slice(0, 16); + cachedData_1 = data.slice(16); + recorder.record(60 /* CachedDataFound */, cachedDataPath); + } + else { + recorder.record(61 /* CachedDataMissed */, cachedDataPath); + } step_1(); // ignored: cached data is optional - recorder.record(err ? 61 /* CachedDataMissed */ : 60 /* CachedDataFound */, cachedDataPath); }); } }; + NodeScriptLoader.prototype._verifyCachedData = function (script, scriptSource, cachedDataPath, hashData) { + var _this = this; + if (!hashData) { + // nothing to do + return; + } + if (script.cachedDataRejected) { + // invalid anyways + return; + } + setTimeout(function () { + // check source hash - the contract is that file paths change when file content + // change (e.g use the commit or version id as cache path). this check is + // for violations of this contract. + var hashDataNow = _this._crypto.createHash('md5').update(scriptSource, 'utf8').digest(); + if (!hashData.equals(hashDataNow)) { + console.warn("FAILED TO VERIFY CACHED DATA. Deleting '" + cachedDataPath + "' now, but a RESTART IS REQUIRED"); + _this._fs.unlink(cachedDataPath, function (err) { return console.error("FAILED to unlink: '" + cachedDataPath + "'", err); }); + } + }, Math.ceil(5000 * (1 + Math.random()))); + }; NodeScriptLoader._BOM = 0xFEFF; NodeScriptLoader._PREFIX = '(function (require, define, __filename, __dirname) { '; NodeScriptLoader._SUFFIX = '\n});'; From ef58820341ba1dac9a35844c1716ab0d64a2a3fd Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 6 Aug 2019 15:54:08 +0200 Subject: [PATCH 251/861] Fix file picker item selection for files that start with . Fixes #78293 --- src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts b/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts index 696f4681b4e..28fb4787d24 100644 --- a/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts +++ b/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts @@ -762,8 +762,8 @@ export class RemoteFileDialog { private pathAppend(uri: URI, additional: string): string { if ((additional === '..') || (additional === '.')) { - const basePath = this.pathFromUri(uri); - return basePath + this.separator + additional; + const basePath = this.pathFromUri(uri, true); + return basePath + additional; } else { return this.pathFromUri(resources.joinPath(uri, additional)); } From 6127460accc50c5af49908c1b0f8847d9450abae Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Tue, 6 Aug 2019 16:10:20 +0200 Subject: [PATCH 252/861] propagate CancellationToken to debug API; see #77293 --- .../workbench/api/browser/mainThreadDebugService.ts | 8 ++++---- src/vs/workbench/api/common/extHost.protocol.ts | 4 ++-- src/vs/workbench/api/node/extHostDebugService.ts | 8 ++++---- .../debug/browser/debugConfigurationManager.ts | 13 +++++++------ src/vs/workbench/contrib/debug/common/debug.ts | 9 +++++---- 5 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadDebugService.ts b/src/vs/workbench/api/browser/mainThreadDebugService.ts index 85039369466..20572fa7783 100644 --- a/src/vs/workbench/api/browser/mainThreadDebugService.ts +++ b/src/vs/workbench/api/browser/mainThreadDebugService.ts @@ -153,13 +153,13 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb type: debugType }; if (hasProvide) { - provider.provideDebugConfigurations = (folder) => { - return this._proxy.$provideDebugConfigurations(handle, folder); + provider.provideDebugConfigurations = (folder, token) => { + return this._proxy.$provideDebugConfigurations(handle, folder, token); }; } if (hasResolve) { - provider.resolveDebugConfiguration = (folder, config) => { - return this._proxy.$resolveDebugConfiguration(handle, folder, config); + provider.resolveDebugConfiguration = (folder, config, token) => { + return this._proxy.$resolveDebugConfiguration(handle, folder, config, token); }; } if (hasProvideDebugAdapter) { diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 5db8a6658a9..65c477284e5 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1250,8 +1250,8 @@ export interface ExtHostDebugServiceShape { $startDASession(handle: number, session: IDebugSessionDto): Promise; $stopDASession(handle: number): Promise; $sendDAMessage(handle: number, message: DebugProtocol.ProtocolMessage): void; - $resolveDebugConfiguration(handle: number, folder: UriComponents | undefined, debugConfiguration: IConfig): Promise; - $provideDebugConfigurations(handle: number, folder: UriComponents | undefined): Promise; + $resolveDebugConfiguration(handle: number, folder: UriComponents | undefined, debugConfiguration: IConfig, token: CancellationToken): Promise; + $provideDebugConfigurations(handle: number, folder: UriComponents | undefined, token: CancellationToken): Promise; $legacyDebugAdapterExecutable(handle: number, folderUri: UriComponents | undefined): Promise; // TODO@AW legacy $provideDebugAdapter(handle: number, session: IDebugSessionDto): Promise; $acceptDebugSessionStarted(session: IDebugSessionDto): void; diff --git a/src/vs/workbench/api/node/extHostDebugService.ts b/src/vs/workbench/api/node/extHostDebugService.ts index be353ca5bde..9b26206924d 100644 --- a/src/vs/workbench/api/node/extHostDebugService.ts +++ b/src/vs/workbench/api/node/extHostDebugService.ts @@ -599,7 +599,7 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { this.fireBreakpointChanges(a, r, c); } - public $provideDebugConfigurations(configProviderHandle: number, folderUri: UriComponents | undefined): Promise { + public $provideDebugConfigurations(configProviderHandle: number, folderUri: UriComponents | undefined, token: CancellationToken): Promise { return asPromise(async () => { const provider = this.getConfigProviderByHandle(configProviderHandle); if (!provider) { @@ -609,7 +609,7 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { throw new Error('DebugConfigurationProvider has no method provideDebugConfigurations'); } const folder = await this.getFolder(folderUri); - return provider.provideDebugConfigurations(folder, CancellationToken.None); + return provider.provideDebugConfigurations(folder, token); }).then(debugConfigurations => { if (!debugConfigurations) { throw new Error('nothing returned from DebugConfigurationProvider.provideDebugConfigurations'); @@ -618,7 +618,7 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { }); } - public $resolveDebugConfiguration(configProviderHandle: number, folderUri: UriComponents | undefined, debugConfiguration: vscode.DebugConfiguration): Promise { + public $resolveDebugConfiguration(configProviderHandle: number, folderUri: UriComponents | undefined, debugConfiguration: vscode.DebugConfiguration, token: CancellationToken): Promise { return asPromise(async () => { const provider = this.getConfigProviderByHandle(configProviderHandle); if (!provider) { @@ -628,7 +628,7 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { throw new Error('DebugConfigurationProvider has no method resolveDebugConfiguration'); } const folder = await this.getFolder(folderUri); - return provider.resolveDebugConfiguration(folder, debugConfiguration, CancellationToken.None); + return provider.resolveDebugConfiguration(folder, debugConfiguration, token); }); } diff --git a/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts b/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts index 6ace957453c..983a3c4eb2a 100644 --- a/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts +++ b/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts @@ -34,6 +34,7 @@ import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { onUnexpectedError } from 'vs/base/common/errors'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; +import { CancellationToken } from 'vs/base/common/cancellation'; const jsonRegistry = Registry.as(JSONExtensions.JSONContribution); jsonRegistry.registerSchema(launchSchemaId, launchSchema); @@ -180,7 +181,7 @@ export class ConfigurationManager implements IConfigurationManager { return providers.length > 0; } - resolveConfigurationByProviders(folderUri: uri | undefined, type: string | undefined, debugConfiguration: IConfig): Promise { + resolveConfigurationByProviders(folderUri: uri | undefined, type: string | undefined, debugConfiguration: IConfig, token?: CancellationToken): Promise { return this.activateDebuggers('onDebugResolve', type).then(() => { // pipe the config through the promises sequentially. Append at the end the '*' types const providers = this.configProviders.filter(p => p.type === type && p.resolveDebugConfiguration) @@ -189,7 +190,7 @@ export class ConfigurationManager implements IConfigurationManager { return providers.reduce((promise, provider) => { return promise.then(config => { if (config) { - return provider.resolveDebugConfiguration!(folderUri, config); + return provider.resolveDebugConfiguration!(folderUri, config, token || CancellationToken.None); } else { return Promise.resolve(config); } @@ -198,9 +199,9 @@ export class ConfigurationManager implements IConfigurationManager { }); } - provideDebugConfigurations(folderUri: uri | undefined, type: string): Promise { + provideDebugConfigurations(folderUri: uri | undefined, type: string, token: CancellationToken): Promise { return this.activateDebuggers('onDebugInitialConfigurations') - .then(() => Promise.all(this.configProviders.filter(p => p.type === type && p.provideDebugConfigurations).map(p => p.provideDebugConfigurations!(folderUri))) + .then(() => Promise.all(this.configProviders.filter(p => p.type === type && p.provideDebugConfigurations).map(p => p.provideDebugConfigurations!(folderUri, token))) .then(results => results.reduce((first, second) => first.concat(second), []))); } @@ -531,7 +532,7 @@ class Launch extends AbstractLaunch implements ILaunch { return this.configurationService.inspect('launch', { resource: this.workspace.uri }).workspaceFolder; } - openConfigFile(sideBySide: boolean, preserveFocus: boolean, type?: string): Promise<{ editor: IEditor | null, created: boolean }> { + openConfigFile(sideBySide: boolean, preserveFocus: boolean, type?: string, token?: CancellationToken): Promise<{ editor: IEditor | null, created: boolean }> { const resource = this.uri; let created = false; @@ -539,7 +540,7 @@ class Launch extends AbstractLaunch implements ILaunch { // launch.json not found: create one by collecting launch configs from debugConfigProviders return this.configurationManager.guessDebugger(type).then(adapter => { if (adapter) { - return this.configurationManager.provideDebugConfigurations(this.workspace.uri, adapter.type).then(initialConfigs => { + return this.configurationManager.provideDebugConfigurations(this.workspace.uri, adapter.type, token || CancellationToken.None).then(initialConfigs => { return adapter.getInitialConfigurationContent(initialConfigs); }); } else { diff --git a/src/vs/workbench/contrib/debug/common/debug.ts b/src/vs/workbench/contrib/debug/common/debug.ts index 8fa02439610..65e28660dc9 100644 --- a/src/vs/workbench/contrib/debug/common/debug.ts +++ b/src/vs/workbench/contrib/debug/common/debug.ts @@ -25,6 +25,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { TaskIdentifier } from 'vs/workbench/contrib/tasks/common/tasks'; import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { CancellationToken } from 'vs/base/common/cancellation'; export const VIEWLET_ID = 'workbench.view.debug'; export const VIEW_CONTAINER: ViewContainer = Registry.as(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer(VIEWLET_ID); @@ -557,8 +558,8 @@ export interface IDebuggerContribution extends IPlatformSpecificAdapterContribut export interface IDebugConfigurationProvider { readonly type: string; - resolveDebugConfiguration?(folderUri: uri | undefined, debugConfiguration: IConfig): Promise; - provideDebugConfigurations?(folderUri: uri | undefined): Promise; + resolveDebugConfiguration?(folderUri: uri | undefined, debugConfiguration: IConfig, token: CancellationToken): Promise; + provideDebugConfigurations?(folderUri: uri | undefined, token: CancellationToken): Promise; debugAdapterExecutable?(folderUri: uri | undefined): Promise; // TODO@AW legacy } @@ -610,7 +611,7 @@ export interface IConfigurationManager { registerDebugAdapterDescriptorFactory(debugAdapterDescriptorFactory: IDebugAdapterDescriptorFactory): IDisposable; unregisterDebugAdapterDescriptorFactory(debugAdapterDescriptorFactory: IDebugAdapterDescriptorFactory): void; - resolveConfigurationByProviders(folderUri: uri | undefined, type: string | undefined, debugConfiguration: any): Promise; + resolveConfigurationByProviders(folderUri: uri | undefined, type: string | undefined, debugConfiguration: any, token: CancellationToken): Promise; getDebugAdapterDescriptor(session: IDebugSession): Promise; registerDebugAdapterFactory(debugTypes: string[], debugAdapterFactory: IDebugAdapterFactory): IDisposable; @@ -663,7 +664,7 @@ export interface ILaunch { /** * Opens the launch.json file. Creates if it does not exist. */ - openConfigFile(sideBySide: boolean, preserveFocus: boolean, type?: string): Promise<{ editor: IEditor | null, created: boolean }>; + openConfigFile(sideBySide: boolean, preserveFocus: boolean, type?: string, token?: CancellationToken): Promise<{ editor: IEditor | null, created: boolean }>; } // Debug service interfaces From 8839c0259d1cfe17f4e6a84e8edb1d263bc1ff8d Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 6 Aug 2019 16:15:18 +0200 Subject: [PATCH 253/861] Use task filter type to filter on provider Fixes #78179 --- .../contrib/tasks/browser/abstractTaskService.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 8b120c0a125..a59f40dd2f4 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -502,7 +502,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (!this.versionAndEngineCompatible(filter)) { return Promise.resolve([]); } - return this.getGroupedTasks().then((map) => { + return this.getGroupedTasks(filter ? filter.type : undefined).then((map) => { if (!filter || !filter.type) { return map.all(); } @@ -1117,7 +1117,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer protected abstract getTaskSystem(): ITaskSystem; - private getGroupedTasks(): Promise { + private getGroupedTasks(type?: string): Promise { return Promise.all([this.extensionService.activateByEvent('onCommand:workbench.action.tasks.runTask'), TaskDefinitionRegistry.onReady()]).then(() => { let validTypes: IStringDictionary = Object.create(null); TaskDefinitionRegistry.all().forEach(definition => validTypes[definition.taskType] = true); @@ -1152,10 +1152,12 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } }; if (this.schemaVersion === JsonSchemaVersion.V2_0_0 && this._providers.size > 0) { - this._providers.forEach((provider) => { - counter++; - provider.provideTasks(validTypes).then(done, error); - }); + for (const [handle, provider] of this._providers) { + if ((type === undefined) || (type === this._providerTypes.get(handle))) { + counter++; + provider.provideTasks(validTypes).then(done, error); + } + } } else { resolve(result); } From 742a6d7240298f3906bed1454d3a63107c71e186 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 6 Aug 2019 16:39:10 +0200 Subject: [PATCH 254/861] Fix powershell color test --- extensions/powershell/test/colorize-results/test_ps1.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/powershell/test/colorize-results/test_ps1.json b/extensions/powershell/test/colorize-results/test_ps1.json index e41d1306499..67380ce77b6 100644 --- a/extensions/powershell/test/colorize-results/test_ps1.json +++ b/extensions/powershell/test/colorize-results/test_ps1.json @@ -465,11 +465,11 @@ "c": ".IsInRole", "t": "source.powershell meta.scriptblock.powershell meta.scriptblock.powershell variable.other.readwrite.powershell variable.other.member.powershell", "r": { - "dark_plus": "variable: #9CDCFE", - "light_plus": "variable: #001080", + "dark_plus": "source.powershell variable.other.member: #DCDCAA", + "light_plus": "source.powershell variable.other.member: #795E26", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", - "hc_black": "variable: #9CDCFE" + "hc_black": "source.powershell variable.other.member: #DCDCAA" } }, { From 5cad6c4879e40eb6212ea6df8d8e024958566221 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 6 Aug 2019 16:52:32 +0200 Subject: [PATCH 255/861] debug: adopt initiCancelationToken fixes #77293 --- .../browser/debugConfigurationManager.ts | 4 ++-- .../contrib/debug/browser/debugService.ts | 22 +++++++++++++------ .../contrib/debug/browser/debugSession.ts | 2 +- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts b/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts index 983a3c4eb2a..637086088b3 100644 --- a/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts +++ b/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts @@ -181,7 +181,7 @@ export class ConfigurationManager implements IConfigurationManager { return providers.length > 0; } - resolveConfigurationByProviders(folderUri: uri | undefined, type: string | undefined, debugConfiguration: IConfig, token?: CancellationToken): Promise { + resolveConfigurationByProviders(folderUri: uri | undefined, type: string | undefined, debugConfiguration: IConfig, token: CancellationToken): Promise { return this.activateDebuggers('onDebugResolve', type).then(() => { // pipe the config through the promises sequentially. Append at the end the '*' types const providers = this.configProviders.filter(p => p.type === type && p.resolveDebugConfiguration) @@ -190,7 +190,7 @@ export class ConfigurationManager implements IConfigurationManager { return providers.reduce((promise, provider) => { return promise.then(config => { if (config) { - return provider.resolveDebugConfiguration!(folderUri, config, token || CancellationToken.None); + return provider.resolveDebugConfiguration!(folderUri, config, token); } else { return Promise.resolve(config); } diff --git a/src/vs/workbench/contrib/debug/browser/debugService.ts b/src/vs/workbench/contrib/debug/browser/debugService.ts index da261aa0032..eddc8876af7 100644 --- a/src/vs/workbench/contrib/debug/browser/debugService.ts +++ b/src/vs/workbench/contrib/debug/browser/debugService.ts @@ -47,6 +47,7 @@ import { isErrorWithActions, createErrorWithActions } from 'vs/base/common/error import { RunOnceScheduler } from 'vs/base/common/async'; import { IExtensionHostDebugService } from 'vs/platform/debug/common/extensionHostDebug'; import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; const DEBUG_BREAKPOINTS_KEY = 'debug.breakpoint'; const DEBUG_BREAKPOINTS_ACTIVATED_KEY = 'debug.breakpointactivated'; @@ -88,6 +89,7 @@ export class DebugService implements IDebugService { private breakpointsToSendOnResourceSaved: Set; private initializing = false; private previousState: State | undefined; + private initCancellationToken: CancellationTokenSource | undefined; constructor( @IStorageService private readonly storageService: IStorageService, @@ -211,6 +213,10 @@ export class DebugService implements IDebugService { } private endInitializingState() { + if (this.initCancellationToken) { + this.initCancellationToken.cancel(); + this.initCancellationToken = undefined; + } if (this.initializing) { this.initializing = false; this.onStateChange(); @@ -355,8 +361,9 @@ export class DebugService implements IDebugService { } const debuggerThenable: Promise = type ? Promise.resolve() : this.configurationManager.guessDebugger().then(dbgr => { type = dbgr && dbgr.type; }); - return debuggerThenable.then(() => - this.configurationManager.resolveConfigurationByProviders(launch && launch.workspace ? launch.workspace.uri : undefined, type, config!).then(config => { + return debuggerThenable.then(() => { + this.initCancellationToken = new CancellationTokenSource(); + return this.configurationManager.resolveConfigurationByProviders(launch && launch.workspace ? launch.workspace.uri : undefined, type, config!, this.initCancellationToken.token).then(config => { // a falsy config indicates an aborted launch if (config && config.type) { return this.substituteVariables(launch, config).then(resolvedConfig => { @@ -396,17 +403,17 @@ export class DebugService implements IDebugService { .then(() => false); } - return launch && launch.openConfigFile(false, true).then(() => false); + return launch && launch.openConfigFile(false, true, undefined, this.initCancellationToken ? this.initCancellationToken.token : undefined).then(() => false); }); } if (launch && type && config === null) { // show launch.json only for "config" being "null". - return launch.openConfigFile(false, true, type).then(() => false); + return launch.openConfigFile(false, true, type, this.initCancellationToken ? this.initCancellationToken.token : undefined).then(() => false); } return false; - }) - ); + }); + }); } /** @@ -587,7 +594,8 @@ export class DebugService implements IDebugService { let substitutionThenable: Promise = Promise.resolve(session.configuration); if (launch && needsToSubstitute && unresolved) { - substitutionThenable = this.configurationManager.resolveConfigurationByProviders(launch.workspace ? launch.workspace.uri : undefined, unresolved.type, unresolved) + this.initCancellationToken = new CancellationTokenSource(); + substitutionThenable = this.configurationManager.resolveConfigurationByProviders(launch.workspace ? launch.workspace.uri : undefined, unresolved.type, unresolved, this.initCancellationToken.token) .then(resolved => { if (resolved) { // start debugging diff --git a/src/vs/workbench/contrib/debug/browser/debugSession.ts b/src/vs/workbench/contrib/debug/browser/debugSession.ts index 320be3360ce..d4548944019 100644 --- a/src/vs/workbench/contrib/debug/browser/debugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/debugSession.ts @@ -169,7 +169,7 @@ export class DebugSession implements IDebugSession { this.raw = new RawDebugSession(debugAdapter, dbgr, this.telemetryService, customTelemetryService, this.windowsService); - return this.raw!.start().then(() => { + return this.raw.start().then(() => { this.registerListeners(); From 1d658ded860195bdcac132e28044aa2b2ea019b5 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 6 Aug 2019 17:27:06 +0200 Subject: [PATCH 256/861] remove unsed ext loader --- .../extensions/worker/extensionLoader.ts | 24 ------------------- 1 file changed, 24 deletions(-) delete mode 100644 src/vs/workbench/services/extensions/worker/extensionLoader.ts diff --git a/src/vs/workbench/services/extensions/worker/extensionLoader.ts b/src/vs/workbench/services/extensions/worker/extensionLoader.ts deleted file mode 100644 index 088fa872920..00000000000 --- a/src/vs/workbench/services/extensions/worker/extensionLoader.ts +++ /dev/null @@ -1,24 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - - -self['extensions'] = {}; -function wrap(name: string, script: string) { - //https://github.com/nodejs/node/blob/master/lib/internal/modules/cjs/loader.js#L125 - return `self['extensions']['${name}']= (function (exports, require) { ${script}\n});`; -} - -export function importWrappedScript(scriptSrc: string, scriptPath: string) { - - importScripts(`data:text/javascript;charset=utf-8,${encodeURIComponent(wrap(scriptPath, scriptSrc))}`); - - // const fn = new Function('exports', 'require', 'module', scriptSrc); - // const exports = Object.create(null); - // const thisRequire = function (path: string) { - // console.log(path); - // }; - // fn(exports, thisRequire, undefined); - // console.log(exports); -} From a6177d979a45c63764275b4d1028de8a451d0025 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 6 Aug 2019 17:49:42 +0200 Subject: [PATCH 257/861] cleanup for pr #66095 --- extensions/git/src/git.ts | 37 +++++++++----- extensions/git/src/repository.ts | 70 ++----------------------- extensions/git/src/test/git.test.ts | 77 +++++++++++++++++++++++++++- extensions/git/src/util.ts | 79 ++++++++++++++++++++++++----- extensions/git/src/watch.ts | 25 +++++++++ 5 files changed, 196 insertions(+), 92 deletions(-) create mode 100644 extensions/git/src/watch.ts diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 246d1fac324..ce2ac8b1f96 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -11,12 +11,15 @@ import * as which from 'which'; 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 { assign, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent, splitInChunks, Limiter } from './util'; 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'; +// https://github.com/microsoft/vscode/issues/65693 +const MAX_CLI_LENGTH = 30000; + const readfile = denodeify(fs.readFile); export interface IGit { @@ -1139,13 +1142,14 @@ export class Repository { args.push(treeish); } - if (paths && paths.length) { - args.push('--'); - args.push.apply(args, paths); - } - try { - await this.run(args); + if (paths && paths.length > 0) { + for (const chunk of splitInChunks(paths, MAX_CLI_LENGTH)) { + await this.run([...args, '--', ...chunk]); + } + } else { + await this.run(args); + } } catch (err) { if (/Please,? commit your changes or stash them/.test(err.stderr || '')) { err.gitErrorCode = GitErrorCodes.DirtyWorkTree; @@ -1276,11 +1280,17 @@ export class Repository { async clean(paths: string[]): Promise { const pathsByGroup = groupBy(paths, p => path.dirname(p)); const groups = Object.keys(pathsByGroup).map(k => pathsByGroup[k]); - const tasks = groups.map(paths => () => this.run(['clean', '-f', '-q', '--'].concat(paths))); - for (let task of tasks) { - await task(); + const limiter = new Limiter(5); + const promises: Promise[] = []; + + for (const paths of groups) { + for (const chunk of splitInChunks(paths, MAX_CLI_LENGTH)) { + promises.push(limiter.queue(() => this.run(['clean', '-f', '-q', '--', ...chunk]))); + } } + + await Promise.all(promises); } async undo(): Promise { @@ -1746,8 +1756,11 @@ export class Repository { } async updateSubmodules(paths: string[]): Promise { - const args = ['submodule', 'update', '--', ...paths]; - await this.run(args); + const args = ['submodule', 'update', '--']; + + for (const chunk of splitInChunks(paths, MAX_CLI_LENGTH)) { + await this.run([...args, ...chunk]); + } } async getSubmodules(): Promise { diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index cd4cddcd724..1102ecaf325 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -5,7 +5,7 @@ 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, ProgressOptions, CancellationToken } 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, combinedDisposable, watch, IFileWatcher } from './util'; +import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent, combinedDisposable, splitInChunks } from './util'; import { memoize, throttle, debounce } from './decorators'; import { toGitUri } from './uri'; import { AutoFetcher } from './autofetch'; @@ -14,6 +14,7 @@ import * as nls from 'vscode-nls'; import * as fs from 'fs'; import { StatusBarCommands } from './statusbar'; import { Branch, Ref, Remote, RefType, GitErrorCodes, Status, LogOptions, Change } from './api/git'; +import { IFileWatcher, watch } from './watch'; const timeout = (millis: number) => new Promise(c => setTimeout(c, millis)); @@ -956,70 +957,9 @@ export class Repository implements Disposable { } }); - const maxCommandLineLength: number = 30000; - - if (toClean.length > 0) { - let sliceStart: number = 0; - let sliceEnd: number = 1; - let accumulatedStringLength = 0; - - while (sliceEnd < toClean.length) { - if ((accumulatedStringLength + (toClean[sliceEnd - 1].length + 1)) > maxCommandLineLength) { - await this.repository.clean(toClean.slice(sliceStart, sliceEnd)); - sliceStart = sliceEnd; - sliceEnd++; - accumulatedStringLength = 0; - } - else { - accumulatedStringLength += toClean[sliceEnd - 1].length + 1; - sliceEnd++; - } - } - - await this.repository.clean(toClean.slice(sliceStart, sliceEnd)); - } - - if (toCheckout.length > 0) { - let sliceStart: number = 0; - let sliceEnd: number = 1; - let accumulatedStringLength = 0; - - while (sliceEnd < toCheckout.length) { - if ((accumulatedStringLength + (toCheckout[sliceEnd - 1].length + 1)) > maxCommandLineLength) { - await this.repository.checkout('', toCheckout.slice(sliceStart, sliceEnd)); - sliceStart = sliceEnd; - sliceEnd++; - accumulatedStringLength = 0; - } - else { - accumulatedStringLength += toCheckout[sliceEnd - 1].length + 1; - sliceEnd++; - } - } - - await this.repository.checkout('', toCheckout.slice(sliceStart, sliceEnd)); - } - - if (submodulesToUpdate.length > 0) { - let sliceStart: number = 0; - let sliceEnd: number = 1; - let accumulatedStringLength = 0; - - while (sliceEnd < submodulesToUpdate.length) { - if ((accumulatedStringLength + (submodulesToUpdate[sliceEnd - 1].length + 1)) > maxCommandLineLength) { - await this.repository.updateSubmodules(submodulesToUpdate.slice(sliceStart, sliceEnd)); - sliceStart = sliceEnd; - sliceEnd++; - accumulatedStringLength = 0; - } - else { - accumulatedStringLength += submodulesToUpdate[sliceEnd - 1].length + 1; - sliceEnd++; - } - } - - await this.repository.updateSubmodules(submodulesToUpdate.slice(sliceStart, sliceEnd)); - } + await this.repository.clean(toClean); + await this.repository.checkout('', toCheckout); + await this.repository.updateSubmodules(submodulesToUpdate); }); } diff --git a/extensions/git/src/test/git.test.ts b/extensions/git/src/test/git.test.ts index f0444ce5795..a860c82352a 100644 --- a/extensions/git/src/test/git.test.ts +++ b/extensions/git/src/test/git.test.ts @@ -6,6 +6,7 @@ import 'mocha'; import { GitStatusParser, parseGitCommit, parseGitmodules, parseLsTree, parseLsFiles } from '../git'; import * as assert from 'assert'; +import { splitInChunks } from '../util'; suite('git', () => { suite('GitStatusParser', () => { @@ -292,4 +293,78 @@ This is a commit message.`; ]); }); }); -}); \ No newline at end of file + + suite('splitInChunks', () => { + test('unit tests', function () { + assert.deepEqual( + [...splitInChunks(['hello', 'there', 'cool', 'stuff'], 6)], + [['hello'], ['there'], ['cool'], ['stuff']] + ); + + assert.deepEqual( + [...splitInChunks(['hello', 'there', 'cool', 'stuff'], 10)], + [['hello', 'there'], ['cool', 'stuff']] + ); + + assert.deepEqual( + [...splitInChunks(['hello', 'there', 'cool', 'stuff'], 12)], + [['hello', 'there'], ['cool', 'stuff']] + ); + + assert.deepEqual( + [...splitInChunks(['hello', 'there', 'cool', 'stuff'], 14)], + [['hello', 'there', 'cool'], ['stuff']] + ); + + assert.deepEqual( + [...splitInChunks(['hello', 'there', 'cool', 'stuff'], 2000)], + [['hello', 'there', 'cool', 'stuff']] + ); + + assert.deepEqual( + [...splitInChunks(['0', '01', '012', '0', '01', '012', '0', '01', '012'], 1)], + [['0'], ['01'], ['012'], ['0'], ['01'], ['012'], ['0'], ['01'], ['012']] + ); + + assert.deepEqual( + [...splitInChunks(['0', '01', '012', '0', '01', '012', '0', '01', '012'], 2)], + [['0'], ['01'], ['012'], ['0'], ['01'], ['012'], ['0'], ['01'], ['012']] + ); + + assert.deepEqual( + [...splitInChunks(['0', '01', '012', '0', '01', '012', '0', '01', '012'], 3)], + [['0', '01'], ['012'], ['0', '01'], ['012'], ['0', '01'], ['012']] + ); + + assert.deepEqual( + [...splitInChunks(['0', '01', '012', '0', '01', '012', '0', '01', '012'], 4)], + [['0', '01'], ['012', '0'], ['01'], ['012', '0'], ['01'], ['012']] + ); + + assert.deepEqual( + [...splitInChunks(['0', '01', '012', '0', '01', '012', '0', '01', '012'], 5)], + [['0', '01'], ['012', '0'], ['01', '012'], ['0', '01'], ['012']] + ); + + assert.deepEqual( + [...splitInChunks(['0', '01', '012', '0', '01', '012', '0', '01', '012'], 6)], + [['0', '01', '012'], ['0', '01', '012'], ['0', '01', '012']] + ); + + assert.deepEqual( + [...splitInChunks(['0', '01', '012', '0', '01', '012', '0', '01', '012'], 7)], + [['0', '01', '012', '0'], ['01', '012', '0'], ['01', '012']] + ); + + assert.deepEqual( + [...splitInChunks(['0', '01', '012', '0', '01', '012', '0', '01', '012'], 8)], + [['0', '01', '012', '0'], ['01', '012', '0', '01'], ['012']] + ); + + assert.deepEqual( + [...splitInChunks(['0', '01', '012', '0', '01', '012', '0', '01', '012'], 9)], + [['0', '01', '012', '0', '01'], ['012', '0', '01', '012']] + ); + }); + }); +}); diff --git a/extensions/git/src/util.ts b/extensions/git/src/util.ts index c4e93850619..d2e201ca01d 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, EventEmitter, Uri } from 'vscode'; -import { dirname, sep, join } from 'path'; +import { Event } from 'vscode'; +import { dirname, sep } from 'path'; import { Readable } from 'stream'; import * as fs from 'fs'; import * as byline from 'byline'; @@ -345,18 +345,69 @@ export function pathEquals(a: string, b: string): boolean { return a === b; } -export interface IFileWatcher extends IDisposable { - readonly event: Event; +export function* splitInChunks(array: string[], maxChunkLength: number): IterableIterator { + let current: string[] = []; + let length = 0; + + for (const value of array) { + let newLength = length + value.length; + + if (newLength > maxChunkLength && current.length > 0) { + yield current; + current = []; + newLength = value.length; + } + + current.push(value); + length = newLength; + } + + if (current.length > 0) { + yield current; + } } -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(); } - }; +interface ILimitedTaskFactory { + factory: () => Promise; + c: (value?: T | Promise) => void; + e: (error?: any) => void; +} + +export class Limiter { + + private runningPromises: number; + private maxDegreeOfParalellism: number; + private outstandingPromises: ILimitedTaskFactory[]; + + constructor(maxDegreeOfParalellism: number) { + this.maxDegreeOfParalellism = maxDegreeOfParalellism; + this.outstandingPromises = []; + this.runningPromises = 0; + } + + queue(factory: () => Promise): Promise { + return new Promise((c, e) => { + this.outstandingPromises.push({ factory, c, e }); + this.consume(); + }); + } + + private consume(): void { + while (this.outstandingPromises.length && this.runningPromises < this.maxDegreeOfParalellism) { + const iLimitedTask = this.outstandingPromises.shift()!; + this.runningPromises++; + + const promise = iLimitedTask.factory(); + promise.then(iLimitedTask.c, iLimitedTask.e); + promise.then(() => this.consumed(), () => this.consumed()); + } + } + + private consumed(): void { + this.runningPromises--; + + if (this.outstandingPromises.length > 0) { + this.consume(); + } + } } diff --git a/extensions/git/src/watch.ts b/extensions/git/src/watch.ts new file mode 100644 index 00000000000..c6670cfa884 --- /dev/null +++ b/extensions/git/src/watch.ts @@ -0,0 +1,25 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Event, EventEmitter, Uri } from 'vscode'; +import { join } from 'path'; +import * as fs from 'fs'; +import { IDisposable } from './util'; + +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(); } + }; +} From 21a4e91688af6798a7bb9d1c44715c7bca88cdf9 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 6 Aug 2019 18:28:28 +0200 Subject: [PATCH 258/861] cleanup --- extensions/git/src/repository.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 1102ecaf325..07dc1c231e8 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -5,7 +5,7 @@ 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, ProgressOptions, CancellationToken } 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, combinedDisposable, splitInChunks } from './util'; +import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent, combinedDisposable } from './util'; import { memoize, throttle, debounce } from './decorators'; import { toGitUri } from './uri'; import { AutoFetcher } from './autofetch'; From 4ceb27c9aea8fd6ec959d460350c7bb9b14053c6 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Tue, 6 Aug 2019 09:56:40 -0700 Subject: [PATCH 259/861] Update settings editor list to 24px and add padding for add new --- .../preferences/browser/media/settingsWidgets.css | 10 +++++----- .../contrib/preferences/browser/settingsWidgets.ts | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/media/settingsWidgets.css b/src/vs/workbench/contrib/preferences/browser/media/settingsWidgets.css index 060fc54921c..ff5f813a4fc 100644 --- a/src/vs/workbench/contrib/preferences/browser/media/settingsWidgets.css +++ b/src/vs/workbench/contrib/preferences/browser/media/settingsWidgets.css @@ -29,7 +29,7 @@ .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-value, .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-sibling { display: inline-block; - line-height: 22px; + line-height: 24px; } /* Use monospace to display glob patterns in exclude widget */ @@ -49,12 +49,11 @@ display: none; position: absolute; right: 0px; - margin-top: 1px; } .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row { position: relative; - max-height: 22px; + max-height: 24px; } .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row:focus { @@ -68,7 +67,7 @@ .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row .monaco-action-bar .action-label { width: 16px; - height: 16px; + height: 20px; padding: 2px; margin-right: 2px; } @@ -103,6 +102,7 @@ } .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .monaco-text-button.setting-list-addButton { + margin-top: 4px; margin-right: 10px; } @@ -112,7 +112,7 @@ .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-valueInput, .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-siblingInput { - height: 22px; + height: 24px; max-width: 320px; flex: 1; margin-right: 10px; diff --git a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts index ad1b781ae28..cb7d13e51e5 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts @@ -346,7 +346,7 @@ export class ListSettingWidget extends Disposable { .map((item, i) => this.renderItem(item, i, focused)) .forEach(itemElement => this.listElement.appendChild(itemElement)); - const listHeight = 22 * this.model.items.length; + const listHeight = 24 * this.model.items.length; this.listElement.style.height = listHeight + 'px'; } From dc6b475be75999e78233f9f6951ef66f18f768ea Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 6 Aug 2019 09:51:03 -0700 Subject: [PATCH 260/861] Add global event window.onDidWriteTerminalData Fixes #78502 --- .../src/singlefolder-tests/terminal.test.ts | 47 +++++++- src/vs/vscode.proposed.d.ts | 20 ++++ .../api/browser/mainThreadTerminalService.ts | 45 ++++++- .../workbench/api/common/extHost.protocol.ts | 5 + src/vs/workbench/api/node/extHost.api.impl.ts | 5 + src/vs/workbench/api/node/extHostTask.ts | 2 +- .../api/node/extHostTerminalService.ts | 112 ++++++++++++------ 7 files changed, 200 insertions(+), 36 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts index dc281a06fd5..e2787a48fd5 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { window, Terminal, Pseudoterminal, EventEmitter, TerminalDimensions, workspace, ConfigurationTarget } from 'vscode'; -import { doesNotThrow, equal, ok } from 'assert'; +import { doesNotThrow, equal, ok, deepEqual } from 'assert'; suite('window namespace tests', () => { suiteSetup(async () => { @@ -201,6 +201,51 @@ suite('window namespace tests', () => { }); }); + suite('window.onDidWriteTerminalData', () => { + test('should listen to all future terminal data events', (done) => { + const openEvents: string[] = []; + const dataEvents: { name: string, data: string }[] = []; + const closeEvents: string[] = []; + const reg1 = window.onDidOpenTerminal(e => openEvents.push(e.name)); + const reg2 = window.onDidWriteTerminalData(e => dataEvents.push({ name: e.terminal.name, data: e.data })); + const reg3 = window.onDidCloseTerminal(e => { + closeEvents.push(e.name); + if (closeEvents.length === 2) { + deepEqual(openEvents, [ 'test1', 'test2' ]); + deepEqual(dataEvents, [ { name: 'test1', data: 'write1' }, { name: 'test2', data: 'write2' } ]); + deepEqual(closeEvents, [ 'test1', 'test2' ]); + reg1.dispose(); + reg2.dispose(); + reg3.dispose(); + done(); + } + }); + + const term1Write = new EventEmitter(); + const term1Close = new EventEmitter(); + window.createTerminal({ name: 'test1', pty: { + onDidWrite: term1Write.event, + onDidClose: term1Close.event, + open: () => { + term1Write.fire('write1'); + term1Close.fire(); + const term2Write = new EventEmitter(); + const term2Close = new EventEmitter(); + window.createTerminal({ name: 'test2', pty: { + onDidWrite: term2Write.event, + onDidClose: term2Close.event, + open: () => { + term2Write.fire('write2'); + term2Close.fire(); + }, + close: () => {} + }}); + }, + close: () => {} + }}); + }); + }); + suite('Terminal renderers (deprecated)', () => { test('should fire onDidOpenTerminal and onDidCloseTerminal from createTerminalRenderer terminal', (done) => { const reg1 = window.onDidOpenTerminal(term => { diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index db42ea4b01a..dbef9622c77 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -752,11 +752,29 @@ declare module 'vscode' { readonly dimensions: TerminalDimensions; } + export interface TerminalDataWriteEvent { + /** + * The [terminal](#Terminal) for which the data was written. + */ + readonly terminal: Terminal; + /** + * The data being written. + */ + readonly data: string; + } + namespace window { /** * An event which fires when the [dimensions](#Terminal.dimensions) of the terminal change. */ export const onDidChangeTerminalDimensions: Event; + + /** + * An event which fires when the terminal's pty slave pseudo-device is written to. In other + * words, this provides access to the raw data stream from the process running within the + * terminal, including VT sequences. + */ + export const onDidWriteTerminalData: Event; } export interface Terminal { @@ -771,6 +789,8 @@ declare module 'vscode' { * Fires when the terminal's pty slave pseudo-device is written to. In other words, this * provides access to the raw data stream from the process running within the terminal, * including VT sequences. + * + * @deprecated Use [window.onDidWriteTerminalData](#onDidWriteTerminalData). */ readonly onDidWriteData: Event; } diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index fcb1f70bfb6..f59e50e0758 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -11,6 +11,7 @@ import { URI } from 'vs/base/common/uri'; import { StopWatch } from 'vs/base/common/stopwatch'; import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @extHostNamedCustomer(MainContext.MainThreadTerminalService) export class MainThreadTerminalService implements MainThreadTerminalServiceShape { @@ -22,12 +23,14 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape private readonly _terminalProcessesReady = new Map void>(); private readonly _terminalOnDidWriteDataListeners = new Map(); private readonly _terminalOnDidAcceptInputListeners = new Map(); + private _dataEventTracker: TerminalDataEventTracker | undefined; constructor( extHostContext: IExtHostContext, @ITerminalService private readonly _terminalService: ITerminalService, @ITerminalInstanceService readonly terminalInstanceService: ITerminalInstanceService, - @IRemoteAgentService readonly _remoteAgentService: IRemoteAgentService + @IRemoteAgentService readonly _remoteAgentService: IRemoteAgentService, + @IInstantiationService private readonly _instantiationService: IInstantiationService, ) { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTerminalService); this._remoteAuthority = extHostContext.remoteAuthority; @@ -172,6 +175,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape } } + /** @deprecated */ public $registerOnDataListener(terminalId: number): void { const terminalInstance = this._terminalService.getInstanceFromId(terminalId); if (!terminalInstance) { @@ -191,14 +195,34 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape terminalInstance.addDisposable(listener); } + public $startSendingDataEvents(): void { + if (!this._dataEventTracker) { + this._dataEventTracker = this._instantiationService.createInstance(TerminalDataEventTracker, (id, data) => { + this._onTerminalData2(id, data); + }); + } + } + + public $stopSendingDataEvents(): void { + if (this._dataEventTracker) { + this._dataEventTracker.dispose(); + this._dataEventTracker = undefined; + } + } + private _onActiveTerminalChanged(terminalId: number | null): void { this._proxy.$acceptActiveTerminalChanged(terminalId); } + /** @deprecated */ private _onTerminalData(terminalId: number, data: string): void { this._proxy.$acceptTerminalProcessData(terminalId, data); } + private _onTerminalData2(terminalId: number, data: string): void { + this._proxy.$acceptTerminalProcessData2(terminalId, data); + } + private _onTitleChanged(terminalId: number, name: string): void { this._proxy.$acceptTerminalTitleChange(terminalId, name); } @@ -371,3 +395,22 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape return terminal; } } + +/** + * Encapsulates temporary tracking of data events from terminal instances, once disposed all + * listeners are removed. + */ +class TerminalDataEventTracker extends DisposableStore { + constructor( + private readonly _callback: (id: number, data: string) => void, + @ITerminalService private readonly _terminalService: ITerminalService + ) { + super(); + this._terminalService.terminalInstances.forEach(instance => this._register(instance)); + this.add(this._terminalService.onInstanceCreated(instance => this._register(instance))); + } + + private _register(instance: ITerminalInstance): void { + this.add(instance.onData(e => this._callback(instance.id, e))); + } +} diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 65c477284e5..d5cd75bf901 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -400,7 +400,10 @@ export interface MainThreadTerminalServiceShape extends IDisposable { $hide(terminalId: number): void; $sendText(terminalId: number, text: string, addNewLine: boolean): void; $show(terminalId: number, preserveFocus: boolean): void; + /** @deprecated */ $registerOnDataListener(terminalId: number): void; + $startSendingDataEvents(): void; + $stopSendingDataEvents(): void; // Process $sendProcessTitle(terminalId: number, title: string): void; @@ -1157,7 +1160,9 @@ export interface ExtHostTerminalServiceShape { $acceptTerminalOpened(id: number, name: string): void; $acceptActiveTerminalChanged(id: number | null): void; $acceptTerminalProcessId(id: number, processId: number): void; + /** @deprecated */ $acceptTerminalProcessData(id: number, data: string): void; + $acceptTerminalProcessData2(id: number, data: string): void; $acceptTerminalRendererInput(id: number, data: string): void; $acceptTerminalTitleChange(id: number, name: string): void; $acceptTerminalDimensions(id: number, cols: number, rows: number): void; diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 3c4e7ee8a66..16a56dbf4cf 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -457,8 +457,13 @@ export function createApiFactory( return extHostTerminalService.onDidChangeActiveTerminal(listener, thisArg, disposables); }, onDidChangeTerminalDimensions(listener, thisArg?, disposables?) { + checkProposedApiEnabled(extension); return extHostTerminalService.onDidChangeTerminalDimensions(listener, thisArg, disposables); }, + onDidWriteTerminalData(listener, thisArg?, disposables?) { + checkProposedApiEnabled(extension); + return extHostTerminalService.onDidWriteTerminalData(listener, thisArg, disposables); + }, get state() { return extHostWindow.state; }, diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index 5c6a6a2c2f3..6c70ab2cde6 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -588,7 +588,7 @@ export class ExtHostTask implements ExtHostTaskShape { // Clone the custom execution to keep the original untouched. This is important for multiple runs of the same task. this._activeCustomExecutions2.set(execution.id, execution2); - await this._terminalService.attachPtyToTerminal(terminalId, await execution2.callback()); + this._terminalService.attachPtyToTerminal(terminalId, await execution2.callback()); } // Once a terminal is spun up for the custom execution task this event will be fired. diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 4462de7b458..f2d58a8e651 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -88,7 +88,9 @@ export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Termi private _pidPromiseComplete: ((value: number | undefined) => any) | undefined; private _rows: number | undefined; + /** @deprecated */ private readonly _onData = new Emitter(); + /** @deprecated */ public get onDidWriteData(): Event { // Tell the main side to start sending data if it's not already this._idPromise.then(id => { @@ -97,6 +99,8 @@ export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Termi return this._onData.event; } + public isOpen: boolean = false; + constructor( proxy: MainThreadTerminalServiceShape, private _name?: string, @@ -305,6 +309,8 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { public get onDidChangeActiveTerminal(): Event { return this._onDidChangeActiveTerminal && this._onDidChangeActiveTerminal.event; } private readonly _onDidChangeTerminalDimensions: Emitter = new Emitter(); public get onDidChangeTerminalDimensions(): Event { return this._onDidChangeTerminalDimensions && this._onDidChangeTerminalDimensions.event; } + private readonly _onDidWriteTerminalData: Emitter; + public get onDidWriteTerminalData(): Event { return this._onDidWriteTerminalData && this._onDidWriteTerminalData.event; } constructor( mainContext: IMainContext, @@ -314,6 +320,10 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { private _logService: ILogService ) { this._proxy = mainContext.getProxy(MainContext.MainThreadTerminalService); + this._onDidWriteTerminalData = new Emitter({ + onFirstListenerAdd: () => this._proxy.$startSendingDataEvents(), + onLastListenerRemove: () => this._proxy.$stopSendingDataEvents() + }); this._updateLastActiveWorkspace(); this._updateVariableResolver(); this._registerListeners(); @@ -341,7 +351,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return terminal; } - public async attachPtyToTerminal(id: number, pty: vscode.Pseudoterminal): Promise { + public attachPtyToTerminal(id: number, pty: vscode.Pseudoterminal): void { const terminal = this._getTerminalByIdEventually(id); if (!terminal) { throw new Error(`Cannot resolve terminal with id ${id} for virtual process`); @@ -409,7 +419,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return renderer; } - public $acceptActiveTerminalChanged(id: number | null): void { + public async $acceptActiveTerminalChanged(id: number | null): Promise { const original = this._activeTerminal; if (id === null) { this._activeTerminal = undefined; @@ -418,38 +428,45 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { } return; } - this.performTerminalIdAction(id, terminal => { - if (terminal) { - this._activeTerminal = terminal; - if (original !== this._activeTerminal) { - this._onDidChangeActiveTerminal.fire(this._activeTerminal); - } + const terminal = await this._getTerminalByIdEventually(id); + if (terminal) { + this._activeTerminal = terminal; + if (original !== this._activeTerminal) { + this._onDidChangeActiveTerminal.fire(this._activeTerminal); } - }); + } } - public $acceptTerminalProcessData(id: number, data: string): void { - this._getTerminalByIdEventually(id).then(terminal => { - if (terminal) { - terminal._fireOnData(data); - } - }); + /** @deprecated */ + public async $acceptTerminalProcessData(id: number, data: string): Promise { + const terminal = await this._getTerminalByIdEventually(id); + if (terminal) { + terminal._fireOnData(data); + } } - public $acceptTerminalDimensions(id: number, cols: number, rows: number): void { - this._getTerminalByIdEventually(id).then(terminal => { - if (terminal) { - if (terminal.setDimensions(cols, rows)) { - this._onDidChangeTerminalDimensions.fire({ - terminal: terminal, - dimensions: terminal.dimensions as vscode.TerminalDimensions - }); - } - } - }); + public async $acceptTerminalProcessData2(id: number, data: string): Promise { + const terminal = await this._getTerminalByIdEventually(id); + if (terminal) { + this._onDidWriteTerminalData.fire({ terminal, data }); + } } - public $acceptTerminalMaximumDimensions(id: number, cols: number, rows: number): void { + public async $acceptTerminalDimensions(id: number, cols: number, rows: number): Promise { + const terminal = await this._getTerminalByIdEventually(id); + if (terminal) { + if (terminal.setDimensions(cols, rows)) { + this._onDidChangeTerminalDimensions.fire({ + terminal: terminal, + dimensions: terminal.dimensions as vscode.TerminalDimensions + }); + } + } + } + + public async $acceptTerminalMaximumDimensions(id: number, cols: number, rows: number): Promise { + await this._getTerminalByIdEventually(id); + if (this._terminalProcesses[id]) { // Virtual processes only - when virtual process resize fires it means that the // terminal's maximum dimensions changed @@ -473,14 +490,16 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { } } - public $acceptTerminalTitleChange(id: number, name: string): void { + public async $acceptTerminalTitleChange(id: number, name: string): Promise { + await this._getTerminalByIdEventually(id); const extHostTerminal = this._getTerminalObjectById(this.terminals, id); if (extHostTerminal) { extHostTerminal.name = name; } } - public $acceptTerminalClosed(id: number): void { + public async $acceptTerminalClosed(id: number): Promise { + await this._getTerminalByIdEventually(id); const index = this._getTerminalObjectIndexById(this.terminals, id); if (index !== null) { const terminal = this._terminals.splice(index, 1)[0]; @@ -493,6 +512,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { if (index !== null) { // The terminal has already been created (via createTerminal*), only fire the event this._onDidOpenTerminal.fire(this.terminals[index]); + this.terminals[index].isOpen = true; return; } @@ -500,13 +520,18 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { const terminal = new ExtHostTerminal(this._proxy, name, id, renderer ? RENDERER_NO_PROCESS_ID : undefined); this._terminals.push(terminal); this._onDidOpenTerminal.fire(terminal); + terminal.isOpen = true; } - public $acceptTerminalProcessId(id: number, processId: number): void { - this.performTerminalIdAction(id, terminal => terminal._setProcessId(processId)); + public async $acceptTerminalProcessId(id: number, processId: number): Promise { + const terminal = await this._getTerminalByIdEventually(id); + if (terminal) { + terminal._setProcessId(processId); + } } public performTerminalIdAction(id: number, callback: (terminal: ExtHostTerminal) => void): void { + // TODO: Use await this._getTerminalByIdEventually(id); let terminal = this._getTerminalById(id); if (terminal) { callback(terminal); @@ -629,7 +654,27 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { public async $startExtensionTerminal(id: number, initialDimensions: ITerminalDimensionsDto | undefined): Promise { // Make sure the ExtHostTerminal exists so onDidOpenTerminal has fired before we call // Pseudoterminal.start - await this._getTerminalByIdEventually(id); + const terminal = await this._getTerminalByIdEventually(id); + if (!terminal) { + return; + } + + // Wait for onDidOpenTerminal to fire + let openPromise: Promise; + if (terminal.isOpen) { + openPromise = Promise.resolve(); + } else { + openPromise = new Promise(r => { + // Ensure open is called after onDidOpenTerminal + const listener = this.onDidOpenTerminal(async e => { + if (e === terminal) { + listener.dispose(); + r(); + } + }); + }); + } + await openPromise; // Processes should be initialized here for normal virtual process terminals, however for // tasks they are responsible for attaching the virtual process to a terminal so this @@ -706,7 +751,8 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { this._proxy.$sendProcessExit(id, exitCode); } - private _getTerminalByIdEventually(id: number, retries: number = 5): Promise { + // TODO: This could be improved by using a single promise and resolve it when the terminal is ready + private _getTerminalByIdEventually(id: number, retries: number = 5): Promise { if (!this._getTerminalPromises[id]) { this._getTerminalPromises[id] = this._createGetTerminalPromise(id, retries); } else { From ac80d49e152a6ec0e915b01b903393d2c9a877a8 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 6 Aug 2019 10:20:19 -0700 Subject: [PATCH 261/861] Ensure all Emitters in terminal are disposed Fixes #78498 --- .../api/browser/mainThreadTerminalService.ts | 12 ++--- .../terminal/browser/terminalInstance.ts | 51 +++++++++---------- .../browser/terminalProcessManager.ts | 19 ++++--- .../contrib/terminal/browser/terminalTab.ts | 4 +- .../common/terminalProcessExtHostProxy.ts | 6 +-- .../contrib/terminal/node/terminalProcess.ts | 14 ++--- .../terminal/node/windowsShellHelper.ts | 8 ++- 7 files changed, 61 insertions(+), 53 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index f59e50e0758..81f7d0d0311 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { IDisposable, DisposableStore, Disposable } from 'vs/base/common/lifecycle'; import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalProcessExtHostProxy, ISpawnExtHostProcessRequest, ITerminalDimensions, EXT_HOST_CREATION_DELAY, IAvailableShellsRequest, IDefaultShellAndArgsRequest, IStartExtensionTerminalRequest } from 'vs/workbench/contrib/terminal/common/terminal'; import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceShape, MainContext, IExtHostContext, IShellLaunchConfigDto, TerminalLaunchConfig, ITerminalDimensionsDto } from 'vs/workbench/api/common/extHost.protocol'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; @@ -400,17 +400,17 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape * Encapsulates temporary tracking of data events from terminal instances, once disposed all * listeners are removed. */ -class TerminalDataEventTracker extends DisposableStore { +class TerminalDataEventTracker extends Disposable { constructor( private readonly _callback: (id: number, data: string) => void, @ITerminalService private readonly _terminalService: ITerminalService ) { super(); - this._terminalService.terminalInstances.forEach(instance => this._register(instance)); - this.add(this._terminalService.onInstanceCreated(instance => this._register(instance))); + this._terminalService.terminalInstances.forEach(instance => this._registerInstance(instance)); + this._register(this._terminalService.onInstanceCreated(instance => this._registerInstance(instance))); } - private _register(instance: ITerminalInstance): void { - this.add(instance.onData(e => this._callback(instance.id, e))); + private _registerInstance(instance: ITerminalInstance): void { + this._register(instance.onData(e => this._callback(instance.id, e))); } } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 4a76d9422f5..6dccb496a00 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -9,7 +9,7 @@ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { debounce } from 'vs/base/common/decorators'; import { Emitter, Event } from 'vs/base/common/event'; import { KeyCode } from 'vs/base/common/keyCodes'; -import * as lifecycle from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle'; import * as platform from 'vs/base/common/platform'; import { TabFocus } from 'vs/editor/common/config/commonEditorConfig'; import * as nls from 'vs/nls'; @@ -165,7 +165,7 @@ interface IGridDimensions { rows: number; } -export class TerminalInstance implements ITerminalInstance { +export class TerminalInstance extends Disposable implements ITerminalInstance { private static readonly EOL_REGEX = /\r?\n/g; private static _lastKnownCanvasDimensions: ICanvasDimensions | undefined; @@ -173,7 +173,7 @@ export class TerminalInstance implements ITerminalInstance { private static _idCounter = 1; private _processManager: ITerminalProcessManager | undefined; - private _pressAnyKeyToCloseListener: lifecycle.IDisposable | undefined; + private _pressAnyKeyToCloseListener: IDisposable | undefined; private _id: number; private _isExiting: boolean; @@ -196,8 +196,7 @@ export class TerminalInstance implements ITerminalInstance { private _titleReadyPromise: Promise; private _titleReadyComplete: (title: string) => any; - private readonly _disposables = new lifecycle.DisposableStore(); - private _messageTitleDisposable: lifecycle.IDisposable | undefined; + private _messageTitleDisposable: IDisposable | undefined; private _widgetManager: TerminalWidgetManager; private _linkHandler: TerminalLinkHandler; @@ -275,6 +274,8 @@ export class TerminalInstance implements ITerminalInstance { @IStorageService private readonly _storageService: IStorageService, @IAccessibilityService private readonly _accessibilityService: IAccessibilityService ) { + super(); + this._skipTerminalCommands = []; this._isExiting = false; this._hadFocusOnExit = false; @@ -321,8 +322,8 @@ export class TerminalInstance implements ITerminalInstance { })); } - public addDisposable(disposable: lifecycle.IDisposable): void { - this._disposables.add(disposable); + public addDisposable(disposable: IDisposable): void { + this._register(disposable); } private _initDimensions(): void { @@ -524,7 +525,7 @@ export class TerminalInstance implements ITerminalInstance { this._commandTrackerAddon = new CommandTrackerAddon(); this._xterm.loadAddon(this._commandTrackerAddon); - this._disposables.add(this._themeService.onThemeChange(theme => this._updateTheme(xterm, theme))); + this._register(this._themeService.onThemeChange(theme => this._updateTheme(xterm, theme))); return xterm; } @@ -608,7 +609,7 @@ export class TerminalInstance implements ITerminalInstance { return true; }); - this._disposables.add(dom.addDisposableListener(xterm.element, 'mousedown', () => { + this._register(dom.addDisposableListener(xterm.element, 'mousedown', () => { // We need to listen to the mouseup event on the document since the user may release // the mouse button anywhere outside of _xterm.element. const listener = dom.addDisposableListener(document, 'mouseup', () => { @@ -620,7 +621,7 @@ export class TerminalInstance implements ITerminalInstance { })); // xterm.js currently drops selection on keyup as we need to handle this case. - this._disposables.add(dom.addDisposableListener(xterm.element, 'keyup', () => { + this._register(dom.addDisposableListener(xterm.element, 'keyup', () => { // Wait until keyup has propagated through the DOM before evaluating // the new selection state. setTimeout(() => this._refreshSelectionContextKey(), 0); @@ -630,7 +631,7 @@ export class TerminalInstance implements ITerminalInstance { const focusTrap: HTMLElement = document.createElement('div'); focusTrap.setAttribute('tabindex', '0'); dom.addClass(focusTrap, 'focus-trap'); - this._disposables.add(dom.addDisposableListener(focusTrap, 'focus', () => { + this._register(dom.addDisposableListener(focusTrap, 'focus', () => { let currentElement = focusTrap; while (!dom.hasClass(currentElement, 'part')) { currentElement = currentElement.parentElement!; @@ -640,18 +641,18 @@ export class TerminalInstance implements ITerminalInstance { })); xtermHelper.insertBefore(focusTrap, xterm.textarea); - this._disposables.add(dom.addDisposableListener(xterm.textarea, 'focus', () => { + this._register(dom.addDisposableListener(xterm.textarea, 'focus', () => { this._terminalFocusContextKey.set(true); this._onFocused.fire(this); })); - this._disposables.add(dom.addDisposableListener(xterm.textarea, 'blur', () => { + this._register(dom.addDisposableListener(xterm.textarea, 'blur', () => { this._terminalFocusContextKey.reset(); this._refreshSelectionContextKey(); })); - this._disposables.add(dom.addDisposableListener(xterm.element, 'focus', () => { + this._register(dom.addDisposableListener(xterm.element, 'focus', () => { this._terminalFocusContextKey.set(true); })); - this._disposables.add(dom.addDisposableListener(xterm.element, 'blur', () => { + this._register(dom.addDisposableListener(xterm.element, 'blur', () => { this._terminalFocusContextKey.reset(); this._refreshSelectionContextKey(); })); @@ -800,11 +801,11 @@ export class TerminalInstance implements ITerminalInstance { public dispose(immediate?: boolean): void { this._logService.trace(`terminalInstance#dispose (id: ${this.id})`); - lifecycle.dispose(this._windowsShellHelper); + dispose(this._windowsShellHelper); this._windowsShellHelper = undefined; - this._linkHandler = lifecycle.dispose(this._linkHandler); - this._commandTrackerAddon = lifecycle.dispose(this._commandTrackerAddon); - this._widgetManager = lifecycle.dispose(this._widgetManager); + this._linkHandler = dispose(this._linkHandler); + this._commandTrackerAddon = dispose(this._commandTrackerAddon); + this._widgetManager = dispose(this._widgetManager); if (this._xterm && this._xterm.element) { this._hadFocusOnExit = dom.hasClass(this._xterm.element, 'focus'); @@ -841,7 +842,7 @@ export class TerminalInstance implements ITerminalInstance { this._isDisposed = true; this._onDisposed.fire(this); } - this._disposables.dispose(); + super.dispose(); } public rendererExit(exitCode: number): void { @@ -1410,12 +1411,10 @@ export class TerminalInstance implements ITerminalInstance { } else { // If the title has not been set by the API or the rename command, unregister the handler that // automatically updates the terminal name - if (this._messageTitleDisposable) { - lifecycle.dispose(this._messageTitleDisposable); - lifecycle.dispose(this._windowsShellHelper); - this._messageTitleDisposable = undefined; - this._windowsShellHelper = undefined; - } + dispose(this._messageTitleDisposable); + this._messageTitleDisposable = undefined; + dispose(this._windowsShellHelper); + this._windowsShellHelper = undefined; } const didTitleChange = title !== this._title; const oldTitle = this._title; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index 29e4aa6fbfc..826122750b8 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -20,6 +20,7 @@ import { IProductService } from 'vs/platform/product/common/product'; import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; +import { Disposable } from 'vs/base/common/lifecycle'; /** The amount of time to consider terminal errors to be related to the launch */ const LAUNCHING_DURATION = 500; @@ -42,7 +43,7 @@ enum ProcessType { * - Pty Process: The pseudoterminal master process (or the winpty agent process) * - Shell Process: The pseudoterminal slave process (ie. the shell) */ -export class TerminalProcessManager implements ITerminalProcessManager { +export class TerminalProcessManager extends Disposable implements ITerminalProcessManager { public processState: ProcessState = ProcessState.UNINITIALIZED; public ptyProcessReady: Promise; public shellProcessId: number | undefined; @@ -57,19 +58,19 @@ export class TerminalProcessManager implements ITerminalProcessManager { private _latencyLastMeasured: number = 0; private _initialCwd: string | undefined; - private readonly _onProcessReady = new Emitter(); + private readonly _onProcessReady = this._register(new Emitter()); public get onProcessReady(): Event { return this._onProcessReady.event; } - private readonly _onBeforeProcessData = new Emitter(); + private readonly _onBeforeProcessData = this._register(new Emitter()); public get onBeforeProcessData(): Event { return this._onBeforeProcessData.event; } - private readonly _onProcessData = new Emitter(); + private readonly _onProcessData = this._register(new Emitter()); public get onProcessData(): Event { return this._onProcessData.event; } - private readonly _onProcessTitle = new Emitter(); + private readonly _onProcessTitle = this._register(new Emitter()); public get onProcessTitle(): Event { return this._onProcessTitle.event; } - private readonly _onProcessExit = new Emitter(); + private readonly _onProcessExit = this._register(new Emitter()); public get onProcessExit(): Event { return this._onProcessExit.event; } - private readonly _onProcessOverrideDimensions = new Emitter(); + private readonly _onProcessOverrideDimensions = this._register(new Emitter()); public get onProcessOverrideDimensions(): Event { return this._onProcessOverrideDimensions.event; } - private readonly _onProcessOverrideShellLaunchConfig = new Emitter(); + private readonly _onProcessOverrideShellLaunchConfig = this._register(new Emitter()); public get onProcessResolvedShellLaunchConfig(): Event { return this._onProcessOverrideShellLaunchConfig.event; } constructor( @@ -86,6 +87,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { @ITerminalInstanceService private readonly _terminalInstanceService: ITerminalInstanceService, @IRemoteAgentService private readonly _remoteAgentService: IRemoteAgentService ) { + super(); this.ptyProcessReady = new Promise(c => { this.onProcessReady(() => { this._logService.debug(`Terminal process ready (shellProcessId: ${this.shellProcessId})`); @@ -104,6 +106,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { this._process.shutdown(immediate); this._process = null; } + super.dispose(); } public async createProcess( diff --git a/src/vs/workbench/contrib/terminal/browser/terminalTab.ts b/src/vs/workbench/contrib/terminal/browser/terminalTab.ts index aefb287ded3..4b49a00187d 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalTab.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalTab.ts @@ -220,9 +220,9 @@ export class TerminalTab extends Disposable implements ITerminalTab { public get terminalInstances(): ITerminalInstance[] { return this._terminalInstances; } - private readonly _onDisposed: Emitter = new Emitter(); + private readonly _onDisposed: Emitter = this._register(new Emitter()); public readonly onDisposed: Event = this._onDisposed.event; - private readonly _onInstancesChanged: Emitter = new Emitter(); + private readonly _onInstancesChanged: Emitter = this._register(new Emitter()); public readonly onInstancesChanged: Event = this._onInstancesChanged.event; constructor( diff --git a/src/vs/workbench/contrib/terminal/common/terminalProcessExtHostProxy.ts b/src/vs/workbench/contrib/terminal/common/terminalProcessExtHostProxy.ts index 80923d84486..dfc07d6efe7 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalProcessExtHostProxy.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalProcessExtHostProxy.ts @@ -18,13 +18,13 @@ export class TerminalProcessExtHostProxy extends Disposable implements ITerminal public readonly onProcessData: Event = this._onProcessData.event; private readonly _onProcessExit = this._register(new Emitter()); public readonly onProcessExit: Event = this._onProcessExit.event; - private readonly _onProcessReady = new Emitter<{ pid: number, cwd: string }>(); + private readonly _onProcessReady = this._register(new Emitter<{ pid: number, cwd: string }>()); public get onProcessReady(): Event<{ pid: number, cwd: string }> { return this._onProcessReady.event; } private readonly _onProcessTitleChanged = this._register(new Emitter()); public readonly onProcessTitleChanged: Event = this._onProcessTitleChanged.event; - private readonly _onProcessOverrideDimensions = new Emitter(); + private readonly _onProcessOverrideDimensions = this._register(new Emitter()); public get onProcessOverrideDimensions(): Event { return this._onProcessOverrideDimensions.event; } - private readonly _onProcessResolvedShellLaunchConfig = new Emitter(); + private readonly _onProcessResolvedShellLaunchConfig = this._register(new Emitter()); public get onProcessResolvedShellLaunchConfig(): Event { return this._onProcessResolvedShellLaunchConfig.event; } private readonly _onInput = this._register(new Emitter()); diff --git a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts index 74d4598d6f5..2c2635f7c1c 100644 --- a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts +++ b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts @@ -10,7 +10,7 @@ import * as pty from 'node-pty'; import * as fs from 'fs'; import { Event, Emitter } from 'vs/base/common/event'; import { getWindowsBuildNumber } from 'vs/workbench/contrib/terminal/node/terminal'; -import { IDisposable } from 'vs/base/common/lifecycle'; +import { Disposable } from 'vs/base/common/lifecycle'; import { IShellLaunchConfig, ITerminalChildProcess, SHELL_PATH_INVALID_EXIT_CODE, SHELL_PATH_DIRECTORY_EXIT_CODE, SHELL_CWD_INVALID_EXIT_CODE } from 'vs/workbench/contrib/terminal/common/terminal'; import { exec } from 'child_process'; import { ILogService } from 'vs/platform/log/common/log'; @@ -18,7 +18,7 @@ import { stat } from 'vs/base/node/pfs'; import { findExecutable } from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; import { URI } from 'vs/base/common/uri'; -export class TerminalProcess implements ITerminalChildProcess, IDisposable { +export class TerminalProcess extends Disposable implements ITerminalChildProcess { private _exitCode: number; private _closeTimeout: any; private _ptyProcess: pty.IPty | undefined; @@ -28,13 +28,13 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable { private _titleInterval: NodeJS.Timer | null = null; private _initialCwd: string; - private readonly _onProcessData = new Emitter(); + private readonly _onProcessData = this._register(new Emitter()); public get onProcessData(): Event { return this._onProcessData.event; } - private readonly _onProcessExit = new Emitter(); + private readonly _onProcessExit = this._register(new Emitter()); public get onProcessExit(): Event { return this._onProcessExit.event; } - private readonly _onProcessReady = new Emitter<{ pid: number, cwd: string }>(); + private readonly _onProcessReady = this._register(new Emitter<{ pid: number, cwd: string }>()); public get onProcessReady(): Event<{ pid: number, cwd: string }> { return this._onProcessReady.event; } - private readonly _onProcessTitleChanged = new Emitter(); + private readonly _onProcessTitleChanged = this._register(new Emitter()); public get onProcessTitleChanged(): Event { return this._onProcessTitleChanged.event; } constructor( @@ -46,6 +46,7 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable { windowsEnableConpty: boolean, @ILogService private readonly _logService: ILogService ) { + super(); let shellName: string; if (os.platform() === 'win32') { shellName = path.basename(shellLaunchConfig.executable || ''); @@ -143,6 +144,7 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable { this._onProcessExit.dispose(); this._onProcessReady.dispose(); this._onProcessTitleChanged.dispose(); + super.dispose(); } private _setupTitlePolling(ptyProcess: pty.IPty) { diff --git a/src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts b/src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts index 030dcd89100..18c24058910 100644 --- a/src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts +++ b/src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts @@ -8,6 +8,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import { ITerminalInstance, IWindowsShellHelper } from 'vs/workbench/contrib/terminal/common/terminal'; import { Terminal as XTermTerminal } from 'xterm'; import WindowsProcessTreeType = require('windows-process-tree'); +import { Disposable } from 'vs/base/common/lifecycle'; const SHELL_EXECUTABLES = [ 'cmd.exe', @@ -24,8 +25,8 @@ const SHELL_EXECUTABLES = [ let windowsProcessTree: typeof WindowsProcessTreeType; -export class WindowsShellHelper implements IWindowsShellHelper { - private _onCheckShell: Emitter | undefined> = new Emitter | undefined>(); +export class WindowsShellHelper extends Disposable implements IWindowsShellHelper { + private _onCheckShell: Emitter | undefined> = this._register(new Emitter | undefined>()); private _isDisposed: boolean; private _currentRequest: Promise | undefined; private _newLineFeed: boolean = false; @@ -35,6 +36,8 @@ export class WindowsShellHelper implements IWindowsShellHelper { private _terminalInstance: ITerminalInstance, private _xterm: XTermTerminal ) { + super(); + if (!platform.isWindows) { throw new Error(`WindowsShellHelper cannot be instantiated on ${platform.platform}`); } @@ -111,6 +114,7 @@ export class WindowsShellHelper implements IWindowsShellHelper { public dispose(): void { this._isDisposed = true; + super.dispose(); } /** From 8fc596d95622c24a7301e888d736bdc6e9bfc0d3 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 6 Aug 2019 10:31:41 -0700 Subject: [PATCH 262/861] Remove unnecessary ternaries --- src/vs/workbench/contrib/terminal/browser/terminalInstance.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index cd0b782993a..1953e9f3b31 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -220,10 +220,10 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { public get maxCols(): number { return this._cols; } public get maxRows(): number { return this._rows; } // TODO: Ideally processId would be merged into processReady - public get processId(): number | undefined { return this._processManager ? this._processManager.shellProcessId : undefined; } + public get processId(): number | undefined { return this._processManager.shellProcessId; } // TODO: How does this work with detached processes? // TODO: Should this be an event as it can fire twice? - public get processReady(): Promise { return this._processManager ? this._processManager.ptyProcessReady : Promise.resolve(undefined); } + public get processReady(): Promise { return this._processManager.ptyProcessReady; } public get title(): string { return this._title; } public get hadFocusOnExit(): boolean { return this._hadFocusOnExit; } public get isTitleSetByProcess(): boolean { return !!this._messageTitleDisposable; } From 948d3446f35bda09991c6aecfc695e45f2d55280 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 6 Aug 2019 10:50:13 -0700 Subject: [PATCH 263/861] Fix #35954. Use nbsp when copying html into clipboard --- .../common/modes/textToHtmlTokenizer.ts | 4 + .../common/modes/textToHtmlTokenizer.test.ts | 104 ++++++++++++++++-- 2 files changed, 97 insertions(+), 11 deletions(-) diff --git a/src/vs/editor/common/modes/textToHtmlTokenizer.ts b/src/vs/editor/common/modes/textToHtmlTokenizer.ts index 80212b74264..4b1afa955ea 100644 --- a/src/vs/editor/common/modes/textToHtmlTokenizer.ts +++ b/src/vs/editor/common/modes/textToHtmlTokenizer.ts @@ -77,6 +77,10 @@ export function tokenizeLineToHTML(text: string, viewLineTokens: IViewLineTokens partContent += '​'; break; + case CharCode.Space: + partContent += ' '; + break; + default: partContent += String.fromCharCode(charCode); } diff --git a/src/vs/editor/test/common/modes/textToHtmlTokenizer.test.ts b/src/vs/editor/test/common/modes/textToHtmlTokenizer.test.ts index 781ea1bb6a5..56dda979b62 100644 --- a/src/vs/editor/test/common/modes/textToHtmlTokenizer.test.ts +++ b/src/vs/editor/test/common/modes/textToHtmlTokenizer.test.ts @@ -109,9 +109,9 @@ suite('Editor Modes - textToHtmlTokenizer', () => { [ '
', 'Ciao', - ' ', + ' ', 'hello', - ' ', + ' ', 'world!', '
' ].join('') @@ -122,9 +122,9 @@ suite('Editor Modes - textToHtmlTokenizer', () => { [ '
', 'Ciao', - ' ', + ' ', 'hello', - ' ', + ' ', 'w', '
' ].join('') @@ -135,9 +135,9 @@ suite('Editor Modes - textToHtmlTokenizer', () => { [ '
', 'Ciao', - ' ', + ' ', 'hello', - ' ', + ' ', '
' ].join('') ); @@ -147,9 +147,9 @@ suite('Editor Modes - textToHtmlTokenizer', () => { [ '
', 'iao', - ' ', + ' ', 'hello', - ' ', + ' ', '
' ].join('') ); @@ -158,9 +158,9 @@ suite('Editor Modes - textToHtmlTokenizer', () => { tokenizeLineToHTML(text, lineTokens, colorMap, 4, 11, 4), [ '
', - ' ', + ' ', 'hello', - ' ', + ' ', '
' ].join('') ); @@ -170,7 +170,7 @@ suite('Editor Modes - textToHtmlTokenizer', () => { [ '
', 'hello', - ' ', + ' ', '
' ].join('') ); @@ -193,6 +193,88 @@ suite('Editor Modes - textToHtmlTokenizer', () => { ].join('') ); }); + test('tokenizeLineToHTML handle spaces #35954', () => { + const text = ' Ciao hello world!'; + const lineTokens = new ViewLineTokens([ + new ViewLineToken( + 2, + ( + (1 << MetadataConsts.FOREGROUND_OFFSET) + ) >>> 0 + ), + new ViewLineToken( + 6, + ( + (3 << MetadataConsts.FOREGROUND_OFFSET) + | ((FontStyle.Bold | FontStyle.Italic) << MetadataConsts.FONT_STYLE_OFFSET) + ) >>> 0 + ), + new ViewLineToken( + 9, + ( + (1 << MetadataConsts.FOREGROUND_OFFSET) + ) >>> 0 + ), + new ViewLineToken( + 14, + ( + (4 << MetadataConsts.FOREGROUND_OFFSET) + ) >>> 0 + ), + new ViewLineToken( + 15, + ( + (1 << MetadataConsts.FOREGROUND_OFFSET) + ) >>> 0 + ), + new ViewLineToken( + 21, + ( + (5 << MetadataConsts.FOREGROUND_OFFSET) + | ((FontStyle.Underline) << MetadataConsts.FONT_STYLE_OFFSET) + ) >>> 0 + ) + ]); + const colorMap = [null!, '#000000', '#ffffff', '#ff0000', '#00ff00', '#0000ff']; + + assert.equal( + tokenizeLineToHTML(text, lineTokens, colorMap, 0, 21, 4), + [ + '
', + '  ', + 'Ciao', + '   ', + 'hello', + ' ', + 'world!', + '
' + ].join('') + ); + + assert.equal( + tokenizeLineToHTML(text, lineTokens, colorMap, 0, 17, 4), + [ + '
', + '  ', + 'Ciao', + '   ', + 'hello', + ' ', + 'wo', + '
' + ].join('') + ); + + assert.equal( + tokenizeLineToHTML(text, lineTokens, colorMap, 0, 3, 4), + [ + '
', + '  ', + 'C', + '
' + ].join('') + ); + }); }); From 5bf573ab9940725c09f5645766fb20406648d846 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 6 Aug 2019 11:18:55 -0700 Subject: [PATCH 264/861] Fix remaining strict init prop errors in terminal Part of #78168 --- .../contrib/terminal/browser/terminal.ts | 2 +- .../terminal/browser/terminalActions.ts | 12 +++--- .../terminal/browser/terminalConfigHelper.ts | 42 +++++++++++-------- .../terminal/browser/terminalInstance.ts | 39 ++++++++++------- .../terminal/browser/terminalLinkHandler.ts | 4 +- .../contrib/terminal/common/terminal.ts | 2 +- .../contrib/terminal/node/terminalProcess.ts | 4 +- 7 files changed, 58 insertions(+), 47 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index c9e3bdb74a3..418b2900f17 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -35,5 +35,5 @@ export interface ITerminalInstanceService { } export interface IBrowserTerminalConfigHelper extends ITerminalConfigHelper { - panelContainer: HTMLElement; + panelContainer: HTMLElement | undefined; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 23077803ab1..41ceb3e71b1 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -1168,7 +1168,7 @@ export class ScrollToPreviousCommandAction extends Action { public run(): Promise { const instance = this.terminalService.getActiveInstance(); - if (instance) { + if (instance && instance.commandTracker) { instance.commandTracker.scrollToPreviousCommand(); instance.focus(); } @@ -1189,7 +1189,7 @@ export class ScrollToNextCommandAction extends Action { public run(): Promise { const instance = this.terminalService.getActiveInstance(); - if (instance) { + if (instance && instance.commandTracker) { instance.commandTracker.scrollToNextCommand(); instance.focus(); } @@ -1210,7 +1210,7 @@ export class SelectToPreviousCommandAction extends Action { public run(): Promise { const instance = this.terminalService.getActiveInstance(); - if (instance) { + if (instance && instance.commandTracker) { instance.commandTracker.selectToPreviousCommand(); instance.focus(); } @@ -1231,7 +1231,7 @@ export class SelectToNextCommandAction extends Action { public run(): Promise { const instance = this.terminalService.getActiveInstance(); - if (instance) { + if (instance && instance.commandTracker) { instance.commandTracker.selectToNextCommand(); instance.focus(); } @@ -1252,7 +1252,7 @@ export class SelectToPreviousLineAction extends Action { public run(): Promise { const instance = this.terminalService.getActiveInstance(); - if (instance) { + if (instance && instance.commandTracker) { instance.commandTracker.selectToPreviousLine(); instance.focus(); } @@ -1273,7 +1273,7 @@ export class SelectToNextLineAction extends Action { public run(): Promise { const instance = this.terminalService.getActiveInstance(); - if (instance) { + if (instance && instance.commandTracker) { instance.commandTracker.selectToNextLine(); instance.focus(); } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts b/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts index 0da7d6c690b..7d7aafdb6b3 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts @@ -26,11 +26,11 @@ const MAXIMUM_FONT_SIZE = 25; * specific test cases can be written. */ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper { - public panelContainer: HTMLElement; + public panelContainer: HTMLElement | undefined; - private _charMeasureElement: HTMLElement; - private _lastFontMeasurement: ITerminalFont; - public config: ITerminalConfiguration; + private _charMeasureElement: HTMLElement | undefined; + private _lastFontMeasurement: ITerminalFont | undefined; + public config!: ITerminalConfiguration; private readonly _onWorkspacePermissionsChanged = new Emitter(); public get onWorkspacePermissionsChanged(): Event { return this._onWorkspacePermissionsChanged.event; } @@ -55,49 +55,55 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper { } public configFontIsMonospace(): boolean { - this._createCharMeasureElementIfNecessary(); const fontSize = 15; const fontFamily = this.config.fontFamily || this._configurationService.getValue('editor').fontFamily || EDITOR_FONT_DEFAULTS.fontFamily; const i_rect = this._getBoundingRectFor('i', fontFamily, fontSize); const w_rect = this._getBoundingRectFor('w', fontFamily, fontSize); - const invalidBounds = !i_rect.width || !w_rect.width; - if (invalidBounds) { - // There is no reason to believe the font is not Monospace. + // Check for invalid bounds, there is no reason to believe the font is not monospace + if (!i_rect || !w_rect || !i_rect.width || !w_rect.width) { return true; } return i_rect.width === w_rect.width; } - private _createCharMeasureElementIfNecessary() { + private _createCharMeasureElementIfNecessary(): HTMLElement { + if (!this.panelContainer) { + throw new Error('Cannot measure element when terminal is not attached'); + } // Create charMeasureElement if it hasn't been created or if it was orphaned by its parent if (!this._charMeasureElement || !this._charMeasureElement.parentElement) { this._charMeasureElement = document.createElement('div'); this.panelContainer.appendChild(this._charMeasureElement); } + return this._charMeasureElement; } - private _getBoundingRectFor(char: string, fontFamily: string, fontSize: number): ClientRect | DOMRect { - const style = this._charMeasureElement.style; + private _getBoundingRectFor(char: string, fontFamily: string, fontSize: number): ClientRect | DOMRect | undefined { + let charMeasureElement: HTMLElement; + try { + charMeasureElement = this._createCharMeasureElementIfNecessary(); + } catch { + return undefined; + } + const style = charMeasureElement.style; style.display = 'inline-block'; style.fontFamily = fontFamily; style.fontSize = fontSize + 'px'; style.lineHeight = 'normal'; - this._charMeasureElement.innerText = char; - const rect = this._charMeasureElement.getBoundingClientRect(); + charMeasureElement.innerText = char; + const rect = charMeasureElement.getBoundingClientRect(); style.display = 'none'; return rect; } private _measureFont(fontFamily: string, fontSize: number, letterSpacing: number, lineHeight: number): ITerminalFont { - this._createCharMeasureElementIfNecessary(); - const rect = this._getBoundingRectFor('X', fontFamily, fontSize); // Bounding client rect was invalid, use last font measurement if available. - if (this._lastFontMeasurement && !rect.width && !rect.height) { + if (this._lastFontMeasurement && (!rect || !rect.width || !rect.height)) { return this._lastFontMeasurement; } @@ -106,8 +112,8 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper { fontSize, letterSpacing, lineHeight, - charWidth: rect.width, - charHeight: Math.ceil(rect.height) + charWidth: rect && rect.width ? rect.width : 0, + charHeight: rect && rect.height ? Math.ceil(rect.height) : 0 }; return this._lastFontMeasurement; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 6dccb496a00..5d568ac2732 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -185,22 +185,22 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { private _wrapperElement: (HTMLElement & { xterm?: XTermTerminal }) | undefined; private _xterm: XTermTerminal | undefined; private _xtermSearch: SearchAddon | undefined; - private _xtermElement: HTMLDivElement; + private _xtermElement: HTMLDivElement | undefined; private _terminalHasTextContextKey: IContextKey; private _terminalA11yTreeFocusContextKey: IContextKey; - private _cols: number; - private _rows: number; + private _cols: number = 0; + private _rows: number = 0; private _dimensionsOverride: ITerminalDimensions | undefined; private _windowsShellHelper: IWindowsShellHelper | undefined; private _xtermReadyPromise: Promise; private _titleReadyPromise: Promise; - private _titleReadyComplete: (title: string) => any; + private _titleReadyComplete: ((title: string) => any) | undefined; private _messageTitleDisposable: IDisposable | undefined; - private _widgetManager: TerminalWidgetManager; - private _linkHandler: TerminalLinkHandler; - private _commandTrackerAddon: CommandTrackerAddon; + private _widgetManager: TerminalWidgetManager | undefined; + private _linkHandler: TerminalLinkHandler | undefined; + private _commandTrackerAddon: CommandTrackerAddon | undefined; private _navigationModeAddon: INavigationMode & ITerminalAddon | undefined; public disableLayout: boolean; @@ -228,7 +228,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { public get hadFocusOnExit(): boolean { return this._hadFocusOnExit; } public get isTitleSetByProcess(): boolean { return !!this._messageTitleDisposable; } public get shellLaunchConfig(): IShellLaunchConfig { return this._shellLaunchConfig; } - public get commandTracker(): CommandTrackerAddon { return this._commandTrackerAddon; } + public get commandTracker(): CommandTrackerAddon | undefined { return this._commandTrackerAddon; } public get navigationMode(): INavigationMode | undefined { return this._navigationModeAddon; } private readonly _onExit = new Emitter(); @@ -494,7 +494,9 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this._xterm.onData(data => this._processManager!.write(data)); // TODO: How does the cwd work on detached processes? this.processReady.then(async () => { - this._linkHandler.processCwd = await this._processManager!.getInitialCwd(); + if (this._linkHandler) { + this._linkHandler.processCwd = await this._processManager!.getInitialCwd(); + } }); // Init winpty compat and link handler after process creation as they rely on the // underlying process OS @@ -661,11 +663,16 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this._container.appendChild(this._wrapperElement); if (this._processManager) { - this._widgetManager = new TerminalWidgetManager(this._wrapperElement); - this._processManager.onProcessReady(() => this._linkHandler.setWidgetManager(this._widgetManager)); + const widgetManager = new TerminalWidgetManager(this._wrapperElement); + this._widgetManager = widgetManager; + this._processManager.onProcessReady(() => { + if (this._linkHandler) { + this._linkHandler.setWidgetManager(widgetManager); + } + }); } else if (this._shellLaunchConfig.isRendererOnly) { this._widgetManager = new TerminalWidgetManager(this._wrapperElement); - this._linkHandler.setWidgetManager(this._widgetManager); + this._linkHandler!.setWidgetManager(this._widgetManager); } const computedStyle = window.getComputedStyle(this._container); @@ -736,7 +743,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } public registerLinkMatcher(regex: RegExp, handler: (url: string) => void, matchIndex?: number, validationCallback?: (uri: string, callback: (isValid: boolean) => void) => void): number { - return this._linkHandler.registerCustomLinkHandler(regex, handler, matchIndex, validationCallback); + return this._linkHandler!.registerCustomLinkHandler(regex, handler, matchIndex, validationCallback); } public deregisterLinkMatcher(linkMatcherId: number): void { @@ -1252,7 +1259,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { private async _updateProcessCwd(): Promise { // reset cwd if it has changed, so file based url paths can be resolved const cwd = await this.getCwd(); - if (cwd) { + if (cwd && this._linkHandler) { this._linkHandler.processCwd = cwd; } return cwd; @@ -1417,11 +1424,11 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this._windowsShellHelper = undefined; } const didTitleChange = title !== this._title; - const oldTitle = this._title; this._title = title; if (didTitleChange) { - if (!oldTitle) { + if (this._titleReadyComplete) { this._titleReadyComplete(title); + this._titleReadyComplete = undefined; } this._onTitleChanged.fire(this); } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts b/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts index ccfa0c6258c..ba6ddcea32f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts @@ -5,7 +5,7 @@ import * as nls from 'vs/nls'; import { URI } from 'vs/base/common/uri'; -import { dispose, IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { DisposableStore } from 'vs/base/common/lifecycle'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/terminalWidgetManager'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -67,7 +67,6 @@ interface IPath { export class TerminalLinkHandler { private readonly _hoverDisposables = new DisposableStore(); - private _mouseMoveDisposable: IDisposable; private _widgetManager: TerminalWidgetManager | undefined; private _processCwd: string | undefined; private _gitDiffPreImagePattern: RegExp; @@ -184,7 +183,6 @@ export class TerminalLinkHandler { public dispose(): void { this._hoverDisposables.dispose(); - this._mouseMoveDisposable = dispose(this._mouseMoveDisposable); } private _wrapLinkHandler(handler: (uri: string) => boolean | void): XtermLinkMatcherHandler { diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 3e16d10bb5a..998f7ee623c 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -483,7 +483,7 @@ export interface ITerminalInstance { * An object that tracks when commands are run and enables navigating and selecting between * them. */ - readonly commandTracker: ICommandTracker; + readonly commandTracker: ICommandTracker | undefined; readonly navigationMode: INavigationMode | undefined; diff --git a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts index 2c2635f7c1c..b8ad7fd4c28 100644 --- a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts +++ b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts @@ -19,7 +19,7 @@ import { findExecutable } from 'vs/workbench/contrib/terminal/node/terminalEnvir import { URI } from 'vs/base/common/uri'; export class TerminalProcess extends Disposable implements ITerminalChildProcess { - private _exitCode: number; + private _exitCode: number | undefined; private _closeTimeout: any; private _ptyProcess: pty.IPty | undefined; private _currentTitle: string = ''; @@ -188,7 +188,7 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess } catch (ex) { // Swallow, the pty has already been killed } - this._onProcessExit.fire(this._exitCode); + this._onProcessExit.fire(this._exitCode || 0); this.dispose(); }); } From 580088df81e269cd1200398f7ab151307bfc9209 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 6 Aug 2019 11:50:18 -0700 Subject: [PATCH 265/861] Re #78168. Folding, find, color picker, dnd --- .../caretOperations/moveCaretCommand.ts | 8 ++++-- .../contrib/colorPicker/colorPickerWidget.ts | 6 ++-- .../editor/contrib/dnd/dragAndDropCommand.ts | 5 ++-- src/vs/editor/contrib/find/findWidget.ts | 28 +++++++++---------- .../editor/contrib/find/replaceAllCommand.ts | 5 ++-- .../contrib/find/test/findController.test.ts | 2 +- src/vs/editor/contrib/folding/folding.ts | 9 ++++++ .../editor/contrib/folding/foldingRanges.ts | 3 +- 8 files changed, 41 insertions(+), 25 deletions(-) diff --git a/src/vs/editor/contrib/caretOperations/moveCaretCommand.ts b/src/vs/editor/contrib/caretOperations/moveCaretCommand.ts index d992856345c..0ce4feb6174 100644 --- a/src/vs/editor/contrib/caretOperations/moveCaretCommand.ts +++ b/src/vs/editor/contrib/caretOperations/moveCaretCommand.ts @@ -17,11 +17,15 @@ export class MoveCaretCommand implements ICommand { private _cutEndIndex: number; private _moved: boolean; - private _selectionId: string; + private _selectionId: string | null; constructor(selection: Selection, isMovingLeft: boolean) { this._selection = selection; this._isMovingLeft = isMovingLeft; + this._cutStartIndex = -1; + this._cutEndIndex = -1; + this._moved = false; + this._selectionId = null; } public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { @@ -64,7 +68,7 @@ export class MoveCaretCommand implements ICommand { } public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection { - let result = helper.getTrackedSelection(this._selectionId); + let result = helper.getTrackedSelection(this._selectionId!); if (this._moved) { result = result.setStartPosition(result.startLineNumber, this._cutStartIndex); result = result.setEndPosition(result.startLineNumber, this._cutEndIndex); diff --git a/src/vs/editor/contrib/colorPicker/colorPickerWidget.ts b/src/vs/editor/contrib/colorPicker/colorPickerWidget.ts index e225e6a844e..b4e8404b423 100644 --- a/src/vs/editor/contrib/colorPicker/colorPickerWidget.ts +++ b/src/vs/editor/contrib/colorPicker/colorPickerWidget.ts @@ -123,8 +123,8 @@ class SaturationBox extends Disposable { private readonly domNode: HTMLElement; private readonly selection: HTMLElement; private readonly canvas: HTMLCanvasElement; - private width: number; - private height: number; + private width!: number; + private height!: number; private monitor: GlobalMouseMoveMonitor | null; private _onDidChange = new Emitter<{ s: number, v: number }>(); @@ -235,7 +235,7 @@ abstract class Strip extends Disposable { protected domNode: HTMLElement; protected overlay: HTMLElement; protected slider: HTMLElement; - private height: number; + private height!: number; private _onDidChange = new Emitter(); readonly onDidChange: Event = this._onDidChange.event; diff --git a/src/vs/editor/contrib/dnd/dragAndDropCommand.ts b/src/vs/editor/contrib/dnd/dragAndDropCommand.ts index f2c9aa86932..8d1d8a32b02 100644 --- a/src/vs/editor/contrib/dnd/dragAndDropCommand.ts +++ b/src/vs/editor/contrib/dnd/dragAndDropCommand.ts @@ -14,13 +14,14 @@ export class DragAndDropCommand implements editorCommon.ICommand { private readonly selection: Selection; private readonly targetPosition: Position; - private targetSelection: Selection; + private targetSelection: Selection | null; private readonly copy: boolean; constructor(selection: Selection, targetPosition: Position, copy: boolean) { this.selection = selection; this.targetPosition = targetPosition; this.copy = copy; + this.targetSelection = null; } public getEditOperations(model: ITextModel, builder: editorCommon.IEditOperationBuilder): void { @@ -102,6 +103,6 @@ export class DragAndDropCommand implements editorCommon.ICommand { } public computeCursorState(model: ITextModel, helper: editorCommon.ICursorStateComputerData): Selection { - return this.targetSelection; + return this.targetSelection!; } } diff --git a/src/vs/editor/contrib/find/findWidget.ts b/src/vs/editor/contrib/find/findWidget.ts index 84528f398cc..4a32619db64 100644 --- a/src/vs/editor/contrib/find/findWidget.ts +++ b/src/vs/editor/contrib/find/findWidget.ts @@ -93,19 +93,19 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas private readonly _keybindingService: IKeybindingService; private readonly _contextKeyService: IContextKeyService; - private _domNode: HTMLElement; - private _findInput: FindInput; - private _replaceInputBox: HistoryInputBox; + private _domNode!: HTMLElement; + private _findInput!: FindInput; + private _replaceInputBox!: HistoryInputBox; - private _toggleReplaceBtn: SimpleButton; - private _matchesCount: HTMLElement; - private _prevBtn: SimpleButton; - private _nextBtn: SimpleButton; - private _toggleSelectionFind: SimpleCheckbox; - private _closeBtn: SimpleButton; - private _preserveCase: Checkbox; - private _replaceBtn: SimpleButton; - private _replaceAllBtn: SimpleButton; + private _toggleReplaceBtn!: SimpleButton; + private _matchesCount!: HTMLElement; + private _prevBtn!: SimpleButton; + private _nextBtn!: SimpleButton; + private _toggleSelectionFind!: SimpleCheckbox; + private _closeBtn!: SimpleButton; + private _preserveCase!: Checkbox; + private _replaceBtn!: SimpleButton; + private _replaceAllBtn!: SimpleButton; private _isVisible: boolean; private _isReplaceVisible: boolean; @@ -118,8 +118,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas private _viewZone?: FindWidgetViewZone; private _viewZoneId?: number; - private _resizeSash: Sash; - private _resized: boolean; + private _resizeSash!: Sash; + private _resized!: boolean; private readonly _updateHistoryDelayer: Delayer; constructor( diff --git a/src/vs/editor/contrib/find/replaceAllCommand.ts b/src/vs/editor/contrib/find/replaceAllCommand.ts index 1b542d6cb0b..bdf2942f014 100644 --- a/src/vs/editor/contrib/find/replaceAllCommand.ts +++ b/src/vs/editor/contrib/find/replaceAllCommand.ts @@ -16,7 +16,7 @@ interface IEditOperation { export class ReplaceAllCommand implements editorCommon.ICommand { private readonly _editorSelection: Selection; - private _trackedEditorSelectionId: string; + private _trackedEditorSelectionId: string | null; private readonly _ranges: Range[]; private readonly _replaceStrings: string[]; @@ -24,6 +24,7 @@ export class ReplaceAllCommand implements editorCommon.ICommand { this._editorSelection = editorSelection; this._ranges = ranges; this._replaceStrings = replaceStrings; + this._trackedEditorSelectionId = null; } public getEditOperations(model: ITextModel, builder: editorCommon.IEditOperationBuilder): void { @@ -66,6 +67,6 @@ export class ReplaceAllCommand implements editorCommon.ICommand { } public computeCursorState(model: ITextModel, helper: editorCommon.ICursorStateComputerData): Selection { - return helper.getTrackedSelection(this._trackedEditorSelectionId); + return helper.getTrackedSelection(this._trackedEditorSelectionId!); } } diff --git a/src/vs/editor/contrib/find/test/findController.test.ts b/src/vs/editor/contrib/find/test/findController.test.ts index 5bd9bb3a072..6ac1767a275 100644 --- a/src/vs/editor/contrib/find/test/findController.test.ts +++ b/src/vs/editor/contrib/find/test/findController.test.ts @@ -24,7 +24,6 @@ export class TestFindController extends CommonFindController { public hasFocus: boolean; public delayUpdateHistory: boolean = false; - public delayedUpdateHistoryPromise: Promise; private _findInputFocused: IContextKey; @@ -37,6 +36,7 @@ export class TestFindController extends CommonFindController { super(editor, contextKeyService, storageService, clipboardService); this._findInputFocused = CONTEXT_FIND_INPUT_FOCUSED.bindTo(contextKeyService); this._updateHistoryDelayer = new Delayer(50); + this.hasFocus = false; } protected _start(opts: IFindStartOptions): void { diff --git a/src/vs/editor/contrib/folding/folding.ts b/src/vs/editor/contrib/folding/folding.ts index 9a9ea25c545..e2d54ddea6c 100644 --- a/src/vs/editor/contrib/folding/folding.ts +++ b/src/vs/editor/contrib/folding/folding.ts @@ -90,6 +90,15 @@ export class FoldingController extends Disposable implements IEditorContribution this._autoHideFoldingControls = this.editor.getConfiguration().contribInfo.showFoldingControls === 'mouseover'; this._useFoldingProviders = this.editor.getConfiguration().contribInfo.foldingStrategy !== 'indentation'; + this.foldingModel = null; + this.hiddenRangeModel = null; + this.rangeProvider = null; + this.foldingRegionPromise = null; + this.foldingStateMemento = null; + this.foldingModelPromise = null; + this.updateScheduler = null; + this.cursorChangedScheduler = null; + this.mouseDownInfo = null; this.foldingDecorationProvider = new FoldingDecorationProvider(editor); this.foldingDecorationProvider.autoHideFoldingControls = this._autoHideFoldingControls; diff --git a/src/vs/editor/contrib/folding/foldingRanges.ts b/src/vs/editor/contrib/folding/foldingRanges.ts index e8a7cd7adef..1c2e0d1fc74 100644 --- a/src/vs/editor/contrib/folding/foldingRanges.ts +++ b/src/vs/editor/contrib/folding/foldingRanges.ts @@ -28,6 +28,7 @@ export class FoldingRegions { this._endIndexes = endIndexes; this._collapseStates = new Uint32Array(Math.ceil(startIndexes.length / 32)); this._types = types; + this._parentsComputed = false; } private ensureParentIndices() { @@ -186,4 +187,4 @@ export class FoldingRegion { hidesLine(lineNumber: number) { return this.startLineNumber < lineNumber && lineNumber <= this.endLineNumber; } -} \ No newline at end of file +} From 4bc97d7fb34f87d7435d943a72e87aaeb7d6ad7e Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 6 Aug 2019 11:50:47 -0700 Subject: [PATCH 266/861] Re #78168 Hover, codeAction --- .../contrib/codeAction/test/codeAction.test.ts | 6 +++--- src/vs/editor/contrib/hover/hover.ts | 16 +++++++++------- src/vs/editor/contrib/hover/hoverWidgets.ts | 1 + src/vs/editor/contrib/hover/modesContentHover.ts | 2 ++ 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/test/codeAction.test.ts b/src/vs/editor/contrib/codeAction/test/codeAction.test.ts index 07c61c66067..41517305e33 100644 --- a/src/vs/editor/contrib/codeAction/test/codeAction.test.ts +++ b/src/vs/editor/contrib/codeAction/test/codeAction.test.ts @@ -59,8 +59,8 @@ suite('CodeAction', () => { command: { abc: { command: new class implements modes.Command { - id: '1'; - title: 'abc'; + id!: '1'; + title!: 'abc'; }, title: 'Extract to inner function in function "test"' } @@ -69,7 +69,7 @@ suite('CodeAction', () => { bcd: { diagnostics: [], edit: new class implements modes.WorkspaceEdit { - edits: modes.ResourceTextEdit[]; + edits!: modes.ResourceTextEdit[]; }, title: 'abc' } diff --git a/src/vs/editor/contrib/hover/hover.ts b/src/vs/editor/contrib/hover/hover.ts index 8dcf20dd2b8..8823037ac48 100644 --- a/src/vs/editor/contrib/hover/hover.ts +++ b/src/vs/editor/contrib/hover/hover.ts @@ -34,27 +34,27 @@ export class ModesHoverController implements IEditorContribution { private readonly _toUnhook = new DisposableStore(); private readonly _didChangeConfigurationHandler: IDisposable; - private _contentWidget: ModesContentHoverWidget; - private _glyphWidget: ModesGlyphHoverWidget; + private _contentWidget: ModesContentHoverWidget | null; + private _glyphWidget: ModesGlyphHoverWidget | null; get contentWidget(): ModesContentHoverWidget { if (!this._contentWidget) { this._createHoverWidget(); } - return this._contentWidget; + return this._contentWidget!; } get glyphWidget(): ModesGlyphHoverWidget { if (!this._glyphWidget) { this._createHoverWidget(); } - return this._glyphWidget; + return this._glyphWidget!; } private _isMouseDown: boolean; private _hoverClicked: boolean; - private _isHoverEnabled: boolean; - private _isHoverSticky: boolean; + private _isHoverEnabled!: boolean; + private _isHoverSticky!: boolean; static get(editor: ICodeEditor): ModesHoverController { return editor.getContribution(ModesHoverController.ID); @@ -69,6 +69,8 @@ export class ModesHoverController implements IEditorContribution { ) { this._isMouseDown = false; this._hoverClicked = false; + this._contentWidget = null; + this._glyphWidget = null; this._hookEvents(); @@ -200,7 +202,7 @@ export class ModesHoverController implements IEditorContribution { return; } - this._glyphWidget.hide(); + this._glyphWidget!.hide(); this._contentWidget.hide(); } diff --git a/src/vs/editor/contrib/hover/hoverWidgets.ts b/src/vs/editor/contrib/hover/hoverWidgets.ts index 6489db5a9fa..040a7ecaeb9 100644 --- a/src/vs/editor/contrib/hover/hoverWidgets.ts +++ b/src/vs/editor/contrib/hover/hoverWidgets.ts @@ -42,6 +42,7 @@ export class ContentHoverWidget extends Widget implements editorBrowser.IContent this._id = id; this._editor = editor; this._isVisible = false; + this._stoleFocus = false; this._containerDomNode = document.createElement('div'); this._containerDomNode.className = 'monaco-editor-hover hidden'; diff --git a/src/vs/editor/contrib/hover/modesContentHover.ts b/src/vs/editor/contrib/hover/modesContentHover.ts index ee2c456fdfa..d42f5153a1d 100644 --- a/src/vs/editor/contrib/hover/modesContentHover.ts +++ b/src/vs/editor/contrib/hover/modesContentHover.ts @@ -214,6 +214,8 @@ export class ModesContentHoverWidget extends ContentHoverWidget { this._computer = new ModesContentComputer(this._editor, markerDecorationsService); this._highlightDecorations = []; this._isChangingDecorations = false; + this._shouldFocus = false; + this._colorPicker = null; this._hoverOperation = new HoverOperation( this._computer, From 8535dc233d557d489a9cfc05323b1b4b54de288f Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 6 Aug 2019 16:39:24 -0700 Subject: [PATCH 267/861] Re #78168 Comment --- .../comments/browser/commentFormActions.ts | 4 +-- .../comments/browser/commentGlyphWidget.ts | 2 +- .../contrib/comments/browser/commentNode.ts | 28 ++++++++++--------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/vs/workbench/contrib/comments/browser/commentFormActions.ts b/src/vs/workbench/contrib/comments/browser/commentFormActions.ts index 362d32e5edd..1b7a6d7ae2e 100644 --- a/src/vs/workbench/contrib/comments/browser/commentFormActions.ts +++ b/src/vs/workbench/contrib/comments/browser/commentFormActions.ts @@ -14,7 +14,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; export class CommentFormActions implements IDisposable { private _buttonElements: HTMLElement[] = []; private readonly _toDispose = new DisposableStore(); - private _actions: IAction[]; + private _actions: IAction[] = []; constructor( private container: HTMLElement, @@ -59,4 +59,4 @@ export class CommentFormActions implements IDisposable { dispose() { this._toDispose.dispose(); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/contrib/comments/browser/commentGlyphWidget.ts b/src/vs/workbench/contrib/comments/browser/commentGlyphWidget.ts index a268f68a24c..12682d319d9 100644 --- a/src/vs/workbench/contrib/comments/browser/commentGlyphWidget.ts +++ b/src/vs/workbench/contrib/comments/browser/commentGlyphWidget.ts @@ -16,7 +16,7 @@ const overviewRulerDefault = new Color(new RGBA(197, 197, 197, 1)); export const overviewRulerCommentingRangeForeground = registerColor('editorGutter.commentRangeForeground', { dark: overviewRulerDefault, light: overviewRulerDefault, hc: overviewRulerDefault }, nls.localize('editorGutterCommentRangeForeground', 'Editor gutter decoration color for commenting ranges.')); export class CommentGlyphWidget { - private _lineNumber: number; + private _lineNumber!: number; private _editor: ICodeEditor; private commentsDecorations: string[] = []; private _commentsOptions: ModelDecorationOptions; diff --git a/src/vs/workbench/contrib/comments/browser/commentNode.ts b/src/vs/workbench/contrib/comments/browser/commentNode.ts index e8d7d850123..e0fce1e0ba0 100644 --- a/src/vs/workbench/contrib/comments/browser/commentNode.ts +++ b/src/vs/workbench/contrib/comments/browser/commentNode.ts @@ -40,22 +40,22 @@ export class CommentNode extends Disposable { private _md: HTMLElement; private _clearTimeout: any; - private _editAction: Action; - private _commentEditContainer: HTMLElement; + private _editAction: Action | null = null; + private _commentEditContainer: HTMLElement | null = null; private _commentDetailsContainer: HTMLElement; - private _actionsToolbarContainer: HTMLElement; + private _actionsToolbarContainer!: HTMLElement; private _reactionsActionBar?: ActionBar; private _reactionActionsContainer?: HTMLElement; - private _commentEditor: SimpleCommentEditor | null; + private _commentEditor: SimpleCommentEditor | null = null; private _commentEditorDisposables: IDisposable[] = []; - private _commentEditorModel: ITextModel; - private _isPendingLabel: HTMLElement; + private _commentEditorModel: ITextModel | null = null; + private _isPendingLabel!: HTMLElement; private _contextKeyService: IContextKeyService; private _commentContextValue: IContextKey; protected actionRunner?: IActionRunner; protected toolbar: ToolBar | undefined; - private _commentFormActions: CommentFormActions; + private _commentFormActions: CommentFormActions | null = null; private _onDidDelete = new Emitter(); @@ -63,7 +63,7 @@ export class CommentNode extends Disposable { return this._domNode; } - public isEditing: boolean; + public isEditing: boolean = false; constructor( private commentThread: modes.CommentThread, @@ -326,8 +326,8 @@ export class CommentNode extends Disposable { } } - private createCommentEditor(): void { - const container = dom.append(this._commentEditContainer, dom.$('.edit-textarea')); + private createCommentEditor(editContainer: HTMLElement): void { + const container = dom.append(editContainer, dom.$('.edit-textarea')); this._commentEditor = this.instantiationService.createInstance(SimpleCommentEditor, container, SimpleCommentEditor.getEditorOptions(), this.parentEditor, this.parentThread); const resource = URI.parse(`comment:commentinput-${this.comment.uniqueIdInThread}-${Date.now()}.md`); this._commentEditorModel = this.modelService.createModel('', this.modeService.createByFilepathOrFirstLine(resource), resource, false); @@ -390,7 +390,7 @@ export class CommentNode extends Disposable { this._commentEditor = null; } - this._commentEditContainer.remove(); + this._commentEditContainer!.remove(); } public switchToEditMode() { @@ -401,7 +401,7 @@ export class CommentNode extends Disposable { this.isEditing = true; this._body.classList.add('hidden'); this._commentEditContainer = dom.append(this._commentDetailsContainer, dom.$('.edit-container')); - this.createCommentEditor(); + this.createCommentEditor(this._commentEditContainer); const formActions = dom.append(this._commentEditContainer, dom.$('.form-actions')); const menus = this.commentService.getCommentMenus(this.owner); @@ -409,7 +409,9 @@ export class CommentNode extends Disposable { this._register(menu); this._register(menu.onDidChange(() => { - this._commentFormActions.setActions(menu); + if (this._commentFormActions) { + this._commentFormActions.setActions(menu); + } })); this._commentFormActions = new CommentFormActions(formActions, (action: IAction): void => { From 8f00b6c89db01610e4ebfde59dea410d07404337 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 6 Aug 2019 17:30:13 -0700 Subject: [PATCH 268/861] Fix #12048. Scrolloff --- src/vs/editor/browser/viewParts/lines/viewLines.ts | 8 ++++++++ src/vs/editor/common/config/commonEditorConfig.ts | 5 +++++ src/vs/editor/common/config/editorOptions.ts | 14 ++++++++++++++ src/vs/monaco.d.ts | 8 ++++++++ 4 files changed, 35 insertions(+) diff --git a/src/vs/editor/browser/viewParts/lines/viewLines.ts b/src/vs/editor/browser/viewParts/lines/viewLines.ts index ba4d49c639a..9b85e624b52 100644 --- a/src/vs/editor/browser/viewParts/lines/viewLines.ts +++ b/src/vs/editor/browser/viewParts/lines/viewLines.ts @@ -71,6 +71,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost, private _typicalHalfwidthCharacterWidth: number; private _isViewportWrapping: boolean; private _revealHorizontalRightPadding: number; + private _scrollOff: number; private _canUseLayerHinting: boolean; private _viewLineOptions: ViewLineOptions; @@ -94,6 +95,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost, this._typicalHalfwidthCharacterWidth = conf.editor.fontInfo.typicalHalfwidthCharacterWidth; this._isViewportWrapping = conf.editor.wrappingInfo.isViewportWrapping; this._revealHorizontalRightPadding = conf.editor.viewInfo.revealHorizontalRightPadding; + this._scrollOff = conf.editor.viewInfo.scrollOff; this._canUseLayerHinting = conf.editor.canUseLayerHinting; this._viewLineOptions = new ViewLineOptions(conf, this._context.theme.type); @@ -150,6 +152,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost, } if (e.viewInfo) { this._revealHorizontalRightPadding = conf.editor.viewInfo.revealHorizontalRightPadding; + this._scrollOff = conf.editor.viewInfo.scrollOff; } if (e.canUseLayerHinting) { this._canUseLayerHinting = conf.editor.canUseLayerHinting; @@ -596,6 +599,11 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost, // Have a box that includes one extra line height (for the horizontal scrollbar) boxStartY = this._context.viewLayout.getVerticalOffsetForLineNumber(range.startLineNumber); boxEndY = this._context.viewLayout.getVerticalOffsetForLineNumber(range.endLineNumber) + this._lineHeight; + + const context = Math.min((viewportHeight / this._lineHeight) / 2, this._scrollOff); + boxStartY -= context * this._lineHeight; + boxEndY += Math.max(0, (context - 1)) * this._lineHeight; + if (verticalType === viewEvents.VerticalRevealType.Simple || verticalType === viewEvents.VerticalRevealType.Bottom) { // Reveal one line more when the last line would be covered by the scrollbar - arrow down case or revealing a line explicitly at bottom boxEndY += this._lineHeight; diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index ce4ee056c46..45f0a760a3c 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -268,6 +268,11 @@ const editorConfiguration: IConfigurationNode = { 'default': 'on', 'description': nls.localize('lineNumbers', "Controls the display of line numbers.") }, + 'editor.scrollOff': { + 'type': 'number', + 'default': EDITOR_DEFAULTS.viewInfo.scrollOff, + 'description': nls.localize('scrollOff', "Controls the number of context lines above and below the cursor.") + }, 'editor.renderFinalNewline': { 'type': 'boolean', 'default': EDITOR_DEFAULTS.viewInfo.renderFinalNewline, diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 79ba4dc836d..86e32ad30b3 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -268,6 +268,11 @@ export interface IEditorOptions { * Defaults to true. */ lineNumbers?: 'on' | 'off' | 'relative' | 'interval' | ((lineNumber: number) => string); + /** + * Controls the number of context lines above and below the cursor. + * Defaults to 0. + */ + scrollOff?: number; /** * Render last line number when the file ends with a newline. * Defaults to true. @@ -982,6 +987,7 @@ export interface InternalEditorViewOptions { readonly ariaLabel: string; readonly renderLineNumbers: RenderLineNumbersType; readonly renderCustomLineNumbers: ((lineNumber: number) => string) | null; + readonly scrollOff: number; readonly renderFinalNewline: boolean; readonly selectOnLineNumbers: boolean; readonly glyphMargin: boolean; @@ -1092,6 +1098,7 @@ export class InternalEditorOptions { readonly pixelRatio: number; readonly editorClassName: string; readonly lineHeight: number; + readonly scrollOff: number; readonly readOnly: boolean; /** * @internal @@ -1184,6 +1191,7 @@ export class InternalEditorOptions { && this.pixelRatio === other.pixelRatio && this.editorClassName === other.editorClassName && this.lineHeight === other.lineHeight + && this.scrollOff === other.scrollOff && this.readOnly === other.readOnly && this.accessibilitySupport === other.accessibilitySupport && this.multiCursorModifier === other.multiCursorModifier @@ -1216,6 +1224,7 @@ export class InternalEditorOptions { pixelRatio: (this.pixelRatio !== newOpts.pixelRatio), editorClassName: (this.editorClassName !== newOpts.editorClassName), lineHeight: (this.lineHeight !== newOpts.lineHeight), + scrollOff: (this.scrollOff !== newOpts.scrollOff), readOnly: (this.readOnly !== newOpts.readOnly), accessibilitySupport: (this.accessibilitySupport !== newOpts.accessibilitySupport), multiCursorModifier: (this.multiCursorModifier !== newOpts.multiCursorModifier), @@ -1290,6 +1299,7 @@ export class InternalEditorOptions { && a.ariaLabel === b.ariaLabel && a.renderLineNumbers === b.renderLineNumbers && a.renderCustomLineNumbers === b.renderCustomLineNumbers + && a.scrollOff === b.scrollOff && a.renderFinalNewline === b.renderFinalNewline && a.selectOnLineNumbers === b.selectOnLineNumbers && a.glyphMargin === b.glyphMargin @@ -1620,6 +1630,7 @@ export interface IConfigurationChangedEvent { readonly pixelRatio: boolean; readonly editorClassName: boolean; readonly lineHeight: boolean; + readonly scrollOff: boolean; readonly readOnly: boolean; readonly accessibilitySupport: boolean; readonly multiCursorModifier: boolean; @@ -2049,6 +2060,7 @@ export class EditorOptionsValidator { disableMonospaceOptimizations: disableMonospaceOptimizations, rulers: rulers, ariaLabel: _string(opts.ariaLabel, defaults.ariaLabel), + scrollOff: _clampedInt(opts.scrollOff, defaults.cursorWidth, 0, Number.MAX_VALUE), renderLineNumbers: renderLineNumbers, renderCustomLineNumbers: renderCustomLineNumbers, renderFinalNewline: _boolean(opts.renderFinalNewline, defaults.renderFinalNewline), @@ -2172,6 +2184,7 @@ export class InternalEditorOptionsFactory { ariaLabel: (accessibilityIsOff ? nls.localize('accessibilityOffAriaLabel', "The editor is not accessible at this time. Press Alt+F1 for options.") : opts.viewInfo.ariaLabel), renderLineNumbers: opts.viewInfo.renderLineNumbers, renderCustomLineNumbers: opts.viewInfo.renderCustomLineNumbers, + scrollOff: opts.viewInfo.scrollOff, renderFinalNewline: opts.viewInfo.renderFinalNewline, selectOnLineNumbers: opts.viewInfo.selectOnLineNumbers, glyphMargin: opts.viewInfo.glyphMargin, @@ -2636,6 +2649,7 @@ export const EDITOR_DEFAULTS: IValidatedEditorOptions = { ariaLabel: nls.localize('editorViewAccessibleLabel', "Editor content"), renderLineNumbers: RenderLineNumbersType.On, renderCustomLineNumbers: null, + scrollOff: 0, renderFinalNewline: true, selectOnLineNumbers: true, glyphMargin: true, diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index eb2000206ce..8c7eaf0e598 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2649,6 +2649,11 @@ declare namespace monaco.editor { * Defaults to true. */ lineNumbers?: 'on' | 'off' | 'relative' | 'interval' | ((lineNumber: number) => string); + /** + * Controls the number of context lines above and below the cursor. + * Defaults to 0. + */ + scrollOff?: number; /** * Render last line number when the file ends with a newline. * Defaults to true. @@ -3297,6 +3302,7 @@ declare namespace monaco.editor { readonly ariaLabel: string; readonly renderLineNumbers: RenderLineNumbersType; readonly renderCustomLineNumbers: ((lineNumber: number) => string) | null; + readonly scrollOff: number; readonly renderFinalNewline: boolean; readonly selectOnLineNumbers: boolean; readonly glyphMargin: boolean; @@ -3372,6 +3378,7 @@ declare namespace monaco.editor { readonly pixelRatio: number; readonly editorClassName: string; readonly lineHeight: number; + readonly scrollOff: number; readonly readOnly: boolean; readonly multiCursorModifier: 'altKey' | 'ctrlKey' | 'metaKey'; readonly multiCursorMergeOverlapping: boolean; @@ -3513,6 +3520,7 @@ declare namespace monaco.editor { readonly pixelRatio: boolean; readonly editorClassName: boolean; readonly lineHeight: boolean; + readonly scrollOff: boolean; readonly readOnly: boolean; readonly accessibilitySupport: boolean; readonly multiCursorModifier: boolean; From 18a4ddc05aedf72ede9e4826e5b27ebfa4df3a41 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 7 Aug 2019 08:00:17 +0200 Subject: [PATCH 269/861] files - avoid read/write with pos and prefer null (fix #73884) --- .../files/node/diskFileSystemProvider.ts | 119 ++++++++++++++++-- .../files/test/node/diskFileService.test.ts | 92 +++++++++++++- 2 files changed, 197 insertions(+), 14 deletions(-) diff --git a/src/vs/platform/files/node/diskFileSystemProvider.ts b/src/vs/platform/files/node/diskFileSystemProvider.ts index 8ef39ec23f0..0ab6883d353 100644 --- a/src/vs/platform/files/node/diskFileSystemProvider.ts +++ b/src/vs/platform/files/node/diskFileSystemProvider.ts @@ -148,6 +148,8 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro } } + private mapHandleToPos: Map = new Map(); + private writeHandles: Set = new Set(); private canFlush: boolean = true; @@ -187,6 +189,13 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro const handle = await promisify(open)(filePath, flags); + // remember this handle to track file position of the handle + // we init the position to 0 since the file descriptor was + // just created and the position was not moved so far (see + // also http://man7.org/linux/man-pages/man2/open.2.html - + // "The file offset is set to the beginning of the file.") + this.mapHandleToPos.set(handle, 0); + // remember that this handle was used for writing if (opts.create) { this.writeHandles.add(handle); @@ -200,6 +209,10 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro async close(fd: number): Promise { try { + + // remove this handle from map of positions + this.mapHandleToPos.delete(fd); + // if a handle is closed that was used for writing, ensure // to flush the contents to disk if possible. if (this.writeHandles.delete(fd) && this.canFlush) { @@ -220,15 +233,81 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro } async read(fd: number, pos: number, data: Uint8Array, offset: number, length: number): Promise { + const normalizedPos = this.normalizePos(fd, pos); + + let bytesRead: number | null = null; try { - const result = await promisify(read)(fd, data, offset, length, pos); + const result = await promisify(read)(fd, data, offset, length, normalizedPos); + if (typeof result === 'number') { - return result; // node.d.ts fail + bytesRead = result; // node.d.ts fail + } else { + bytesRead = result.bytesRead; } - return result.bytesRead; + return bytesRead; } catch (error) { throw this.toFileSystemProviderError(error); + } finally { + this.updatePos(fd, normalizedPos, bytesRead); + } + } + + private normalizePos(fd: number, pos: number): number | null { + + // when calling fs.read/write we try to avoid passing in the "pos" argument and + // rather prefer to pass in "null" because this avoids an extra seek(pos) + // call that in some cases can even fail (e.g. when opening a file over FTP - + // see https://github.com/microsoft/vscode/issues/73884). + // + // as such, we compare the passed in position argument with our last known + // position for the file descriptor and use "null" if they match. + if (pos === this.mapHandleToPos.get(fd)) { + return null; + } + + return pos; + } + + private updatePos(fd: number, pos: number | null, bytesLength: number | null): void { + const lastKnownPos = this.mapHandleToPos.get(fd); + if (typeof lastKnownPos === 'number') { + + // pos !== null signals that previously a position was used that is + // not null. node.js documentation explains, that in this case + // the internal file pointer is not moving and as such we do not move + // our position pointer. + // + // Docs: "If position is null, data will be read from the current file position, + // and the file position will be updated. If position is an integer, the file position + // will remain unchanged." + if (typeof pos === 'number') { + // do not modify the position + } + + // bytesLength = number is a signal that the read/write operation was + // successful and as such we need to advance the position in the Map + // + // Docs (http://man7.org/linux/man-pages/man2/read.2.html): + // "On files that support seeking, the read operation commences at the + // file offset, and the file offset is incremented by the number of + // bytes read." + // + // Docs (http://man7.org/linux/man-pages/man2/write.2.html): + // "For a seekable file (i.e., one to which lseek(2) may be applied, for + // example, a regular file) writing takes place at the file offset, and + // the file offset is incremented by the number of bytes actually + // written." + else if (typeof bytesLength === 'number') { + this.mapHandleToPos.set(fd, lastKnownPos + bytesLength); + } + + // bytesLength = null signals an error in the read/write operation + // and as such we drop the handle from the Map because the position + // is unspecificed at this point. + else { + this.mapHandleToPos.delete(fd); + } } } @@ -240,15 +319,23 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro } private async doWrite(fd: number, pos: number, data: Uint8Array, offset: number, length: number): Promise { + const normalizedPos = this.normalizePos(fd, pos); + + let bytesWritten: number | null = null; try { - const result = await promisify(write)(fd, data, offset, length, pos); + const result = await promisify(write)(fd, data, offset, length, normalizedPos); + if (typeof result === 'number') { - return result; // node.d.ts fail + bytesWritten = result; // node.d.ts fail + } else { + bytesWritten = result.bytesWritten; } - return result.bytesWritten; + return bytesWritten; } catch (error) { throw this.toFileSystemProviderError(error); + } finally { + this.updatePos(fd, normalizedPos, bytesWritten); } } @@ -441,14 +528,17 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro watcherOptions?: IWatcherOptions ): WindowsWatcherService | UnixWatcherService | NsfwWatcherService }; - let watcherOptions = undefined; + let watcherOptions: IWatcherOptions | undefined = undefined; + + // requires a polling watcher if (this.watcherOptions && this.watcherOptions.usePolling) { - // requires a polling watcher watcherImpl = UnixWatcherService; watcherOptions = this.watcherOptions; - } else { - // Single Folder Watcher + } + + // Single Folder Watcher + else { if (this.recursiveFoldersToWatch.length === 1) { if (isWindows) { watcherImpl = WindowsWatcherService; @@ -471,6 +561,7 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro if (msg.type === 'error') { this._onDidWatchErrorOccur.fire(msg.message); } + this.logService[msg.type](msg.message); }, this.logService.getLevel() === LogLevel.Trace, @@ -478,7 +569,7 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro ); if (!this.recursiveWatcherLogLevelListener) { - this.recursiveWatcherLogLevelListener = this.logService.onDidChangeLogLevel(_ => { + this.recursiveWatcherLogLevelListener = this.logService.onDidChangeLogLevel(() => { if (this.recursiveWatcher) { this.recursiveWatcher.setVerboseLogging(this.logService.getLevel() === LogLevel.Trace); } @@ -496,11 +587,13 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro if (msg.type === 'error') { this._onDidWatchErrorOccur.fire(msg.message); } + this.logService[msg.type](msg.message); }, this.logService.getLevel() === LogLevel.Trace ); - const logLevelListener = this.logService.onDidChangeLogLevel(_ => { + + const logLevelListener = this.logService.onDidChangeLogLevel(() => { watcherService.setVerboseLogging(this.logService.getLevel() === LogLevel.Trace); }); @@ -553,4 +646,4 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro dispose(this.recursiveWatcherLogLevelListener); this.recursiveWatcherLogLevelListener = undefined; } -} \ No newline at end of file +} diff --git a/src/vs/platform/files/test/node/diskFileService.test.ts b/src/vs/platform/files/test/node/diskFileService.test.ts index 6d10050ec0e..3b7c887936f 100644 --- a/src/vs/platform/files/test/node/diskFileService.test.ts +++ b/src/vs/platform/files/test/node/diskFileService.test.ts @@ -1915,4 +1915,94 @@ suite('Disk File Service', () => { function hasChange(changes: IFileChange[], type: FileChangeType, resource: URI): boolean { return changes.some(change => change.type === type && isEqual(change.resource, resource)); } -}); \ No newline at end of file + + test('read - mixed positions', async () => { + const resource = URI.file(join(testDir, 'lorem.txt')); + + // read multiple times from position 0 + let buffer = VSBuffer.alloc(1024); + let fd = await fileProvider.open(resource, { create: false }); + for (let i = 0; i < 3; i++) { + await fileProvider.read(fd, 0, buffer.buffer, 0, 26); + assert.equal(buffer.slice(0, 26).toString(), 'Lorem ipsum dolor sit amet'); + } + await fileProvider.close(fd); + + // read multiple times at various locations + buffer = VSBuffer.alloc(1024); + fd = await fileProvider.open(resource, { create: false }); + + let posInFile = 0; + + await fileProvider.read(fd, posInFile, buffer.buffer, 0, 26); + assert.equal(buffer.slice(0, 26).toString(), 'Lorem ipsum dolor sit amet'); + posInFile += 26; + + await fileProvider.read(fd, posInFile, buffer.buffer, 0, 1); + assert.equal(buffer.slice(0, 1).toString(), ','); + posInFile += 1; + + await fileProvider.read(fd, posInFile, buffer.buffer, 0, 12); + assert.equal(buffer.slice(0, 12).toString(), ' consectetur'); + posInFile += 12; + + await fileProvider.read(fd, 98 /* no longer in sequence of posInFile */, buffer.buffer, 0, 9); + assert.equal(buffer.slice(0, 9).toString(), 'fermentum'); + + await fileProvider.read(fd, 27, buffer.buffer, 0, 12); + assert.equal(buffer.slice(0, 12).toString(), ' consectetur'); + + await fileProvider.read(fd, 26, buffer.buffer, 0, 1); + assert.equal(buffer.slice(0, 1).toString(), ','); + + await fileProvider.read(fd, 0, buffer.buffer, 0, 26); + assert.equal(buffer.slice(0, 26).toString(), 'Lorem ipsum dolor sit amet'); + + await fileProvider.read(fd, posInFile /* back in sequence */, buffer.buffer, 0, 11); + assert.equal(buffer.slice(0, 11).toString(), ' adipiscing'); + + await fileProvider.close(fd); + }); + + test('write - mixed positions', async () => { + const resource = URI.file(join(testDir, 'lorem.txt')); + + const buffer = VSBuffer.alloc(1024); + const fdWrite = await fileProvider.open(resource, { create: true }); + const fdRead = await fileProvider.open(resource, { create: false }); + + let posInFileWrite = 0; + let posInFileRead = 0; + + const initialContents = VSBuffer.fromString('Lorem ipsum dolor sit amet'); + await fileProvider.write(fdWrite, posInFileWrite, initialContents.buffer, 0, initialContents.byteLength); + posInFileWrite += initialContents.byteLength; + + await fileProvider.read(fdRead, posInFileRead, buffer.buffer, 0, 26); + assert.equal(buffer.slice(0, 26).toString(), 'Lorem ipsum dolor sit amet'); + posInFileRead += 26; + + const contents = VSBuffer.fromString('Hello World'); + + await fileProvider.write(fdWrite, posInFileWrite, contents.buffer, 0, contents.byteLength); + posInFileWrite += contents.byteLength; + + await fileProvider.read(fdRead, posInFileRead, buffer.buffer, 0, contents.byteLength); + assert.equal(buffer.slice(0, contents.byteLength).toString(), 'Hello World'); + posInFileRead += contents.byteLength; + + await fileProvider.write(fdWrite, 6, contents.buffer, 0, contents.byteLength); + + await fileProvider.read(fdRead, 0, buffer.buffer, 0, 11); + assert.equal(buffer.slice(0, 11).toString(), 'Lorem Hello'); + + await fileProvider.write(fdWrite, posInFileWrite, contents.buffer, 0, contents.byteLength); + posInFileWrite += contents.byteLength; + + await fileProvider.read(fdRead, posInFileWrite - contents.byteLength, buffer.buffer, 0, contents.byteLength); + assert.equal(buffer.slice(0, contents.byteLength).toString(), 'Hello World'); + + await fileProvider.close(fdWrite); + await fileProvider.close(fdRead); + }); +}); From 8ffe01a66584ca8c6d2ece05df0d1f4c7fe5c2a6 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 7 Aug 2019 08:18:47 +0200 Subject: [PATCH 270/861] :lipstick: --- src/vs/base/node/encoding.ts | 6 + src/vs/base/node/stream.ts | 109 ++++++++++++++++- .../services/textfile/node/textFileService.ts | 113 +----------------- 3 files changed, 120 insertions(+), 108 deletions(-) diff --git a/src/vs/base/node/encoding.ts b/src/vs/base/node/encoding.ts index 8e23d0adeb2..d89114aa099 100644 --- a/src/vs/base/node/encoding.ts +++ b/src/vs/base/node/encoding.ts @@ -14,6 +14,12 @@ export const UTF8_with_bom = 'utf8bom'; export const UTF16be = 'utf16be'; export const UTF16le = 'utf16le'; +export type UTF_ENCODING = typeof UTF8 | typeof UTF8_with_bom | typeof UTF16be | typeof UTF16le; + +export function isUTFEncoding(encoding: string): encoding is UTF_ENCODING { + return [UTF8, UTF8_with_bom, UTF16be, UTF16le].some(utfEncoding => utfEncoding === encoding); +} + export const UTF16be_BOM = [0xFE, 0xFF]; export const UTF16le_BOM = [0xFF, 0xFE]; export const UTF8_BOM = [0xEF, 0xBB, 0xBF]; diff --git a/src/vs/base/node/stream.ts b/src/vs/base/node/stream.ts index 12f66a76556..16b73835bd1 100644 --- a/src/vs/base/node/stream.ts +++ b/src/vs/base/node/stream.ts @@ -4,6 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import * as fs from 'fs'; +import { VSBufferReadableStream, VSBufferReadable, VSBuffer } from 'vs/base/common/buffer'; +import { Readable } from 'stream'; +import { isUndefinedOrNull } from 'vs/base/common/types'; +import { UTF8, UTF8_with_bom, UTF8_BOM, UTF16be, UTF16le_BOM, UTF16be_BOM, UTF16le, UTF_ENCODING } from 'vs/base/node/encoding'; /** * Reads a file until a matching string is found. @@ -66,4 +70,107 @@ export function readToMatchingString(file: string, matchingString: string, chunk readChunk(); }) ); -} \ No newline at end of file +} + +export function streamToNodeReadable(stream: VSBufferReadableStream): Readable { + return new class extends Readable { + private listening = false; + + _read(size?: number): void { + if (!this.listening) { + this.listening = true; + + // Data + stream.on('data', data => { + try { + if (!this.push(data.buffer)) { + stream.pause(); // pause the stream if we should not push anymore + } + } catch (error) { + this.emit(error); + } + }); + + // End + stream.on('end', () => { + try { + this.push(null); // signal EOS + } catch (error) { + this.emit(error); + } + }); + + // Error + stream.on('error', error => this.emit('error', error)); + } + + // ensure the stream is flowing + stream.resume(); + } + + _destroy(error: Error | null, callback: (error: Error | null) => void): void { + stream.destroy(); + + callback(null); + } + }; +} + +export function nodeReadableToString(stream: NodeJS.ReadableStream): Promise { + return new Promise((resolve, reject) => { + let result = ''; + + stream.on('data', chunk => result += chunk); + stream.on('error', reject); + stream.on('end', () => resolve(result)); + }); +} + +export function nodeStreamToVSBufferReadable(stream: NodeJS.ReadWriteStream, addBOM?: { encoding: UTF_ENCODING }): VSBufferReadable { + let bytesRead = 0; + let done = false; + + return { + read(): VSBuffer | null { + if (done) { + return null; + } + + const res = stream.read(); + if (isUndefinedOrNull(res)) { + done = true; + + // If we are instructed to add a BOM but we detect that no + // bytes have been read, we must ensure to return the BOM + // ourselves so that we comply with the contract. + if (bytesRead === 0 && addBOM) { + switch (addBOM.encoding) { + case UTF8: + case UTF8_with_bom: + return VSBuffer.wrap(Buffer.from(UTF8_BOM)); + case UTF16be: + return VSBuffer.wrap(Buffer.from(UTF16be_BOM)); + case UTF16le: + return VSBuffer.wrap(Buffer.from(UTF16le_BOM)); + } + } + + return null; + } + + // Handle String + if (typeof res === 'string') { + bytesRead += res.length; + + return VSBuffer.fromString(res); + } + + // Handle Buffer + else { + bytesRead += res.byteLength; + + return VSBuffer.wrap(res); + } + } + }; +} diff --git a/src/vs/workbench/services/textfile/node/textFileService.ts b/src/vs/workbench/services/textfile/node/textFileService.ts index 93c43cd1fef..f940da7889e 100644 --- a/src/vs/workbench/services/textfile/node/textFileService.ts +++ b/src/vs/workbench/services/textfile/node/textFileService.ts @@ -17,16 +17,16 @@ import { isMacintosh } from 'vs/base/common/platform'; import product from 'vs/platform/product/node/product'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { UTF8, UTF8_with_bom, UTF16be, UTF16le, encodingExists, encodeStream, UTF8_BOM, UTF16be_BOM, UTF16le_BOM, toDecodeStream, IDecodeStreamResult, detectEncodingByBOMFromBuffer } from 'vs/base/node/encoding'; +import { UTF8, UTF8_with_bom, UTF16be, UTF16le, encodingExists, encodeStream, UTF8_BOM, toDecodeStream, IDecodeStreamResult, detectEncodingByBOMFromBuffer, isUTFEncoding } from 'vs/base/node/encoding'; import { WORKSPACE_EXTENSION } from 'vs/platform/workspaces/common/workspaces'; import { joinPath, extname, isEqualOrParent } from 'vs/base/common/resources'; import { Disposable } from 'vs/base/common/lifecycle'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { VSBufferReadable, VSBuffer, VSBufferReadableStream } from 'vs/base/common/buffer'; +import { VSBufferReadable } from 'vs/base/common/buffer'; import { Readable } from 'stream'; -import { isUndefinedOrNull } from 'vs/base/common/types'; import { createTextBufferFactoryFromStream } from 'vs/editor/common/model/textModel'; import { ITextSnapshot } from 'vs/editor/common/model'; +import { nodeReadableToString, streamToNodeReadable, nodeStreamToVSBufferReadable } from 'vs/base/node/stream'; export class NodeTextFileService extends TextFileService { @@ -45,7 +45,7 @@ export class NodeTextFileService extends TextFileService { return { ...bufferStream, encoding: decoder.detected.encoding || UTF8, - value: await this.nodeReadableToString(decoder.stream) + value: await nodeReadableToString(decoder.stream) }; } @@ -68,7 +68,7 @@ export class NodeTextFileService extends TextFileService { const bufferStream = await this.fileService.readFileStream(resource, options); // read through encoding library - const decoder = await toDecodeStream(this.streamToNodeReadable(bufferStream.value), { + const decoder = await toDecodeStream(streamToNodeReadable(bufferStream.value), { guessEncoding: (options && options.autoGuessEncoding) || this.textResourceConfigurationService.getValue(resource, 'files.autoGuessEncoding'), overwriteEncoding: detectedEncoding => this.encoding.getReadEncoding(resource, options, detectedEncoding) }); @@ -108,60 +108,6 @@ export class NodeTextFileService extends TextFileService { return ensuredOptions; } - private streamToNodeReadable(stream: VSBufferReadableStream): Readable { - return new class extends Readable { - private listening = false; - - _read(size?: number): void { - if (!this.listening) { - this.listening = true; - - // Data - stream.on('data', data => { - try { - if (!this.push(data.buffer)) { - stream.pause(); // pause the stream if we should not push anymore - } - } catch (error) { - this.emit(error); - } - }); - - // End - stream.on('end', () => { - try { - this.push(null); // signal EOS - } catch (error) { - this.emit(error); - } - }); - - // Error - stream.on('error', error => this.emit('error', error)); - } - - // ensure the stream is flowing - stream.resume(); - } - - _destroy(error: Error | null, callback: (error: Error | null) => void): void { - stream.destroy(); - - callback(null); - } - }; - } - - private nodeReadableToString(stream: NodeJS.ReadableStream): Promise { - return new Promise((resolve, reject) => { - let result = ''; - - stream.on('data', chunk => result += chunk); - stream.on('error', reject); - stream.on('end', () => resolve(result)); - }); - } - protected async doCreate(resource: URI, value?: string, options?: ICreateFileOptions): Promise { // check for encoding @@ -238,7 +184,7 @@ export class NodeTextFileService extends TextFileService { const encodedReadable = readable.pipe(encoder); - return this.nodeStreamToReadable(encodedReadable, encoding, addBOM); + return nodeStreamToVSBufferReadable(encodedReadable, addBOM && isUTFEncoding(encoding) ? { encoding } : undefined); } private snapshotToNodeReadable(snapshot: ITextSnapshot): Readable { @@ -266,53 +212,6 @@ export class NodeTextFileService extends TextFileService { }); } - private nodeStreamToReadable(stream: NodeJS.ReadWriteStream, encoding: string, addBOM: boolean): VSBufferReadable { - let bytesRead = 0; - let done = false; - - return { - read(): VSBuffer | null { - if (done) { - return null; - } - - const res = stream.read(); - if (isUndefinedOrNull(res)) { - done = true; - - // If we are instructed to add a BOM but we detect that no - // bytes have been read, we must ensure to return the BOM - // ourselves so that we comply with the contract. - if (bytesRead === 0 && addBOM) { - switch (encoding) { - case UTF8: - case UTF8_with_bom: - return VSBuffer.wrap(Buffer.from(UTF8_BOM)); - case UTF16be: - return VSBuffer.wrap(Buffer.from(UTF16be_BOM)); - case UTF16le: - return VSBuffer.wrap(Buffer.from(UTF16le_BOM)); - } - } - - return null; - } - - // Handle String - if (typeof res === 'string') { - bytesRead += res.length; - return VSBuffer.fromString(res); - } - - // Handle Buffer - else { - bytesRead += res.byteLength; - return VSBuffer.wrap(res); - } - } - }; - } - private async writeElevated(resource: URI, value: string | ITextSnapshot, options?: IWriteTextFileOptions): Promise { // write into a tmp file first From 074e1bb82ffd3ffa54fceff75786ad9ab94107db Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 7 Aug 2019 08:57:12 +0200 Subject: [PATCH 271/861] skip flaky test related to #78602 --- src/vs/platform/files/test/node/diskFileService.test.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/platform/files/test/node/diskFileService.test.ts b/src/vs/platform/files/test/node/diskFileService.test.ts index 3b7c887936f..6ccaf1b5a5c 100644 --- a/src/vs/platform/files/test/node/diskFileService.test.ts +++ b/src/vs/platform/files/test/node/diskFileService.test.ts @@ -613,7 +613,12 @@ suite('Disk File Service', () => { await testMoveFolderAcrossProviders(); }); - test('move - directory - across providers (unbuffered => buffered)', async () => { + test('move - directory - across providers (unbuffered => buffered)', async function () { + if (process.platform === 'linux') { + this.skip(); + return; + } + setCapabilities(fileProvider, FileSystemProviderCapabilities.FileReadWrite); setCapabilities(testProvider, FileSystemProviderCapabilities.FileOpenReadWriteClose); From 36f4f376d13cf83908b9b9fb03b936ee75705bd2 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 7 Aug 2019 09:18:40 +0200 Subject: [PATCH 272/861] build: arm64 --- build/azure-pipelines/linux/multiarch/arm64/build.sh | 3 +++ .../azure-pipelines/linux/multiarch/arm64/prebuild.sh | 3 +++ .../azure-pipelines/linux/multiarch/arm64/publish.sh | 3 +++ build/azure-pipelines/product-build.yml | 11 +++++++++++ build/gulpfile.reh.js | 2 ++ 5 files changed, 22 insertions(+) create mode 100755 build/azure-pipelines/linux/multiarch/arm64/build.sh create mode 100755 build/azure-pipelines/linux/multiarch/arm64/prebuild.sh create mode 100755 build/azure-pipelines/linux/multiarch/arm64/publish.sh diff --git a/build/azure-pipelines/linux/multiarch/arm64/build.sh b/build/azure-pipelines/linux/multiarch/arm64/build.sh new file mode 100755 index 00000000000..4f01bc9a7e5 --- /dev/null +++ b/build/azure-pipelines/linux/multiarch/arm64/build.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +set -e +echo 'noop' \ No newline at end of file diff --git a/build/azure-pipelines/linux/multiarch/arm64/prebuild.sh b/build/azure-pipelines/linux/multiarch/arm64/prebuild.sh new file mode 100755 index 00000000000..4f01bc9a7e5 --- /dev/null +++ b/build/azure-pipelines/linux/multiarch/arm64/prebuild.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +set -e +echo 'noop' \ No newline at end of file diff --git a/build/azure-pipelines/linux/multiarch/arm64/publish.sh b/build/azure-pipelines/linux/multiarch/arm64/publish.sh new file mode 100755 index 00000000000..4f01bc9a7e5 --- /dev/null +++ b/build/azure-pipelines/linux/multiarch/arm64/publish.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +set -e +echo 'noop' \ No newline at end of file diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index c6a1790c027..24e62aa4abf 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -66,6 +66,17 @@ jobs: steps: - template: linux/product-build-linux-multiarch.yml +- job: LinuxArm64 + condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false'), eq(variables['VSCODE_BUILD_LINUX_ARM64'], 'true'), ne(variables['VSCODE_QUALITY'], 'stable')) + pool: + vmImage: 'Ubuntu-16.04' + variables: + VSCODE_ARCH: arm64 + dependsOn: + - Compile + steps: + - template: linux/product-build-linux-multiarch.yml + - job: LinuxAlpine condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false'), eq(variables['VSCODE_BUILD_LINUX_ALPINE'], 'true'), ne(variables['VSCODE_QUALITY'], 'stable')) pool: diff --git a/build/gulpfile.reh.js b/build/gulpfile.reh.js index 7085c4f8f50..a956fba979e 100644 --- a/build/gulpfile.reh.js +++ b/build/gulpfile.reh.js @@ -31,6 +31,7 @@ const BUILD_TARGETS = [ { platform: 'linux', arch: 'ia32', pkgTarget: 'node8-linux-x86' }, { platform: 'linux', arch: 'x64', pkgTarget: 'node8-linux-x64' }, { platform: 'linux', arch: 'armhf', pkgTarget: 'node8-linux-armv7' }, + { platform: 'linux', arch: 'arm64', pkgTarget: 'node8-linux-arm64' }, { platform: 'linux', arch: 'alpine', pkgTarget: 'node8-linux-alpine' }, ]; @@ -41,6 +42,7 @@ gulp.task('vscode-reh-win32-x64-min', noop); gulp.task('vscode-reh-darwin-min', noop); gulp.task('vscode-reh-linux-x64-min', noop); gulp.task('vscode-reh-linux-armhf-min', noop); +gulp.task('vscode-reh-linux-arm64-min', noop); gulp.task('vscode-reh-linux-alpine-min', noop); gulp.task('vscode-reh-web-win32-ia32-min', noop); From 7e4f523d174a0acda7b2fb4711172b8fbfae6817 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 7 Aug 2019 09:20:31 +0200 Subject: [PATCH 273/861] distro --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index f2d6e909082..5e26e11a271 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "1f46578f6299fb1c3313c049aef73f96a710f8f8", + "distro": "1c5d2d8f81dfa0c0378c56925b7b12b0eaf47a09", "author": { "name": "Microsoft Corporation" }, @@ -158,4 +158,4 @@ "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} +} \ No newline at end of file From c250eb75d893fcc4f38c70267df36d06d235ce4a Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 7 Aug 2019 09:21:44 +0200 Subject: [PATCH 274/861] distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5e26e11a271..c403ed65d6f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "1c5d2d8f81dfa0c0378c56925b7b12b0eaf47a09", + "distro": "10a221be8c29d615092ab914b28bc4ece10f67bc", "author": { "name": "Microsoft Corporation" }, From 1ec1b9fe56de6803f64abc88dffb22df97b39f13 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 7 Aug 2019 09:13:21 +0200 Subject: [PATCH 275/861] More fixes for #78168 --- src/vs/base/browser/dom.ts | 4 +- src/vs/base/test/common/utils.ts | 4 +- .../editor/browser/widget/diffEditorWidget.ts | 63 ++++++++++++------- src/vs/editor/contrib/find/findWidget.ts | 20 +----- src/vs/editor/contrib/folding/folding.ts | 3 +- src/vs/editor/contrib/hover/hover.ts | 8 +-- src/vs/editor/contrib/hover/hoverWidgets.ts | 1 + 7 files changed, 50 insertions(+), 53 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index fdaab73b0b7..717041747da 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -50,8 +50,8 @@ interface IDomClassList { const _manualClassList = new class implements IDomClassList { - private _lastStart: number; - private _lastEnd: number; + private _lastStart: number = -1; + private _lastEnd: number = -1; private _findClassName(node: HTMLElement, className: string): void { diff --git a/src/vs/base/test/common/utils.ts b/src/vs/base/test/common/utils.ts index 0fb02a0193d..26b225a1fa9 100644 --- a/src/vs/base/test/common/utils.ts +++ b/src/vs/base/test/common/utils.ts @@ -12,8 +12,8 @@ export type ValueCallback = (value: T | Promise) => void; export class DeferredPromise { - private completeCallback: ValueCallback; - private errorCallback: (err: any) => void; + private completeCallback!: ValueCallback; + private errorCallback!: (err: any) => void; public p: Promise; diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index 4bb1a3b218f..260f479df55 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -8,7 +8,7 @@ import * as nls from 'vs/nls'; import * as dom from 'vs/base/browser/dom'; import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode'; import { ISashEvent, IVerticalSashLayoutProvider, Sash, SashState } from 'vs/base/browser/ui/sash/sash'; -import { RunOnceScheduler } from 'vs/base/common/async'; +import { RunOnceScheduler, IntervalTimer } from 'vs/base/common/async'; import { Color } from 'vs/base/common/color'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; @@ -156,17 +156,17 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE private _width: number; private _height: number; private _reviewHeight: number; - private readonly _measureDomElementToken: number; + private readonly _measureDomElementToken: IntervalTimer | null; - private originalEditor: CodeEditorWidget; + private readonly originalEditor: CodeEditorWidget; private readonly _originalDomNode: HTMLElement; private readonly _originalEditorState: VisualEditorState; - private _originalOverviewRuler: editorBrowser.IOverviewRuler; + private _originalOverviewRuler: editorBrowser.IOverviewRuler | null; - private modifiedEditor: CodeEditorWidget; + private readonly modifiedEditor: CodeEditorWidget; private readonly _modifiedDomNode: HTMLElement; private readonly _modifiedEditorState: VisualEditorState; - private _modifiedOverviewRuler: editorBrowser.IOverviewRuler; + private _modifiedOverviewRuler: editorBrowser.IOverviewRuler | null; private _currentlyChangingViewZones: boolean; private _beginUpdateDecorationsTimeout: number; @@ -182,7 +182,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE private _renderSideBySide: boolean; private _renderIndicators: boolean; private _enableSplitViewResizing: boolean; - private _strategy: IDiffEditorWidgetStyle; + private _strategy!: IDiffEditorWidgetStyle; private readonly _updateDecorationsRunner: RunOnceScheduler; @@ -308,8 +308,11 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE rightServices.set(IContextKeyService, rightContextKeyService); const rightScopedInstantiationService = instantiationService.createChild(rightServices); - this._createLeftHandSideEditor(options, leftScopedInstantiationService); - this._createRightHandSideEditor(options, rightScopedInstantiationService); + this.originalEditor = this._createLeftHandSideEditor(options, leftScopedInstantiationService); + this.modifiedEditor = this._createRightHandSideEditor(options, rightScopedInstantiationService); + + this._originalOverviewRuler = null; + this._modifiedOverviewRuler = null; this._reviewPane = new DiffReview(this); this._containerDomElement.appendChild(this._reviewPane.domNode.domNode); @@ -317,7 +320,10 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE this._containerDomElement.appendChild(this._reviewPane.actionBarContainer.domNode); if (options.automaticLayout) { - this._measureDomElementToken = window.setInterval(() => this._measureDomElement(false), 100); + this._measureDomElementToken = new IntervalTimer(); + this._measureDomElementToken.cancelAndSet(() => this._measureDomElement(false), 100); + } else { + this._measureDomElementToken = null; } // enableSplitViewResizing @@ -397,10 +403,10 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE this._layoutOverviewRulers(); } - private _createLeftHandSideEditor(options: editorOptions.IDiffEditorOptions, instantiationService: IInstantiationService): void { - this.originalEditor = this._createInnerEditor(instantiationService, this._originalDomNode, this._adjustOptionsForLeftHandSide(options, this._originalIsEditable)); + private _createLeftHandSideEditor(options: editorOptions.IDiffEditorOptions, instantiationService: IInstantiationService): CodeEditorWidget { + const editor = this._createInnerEditor(instantiationService, this._originalDomNode, this._adjustOptionsForLeftHandSide(options, this._originalIsEditable)); - this._register(this.originalEditor.onDidScrollChange((e) => { + this._register(editor.onDidScrollChange((e) => { if (this._isHandlingScrollEvent) { return; } @@ -417,21 +423,23 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE this._layoutOverviewViewport(); })); - this._register(this.originalEditor.onDidChangeViewZones(() => { + this._register(editor.onDidChangeViewZones(() => { this._onViewZonesChanged(); })); - this._register(this.originalEditor.onDidChangeModelContent(() => { + this._register(editor.onDidChangeModelContent(() => { if (this._isVisible) { this._beginUpdateDecorationsSoon(); } })); + + return editor; } - private _createRightHandSideEditor(options: editorOptions.IDiffEditorOptions, instantiationService: IInstantiationService): void { - this.modifiedEditor = this._createInnerEditor(instantiationService, this._modifiedDomNode, this._adjustOptionsForRightHandSide(options)); + private _createRightHandSideEditor(options: editorOptions.IDiffEditorOptions, instantiationService: IInstantiationService): CodeEditorWidget { + const editor = this._createInnerEditor(instantiationService, this._modifiedDomNode, this._adjustOptionsForRightHandSide(options)); - this._register(this.modifiedEditor.onDidScrollChange((e) => { + this._register(editor.onDidScrollChange((e) => { if (this._isHandlingScrollEvent) { return; } @@ -448,21 +456,23 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE this._layoutOverviewViewport(); })); - this._register(this.modifiedEditor.onDidChangeViewZones(() => { + this._register(editor.onDidChangeViewZones(() => { this._onViewZonesChanged(); })); - this._register(this.modifiedEditor.onDidChangeConfiguration((e) => { - if (e.fontInfo && this.modifiedEditor.getModel()) { + this._register(editor.onDidChangeConfiguration((e) => { + if (e.fontInfo && editor.getModel()) { this._onViewZonesChanged(); } })); - this._register(this.modifiedEditor.onDidChangeModelContent(() => { + this._register(editor.onDidChangeModelContent(() => { if (this._isVisible) { this._beginUpdateDecorationsSoon(); } })); + + return editor; } protected _createInnerEditor(instantiationService: IInstantiationService, container: HTMLElement, options: editorOptions.IEditorOptions): CodeEditorWidget { @@ -477,7 +487,9 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE this._beginUpdateDecorationsTimeout = -1; } - window.clearInterval(this._measureDomElementToken); + if (this._measureDomElementToken) { + this._measureDomElementToken.dispose(); + } this._cleanViewZonesAndDecorations(); @@ -813,6 +825,9 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE } private _layoutOverviewRulers(): void { + if (!this._originalOverviewRuler || !this._modifiedOverviewRuler) { + return; + } let freeSpace = DiffEditorWidget.ENTIRE_DIFF_OVERVIEW_WIDTH - 2 * DiffEditorWidget.ONE_OVERVIEW_WIDTH; let layoutInfo = this.modifiedEditor.getLayoutInfo(); if (layoutInfo) { @@ -914,7 +929,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE } private _updateDecorations(): void { - if (!this.originalEditor.getModel() || !this.modifiedEditor.getModel()) { + if (!this.originalEditor.getModel() || !this.modifiedEditor.getModel() || !this._originalOverviewRuler || !this._modifiedOverviewRuler) { return; } const lineChanges = (this._diffComputationResult ? this._diffComputationResult.changes : []); diff --git a/src/vs/editor/contrib/find/findWidget.ts b/src/vs/editor/contrib/find/findWidget.ts index 4a32619db64..529d582ee47 100644 --- a/src/vs/editor/contrib/find/findWidget.ts +++ b/src/vs/editor/contrib/find/findWidget.ts @@ -784,7 +784,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas return ` (${kb.getLabel()})`; } - private _buildFindPart(): HTMLElement { + private _buildDomNode(): void { // Find input this._findInput = this._register(new ContextScopedFindInput(null, this._contextViewProvider, { width: FIND_INPUT_AREA_WIDTH, @@ -908,10 +908,6 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas findPart.appendChild(this._closeBtn.domNode); - return findPart; - } - - private _buildReplacePart(): HTMLElement { // Replace input let replaceInput = document.createElement('div'); replaceInput.className = 'replace-input'; @@ -977,16 +973,6 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas replacePart.appendChild(this._replaceBtn.domNode); replacePart.appendChild(this._replaceAllBtn.domNode); - return replacePart; - } - - private _buildDomNode(): void { - // Find part - let findPart = this._buildFindPart(); - - // Replace part - let replacePart = this._buildReplacePart(); - // Toggle replace button this._toggleReplaceBtn = this._register(new SimpleButton({ label: NLS_TOGGLE_REPLACE_MODE_BTN_LABEL, @@ -1014,10 +1000,6 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas this._domNode.appendChild(findPart); this._domNode.appendChild(replacePart); - this._buildSash(); - } - - private _buildSash() { this._resizeSash = new Sash(this._domNode, this, { orientation: Orientation.VERTICAL }); this._resized = false; let originalWidth = FIND_WIDGET_INITIAL_WIDTH; diff --git a/src/vs/editor/contrib/folding/folding.ts b/src/vs/editor/contrib/folding/folding.ts index e2d54ddea6c..cd7cdbe1d13 100644 --- a/src/vs/editor/contrib/folding/folding.ts +++ b/src/vs/editor/contrib/folding/folding.ts @@ -79,6 +79,7 @@ export class FoldingController extends Disposable implements IEditorContribution private cursorChangedScheduler: RunOnceScheduler | null; private readonly localToDispose = this._register(new DisposableStore()); + private mouseDownInfo: { lineNumber: number, iconClicked: boolean } | null; constructor( editor: ICodeEditor, @@ -340,8 +341,6 @@ export class FoldingController extends Disposable implements IEditorContribution } - private mouseDownInfo: { lineNumber: number, iconClicked: boolean } | null; - private onEditorMouseDown(e: IEditorMouseEvent): void { this.mouseDownInfo = null; diff --git a/src/vs/editor/contrib/hover/hover.ts b/src/vs/editor/contrib/hover/hover.ts index 8823037ac48..583e4c65dee 100644 --- a/src/vs/editor/contrib/hover/hover.ts +++ b/src/vs/editor/contrib/hover/hover.ts @@ -39,14 +39,14 @@ export class ModesHoverController implements IEditorContribution { get contentWidget(): ModesContentHoverWidget { if (!this._contentWidget) { - this._createHoverWidget(); + this._createHoverWidgets(); } return this._contentWidget!; } get glyphWidget(): ModesGlyphHoverWidget { if (!this._glyphWidget) { - this._createHoverWidget(); + this._createHoverWidgets(); } return this._glyphWidget!; } @@ -198,7 +198,7 @@ export class ModesHoverController implements IEditorContribution { } private _hideWidgets(): void { - if (!this._contentWidget || (this._isMouseDown && this._hoverClicked && this._contentWidget.isColorPickerVisible())) { + if (!this._glyphWidget || !this._contentWidget || (this._isMouseDown && this._hoverClicked && this._contentWidget.isColorPickerVisible())) { return; } @@ -206,7 +206,7 @@ export class ModesHoverController implements IEditorContribution { this._contentWidget.hide(); } - private _createHoverWidget() { + private _createHoverWidgets() { this._contentWidget = new ModesContentHoverWidget(this._editor, this._markerDecorationsService, this._themeService, this._keybindingService, this._modeService, this._openerService); this._glyphWidget = new ModesGlyphHoverWidget(this._editor, this._modeService, this._openerService); } diff --git a/src/vs/editor/contrib/hover/hoverWidgets.ts b/src/vs/editor/contrib/hover/hoverWidgets.ts index 040a7ecaeb9..13dff650038 100644 --- a/src/vs/editor/contrib/hover/hoverWidgets.ts +++ b/src/vs/editor/contrib/hover/hoverWidgets.ts @@ -73,6 +73,7 @@ export class ContentHoverWidget extends Widget implements editorBrowser.IContent this._editor.addContentWidget(this); this._showAtPosition = null; this._showAtRange = null; + this._stoleFocus = false; } public getId(): string { From a71127033c20fd305b62d284b255ee394883f8ed Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 7 Aug 2019 09:52:23 +0200 Subject: [PATCH 276/861] distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c403ed65d6f..5393ef2087c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "10a221be8c29d615092ab914b28bc4ece10f67bc", + "distro": "f123663d79c57c07e3f70b2d0938f1a58ff4d1da", "author": { "name": "Microsoft Corporation" }, From a7fa418e34644da8bdcc6994c2626270e29f738f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 7 Aug 2019 10:02:32 +0200 Subject: [PATCH 277/861] fix #78602 --- .../files/test/node/diskFileService.test.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/vs/platform/files/test/node/diskFileService.test.ts b/src/vs/platform/files/test/node/diskFileService.test.ts index 6ccaf1b5a5c..c744c83f3e2 100644 --- a/src/vs/platform/files/test/node/diskFileService.test.ts +++ b/src/vs/platform/files/test/node/diskFileService.test.ts @@ -115,7 +115,7 @@ export class TestDiskFileSystemProvider extends DiskFileSystemProvider { } } -suite('Disk File Service', () => { +suite('Disk File Service', function () { const parentDir = getRandomTestPath(tmpdir(), 'vsctests', 'diskfileservice'); const testSchema = 'test'; @@ -127,6 +127,12 @@ suite('Disk File Service', () => { const disposables = new DisposableStore(); + // Given issues such as https://github.com/microsoft/vscode/issues/78602 + // we see random test failures when accessing the native file system. To + // diagnose further, we retry node.js file access tests up to 3 times to + // rule out any random disk issue. + this.retries(3); + setup(async () => { const logService = new NullLogService(); @@ -614,11 +620,6 @@ suite('Disk File Service', () => { }); test('move - directory - across providers (unbuffered => buffered)', async function () { - if (process.platform === 'linux') { - this.skip(); - return; - } - setCapabilities(fileProvider, FileSystemProviderCapabilities.FileReadWrite); setCapabilities(testProvider, FileSystemProviderCapabilities.FileOpenReadWriteClose); From 69b1bfb5a19ddf2336a5f28792e30f6682e4a79c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 7 Aug 2019 10:07:05 +0200 Subject: [PATCH 278/861] update with changes on master --- .../electron-browser/extensionService.ts | 2 +- .../webWorkerExtensionHostStarter.ts | 16 +- .../extensions/worker/extHost.api.impl.ts | 148 +++++++++----- .../worker/extHostExtensionService.ts | 180 ++++++++++++------ .../extensions/worker/extensionHostMain.ts | 27 ++- 5 files changed, 249 insertions(+), 124 deletions(-) diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index c8a224a1070..8d8b85b0f01 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -350,7 +350,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten } const result: ExtensionHostProcessManager[] = []; - const workerExtensions = { ['jrieken.helloworld']: true }; + const workerExtensions: Record = { ['jrieken.helloworld']: true }; const extHostProcessWorker = this._instantiationService.createInstance(ExtensionHostProcessWorker, autoStart, extensions.then(e => e.filter(e => !workerExtensions[e.identifier.value])), this._extensionHostLogsLocation); const extHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, true, extHostProcessWorker, null, initialActivationEvents); diff --git a/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts b/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts index a7d616c257c..4c8492f1409 100644 --- a/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts +++ b/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts @@ -17,12 +17,12 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { ILabelService } from 'vs/platform/label/common/label'; import { ILogService } from 'vs/platform/log/common/log'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import * as platform from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; import { IExtensionHostStarter } from 'vs/workbench/services/extensions/common/extensions'; import { IProductService } from 'vs/platform/product/common/product'; +import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { @@ -41,7 +41,7 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { @IWorkspaceContextService private readonly _contextService: IWorkspaceContextService, @ILabelService private readonly _labelService: ILabelService, @ILogService private readonly _logService: ILogService, - @IEnvironmentService private readonly _environmentService: IEnvironmentService, + @IWorkbenchEnvironmentService private readonly _environmentService: IWorkbenchEnvironmentService, @IProductService private readonly _productService: IProductService, ) { @@ -121,14 +121,16 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { environment: { isExtensionDevelopmentDebug: false, // < todo@joh appRoot: this._environmentService.appRoot ? URI.file(this._environmentService.appRoot) : undefined, - appSettingsHome: this._environmentService.appSettingsHome ? URI.file(this._environmentService.appSettingsHome) : undefined, + appSettingsHome: this._environmentService.appSettingsHome ? this._environmentService.appSettingsHome : undefined, appName: this._productService.nameLong, appUriScheme: this._productService.urlProtocol, appLanguage: platform.language, extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI, extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI, globalStorageHome: URI.file(this._environmentService.globalStorageHome), - userHome: URI.file(this._environmentService.userHome) + userHome: URI.file(this._environmentService.userHome), + webviewResourceRoot: this._environmentService.webviewResourceRoot, + webviewCspSource: this._environmentService.webviewCspSource, }, workspace: this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? undefined : { configuration: workspace.configuration || undefined, @@ -141,7 +143,11 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { telemetryInfo, logLevel: this._logService.getLevel(), logsLocation: this._extensionHostLogsLocation, - autoStart: true// < todo@joh this._autoStart + autoStart: true,// < todo@joh this._autoStart, + remote: { + authority: this._environmentService.configuration.remoteAuthority, + isRemote: false + }, }; return r; }); diff --git a/src/vs/workbench/services/extensions/worker/extHost.api.impl.ts b/src/vs/workbench/services/extensions/worker/extHost.api.impl.ts index 3b4950702e6..e0c1f3ad4d1 100644 --- a/src/vs/workbench/services/extensions/worker/extHost.api.impl.ts +++ b/src/vs/workbench/services/extensions/worker/extHost.api.impl.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import * as nls from 'vs/nls'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; import * as errors from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; @@ -32,7 +33,6 @@ import { ExtensionActivatedByAPI } from 'vs/workbench/api/common/extHostExtensio import { ExtHostExtensionService } from './extHostExtensionService'; import { ExtHostFileSystem } from 'vs/workbench/api/common/extHostFileSystem'; import { ExtHostFileSystemEventService } from 'vs/workbench/api/common/extHostFileSystemEventService'; -import { ExtHostHeapService } from 'vs/workbench/api/common/extHostHeapService'; import { ExtHostLanguageFeatures } from 'vs/workbench/api/common/extHostLanguageFeatures'; import { ExtHostLanguages } from 'vs/workbench/api/common/extHostLanguages'; import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; @@ -49,6 +49,7 @@ import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; // import { ExtHostTerminalService } from 'vs/workbench/api/node/extHostTerminalService'; import { ExtHostEditors } from 'vs/workbench/api/common/extHostTextEditors'; import { ExtHostTreeViews } from 'vs/workbench/api/common/extHostTreeViews'; +// import { ExtHostDownloadService } from 'vs/workbench/api/node/extHostDownloadService'; import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters'; import * as extHostTypes from 'vs/workbench/api/common/extHostTypes'; import { ExtHostUrls } from 'vs/workbench/api/common/extHostUrls'; @@ -62,10 +63,15 @@ import * as vscode from 'vscode'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { originalFSPath } from 'vs/base/common/resources'; // import { CLIServer } from 'vs/workbench/api/node/extHostCLIServer'; -import { withNullAsUndefined } from 'vs/base/common/types'; import { values } from 'vs/base/common/collections'; -import { IURITransformer } from 'vs/base/common/uriIpc'; // import { Schemas } from 'vs/base/common/network'; +import { IURITransformer } from 'vs/base/common/uriIpc'; +import { ExtHostEditorInsets } from 'vs/workbench/api/common/extHostCodeInsets'; +import { ExtHostLabelService } from 'vs/workbench/api/common/extHostLabelService'; +// import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; +// import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; +// import { getSingletonServiceDescriptors } from 'vs/platform/instantiation/common/extensions'; +import { getRemoteName } from 'vs/platform/remote/common/remoteHosts'; export interface IExtensionApiFactory { (extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode; @@ -90,44 +96,51 @@ export function createApiFactory( extensionService: ExtHostExtensionService, extHostLogService: ExtHostLogService, extHostStorage: ExtHostStorage, - schemeTransformer: IURITransformer | null + uriTransformer: IURITransformer | null ): IExtensionApiFactory { + // bootstrap services + // const services = new ServiceCollection(...getSingletonServiceDescriptors()); + // const instaService = new InstantiationService(services); + // Addressable instances rpcProtocol.set(ExtHostContext.ExtHostLogService, extHostLogService); - const extHostHeapService = rpcProtocol.set(ExtHostContext.ExtHostHeapService, new ExtHostHeapService()); const extHostDecorations = rpcProtocol.set(ExtHostContext.ExtHostDecorations, new ExtHostDecorations(rpcProtocol)); - const extHostWebviews = rpcProtocol.set(ExtHostContext.ExtHostWebviews, new ExtHostWebviews(rpcProtocol)); + const extHostWebviews = rpcProtocol.set(ExtHostContext.ExtHostWebviews, new ExtHostWebviews(rpcProtocol, initData.environment)); const extHostUrls = rpcProtocol.set(ExtHostContext.ExtHostUrls, new ExtHostUrls(rpcProtocol)); const extHostDocumentsAndEditors = rpcProtocol.set(ExtHostContext.ExtHostDocumentsAndEditors, new ExtHostDocumentsAndEditors(rpcProtocol)); const extHostDocuments = rpcProtocol.set(ExtHostContext.ExtHostDocuments, new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors)); const extHostDocumentContentProviders = rpcProtocol.set(ExtHostContext.ExtHostDocumentContentProviders, new ExtHostDocumentContentProvider(rpcProtocol, extHostDocumentsAndEditors, extHostLogService)); const extHostDocumentSaveParticipant = rpcProtocol.set(ExtHostContext.ExtHostDocumentSaveParticipant, new ExtHostDocumentSaveParticipant(extHostLogService, extHostDocuments, rpcProtocol.getProxy(MainContext.MainThreadTextEditors))); const extHostEditors = rpcProtocol.set(ExtHostContext.ExtHostEditors, new ExtHostEditors(rpcProtocol, extHostDocumentsAndEditors)); - const extHostCommands = rpcProtocol.set(ExtHostContext.ExtHostCommands, new ExtHostCommands(rpcProtocol, extHostHeapService, extHostLogService)); + const extHostCommands = rpcProtocol.set(ExtHostContext.ExtHostCommands, new ExtHostCommands(rpcProtocol, extHostLogService)); const extHostTreeViews = rpcProtocol.set(ExtHostContext.ExtHostTreeViews, new ExtHostTreeViews(rpcProtocol.getProxy(MainContext.MainThreadTreeViews), extHostCommands, extHostLogService)); + // rpcProtocol.set(ExtHostContext.ExtHostDownloadService, new ExtHostDownloadService(rpcProtocol.getProxy(MainContext.MainThreadDownloadService), extHostCommands)); rpcProtocol.set(ExtHostContext.ExtHostWorkspace, extHostWorkspace); rpcProtocol.set(ExtHostContext.ExtHostConfiguration, extHostConfiguration); + const extHostEditorInsets = rpcProtocol.set(ExtHostContext.ExtHostEditorInsets, new ExtHostEditorInsets(rpcProtocol.getProxy(MainContext.MainThreadEditorInsets), extHostEditors, initData.environment)); const extHostDiagnostics = rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, new ExtHostDiagnostics(rpcProtocol)); - const extHostLanguageFeatures = rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, new ExtHostLanguageFeatures(rpcProtocol, schemeTransformer, extHostDocuments, extHostCommands, extHostHeapService, extHostDiagnostics, extHostLogService)); + const extHostLanguageFeatures = rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, new ExtHostLanguageFeatures(rpcProtocol, uriTransformer, extHostDocuments, extHostCommands, extHostDiagnostics, extHostLogService)); const extHostFileSystem = rpcProtocol.set(ExtHostContext.ExtHostFileSystem, new ExtHostFileSystem(rpcProtocol, extHostLanguageFeatures)); const extHostFileSystemEvent = rpcProtocol.set(ExtHostContext.ExtHostFileSystemEventService, new ExtHostFileSystemEventService(rpcProtocol, extHostDocumentsAndEditors)); const extHostQuickOpen = rpcProtocol.set(ExtHostContext.ExtHostQuickOpen, new ExtHostQuickOpen(rpcProtocol, extHostWorkspace, extHostCommands)); - // const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(rpcProtocol, extHostConfiguration, extHostLogService)); - // const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, new ExtHostDebugService(rpcProtocol, extHostWorkspace, extensionService, extHostDocumentsAndEditors, extHostConfiguration, extHostTerminalService, extHostCommands)); + // const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(rpcProtocol, extHostConfiguration, extHostWorkspace, extHostDocumentsAndEditors, extHostLogService)); + // const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, instaService.createInstance(ExtHostDebugService, rpcProtocol, extHostWorkspace, extensionService, extHostDocumentsAndEditors, extHostConfiguration, extHostTerminalService, extHostCommands)); const extHostSCM = rpcProtocol.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(rpcProtocol, extHostCommands, extHostLogService)); const extHostComment = rpcProtocol.set(ExtHostContext.ExtHostComments, new ExtHostComments(rpcProtocol, extHostCommands, extHostDocuments)); - // const extHostSearch = rpcProtocol.set(ExtHostContext.ExtHostSearch, new ExtHostSearch(rpcProtocol, schemeTransformer, extHostLogService)); + // const extHostSearch = rpcProtocol.set(ExtHostContext.ExtHostSearch, new ExtHostSearch(rpcProtocol, uriTransformer, extHostLogService)); // const extHostTask = rpcProtocol.set(ExtHostContext.ExtHostTask, new ExtHostTask(rpcProtocol, extHostWorkspace, extHostDocumentsAndEditors, extHostConfiguration, extHostTerminalService)); const extHostWindow = rpcProtocol.set(ExtHostContext.ExtHostWindow, new ExtHostWindow(rpcProtocol)); rpcProtocol.set(ExtHostContext.ExtHostExtensionService, extensionService); const extHostProgress = rpcProtocol.set(ExtHostContext.ExtHostProgress, new ExtHostProgress(rpcProtocol.getProxy(MainContext.MainThreadProgress))); const extHostOutputService = rpcProtocol.set(ExtHostContext.ExtHostOutputService, new ExtHostOutputService(PushOutputChannelFactory, initData.logsLocation, rpcProtocol)); rpcProtocol.set(ExtHostContext.ExtHostStorage, extHostStorage); - // if (initData.remoteAuthority) { + const extHostLabelService = rpcProtocol.set(ExtHostContext.ExtHosLabelService, new ExtHostLabelService(rpcProtocol)); + + // if (initData.remote.isRemote && initData.remote.authority) { // extHostTask.registerTaskSystem(Schemas.vscodeRemote, { // scheme: Schemas.vscodeRemote, - // authority: initData.remoteAuthority, + // authority: initData.remote.authority, // platform: process.platform // }); @@ -143,6 +156,7 @@ export function createApiFactory( rpcProtocol.set(ExtHostContext.ExtHostDebugService, proxy); rpcProtocol.set(ExtHostContext.ExtHostSearch, proxy); rpcProtocol.set(ExtHostContext.ExtHostTask, proxy); + rpcProtocol.set(ExtHostContext.ExtHostDownloadService, proxy); // Check that no named customers are missing const expected: ProxyIdentifier[] = values(ExtHostContext); @@ -156,7 +170,8 @@ export function createApiFactory( const extHostLanguages = new ExtHostLanguages(rpcProtocol, extHostDocuments); // Register an output channel for exthost log - // extHostOutputService.createOutputChannelFromLogFile(outputChannelName, extHostLogService.logFile); // < todo@joh + const outputChannelName = initData.remote.isRemote ? nls.localize('remote extension host Log', "Remote Extension Host") : nls.localize('extension host Log', "Extension Host"); + extHostOutputService.createOutputChannelFromLogFile(outputChannelName, extHostLogService.logFile); // Register API-ish commands ExtHostApiCommands.register(extHostCommands); @@ -165,7 +180,7 @@ export function createApiFactory( // Check document selectors for being overly generic. Technically this isn't a problem but // in practice many extensions say they support `fooLang` but need fs-access to do so. Those - // extension should specify then the `file`-scheme, e.g `{ scheme: 'fooLang', language: 'fooLang' }` + // extension should specify then the `file`-scheme, e.g. `{ scheme: 'fooLang', language: 'fooLang' }` // We only inform once, it is not a warning because we just want to raise awareness and because // we cannot say if the extension is doing it right or wrong... const checkSelector = (function () { @@ -237,11 +252,15 @@ export function createApiFactory( }, getCommands(filterInternal: boolean = false): Thenable { return extHostCommands.getCommands(filterInternal); - } + }, + onDidExecuteCommand: proposedApiFunction(extension, (listener, thisArgs?, disposables?) => { + checkProposedApiEnabled(extension); + return extHostCommands.onDidExecuteCommand(listener, thisArgs, disposables); + }), }; // namespace: env - const env: typeof vscode.env = Object.freeze({ + const env: typeof vscode.env = { get machineId() { return initData.telemetryInfo.machineId; }, get sessionId() { return initData.telemetryInfo.sessionId; }, get language() { return initData.environment.appLanguage; }, @@ -259,22 +278,37 @@ export function createApiFactory( get clipboard(): vscode.Clipboard { return extHostClipboard; }, + get shell(): string { + throw new Error('not implemented'); + // return extHostTerminalService.getDefaultShell(configProvider); + }, openExternal(uri: URI) { - return extHostWindow.openUri(uri, { allowTunneling: Boolean(initData.remoteAuthority) }); + return extHostWindow.openUri(uri, { allowTunneling: !!initData.remote.isRemote }); + }, + get remoteName() { + return getRemoteName(initData.remote.authority); } - }); + }; + if (!initData.environment.extensionTestsLocationURI) { + // allow to patch env-function when running tests + Object.freeze(env); + } + + const extensionKind = initData.remote.isRemote + ? extHostTypes.ExtensionKind.Workspace + : extHostTypes.ExtensionKind.UI; // namespace: extensions const extensions: typeof vscode.extensions = { getExtension(extensionId: string): Extension | undefined { const desc = extensionRegistry.getExtensionDescription(extensionId); if (desc) { - return new Extension(extensionService, desc); + return new Extension(extensionService, desc, extensionKind); } return undefined; }, get all(): Extension[] { - return extensionRegistry.getAllExtensionDescriptions().map((desc) => new Extension(extensionService, desc)); + return extensionRegistry.getAllExtensionDescriptions().map((desc) => new Extension(extensionService, desc, extensionKind)); }, get onDidChange() { return extensionRegistry.onDidChange; @@ -307,10 +341,6 @@ export function createApiFactory( registerCodeLensProvider(selector: vscode.DocumentSelector, provider: vscode.CodeLensProvider): vscode.Disposable { return extHostLanguageFeatures.registerCodeLensProvider(extension, checkSelector(selector), provider); }, - registerCodeInsetProvider(selector: vscode.DocumentSelector, provider: vscode.CodeInsetProvider): vscode.Disposable { - checkProposedApiEnabled(extension); - return extHostLanguageFeatures.registerCodeInsetProvider(extension, checkSelector(selector), provider); - }, registerDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.DefinitionProvider): vscode.Disposable { return extHostLanguageFeatures.registerDefinitionProvider(extension, checkSelector(selector), provider); }, @@ -474,8 +504,24 @@ export function createApiFactory( showSaveDialog(options) { return extHostDialogs.showSaveDialog(options); }, - createStatusBarItem(position?: vscode.StatusBarAlignment, priority?: number): vscode.StatusBarItem { - return extHostStatusBar.createStatusBarEntry(extension.identifier, position, priority); + createStatusBarItem(alignmentOrOptions?: vscode.StatusBarAlignment | vscode.window.StatusBarItemOptions, priority?: number): vscode.StatusBarItem { + let id: string; + let name: string; + let alignment: number | undefined; + + if (alignmentOrOptions && typeof alignmentOrOptions !== 'number') { + id = alignmentOrOptions.id; + name = alignmentOrOptions.name; + alignment = alignmentOrOptions.alignment; + priority = alignmentOrOptions.priority; + } else { + id = extension.identifier.value; + name = nls.localize('extensionLabel', "{0} (Extension)", extension.displayName || extension.name); + alignment = alignmentOrOptions; + priority = priority; + } + + return extHostStatusBar.createStatusBarEntry(id, name, alignment, priority); }, setStatusBarMessage(text: string, timeoutOrThenable?: number | Thenable): vscode.Disposable { return extHostStatusBar.setStatusBarMessage(text, timeoutOrThenable); @@ -493,10 +539,17 @@ export function createApiFactory( createWebviewPanel(viewType: string, title: string, showOptions: vscode.ViewColumn | { viewColumn: vscode.ViewColumn, preserveFocus?: boolean }, options: vscode.WebviewPanelOptions & vscode.WebviewOptions): vscode.WebviewPanel { return extHostWebviews.createWebviewPanel(extension, viewType, title, showOptions, options); }, - createTerminal(nameOrOptions?: vscode.TerminalOptions | string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal { + createWebviewTextEditorInset(editor: vscode.TextEditor, line: number, height: number, options: vscode.WebviewOptions): vscode.WebviewEditorInset { + checkProposedApiEnabled(extension); + return extHostEditorInsets.createWebviewEditorInset(editor, line, height, options, extension); + }, + createTerminal(nameOrOptions?: vscode.TerminalOptions | vscode.ExtensionTerminalOptions | string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal { throw new Error('not implemented'); // if (typeof nameOrOptions === 'object') { - // return extHostTerminalService.createTerminalFromOptions(nameOrOptions); + // if ('pty' in nameOrOptions) { + // return extHostTerminalService.createExtensionTerminal(nameOrOptions); + // } + // return extHostTerminalService.createTerminalFromOptions(nameOrOptions); // } // return extHostTerminalService.createTerminal(nameOrOptions, shellPath, shellArgs); }, @@ -550,6 +603,9 @@ export function createApiFactory( get workspaceFile() { return extHostWorkspace.workspaceFile; }, + set workspaceFile(value) { + throw errors.readonly(); + }, updateWorkspaceFolders: (index, deleteCount, ...workspaceFoldersToAdd) => { return extHostWorkspace.updateWorkspaceFolders(extension, index, deleteCount || 0, ...workspaceFoldersToAdd); }, @@ -560,7 +616,8 @@ export function createApiFactory( return extHostWorkspace.getRelativePath(pathOrUri, includeWorkspace); }, findFiles: (include, exclude, maxResults?, token?) => { - return extHostWorkspace.findFiles(typeConverters.GlobPattern.from(include), typeConverters.GlobPattern.from(withNullAsUndefined(exclude)), maxResults, extension.identifier, token); + // Note, undefined/null have different meanings on "exclude" + return extHostWorkspace.findFiles(typeConverters.GlobPattern.from(include), typeConverters.GlobPattern.from(exclude), maxResults, extension.identifier, token); }, findTextInFiles: (query: vscode.TextSearchQuery, optionsOrCallback: vscode.FindTextInFilesOptions | ((result: vscode.TextSearchResult) => void), callbackOrToken?: vscode.CancellationToken | ((result: vscode.TextSearchResult) => void), token?: vscode.CancellationToken) => { let options: vscode.FindTextInFilesOptions; @@ -639,11 +696,14 @@ export function createApiFactory( }, registerTaskProvider: (type: string, provider: vscode.TaskProvider) => { throw new Error('not implemented'); - // return extHostTask.registerTaskProvider(extension, provider); + // return extHostTask.registerTaskProvider(extension, type, provider); }, registerFileSystemProvider(scheme, provider, options) { return extHostFileSystem.registerFileSystemProvider(scheme, provider, options); }, + get fs() { + return extHostFileSystem.fileSystem; + }, registerFileSearchProvider: proposedApiFunction(extension, (scheme: string, provider: vscode.FileSearchProvider) => { throw new Error('not implemented'); // return extHostSearch.registerFileSearchProvider(scheme, provider); @@ -652,17 +712,11 @@ export function createApiFactory( throw new Error('not implemented'); // return extHostSearch.registerTextSearchProvider(scheme, provider); }), - registerDocumentCommentProvider: proposedApiFunction(extension, (provider: vscode.DocumentCommentProvider) => { - return extHostComment.registerDocumentCommentProvider(extension.identifier, provider); - }), - registerWorkspaceCommentProvider: proposedApiFunction(extension, (provider: vscode.WorkspaceCommentProvider) => { - return extHostComment.registerWorkspaceCommentProvider(extension.identifier, provider); - }), registerRemoteAuthorityResolver: proposedApiFunction(extension, (authorityPrefix: string, resolver: vscode.RemoteAuthorityResolver) => { return extensionService.registerRemoteAuthorityResolver(authorityPrefix, resolver); }), registerResourceLabelFormatter: proposedApiFunction(extension, (formatter: vscode.ResourceLabelFormatter) => { - return extHostFileSystem.registerResourceLabelFormatter(formatter); + return extHostLabelService.$registerResourceLabelFormatter(formatter); }), onDidRenameFile: proposedApiFunction(extension, (listener: (e: vscode.FileRenameEvent) => any, thisArg?: any, disposables?: vscode.Disposable[]) => { return extHostFileSystemEvent.onDidRenameFile(listener, thisArg, disposables); @@ -682,7 +736,7 @@ export function createApiFactory( } }; - const comment: typeof vscode.comment = { + const comment: typeof vscode.comments = { createCommentController(id: string, label: string) { return extHostComment.createCommentController(extension, id, label); } @@ -690,7 +744,7 @@ export function createApiFactory( const comments = comment; - // // namespace: debug + // namespace: debug // const debug: typeof vscode.debug = { // get activeDebugSession() { // return extHostDebugService.activeDebugSession; @@ -738,7 +792,7 @@ export function createApiFactory( // const tasks: typeof vscode.tasks = { // registerTaskProvider: (type: string, provider: vscode.TaskProvider) => { - // return extHostTask.registerTaskProvider(extension, provider); + // return extHostTask.registerTaskProvider(extension, type, provider); // }, // fetchTasks: (filter?: vscode.TaskFilter): Thenable => { // return extHostTask.fetchTasks(filter); @@ -810,7 +864,9 @@ export function createApiFactory( EndOfLine: extHostTypes.EndOfLine, EventEmitter: Emitter, ExtensionExecutionContext: extHostTypes.ExtensionExecutionContext, + ExtensionKind: extHostTypes.ExtensionKind, CustomExecution: extHostTypes.CustomExecution, + CustomExecution2: extHostTypes.CustomExecution2, FileChangeType: extHostTypes.FileChangeType, FileSystemError: extHostTypes.FileSystemError, FileType: files.FileType, @@ -877,16 +933,18 @@ class Extension implements vscode.Extension { private _extensionService: ExtHostExtensionService; private _identifier: ExtensionIdentifier; - public id: string; - public extensionPath: string; - public packageJSON: IExtensionDescription; + readonly id: string; + readonly extensionPath: string; + readonly packageJSON: IExtensionDescription; + readonly extensionKind: vscode.ExtensionKind; - constructor(extensionService: ExtHostExtensionService, description: IExtensionDescription) { + constructor(extensionService: ExtHostExtensionService, description: IExtensionDescription, kind: extHostTypes.ExtensionKind) { this._extensionService = extensionService; this._identifier = description.identifier; this.id = description.identifier.value; this.extensionPath = path.normalize(originalFSPath(description.extensionLocation)); this.packageJSON = description; + this.extensionKind = kind; } get isActive(): boolean { diff --git a/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts b/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts index 9e8e3eb7cd4..6e4cc7adb42 100644 --- a/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts +++ b/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import * as path from 'vs/base/common/path'; import { originalFSPath } from 'vs/base/common/resources'; import { Barrier } from 'vs/base/common/async'; -import { dispose, toDisposable } from 'vs/base/common/lifecycle'; +import { dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { TernarySearchTree } from 'vs/base/common/map'; import { URI } from 'vs/base/common/uri'; import { ILogService } from 'vs/platform/log/common/log'; @@ -15,7 +15,7 @@ import { createApiFactory, IExtensionApiFactory } from './extHost.api.impl'; // import { NodeModuleRequireInterceptor, VSCodeNodeModuleFactory, KeytarNodeModuleFactory, OpenNodeModuleFactory } from 'vs/workbench/api/node/extHostRequireInterceptor'; import { ExtHostExtensionServiceShape, IEnvironment, IInitData, IMainContext, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape, IResolveAuthorityResult } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; -import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionModule, HostExtension } from 'vs/workbench/api/common/extHostExtensionActivator'; +import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionModule, HostExtension, ExtensionActivationTimesFragment } from 'vs/workbench/api/common/extHostExtensionActivator'; import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; @@ -26,7 +26,6 @@ import { CancellationTokenSource } from 'vs/base/common/cancellation'; import * as errors from 'vs/base/common/errors'; import * as vscode from 'vscode'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; -import { IWorkspace } from 'vs/platform/workspace/common/workspace'; import { Schemas } from 'vs/base/common/network'; // import { withNullAsUndefined } from 'vs/base/common/types'; import { VSBuffer } from 'vs/base/common/buffer'; @@ -34,18 +33,35 @@ import { ExtensionMemento } from 'vs/workbench/api/common/extHostMemento'; // import { ExtensionStoragePaths } from 'vs/workbench/api/node/extHostStoragePaths'; import { RemoteAuthorityResolverError, ExtensionExecutionContext } from 'vs/workbench/api/common/extHostTypes'; import { IURITransformer } from 'vs/base/common/uriIpc'; +import { ResolvedAuthority, ResolvedOptions } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { endsWith } from 'vs/base/common/strings'; interface ITestRunner { + /** Old test runner API, as exported from `vscode/lib/testrunner` */ run(testsRoot: string, clb: (error: Error, failures?: number) => void): void; } +interface INewTestRunner { + /** New test runner API, as explained in the extension test doc */ + run(): Promise; +} + export interface IHostUtils { exit(code?: number): void; exists(path: string): Promise; realpath(path: string): Promise; } +type TelemetryActivationEventFragment = { + id: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' }; + name: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' }; + extensionVersion: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' }; + publisherDisplayName: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; + activationEvents: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; + isBuiltin: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true }; + reason: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; +}; + export class ExtHostExtensionService implements ExtHostExtensionServiceShape { private static readonly WORKSPACE_CONTAINS_TIMEOUT = 7000; @@ -76,6 +92,8 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { private _started: boolean; + private readonly _disposables: DisposableStore; + constructor( hostUtils: IHostUtils, initData: IInitData, @@ -93,6 +111,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { this._extHostConfiguration = extHostConfiguration; // this._environment = environment; this._extHostLogService = extHostLogService; + this._disposables = new DisposableStore(); this._mainThreadWorkspaceProxy = this._extHostContext.getProxy(MainContext.MainThreadWorkspace); this._mainThreadTelemetryProxy = this._extHostContext.getProxy(MainContext.MainThreadTelemetry); @@ -137,7 +156,6 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { uriTransformer ); - this._resolvers = Object.create(null); this._started = false; @@ -304,32 +322,32 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { private _logExtensionActivationTimes(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason, outcome: string, activationTimes?: ExtensionActivationTimes) { const event = getTelemetryActivationEvent(extensionDescription, reason); - /* __GDPR__ - "extensionActivationTimes" : { - "${include}": [ - "${TelemetryActivationEvent}", - "${ExtensionActivationTimes}" - ], - "outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } - } - */ - this._mainThreadTelemetryProxy.$publicLog('extensionActivationTimes', { + type ExtensionActivationTimesClassification = { + outcome: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; + } & TelemetryActivationEventFragment & ExtensionActivationTimesFragment; + + type ExtensionActivationTimesEvent = { + outcome: string + } & ActivationTimesEvent & TelemetryActivationEvent; + + type ActivationTimesEvent = { + startup?: boolean; + codeLoadingTime?: number; + activateCallTime?: number; + activateResolvedTime?: number; + }; + + this._mainThreadTelemetryProxy.$publicLog2('extensionActivationTimes', { ...event, ...(activationTimes || {}), - outcome, + outcome }); } private _doActivateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): Promise { const event = getTelemetryActivationEvent(extensionDescription, reason); - /* __GDPR__ - "activatePlugin" : { - "${include}": [ - "${TelemetryActivationEvent}" - ] - } - */ - this._mainThreadTelemetryProxy.$publicLog('activatePlugin', event); + type ActivatePluginClassification = {} & TelemetryActivationEventFragment; + this._mainThreadTelemetryProxy.$publicLog2('activatePlugin', event); if (!extensionDescription.main) { // Treat the extension as being empty => NOT AN ERROR CASE return Promise.resolve(new EmptyExtension(ExtensionActivationTimes.NONE)); @@ -346,7 +364,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { }); } - private _loadExtensionContext(extensionDescription: IExtensionDescription): Promise { + private _loadExtensionContext(extensionDescription: IExtensionDescription): Promise { const globalState = new ExtensionMemento(extensionDescription.identifier.value, true, this._storage); const workspaceState = new ExtensionMemento(extensionDescription.identifier.value, false, this._storage); @@ -363,11 +381,13 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { workspaceState, subscriptions: [], get extensionPath() { return extensionDescription.extensionLocation.fsPath; }, + // storagePath: this._storagePath.workspaceValue(extensionDescription), + // globalStoragePath: this._storagePath.globalValue(extensionDescription), get storagePath(): string { throw new Error('not impl'); },// this._storagePath.workspaceValue(extensionDescription), get globalStoragePath(): string { throw new Error('not impl'); },// this._storagePath.globalValue(extensionDescription), asAbsolutePath: (relativePath: string) => { return path.join(extensionDescription.extensionLocation.fsPath, relativePath); }, logPath: that._extHostLogService.getLogDirectory(extensionDescription.identifier), - executionContext: this._initData.remoteAuthority ? ExtensionExecutionContext.Remote : ExtensionExecutionContext.Local + executionContext: this._initData.remote.isRemote ? ExtensionExecutionContext.Remote : ExtensionExecutionContext.Local, }); }); } @@ -389,6 +409,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { try { activationTimesBuilder.activateCallStart(); logService.trace(`ExtensionService#_callActivateOptional ${extensionId.value}`); + // const activateResult: Promise = extensionModule.activate.apply(global, [context]); const activateResult: Promise = extensionModule.activate.apply(undefined, [context]); activationTimesBuilder.activateCallStop(); @@ -414,27 +435,33 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { console.error(err); }); - return this._handleWorkspaceContainsEagerExtensions(this._extHostWorkspace.workspace); + this._disposables.add(this._extHostWorkspace.onDidChangeWorkspace((e) => this._handleWorkspaceContainsEagerExtensions(e.added))); + const folders = this._extHostWorkspace.workspace ? this._extHostWorkspace.workspace.folders : []; + return this._handleWorkspaceContainsEagerExtensions(folders); } - private _handleWorkspaceContainsEagerExtensions(workspace: IWorkspace | undefined): Promise { - if (!workspace || workspace.folders.length === 0) { + private _handleWorkspaceContainsEagerExtensions(folders: ReadonlyArray): Promise { + if (folders.length === 0) { return Promise.resolve(undefined); } return Promise.all( this._registry.getAllExtensionDescriptions().map((desc) => { - return this._handleWorkspaceContainsEagerExtension(workspace, desc); + return this._handleWorkspaceContainsEagerExtension(folders, desc); }) ).then(() => { }); } - private _handleWorkspaceContainsEagerExtension(workspace: IWorkspace, desc: IExtensionDescription): Promise { + private _handleWorkspaceContainsEagerExtension(folders: ReadonlyArray, desc: IExtensionDescription): Promise { const activationEvents = desc.activationEvents; if (!activationEvents) { return Promise.resolve(undefined); } + if (this.isActivated(desc.identifier)) { + return Promise.resolve(undefined); + } + const fileNames: string[] = []; const globPatterns: string[] = []; @@ -453,16 +480,16 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { return Promise.resolve(undefined); } - const fileNamePromise = Promise.all(fileNames.map((fileName) => this._activateIfFileName(workspace, desc.identifier, fileName))).then(() => { }); - const globPatternPromise = this._activateIfGlobPatterns(desc.identifier, globPatterns); + const fileNamePromise = Promise.all(fileNames.map((fileName) => this._activateIfFileName(folders, desc.identifier, fileName))).then(() => { }); + const globPatternPromise = this._activateIfGlobPatterns(folders, desc.identifier, globPatterns); return Promise.all([fileNamePromise, globPatternPromise]).then(() => { }); } - private async _activateIfFileName(workspace: IWorkspace, extensionId: ExtensionIdentifier, fileName: string): Promise { + private async _activateIfFileName(folders: ReadonlyArray, extensionId: ExtensionIdentifier, fileName: string): Promise { // find exact path - for (const { uri } of workspace.folders) { + for (const { uri } of folders) { if (await this._hostUtils.exists(path.join(URI.revive(uri).fsPath, fileName))) { // the file was found return ( @@ -475,7 +502,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { return undefined; } - private async _activateIfGlobPatterns(extensionId: ExtensionIdentifier, globPatterns: string[]): Promise { + private async _activateIfGlobPatterns(folders: ReadonlyArray, extensionId: ExtensionIdentifier, globPatterns: string[]): Promise { this._extHostLogService.trace(`extensionHostMain#activateIfGlobPatterns: fileSearch, extension: ${extensionId.value}, entryPoint: workspaceContains`); if (globPatterns.length === 0) { @@ -483,7 +510,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { } const tokenSource = new CancellationTokenSource(); - const searchP = this._mainThreadWorkspaceProxy.$checkExists(globPatterns, tokenSource.token); + const searchP = this._mainThreadWorkspaceProxy.$checkExists(folders.map(folder => folder.uri), globPatterns, tokenSource.token); const timer = setTimeout(async () => { tokenSource.cancel(); @@ -531,7 +558,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { const extensionTestsPath = originalFSPath(extensionTestsLocationURI); // Require the test runner via node require from the provided path - let testRunner: ITestRunner | undefined; + let testRunner: ITestRunner | INewTestRunner | undefined; let requireError: Error | undefined; try { testRunner = require.__$__nodeRequire(extensionTestsPath); @@ -539,10 +566,10 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { requireError = error; } - // Execute the runner if it follows our spec + // Execute the runner if it follows the old `run` spec if (testRunner && typeof testRunner.run === 'function') { return new Promise((c, e) => { - testRunner!.run(extensionTestsPath, (error, failures) => { + const oldTestRunnerCallback = (error: Error, failures: number | undefined) => { if (error) { e(error.toString()); } else { @@ -551,7 +578,22 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { // after tests have run, we shutdown the host this._gracefulExit(error || (typeof failures === 'number' && failures > 0) ? 1 /* ERROR */ : 0 /* OK */); - }); + }; + + const runResult = testRunner!.run(extensionTestsPath, oldTestRunnerCallback); + + // Using the new API `run(): Promise` + if (runResult && runResult.then) { + runResult + .then(() => { + c(); + this._gracefulExit(0); + }) + .catch((err: Error) => { + e(err.toString()); + this._gracefulExit(1); + }); + } }); } @@ -568,7 +610,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { // messages to the main process, we delay the exit() by some time setTimeout(() => { // If extension tests are running, give the exit code to the renderer - if (this._initData.remoteAuthority && !!this._initData.environment.extensionTestsLocationURI) { + if (this._initData.remote.isRemote && !!this._initData.environment.extensionTestsLocationURI) { this._mainThreadExtensionsProxy.$onExtensionHostExit(code); return; } @@ -620,12 +662,22 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { try { const result = await resolver.resolve(remoteAuthority, { resolveAttempt }); + + // Split merged API result into separate authority/options + const authority: ResolvedAuthority = { + authority: remoteAuthority, + host: result.host, + port: result.port + }; + const options: ResolvedOptions = { + extensionHostEnv: result.extensionHostEnv + }; + return { type: 'ok', value: { - authority: remoteAuthority, - host: result.host, - port: result.port, + authority, + options } }; } catch (err) { @@ -705,13 +757,29 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { return buff; } + public async $setRemoteEnvironment(env: { [key: string]: string | null }): Promise { + if (!this._initData.remote.isRemote) { + return; + } + + for (const key in env) { + const value = env[key]; + if (value === null) { + delete process.env[key]; + } else { + process.env[key] = value; + } + } + } } async function loadCommonJSModule(logService: ILogService, modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { // fake commonjs world const module = { exports: {} }; + //@ts-ignore self['module'] = module; + //@ts-ignore self['exports'] = module.exports; // that's improper but might help extensions that aren't author correctly @@ -730,22 +798,20 @@ async function loadCommonJSModule(logService: ILogService, modulePath: string return module.exports as T; } -function getTelemetryActivationEvent(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): any { +type TelemetryActivationEvent = { + id: string; + name: string; + extensionVersion: string; + publisherDisplayName: string; + activationEvents: string | null; + isBuiltin: boolean; + reason: string; +}; + +function getTelemetryActivationEvent(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): TelemetryActivationEvent { const reasonStr = reason instanceof ExtensionActivatedByEvent ? reason.activationEvent : reason instanceof ExtensionActivatedByAPI ? 'api' : ''; - - /* __GDPR__FRAGMENT__ - "TelemetryActivationEvent" : { - "id": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" }, - "name": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" }, - "extensionVersion": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" }, - "publisherDisplayName": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "activationEvents": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "isBuiltin": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "reason": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } - } - */ const event = { id: extensionDescription.identifier.value, name: extensionDescription.name, diff --git a/src/vs/workbench/services/extensions/worker/extensionHostMain.ts b/src/vs/workbench/services/extensions/worker/extensionHostMain.ts index b8992b876d0..54094e12547 100644 --- a/src/vs/workbench/services/extensions/worker/extensionHostMain.ts +++ b/src/vs/workbench/services/extensions/worker/extensionHostMain.ts @@ -5,8 +5,7 @@ import { timeout } from 'vs/base/common/async'; import * as errors from 'vs/base/common/errors'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; -import { Counter } from 'vs/base/common/numbers'; +import { DisposableStore } from 'vs/base/common/lifecycle'; import { URI, setUriThrowOnMissingScheme } from 'vs/base/common/uri'; import { IURITransformer } from 'vs/base/common/uriIpc'; import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; @@ -41,10 +40,7 @@ export class ExtensionHostMain { private _isTerminating: boolean; private readonly _hostUtils: IHostUtils; private readonly _extensionService: ExtHostExtensionService; - private readonly _extHostLogService: ExtHostLogService; - private disposables: IDisposable[] = []; - - private _searchRequestIdProvider: Counter; + private readonly _disposables = new DisposableStore(); constructor( protocol: IMessagePassingProtocol, @@ -59,20 +55,19 @@ export class ExtensionHostMain { const rpcProtocol = new RPCProtocol(protocol, null, uriTransformer); // ensure URIs are transformed and revived - initData = this.transform(initData, rpcProtocol); + initData = ExtensionHostMain._transform(initData, rpcProtocol); // allow to patch console consolePatchFn(rpcProtocol.getProxy(MainContext.MainThreadConsole)); // services - this._extHostLogService = new ExtHostLogService(logServiceFn(initData), initData.logsLocation.fsPath); - this.disposables.push(this._extHostLogService); + const extHostLogService = new ExtHostLogService(logServiceFn(initData), initData.logsLocation.fsPath); + this._disposables.add(extHostLogService); - this._searchRequestIdProvider = new Counter(); - const extHostWorkspace = new ExtHostWorkspace(rpcProtocol, this._extHostLogService, this._searchRequestIdProvider, withNullAsUndefined(initData.workspace)); + const extHostWorkspace = new ExtHostWorkspace(rpcProtocol, extHostLogService, withNullAsUndefined(initData.workspace)); - this._extHostLogService.info('extension host started'); - this._extHostLogService.trace('initData', initData); + extHostLogService.info('extension host started'); + extHostLogService.trace('initData', initData); const extHostConfiguraiton = new ExtHostConfiguration(rpcProtocol.getProxy(MainContext.MainThreadConfiguration), extHostWorkspace); this._extensionService = new ExtHostExtensionService( @@ -82,7 +77,7 @@ export class ExtensionHostMain { extHostWorkspace, extHostConfiguraiton, initData.environment, - this._extHostLogService, + extHostLogService, uriTransformer ); @@ -127,7 +122,7 @@ export class ExtensionHostMain { } this._isTerminating = true; - this.disposables = dispose(this.disposables); + this._disposables.dispose(); errors.setUnexpectedErrorHandler((err) => { // TODO: write to log once we have one @@ -141,7 +136,7 @@ export class ExtensionHostMain { }, 1000); } - private transform(initData: IInitData, rpcProtocol: RPCProtocol): IInitData { + private static _transform(initData: IInitData, rpcProtocol: RPCProtocol): IInitData { initData.extensions.forEach((ext) => (ext).extensionLocation = URI.revive(rpcProtocol.transformIncomingURIs(ext.extensionLocation))); initData.environment.appRoot = URI.revive(rpcProtocol.transformIncomingURIs(initData.environment.appRoot)); initData.environment.appSettingsHome = URI.revive(rpcProtocol.transformIncomingURIs(initData.environment.appSettingsHome)); From 0db668ac8a9d8accf2b4807d7715dce7a30cc044 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 7 Aug 2019 10:16:31 +0200 Subject: [PATCH 279/861] tiny tweaks --- src/vs/base/common/worker/simpleWorker.ts | 5 ++--- src/vs/code/electron-browser/workbench/workbench.html | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/vs/base/common/worker/simpleWorker.ts b/src/vs/base/common/worker/simpleWorker.ts index 6331cfb910e..6c9815d3aaa 100644 --- a/src/vs/base/common/worker/simpleWorker.ts +++ b/src/vs/base/common/worker/simpleWorker.ts @@ -12,8 +12,7 @@ const INITIALIZE = '$initialize'; export interface IWorker extends IDisposable { getId(): number; - postMessage(message: any, transfer?: Transferable[]): void; - dispose(): void; + postMessage(message: any, transfer: Transferable[]): void; } export interface IWorkerCallback { @@ -214,7 +213,7 @@ export class SimpleWorkerClient extends Disp )); this._protocol = new SimpleWorkerProtocol({ - sendMessage: (msg: any, transfer?: Transferable[]): void => { + sendMessage: (msg: any, transfer: ArrayBuffer[]): void => { this._worker.postMessage(msg, transfer); }, handleMessage: (method: string, args: any[]): Promise => { diff --git a/src/vs/code/electron-browser/workbench/workbench.html b/src/vs/code/electron-browser/workbench/workbench.html index 42a9682a00c..483d01493f5 100644 --- a/src/vs/code/electron-browser/workbench/workbench.html +++ b/src/vs/code/electron-browser/workbench/workbench.html @@ -8,6 +8,6 @@ - - + + From 9e65debe363ac10ae1a383eb885a6a2dbff16d06 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 7 Aug 2019 10:58:42 +0200 Subject: [PATCH 280/861] zen mode: To properly reset line numbers we need to read the configuration for each editor respecting it's uri. fixes #78545 --- src/vs/workbench/browser/layout.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 9ddefc89b44..89d9dca6b46 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -34,6 +34,7 @@ import { Part } from 'vs/workbench/browser/part'; import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar'; import { IActivityBarService } from 'vs/workbench/services/activityBar/browser/activityBarService'; import { IFileService } from 'vs/platform/files/common/files'; +import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; enum Settings { MENUBAR_VISIBLE = 'window.menuBarVisibility', @@ -578,7 +579,15 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi this.state.zenMode.active = !this.state.zenMode.active; this.state.zenMode.transitionDisposables.clear(); - const setLineNumbers = (lineNumbers: any) => this.editorService.visibleTextEditorWidgets.forEach(editor => editor.updateOptions({ lineNumbers })); + const setLineNumbers = (lineNumbers?: any) => this.editorService.visibleTextEditorWidgets.forEach(editor => { + // To properly reset line numbers we need to read the configuration for each editor respecting it's uri. + if (!lineNumbers && isCodeEditor(editor) && editor.hasModel()) { + const model = editor.getModel(); + this.configurationService.getValue('editor.lineNumbers', { resource: model.uri }); + } else { + editor.updateOptions({ lineNumbers }); + } + }); // Check if zen mode transitioned to full screen and if now we are out of zen mode // -> we need to go out of full screen (same goes for the centered editor layout) @@ -641,7 +650,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi this.centerEditorLayout(false, true); } - setLineNumbers(this.configurationService.getValue('editor.lineNumbers')); + setLineNumbers(); // Status bar and activity bar visibility come from settings -> update their visibility. this.doUpdateLayoutConfiguration(true); From a383dc06076222cf7b40008703276ecd9677a74c Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 7 Aug 2019 11:03:51 +0200 Subject: [PATCH 281/861] atomic ext host restart (fix #78609) --- .../relauncher.contribution.ts | 3 ++- .../common/abstractExtensionService.ts | 6 +---- .../services/extensions/common/extensions.ts | 12 ---------- .../workspaceEditingService.ts | 24 ++++++++++++------- 4 files changed, 19 insertions(+), 26 deletions(-) diff --git a/src/vs/workbench/contrib/relauncher/electron-browser/relauncher.contribution.ts b/src/vs/workbench/contrib/relauncher/electron-browser/relauncher.contribution.ts index b53f3002e94..cae44658169 100644 --- a/src/vs/workbench/contrib/relauncher/electron-browser/relauncher.contribution.ts +++ b/src/vs/workbench/contrib/relauncher/electron-browser/relauncher.contribution.ts @@ -167,8 +167,9 @@ export class WorkspaceChangeExtHostRelauncher extends Disposable implements IWor if (!!environmentService.extensionTestsLocationURI) { return; // no restart when in tests: see https://github.com/Microsoft/vscode/issues/66936 } + if (environmentService.configuration.remoteAuthority) { - windowSevice.reloadWindow(); // TODO aeschli, workaround + windowSevice.reloadWindow(); // TODO@aeschli, workaround } else { extensionService.restartExtensionHost(); } diff --git a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts index 4581a00ea9b..6445a03a6e6 100644 --- a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts +++ b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts @@ -170,14 +170,10 @@ export abstract class AbstractExtensionService extends Disposable implements IEx this._startExtensionHostProcess(false, Array.from(this._allRequestedActivateEvents.keys())); } - public startExtensionHost(): void { + protected startExtensionHost(): void { this._startExtensionHostProcess(false, Array.from(this._allRequestedActivateEvents.keys())); } - public stopExtensionHost(): void { - this._stopExtensionHostProcess(); - } - public activateByEvent(activationEvent: string): Promise { if (this._installedExtensionsReady.isOpen()) { // Extensions have been scanned and interpreted diff --git a/src/vs/workbench/services/extensions/common/extensions.ts b/src/vs/workbench/services/extensions/common/extensions.ts index 0a56702ac0b..7c26e61e181 100644 --- a/src/vs/workbench/services/extensions/common/extensions.ts +++ b/src/vs/workbench/services/extensions/common/extensions.ts @@ -219,16 +219,6 @@ export interface IExtensionService { */ restartExtensionHost(): void; - /** - * Starts the extension host. - */ - startExtensionHost(): void; - - /** - * Stops the extension host. - */ - stopExtensionHost(): void; - /** * Modify the environment of the remote extension host * @param env New properties for the remote extension host @@ -282,8 +272,6 @@ export class NullExtensionService implements IExtensionService { getExtensionsStatus(): { [id: string]: IExtensionsStatus; } { return Object.create(null); } getInspectPort(): number { return 0; } restartExtensionHost(): void { } - startExtensionHost(): void { } - stopExtensionHost(): void { } async setRemoteEnvironment(_env: { [key: string]: string | null }): Promise { } canAddExtension(): boolean { return false; } canRemoveExtension(): boolean { return false; } diff --git a/src/vs/workbench/services/workspace/electron-browser/workspaceEditingService.ts b/src/vs/workbench/services/workspace/electron-browser/workspaceEditingService.ts index ee955429c1f..a3984b976c8 100644 --- a/src/vs/workbench/services/workspace/electron-browser/workspaceEditingService.ts +++ b/src/vs/workbench/services/workspace/electron-browser/workspaceEditingService.ts @@ -220,6 +220,7 @@ export class WorkspaceEditingService implements IWorkspaceEditingService { private async doAddFolders(foldersToAdd: IWorkspaceFolderCreationData[], index?: number, donotNotifyError: boolean = false): Promise { const state = this.contextService.getWorkbenchState(); if (this.environmentService.configuration.remoteAuthority) { + // Do not allow workspace folders with scheme different than the current remote scheme const schemas = this.contextService.getWorkspace().folders.map(f => f.uri.scheme); if (schemas.length && foldersToAdd.some(f => schemas.indexOf(f.uri.scheme) === -1)) { @@ -286,6 +287,7 @@ export class WorkspaceEditingService implements IWorkspaceEditingService { if (path && !await this.isValidTargetWorkspacePath(path)) { return; } + const remoteAuthority = this.environmentService.configuration.remoteAuthority; const untitledWorkspace = await this.workspaceService.createUntitledWorkspace(folders, remoteAuthority); if (path) { @@ -293,6 +295,7 @@ export class WorkspaceEditingService implements IWorkspaceEditingService { } else { path = untitledWorkspace.configPath; } + return this.enterWorkspace(path); } @@ -300,17 +303,18 @@ export class WorkspaceEditingService implements IWorkspaceEditingService { if (!await this.isValidTargetWorkspacePath(path)) { return; } + const workspaceIdentifier = this.getCurrentWorkspaceIdentifier(); if (!workspaceIdentifier) { return; } + await this.saveWorkspaceAs(workspaceIdentifier, path); return this.enterWorkspace(path); } async isValidTargetWorkspacePath(path: URI): Promise { - const windows = await this.windowsService.getWindows(); // Prevent overwriting a workspace that is currently opened in another window @@ -382,30 +386,34 @@ export class WorkspaceEditingService implements IWorkspaceEditingService { } const workspace = await this.workspaceService.getWorkspaceIdentifier(path); + // Settings migration (only if we come from a folder workspace) if (this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) { await this.migrateWorkspaceSettings(workspace); } + const workspaceImpl = this.contextService as WorkspaceService; await workspaceImpl.initialize(workspace); - // Restart extension host if first root folder changed (impact on deprecated workspace.rootPath API) - // Stop the extension host first to give extensions most time to shutdown - this.extensionService.stopExtensionHost(); - const result = await this.windowService.enterWorkspace(path); if (result) { await this.migrateStorage(result.workspace); + // Reinitialize backup service if (this.backupFileService instanceof BackupFileService) { this.backupFileService.initialize(toBackupWorkspaceResource(result.backupPath!, this.environmentService)); } } + // TODO@aeschli: workaround until restarting works if (this.environmentService.configuration.remoteAuthority) { - this.windowService.reloadWindow(); // TODO aeschli: workaround until restarting works - } else { - this.extensionService.startExtensionHost(); + this.windowService.reloadWindow(); + } + + // Restart the extension host: entering a workspace means a new location for + // storage and potentially a change in the workspace.rootPath property. + else { + this.extensionService.restartExtensionHost(); } } From 88e570c59fce1fe98f3d553dfcc81d984432df2e Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 7 Aug 2019 11:09:48 +0200 Subject: [PATCH 282/861] disable pr triggers --- build/azure-pipelines/product-build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index 24e62aa4abf..f38f4311826 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -140,6 +140,7 @@ jobs: - template: sync-mooncake.yml trigger: none +pr: none schedules: - cron: "0 5 * * Mon-Fri" From 4968e0a712a564e2fd833ce4522c49e8b996fdb4 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 7 Aug 2019 11:21:26 +0200 Subject: [PATCH 283/861] fix #77419 --- .../backup/common/backupFileService.ts | 31 +++++++++++++------ .../workspaceEditingService.ts | 6 +++- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/services/backup/common/backupFileService.ts b/src/vs/workbench/services/backup/common/backupFileService.ts index 04394b745b0..65af4c1ee30 100644 --- a/src/vs/workbench/services/backup/common/backupFileService.ts +++ b/src/vs/workbench/services/backup/common/backupFileService.ts @@ -111,15 +111,10 @@ export class BackupFileService implements IBackupFileService { private impl: IBackupFileService; constructor( - @IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService, - @IFileService fileService: IFileService + @IWorkbenchEnvironmentService private environmentService: IWorkbenchEnvironmentService, + @IFileService protected fileService: IFileService ) { - const backupWorkspaceResource = environmentService.configuration.backupWorkspaceResource; - if (backupWorkspaceResource) { - this.impl = new BackupFileServiceImpl(backupWorkspaceResource, this.hashPath, fileService); - } else { - this.impl = new InMemoryBackupFileService(this.hashPath); - } + this.initialize(); } protected hashPath(resource: URI): string { @@ -128,9 +123,25 @@ export class BackupFileService implements IBackupFileService { return hash(str).toString(16); } - initialize(backupWorkspaceResource: URI): void { + private initialize(): void { + const backupWorkspaceResource = this.environmentService.configuration.backupWorkspaceResource; + if (backupWorkspaceResource) { + this.impl = new BackupFileServiceImpl(backupWorkspaceResource, this.hashPath, this.fileService); + } else { + this.impl = new InMemoryBackupFileService(this.hashPath); + } + } + + reinitialize(): void { + + // Re-init implementation (unless we are running in-memory) if (this.impl instanceof BackupFileServiceImpl) { - this.impl.initialize(backupWorkspaceResource); + const backupWorkspaceResource = this.environmentService.configuration.backupWorkspaceResource; + if (backupWorkspaceResource) { + this.impl.initialize(backupWorkspaceResource); + } else { + this.impl = new InMemoryBackupFileService(this.hashPath); + } } } diff --git a/src/vs/workbench/services/workspace/electron-browser/workspaceEditingService.ts b/src/vs/workbench/services/workspace/electron-browser/workspaceEditingService.ts index a3984b976c8..abf9f135d3d 100644 --- a/src/vs/workbench/services/workspace/electron-browser/workspaceEditingService.ts +++ b/src/vs/workbench/services/workspace/electron-browser/workspaceEditingService.ts @@ -397,11 +397,15 @@ export class WorkspaceEditingService implements IWorkspaceEditingService { const result = await this.windowService.enterWorkspace(path); if (result) { + + // Migrate storage to new workspace await this.migrateStorage(result.workspace); // Reinitialize backup service + this.environmentService.configuration.backupPath = result.backupPath; + this.environmentService.configuration.backupWorkspaceResource = result.backupPath ? toBackupWorkspaceResource(result.backupPath, this.environmentService) : undefined; if (this.backupFileService instanceof BackupFileService) { - this.backupFileService.initialize(toBackupWorkspaceResource(result.backupPath!, this.environmentService)); + this.backupFileService.reinitialize(); } } From 56e836965104c8b76f65a76409c02cb44389e728 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 7 Aug 2019 11:28:40 +0200 Subject: [PATCH 284/861] fixes #78440 --- package.json | 5 +- src/typings/vscode-minimist.d.ts | 92 +++++++++++++++++++ src/vs/platform/environment/node/argv.ts | 2 +- .../test/node/environmentService.test.ts | 11 +++ .../node/extensionHostProcessSetup.ts | 2 +- .../quickopen.perf.integrationTest.ts | 2 +- .../textsearch.perf.integrationTest.ts | 2 +- yarn.lock | 10 +- 8 files changed, 114 insertions(+), 12 deletions(-) create mode 100644 src/typings/vscode-minimist.d.ts diff --git a/package.json b/package.json index 5393ef2087c..f2113d68da9 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,6 @@ "iconv-lite": "0.5.0", "jschardet": "1.6.0", "keytar": "^4.11.0", - "minimist": "1.2.0", "native-is-elevated": "0.3.0", "native-keymap": "2.0.0", "native-watchdog": "1.0.0", @@ -47,6 +46,7 @@ "sudo-prompt": "9.0.0", "v8-inspect-profiler": "^0.0.20", "vscode-chokidar": "2.1.7", + "vscode-minimist": "^1.2.1", "vscode-proxy-agent": "0.4.0", "vscode-ripgrep": "^1.5.5", "vscode-sqlite3": "4.0.8", @@ -60,7 +60,6 @@ "devDependencies": { "7zip": "0.0.6", "@types/keytar": "^4.4.0", - "@types/minimist": "^1.2.0", "@types/mocha": "2.2.39", "@types/node": "^10.12.12", "@types/semver": "^5.5.0", @@ -158,4 +157,4 @@ "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} \ No newline at end of file +} diff --git a/src/typings/vscode-minimist.d.ts b/src/typings/vscode-minimist.d.ts new file mode 100644 index 00000000000..17558a1a738 --- /dev/null +++ b/src/typings/vscode-minimist.d.ts @@ -0,0 +1,92 @@ +// Type definitions for minimist 1.2.0 +// Project: https://github.com/substack/minimist +// Definitions by: Bart van der Schoor , Necroskillz , kamranayub +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +/** + * Return an argument object populated with the array arguments from args + * + * @param args An optional argument array (typically `process.argv.slice(2)`) + * @param opts An optional options object to customize the parsing + */ +declare function minimist(args?: string[], opts?: minimist.Opts): minimist.ParsedArgs; + +/** + * Return an argument object populated with the array arguments from args. Strongly-typed + * to be the intersect of type T with minimist.ParsedArgs. + * + * @type T The type that will be intersected with minimist.ParsedArgs to represent the argument object + * @param args An optional argument array (typically `process.argv.slice(2)`) + * @param opts An optional options object to customize the parsing + */ +declare function minimist(args?: string[], opts?: minimist.Opts): T & minimist.ParsedArgs; + +/** + * Return an argument object populated with the array arguments from args. Strongly-typed + * to be the the type T which should extend minimist.ParsedArgs + * + * @type T The type that extends minimist.ParsedArgs and represents the argument object + * @param args An optional argument array (typically `process.argv.slice(2)`) + * @param opts An optional options object to customize the parsing + */ +declare function minimist(args?: string[], opts?: minimist.Opts): T; + +declare namespace minimist { + export interface Opts { + /** + * A string or array of strings argument names to always treat as strings + */ + string?: string | string[]; + + /** + * A boolean, string or array of strings to always treat as booleans. If true will treat + * all double hyphenated arguments without equals signs as boolean (e.g. affects `--foo`, not `-f` or `--foo=bar`) + */ + boolean?: boolean | string | string[]; + + /** + * An object mapping string names to strings or arrays of string argument names to use as aliases + */ + alias?: { [key: string]: string | string[] }; + + /** + * An object mapping string argument names to default values + */ + default?: { [key: string]: any }; + + /** + * When true, populate argv._ with everything after the first non-option + */ + stopEarly?: boolean; + + /** + * A function which is invoked with a command line parameter not defined in the opts + * configuration object. If the function returns false, the unknown option is not added to argv + */ + unknown?: (arg: string) => boolean; + + /** + * When true, populate argv._ with everything before the -- and argv['--'] with everything after the --. + * Note that with -- set, parsing for arguments still stops after the `--`. + */ + '--'?: boolean; + } + + export interface ParsedArgs { + [arg: string]: any; + + /** + * If opts['--'] is true, populated with everything after the -- + */ + '--'?: string[]; + + /** + * Contains all the arguments that didn't have an option associated with them + */ + _: string[]; + } +} + +declare module "vscode-minimist" { + export = minimist; +} diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index dc90930ecbe..5e22e54d396 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as minimist from 'minimist'; +import * as minimist from 'vscode-minimist'; import * as os from 'os'; import { localize } from 'vs/nls'; import { ParsedArgs } from 'vs/platform/environment/common/environment'; diff --git a/src/vs/platform/environment/test/node/environmentService.test.ts b/src/vs/platform/environment/test/node/environmentService.test.ts index dd34d5a9149..8a69fb2d740 100644 --- a/src/vs/platform/environment/test/node/environmentService.test.ts +++ b/src/vs/platform/environment/test/node/environmentService.test.ts @@ -52,4 +52,15 @@ suite('EnvironmentService', () => { assert.equal(parse(['--user-data-dir', './dir'], { cwd: () => '/foo', env: { 'VSCODE_CWD': '/bar' } }), path.resolve('/bar/dir'), 'should use VSCODE_CWD as the cwd when --user-data-dir is specified'); }); + + // https://github.com/microsoft/vscode/issues/78440 + test.only('careful with boolean file names', function () { + let actual = parseArgs(['-r', 'arg.txt']); + assert(actual['reuse-window']); + assert.deepEqual(actual._, ['arg.txt']); + + actual = parseArgs(['-r', 'true.txt']); + assert(actual['reuse-window']); + assert.deepEqual(actual._, ['true.txt']); + }); }); diff --git a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts index 1a5822e645f..a9fb15289b2 100644 --- a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts +++ b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts @@ -5,7 +5,7 @@ import * as nativeWatchdog from 'native-watchdog'; import * as net from 'net'; -import * as minimist from 'minimist'; +import * as minimist from 'vscode-minimist'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Event, Emitter } from 'vs/base/common/event'; import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; diff --git a/src/vs/workbench/test/electron-browser/quickopen.perf.integrationTest.ts b/src/vs/workbench/test/electron-browser/quickopen.perf.integrationTest.ts index 4b246719249..b23a042280b 100644 --- a/src/vs/workbench/test/electron-browser/quickopen.perf.integrationTest.ts +++ b/src/vs/workbench/test/electron-browser/quickopen.perf.integrationTest.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import * as minimist from 'minimist'; +import * as minimist from 'vscode-minimist'; import * as path from 'vs/base/common/path'; import { CancellationToken } from 'vs/base/common/cancellation'; import { URI } from 'vs/base/common/uri'; diff --git a/src/vs/workbench/test/electron-browser/textsearch.perf.integrationTest.ts b/src/vs/workbench/test/electron-browser/textsearch.perf.integrationTest.ts index e08748c6364..ee857b6b8b3 100644 --- a/src/vs/workbench/test/electron-browser/textsearch.perf.integrationTest.ts +++ b/src/vs/workbench/test/electron-browser/textsearch.perf.integrationTest.ts @@ -13,7 +13,7 @@ import { ISearchService } from 'vs/workbench/services/search/common/search'; import { ITelemetryService, ITelemetryInfo } from 'vs/platform/telemetry/common/telemetry'; import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import * as minimist from 'minimist'; +import * as minimist from 'vscode-minimist'; import * as path from 'vs/base/common/path'; import { LocalSearchService } from 'vs/workbench/services/search/node/searchService'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; diff --git a/yarn.lock b/yarn.lock index c0b3855173d..70b8c2fcdf7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -112,11 +112,6 @@ resolved "https://registry.yarnpkg.com/@types/keytar/-/keytar-4.4.0.tgz#ca24e6ee6d0df10c003aafe26e93113b8faf0d8e" integrity sha512-cq/NkUUy6rpWD8n7PweNQQBpw2o0cf5v6fbkUVEpOB9VzzIvyPvSEId1/goIj+MciW2v1Lw5mRimKO01XgE9EA== -"@types/minimist@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.0.tgz#69a23a3ad29caf0097f06eda59b361ee2f0639f6" - integrity sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY= - "@types/mocha@2.2.39": version "2.2.39" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.39.tgz#f68d63db8b69c38e9558b4073525cf96c4f7a829" @@ -9546,6 +9541,11 @@ vscode-fsevents@1.2.12: dependencies: nan "^2.14.0" +vscode-minimist@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/vscode-minimist/-/vscode-minimist-1.2.1.tgz#e63d3f4a9bf3680dcb8f9304eed612323fd6926a" + integrity sha512-cmB72+qDoiCFJ1UKnGUBdGYfXzdpJ3bQM/D/+XhkVk5v7uZgLbYiCz5JcwVyk7NC7hSi5VGtQ4wihzmi12NeXw== + vscode-nls-dev@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/vscode-nls-dev/-/vscode-nls-dev-3.3.1.tgz#15fc03e0c9ca5a150abb838690d9554ac06f77e4" From 3f4b96732ca7e699635cc262557eaadad24a14d2 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 7 Aug 2019 11:41:21 +0200 Subject: [PATCH 285/861] fixes #78541 --- extensions/git/src/commands.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 075860b55a5..fef9d4a1f85 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1498,12 +1498,12 @@ export class CommandCenter { await this._branch(repository, undefined, true); } - private async _branch(repository: Repository, defaultName?: string, from = false): Promise { + private async promptForBranchName(defaultName?: string): Promise { const config = workspace.getConfiguration('git'); const branchWhitespaceChar = config.get('branchWhitespaceChar')!; const branchValidationRegex = config.get('branchValidationRegex')!; const sanitize = (name: string) => name ? - name.trim().replace(/^\.|\/\.|\.\.|~|\^|:|\/$|\.lock$|\.lock\/|\\|\*|\s|^\s*$|\.$|\[|\]$/g, branchWhitespaceChar) + name.trim().replace(/^-+/, '').replace(/^\.|\/\.|\.\.|~|\^|:|\/$|\.lock$|\.lock\/|\\|\*|\s|^\s*$|\.$|\[|\]$/g, branchWhitespaceChar) : name; const rawBranchName = defaultName || await window.showInputBox({ @@ -1520,7 +1520,11 @@ export class CommandCenter { } }); - const branchName = sanitize(rawBranchName || ''); + return sanitize(rawBranchName || ''); + } + + private async _branch(repository: Repository, defaultName?: string, from = false): Promise { + const branchName = await this.promptForBranchName(defaultName); if (!branchName) { return; @@ -1582,25 +1586,21 @@ export class CommandCenter { @command('git.renameBranch', { repository: true }) async renameBranch(repository: Repository): Promise { - const name = await window.showInputBox({ - placeHolder: localize('branch name', "Branch name"), - prompt: localize('provide branch name', "Please provide a branch name"), - value: repository.HEAD && repository.HEAD.name - }); + const branchName = await this.promptForBranchName(); - if (!name || name.trim().length === 0) { + if (!branchName) { return; } try { - await repository.renameBranch(name); + await repository.renameBranch(branchName); } catch (err) { switch (err.gitErrorCode) { case GitErrorCodes.InvalidBranchName: window.showErrorMessage(localize('invalid branch name', 'Invalid branch name')); return; case GitErrorCodes.BranchAlreadyExists: - window.showErrorMessage(localize('branch already exists', "A branch named '{0}' already exists", name)); + window.showErrorMessage(localize('branch already exists', "A branch named '{0}' already exists", branchName)); return; default: throw err; From 94b8b80fd39e6bb76b4c2d2c32ed47bc5189751e Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 7 Aug 2019 11:49:36 +0200 Subject: [PATCH 286/861] Reveal and select new tasks from configure task Also, make a best effort to position cursor at task if configuring an existing task Fixes #78147 --- .../tasks/browser/abstractTaskService.ts | 78 +++++++++++++++---- 1 file changed, 63 insertions(+), 15 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index a59f40dd2f4..be59e276ec8 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -73,6 +73,11 @@ import { RunAutomaticTasks } from 'vs/workbench/contrib/tasks/browser/runAutomat import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; +import { format } from 'vs/base/common/jsonFormatter'; +import { ITextModelService } from 'vs/editor/common/services/resolverService'; +import { applyEdits } from 'vs/base/common/jsonEdit'; +import { ITextEditor } from 'vs/workbench/common/editor'; +import { ITextEditorSelection } from 'vs/platform/editor/common/editor'; export namespace ConfigureTaskAction { export const ID = 'workbench.action.tasks.configureTaskRunner'; @@ -220,7 +225,8 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService, @IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService, @ITerminalInstanceService private readonly terminalInstanceService: ITerminalInstanceService, - @IRemoteAgentService private readonly remoteAgentService: IRemoteAgentService + @IRemoteAgentService private readonly remoteAgentService: IRemoteAgentService, + @ITextModelService private readonly textModelResolverService: ITextModelService ) { super(); @@ -769,6 +775,60 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer return false; } + private openEditorAtTask(resource: URI | undefined, task: TaskConfig.CustomTask | TaskConfig.ConfiguringTask | string | undefined): Promise { + if (resource === undefined) { + return Promise.resolve(undefined); + } + let selection: ITextEditorSelection | undefined; + return this.fileService.readFile(resource).then(content => content.value).then(async content => { + if (!content) { + return undefined; + } + if (task) { + const contentValue = content.toString(); + let stringValue: string; + if (typeof task === 'string') { + stringValue = task; + } else { + const model = (await this.textModelResolverService.createModelReference(resource)).object.textEditorModel; + const { tabSize, insertSpaces } = model.getOptions(); + const eol = model.getEOL(); + const edits = format(JSON.stringify(task), undefined, { eol, tabSize, insertSpaces }); + let stringified = applyEdits(JSON.stringify(task), edits); + const regex = new RegExp(eol + '\\t', 'g'); + stringified = stringified.replace(regex, eol + '\t\t\t'); + const twoTabs = '\t\t'; + stringValue = twoTabs + stringified.slice(0, stringified.length - 1) + twoTabs + stringified.slice(stringified.length - 1); + } + + const index = contentValue.indexOf(stringValue); + let startLineNumber = 1; + for (let i = 0; i < index; i++) { + if (contentValue.charAt(i) === '\n') { + startLineNumber++; + } + } + let endLineNumber = startLineNumber; + for (let i = 0; i < stringValue.length; i++) { + if (stringValue.charAt(i) === '\n') { + endLineNumber++; + } + } + selection = startLineNumber > 1 ? { startLineNumber, startColumn: startLineNumber === endLineNumber ? 4 : 3, endLineNumber, endColumn: startLineNumber === endLineNumber ? undefined : 4 } : undefined; + } + + return this.editorService.openEditor({ + resource, + options: { + pinned: false, + forceReload: true, // because content might have changed + selection, + revealInCenterIfOutsideViewport: !!selection + } + }); + }); + } + public customize(task: ContributedTask | CustomTask, properties?: CustomizationProperties, openConfig?: boolean): Promise { const workspaceFolder = task.getWorkspaceFolder(); if (!workspaceFolder) { @@ -867,14 +927,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer */ this.telemetryService.publicLog(AbstractTaskService.CustomizationTelemetryEventName, event); if (openConfig) { - let resource = workspaceFolder.toResource('.vscode/tasks.json'); - this.editorService.openEditor({ - resource, - options: { - pinned: false, - forceReload: true // because content might have changed - } - }); + this.openEditorAtTask(workspaceFolder.toResource('.vscode/tasks.json'), toCustomize); } }); } @@ -896,12 +949,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer } else { resource = (this._workspaceFolders && (this._workspaceFolders.length > 0)) ? this._workspaceFolders[0].toResource('.vscode/tasks.json') : undefined; } - return this.editorService.openEditor({ - resource, - options: { - pinned: false - } - }).then(() => undefined); + return this.openEditorAtTask(resource, task ? task._label : undefined).then(() => undefined); } private createRunnableTask(tasks: TaskMap, group: TaskGroup): { task: Task; resolver: ITaskResolver } | undefined { From 8c1273209ea734a0409ef04994b8acd43b9dd872 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Wed, 7 Aug 2019 11:58:36 +0200 Subject: [PATCH 287/861] fix broken EH debugging --- src/vs/workbench/browser/web.simpleservices.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 7240412d27a..f9c7b18deee 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -728,7 +728,9 @@ export class SimpleWindowsService implements IWindowsService { } // add connection token - newAddress += `${this.workbenchEnvironmentService.configuration.connectionToken ? `tkn=${this.workbenchEnvironmentService.configuration.connectionToken}` : ''}`; + if (this.workbenchEnvironmentService.configuration.connectionToken) { + newAddress += `&tkn=${this.workbenchEnvironmentService.configuration.connectionToken}`; + } window.open(newAddress); From 49a5dddb8f358ab0ad5412f9658da7c67d8111d8 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 7 Aug 2019 12:12:47 +0200 Subject: [PATCH 288/861] distro --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index f2113d68da9..02390ee4179 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "f123663d79c57c07e3f70b2d0938f1a58ff4d1da", + "distro": "4694b56986953df2562df7cc65b4d7806e46c138", "author": { "name": "Microsoft Corporation" }, @@ -157,4 +157,4 @@ "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} +} \ No newline at end of file From 8a2819be58042fcdaf8d51ec3878a2bfd266bbe5 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 7 Aug 2019 12:18:44 +0200 Subject: [PATCH 289/861] fixes #66620 --- extensions/git/src/commands.ts | 13 ------------- extensions/git/src/repository.ts | 2 +- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index fef9d4a1f85..bece1ac592a 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1361,19 +1361,6 @@ export class CommandCenter { await this.commitWithAnyInput(repository); } - @command('git.commitWithInput', { repository: true }) - async commitWithInput(repository: Repository): Promise { - if (!repository.inputBox.value) { - return; - } - - const didCommit = await this.smartCommit(repository, async () => repository.inputBox.value); - - if (didCommit) { - repository.inputBox.value = await repository.getCommitTemplate(); - } - } - @command('git.commitStaged', { repository: true }) async commitStaged(repository: Repository): Promise { await this.commitWithAnyInput(repository, { all: false }); diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 07dc1c231e8..a9af9324db6 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -680,7 +680,7 @@ export class Repository implements Disposable { const root = Uri.file(repository.root); this._sourceControl = scm.createSourceControl('git', 'Git', root); this._sourceControl.inputBox.placeholder = localize('commitMessage', "Message (press {0} to commit)"); - this._sourceControl.acceptInputCommand = { command: 'git.commitWithInput', title: localize('commit', "Commit"), arguments: [this._sourceControl] }; + this._sourceControl.acceptInputCommand = { command: 'git.commit', title: localize('commit', "Commit"), arguments: [this._sourceControl] }; this._sourceControl.quickDiffProvider = this; this._sourceControl.inputBox.validateInput = this.validateInput.bind(this); this.disposables.push(this._sourceControl); From 6bf98da0535ca347c339065086bc0a6457f58415 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 7 Aug 2019 12:31:18 +0200 Subject: [PATCH 290/861] strict init (#78168) --- src/vs/base/common/path.ts | 2 ++ src/vs/base/node/encoding.ts | 6 ++--- src/vs/base/parts/ipc/test/node/ipc.test.ts | 2 +- .../parts/quickopen/browser/quickOpenModel.ts | 4 ++-- src/vs/code/electron-main/sharedProcess.ts | 2 +- .../browser/quickOpen/editorQuickOpen.ts | 6 ++--- .../watcher/win32/csharpWatcherService.ts | 2 +- .../files/test/node/diskFileService.test.ts | 4 ++-- .../electron-browser/localizationsService.ts | 4 ++-- .../localizations/node/localizations.ts | 4 ++-- src/vs/platform/progress/common/progress.ts | 2 +- .../platform/request/node/requestService.ts | 4 ++-- .../notifications/notificationsCenter.ts | 2 +- .../notifications/notificationsStatus.ts | 6 ++--- .../notifications/notificationsViewer.ts | 16 ++++++++------ src/vs/workbench/common/contributions.ts | 6 ++--- .../common/editor/textEditorModel.ts | 4 ++-- src/vs/workbench/common/notifications.ts | 22 +++++++++++-------- .../contrib/feedback/browser/feedback.ts | 20 ++++++++--------- .../feedback/browser/feedbackStatusbarItem.ts | 18 ++++++++------- .../common/configurationEditingService.ts | 2 +- .../output/node/outputChannelModelService.ts | 2 +- .../services/search/common/searchService.ts | 4 +++- .../test/common/notifications.test.ts | 4 ++-- 24 files changed, 80 insertions(+), 68 deletions(-) diff --git a/src/vs/base/common/path.ts b/src/vs/base/common/path.ts index c8532347224..5ab3ac2621c 100644 --- a/src/vs/base/common/path.ts +++ b/src/vs/base/common/path.ts @@ -58,6 +58,8 @@ class ErrorInvalidArgType extends Error { msg += `. Received type ${typeof actual}`; super(msg); + + this.code = 'ERR_INVALID_ARG_TYPE'; } } diff --git a/src/vs/base/node/encoding.ts b/src/vs/base/node/encoding.ts index d89114aa099..83428b3590c 100644 --- a/src/vs/base/node/encoding.ts +++ b/src/vs/base/node/encoding.ts @@ -47,8 +47,8 @@ export function toDecodeStream(readable: Readable, options: IDecodeStreamOptions return new Promise((resolve, reject) => { const writer = new class extends Writable { - private decodeStream: NodeJS.ReadWriteStream; - private decodeStreamPromise: Promise; + private decodeStream: NodeJS.ReadWriteStream | undefined; + private decodeStreamPromise: Promise | undefined; private bufferedChunks: Buffer[] = []; private bytesBuffered = 0; @@ -122,7 +122,7 @@ export function toDecodeStream(readable: Readable, options: IDecodeStreamOptions // detection. thus, wrap up starting the stream even // without all the data to get things going else { - this._startDecodeStream(() => this.decodeStream.end(callback)); + this._startDecodeStream(() => this.decodeStream!.end(callback)); } } }; diff --git a/src/vs/base/parts/ipc/test/node/ipc.test.ts b/src/vs/base/parts/ipc/test/node/ipc.test.ts index 14f059f5e08..e30252caa76 100644 --- a/src/vs/base/parts/ipc/test/node/ipc.test.ts +++ b/src/vs/base/parts/ipc/test/node/ipc.test.ts @@ -31,7 +31,7 @@ class QueueProtocol implements IMessagePassingProtocol { }); readonly onMessage = this._onMessage.event; - other: QueueProtocol; + other!: QueueProtocol; send(buffer: VSBuffer): void { this.other.receive(buffer); diff --git a/src/vs/base/parts/quickopen/browser/quickOpenModel.ts b/src/vs/base/parts/quickopen/browser/quickOpenModel.ts index 165db403b5d..6b549c62b44 100644 --- a/src/vs/base/parts/quickopen/browser/quickOpenModel.ts +++ b/src/vs/base/parts/quickopen/browser/quickOpenModel.ts @@ -57,7 +57,7 @@ export class QuickOpenEntry { private labelHighlights: IHighlight[]; private descriptionHighlights?: IHighlight[]; private detailHighlights?: IHighlight[]; - private hidden: boolean; + private hidden: boolean | undefined; constructor(highlights: IHighlight[] = []) { this.id = (IDS++).toString(); @@ -148,7 +148,7 @@ export class QuickOpenEntry { * Allows to reuse the same model while filtering. Hidden entries will not show up in the viewer. */ isHidden(): boolean { - return this.hidden; + return !!this.hidden; } /** diff --git a/src/vs/code/electron-main/sharedProcess.ts b/src/vs/code/electron-main/sharedProcess.ts index 60926b0d146..f5b010da563 100644 --- a/src/vs/code/electron-main/sharedProcess.ts +++ b/src/vs/code/electron-main/sharedProcess.ts @@ -18,7 +18,7 @@ export class SharedProcess implements ISharedProcess { private barrier = new Barrier(); - private window: Electron.BrowserWindow | null; + private window: Electron.BrowserWindow | null = null; constructor( private readonly machineId: string, diff --git a/src/vs/editor/standalone/browser/quickOpen/editorQuickOpen.ts b/src/vs/editor/standalone/browser/quickOpen/editorQuickOpen.ts index c8fb32757b4..96bcc2ea3c4 100644 --- a/src/vs/editor/standalone/browser/quickOpen/editorQuickOpen.ts +++ b/src/vs/editor/standalone/browser/quickOpen/editorQuickOpen.ts @@ -31,9 +31,9 @@ export class QuickOpenController implements editorCommon.IEditorContribution, ID } private readonly editor: ICodeEditor; - private widget: QuickOpenEditorWidget | null; - private rangeHighlightDecorationId: string | null; - private lastKnownEditorSelection: Selection | null; + private widget: QuickOpenEditorWidget | null = null; + private rangeHighlightDecorationId: string | null = null; + private lastKnownEditorSelection: Selection | null = null; constructor(editor: ICodeEditor, @IThemeService private readonly themeService: IThemeService) { this.editor = editor; diff --git a/src/vs/platform/files/node/watcher/win32/csharpWatcherService.ts b/src/vs/platform/files/node/watcher/win32/csharpWatcherService.ts index 94050df7ee7..c2d96732a3c 100644 --- a/src/vs/platform/files/node/watcher/win32/csharpWatcherService.ts +++ b/src/vs/platform/files/node/watcher/win32/csharpWatcherService.ts @@ -18,7 +18,7 @@ export class OutOfProcessWin32FolderWatcher { private ignored: glob.ParsedPattern[]; - private handle: cp.ChildProcess; + private handle: cp.ChildProcess | undefined; private restartCounter: number; constructor( diff --git a/src/vs/platform/files/test/node/diskFileService.test.ts b/src/vs/platform/files/test/node/diskFileService.test.ts index c744c83f3e2..238ccd8ede7 100644 --- a/src/vs/platform/files/test/node/diskFileService.test.ts +++ b/src/vs/platform/files/test/node/diskFileService.test.ts @@ -62,9 +62,9 @@ export class TestDiskFileSystemProvider extends DiskFileSystemProvider { totalBytesRead: number = 0; - private invalidStatSize: boolean; + private invalidStatSize: boolean = false; - private _testCapabilities: FileSystemProviderCapabilities; + private _testCapabilities!: FileSystemProviderCapabilities; get capabilities(): FileSystemProviderCapabilities { if (!this._testCapabilities) { this._testCapabilities = diff --git a/src/vs/platform/localizations/electron-browser/localizationsService.ts b/src/vs/platform/localizations/electron-browser/localizationsService.ts index 353161166e8..add4dfb2fcf 100644 --- a/src/vs/platform/localizations/electron-browser/localizationsService.ts +++ b/src/vs/platform/localizations/electron-browser/localizationsService.ts @@ -11,7 +11,7 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio export class LocalizationsService implements ILocalizationsService { - _serviceBrand: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; private channel: IChannel; @@ -24,4 +24,4 @@ export class LocalizationsService implements ILocalizationsService { getLanguageIds(type?: LanguageType): Promise { return this.channel.call('getLanguageIds', type); } -} \ No newline at end of file +} diff --git a/src/vs/platform/localizations/node/localizations.ts b/src/vs/platform/localizations/node/localizations.ts index 9467d8a6282..2311778a2fa 100644 --- a/src/vs/platform/localizations/node/localizations.ts +++ b/src/vs/platform/localizations/node/localizations.ts @@ -93,7 +93,7 @@ class LanguagePacksCache extends Disposable { private languagePacks: { [language: string]: ILanguagePack } = {}; private languagePacksFilePath: string; private languagePacksFileLimiter: Queue; - private initializedCache: boolean; + private initializedCache: boolean | undefined; constructor( @IEnvironmentService environmentService: IEnvironmentService, @@ -184,4 +184,4 @@ class LanguagePacksCache extends Disposable { .then(() => result, error => this.logService.error(error)); }); } -} \ No newline at end of file +} diff --git a/src/vs/platform/progress/common/progress.ts b/src/vs/platform/progress/common/progress.ts index 634b38b1929..117e1af70de 100644 --- a/src/vs/platform/progress/common/progress.ts +++ b/src/vs/platform/progress/common/progress.ts @@ -120,7 +120,7 @@ export interface IOperation { export class LongRunningOperation extends Disposable { private currentOperationId = 0; private readonly currentOperationDisposables = this._register(new DisposableStore()); - private currentProgressRunner: IProgressRunner; + private currentProgressRunner: IProgressRunner | undefined; private currentProgressTimeout: any; constructor( diff --git a/src/vs/platform/request/node/requestService.ts b/src/vs/platform/request/node/requestService.ts index e0c572277d3..8ca875f6fa9 100644 --- a/src/vs/platform/request/node/requestService.ts +++ b/src/vs/platform/request/node/requestService.ts @@ -38,7 +38,7 @@ export class RequestService extends Disposable implements IRequestService { _serviceBrand: any; private proxyUrl?: string; - private strictSSL: boolean; + private strictSSL: boolean | undefined; private authorization?: string; constructor( @@ -143,4 +143,4 @@ export class RequestService extends Disposable implements IRequestService { } -} \ No newline at end of file +} diff --git a/src/vs/workbench/browser/parts/notifications/notificationsCenter.ts b/src/vs/workbench/browser/parts/notifications/notificationsCenter.ts index adef1d21348..a0077787b11 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsCenter.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsCenter.ts @@ -285,4 +285,4 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { if (notificationBorderColor) { collector.addRule(`.monaco-workbench > .notifications-center .notifications-list-container .monaco-list-row[data-last-element="false"] > .notification-list-item { border-bottom: 1px solid ${notificationBorderColor}; }`); } -}); \ No newline at end of file +}); diff --git a/src/vs/workbench/browser/parts/notifications/notificationsStatus.ts b/src/vs/workbench/browser/parts/notifications/notificationsStatus.ts index acb18855f3b..69c224d207b 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsStatus.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsStatus.ts @@ -11,12 +11,12 @@ import { localize } from 'vs/nls'; export class NotificationsStatus extends Disposable { - private notificationsCenterStatusItem: IStatusbarEntryAccessor; + private notificationsCenterStatusItem: IStatusbarEntryAccessor | undefined; private currentNotifications = new Set(); private currentStatusMessage: [IStatusMessageViewItem, IDisposable] | undefined; - private isNotificationsCenterVisible: boolean; + private isNotificationsCenterVisible: boolean | undefined; constructor( private model: INotificationsModel, @@ -172,4 +172,4 @@ export class NotificationsStatus extends Disposable { // Remember as current status message this.currentStatusMessage = [item, statusMessageDispose]; } -} \ No newline at end of file +} diff --git a/src/vs/workbench/browser/parts/notifications/notificationsViewer.ts b/src/vs/workbench/browser/parts/notifications/notificationsViewer.ts index 1e52e099f54..03887faece7 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsViewer.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsViewer.ts @@ -62,7 +62,7 @@ export class NotificationsListDelegate implements IListVirtualDelegate { - const action = notification.actions.primary![index]; + const action = primaryActions[index]; button.label = action.label; this.inputDisposables.add(button.onDidClick(e => { diff --git a/src/vs/workbench/common/contributions.ts b/src/vs/workbench/common/contributions.ts index cc28bacaf7c..0f5d7b038ca 100644 --- a/src/vs/workbench/common/contributions.ts +++ b/src/vs/workbench/common/contributions.ts @@ -38,8 +38,8 @@ export interface IWorkbenchContributionsRegistry { } class WorkbenchContributionsRegistry implements IWorkbenchContributionsRegistry { - private instantiationService: IInstantiationService; - private lifecycleService: ILifecycleService; + private instantiationService: IInstantiationService | undefined; + private lifecycleService: ILifecycleService | undefined; private readonly toBeInstantiated: Map[]> = new Map[]>(); @@ -67,7 +67,7 @@ class WorkbenchContributionsRegistry implements IWorkbenchContributionsRegistry this.lifecycleService = accessor.get(ILifecycleService); [LifecyclePhase.Starting, LifecyclePhase.Ready, LifecyclePhase.Restored, LifecyclePhase.Eventually].forEach(phase => { - this.instantiateByPhase(this.instantiationService, this.lifecycleService, phase); + this.instantiateByPhase(this.instantiationService!, this.lifecycleService!, phase); }); } diff --git a/src/vs/workbench/common/editor/textEditorModel.ts b/src/vs/workbench/common/editor/textEditorModel.ts index 239fd95cc28..da75c1b3e9c 100644 --- a/src/vs/workbench/common/editor/textEditorModel.ts +++ b/src/vs/workbench/common/editor/textEditorModel.ts @@ -17,8 +17,8 @@ import { withUndefinedAsNull } from 'vs/base/common/types'; * The base text editor model leverages the code editor model. This class is only intended to be subclassed and not instantiated. */ export abstract class BaseTextEditorModel extends EditorModel implements ITextEditorModel, IModeSupport { - protected textEditorModelHandle: URI | null; - private createdEditorModel: boolean; + protected textEditorModelHandle: URI | null = null; + private createdEditorModel: boolean | undefined; private readonly modelDisposeListener = this._register(new MutableDisposable()); diff --git a/src/vs/workbench/common/notifications.ts b/src/vs/workbench/common/notifications.ts index b83f9599436..9546898f8c9 100644 --- a/src/vs/workbench/common/notifications.ts +++ b/src/vs/workbench/common/notifications.ts @@ -243,7 +243,7 @@ export interface INotificationViewItem { readonly silent: boolean; readonly message: INotificationMessage; readonly source: string | undefined; - readonly actions: INotificationActions; + readonly actions: INotificationActions | undefined; readonly progress: INotificationViewItemProgress; readonly expanded: boolean; @@ -391,10 +391,10 @@ export class NotificationViewItem extends Disposable implements INotificationVie // RegEx: [, anything not ], ], (, http://|https://|command:, no whitespace) private static LINK_REGEX = /\[([^\]]+)\]\(((?:https?:\/\/|command:)[^\)\s]+)(?: "([^"]+)")?\)/gi; - private _expanded: boolean; + private _expanded: boolean | undefined; - private _actions: INotificationActions; - private _progress: NotificationViewItemProgress; + private _actions: INotificationActions | undefined; + private _progress: NotificationViewItemProgress | undefined; private readonly _onDidExpansionChange: Emitter = this._register(new Emitter()); readonly onDidExpansionChange: Event = this._onDidExpansionChange.event; @@ -505,7 +505,7 @@ export class NotificationViewItem extends Disposable implements INotificationVie } get expanded(): boolean { - return this._expanded; + return !!this._expanded; } get severity(): Severity { @@ -534,6 +534,10 @@ export class NotificationViewItem extends Disposable implements INotificationVie } hasPrompt(): boolean { + if (!this._actions) { + return false; + } + if (!this._actions.primary) { return false; } @@ -562,7 +566,7 @@ export class NotificationViewItem extends Disposable implements INotificationVie return this._source; } - get actions(): INotificationActions { + get actions(): INotificationActions | undefined { return this._actions; } @@ -635,8 +639,8 @@ export class NotificationViewItem extends Disposable implements INotificationVie return false; } - const primaryActions = this._actions.primary || []; - const otherPrimaryActions = other.actions.primary || []; + const primaryActions = (this._actions && this._actions.primary) || []; + const otherPrimaryActions = (other.actions && other.actions.primary) || []; if (primaryActions.length !== otherPrimaryActions.length) { return false; } @@ -704,4 +708,4 @@ class StatusMessageViewItem { return { message, options }; } -} \ No newline at end of file +} diff --git a/src/vs/workbench/contrib/feedback/browser/feedback.ts b/src/vs/workbench/contrib/feedback/browser/feedback.ts index 9cebd7fe920..618dc7edaa9 100644 --- a/src/vs/workbench/contrib/feedback/browser/feedback.ts +++ b/src/vs/workbench/contrib/feedback/browser/feedback.ts @@ -46,13 +46,13 @@ export class FeedbackDropdown extends Dropdown { private readonly feedbackDelegate: IFeedbackDelegate; - private feedbackForm: HTMLFormElement | null; - private feedbackDescriptionInput: HTMLTextAreaElement | null; - private smileyInput: HTMLElement | null; - private frownyInput: HTMLElement | null; - private sendButton: Button; - private hideButton: HTMLInputElement; - private remainingCharacterCount: HTMLElement; + private feedbackForm: HTMLFormElement | null = null; + private feedbackDescriptionInput: HTMLTextAreaElement | null = null; + private smileyInput: HTMLElement | null = null; + private frownyInput: HTMLElement | null = null; + private sendButton: Button | null = null; + private hideButton: HTMLInputElement | null = null; + private remainingCharacterCount: HTMLElement | null = null; private requestFeatureLink: string | undefined; @@ -253,7 +253,7 @@ export class FeedbackDropdown extends Dropdown { // Checkbox: Hide Feedback Smiley const hideButtonContainer = dom.append(buttonsContainer, dom.$('div.hide-button-container')); - this.hideButton = dom.append(hideButtonContainer, dom.$('input.hide-button')); + this.hideButton = dom.append(hideButtonContainer, dom.$('input.hide-button')) as HTMLInputElement; this.hideButton.type = 'checkbox'; this.hideButton.checked = true; this.hideButton.id = 'hide-button'; @@ -316,7 +316,7 @@ export class FeedbackDropdown extends Dropdown { } private updateCharCountText(): void { - if (this.feedbackDescriptionInput) { + if (this.feedbackDescriptionInput && this.remainingCharacterCount && this.sendButton) { this.remainingCharacterCount.innerText = this.getCharCountText(this.feedbackDescriptionInput.value.length); this.sendButton.enabled = this.feedbackDescriptionInput.value.length > 0; } @@ -434,4 +434,4 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => { if (linkColor) { collector.addRule(`.monaco-workbench .feedback-form .content .channels a { color: ${linkColor}; }`); } -}); \ No newline at end of file +}); diff --git a/src/vs/workbench/contrib/feedback/browser/feedbackStatusbarItem.ts b/src/vs/workbench/contrib/feedback/browser/feedbackStatusbarItem.ts index 43d18373cc3..c609aa4132f 100644 --- a/src/vs/workbench/contrib/feedback/browser/feedbackStatusbarItem.ts +++ b/src/vs/workbench/contrib/feedback/browser/feedbackStatusbarItem.ts @@ -47,8 +47,8 @@ class TwitterFeedbackService implements IFeedbackDelegate { } export class FeedbackStatusbarConribution extends Disposable implements IWorkbenchContribution { - private dropdown: FeedbackDropdown; - private entry: IStatusbarEntryAccessor; + private dropdown: FeedbackDropdown | undefined; + private entry: IStatusbarEntryAccessor | undefined; constructor( @IStatusbarService statusbarService: IStatusbarService, @@ -72,15 +72,17 @@ export class FeedbackStatusbarConribution extends Disposable implements IWorkben this.dropdown = this._register(this.instantiationService.createInstance(FeedbackDropdown, statusContainr.getElementsByClassName('octicon').item(0), { contextViewProvider: this.contextViewService, feedbackService: this.instantiationService.createInstance(TwitterFeedbackService), - onFeedbackVisibilityChange: visible => this.entry.update(this.getStatusEntry(visible)) + onFeedbackVisibilityChange: visible => this.entry!.update(this.getStatusEntry(visible)) })); } } - if (!this.dropdown.isVisible()) { - this.dropdown.show(); - } else { - this.dropdown.hide(); + if (this.dropdown) { + if (!this.dropdown.isVisible()) { + this.dropdown.show(); + } else { + this.dropdown.hide(); + } } } @@ -92,4 +94,4 @@ export class FeedbackStatusbarConribution extends Disposable implements IWorkben }; } -} \ No newline at end of file +} diff --git a/src/vs/workbench/services/configuration/common/configurationEditingService.ts b/src/vs/workbench/services/configuration/common/configurationEditingService.ts index ffef24c5573..90b8895fc96 100644 --- a/src/vs/workbench/services/configuration/common/configurationEditingService.ts +++ b/src/vs/workbench/services/configuration/common/configurationEditingService.ts @@ -133,7 +133,7 @@ export class ConfigurationEditingService { public _serviceBrand: any; private queue: Queue; - private remoteSettingsResource: URI | null; + private remoteSettingsResource: URI | null = null; constructor( @IConfigurationService private readonly configurationService: IConfigurationService, diff --git a/src/vs/workbench/services/output/node/outputChannelModelService.ts b/src/vs/workbench/services/output/node/outputChannelModelService.ts index da44834ef94..e841597dcac 100644 --- a/src/vs/workbench/services/output/node/outputChannelModelService.ts +++ b/src/vs/workbench/services/output/node/outputChannelModelService.ts @@ -213,7 +213,7 @@ export class OutputChannelModelService extends AsbtractOutputChannelModelService this.instantiationService.createInstance(DelegatedOutputChannelModel, id, modelUri, mimeType, this.outputDir); } - private _outputDir: Promise | null; + private _outputDir: Promise | null = null; private get outputDir(): Promise { if (!this._outputDir) { const outputDir = URI.file(join(this.environmentService.logsPath, `output_${this.environmentService.configuration.windowId}_${toLocalISOString(new Date()).replace(/-|:|\.\d+Z$/g, '')}`)); diff --git a/src/vs/workbench/services/search/common/searchService.ts b/src/vs/workbench/services/search/common/searchService.ts index 53a81175157..8325ceb8317 100644 --- a/src/vs/workbench/services/search/common/searchService.ts +++ b/src/vs/workbench/services/search/common/searchService.ts @@ -21,9 +21,11 @@ import { deserializeSearchError, FileMatch, ICachedSearchStats, IFileMatch, IFil import { addContextToEditorMatches, editorMatchesToTextSearchResults } from 'vs/workbench/services/search/common/searchHelpers'; import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; export class SearchService extends Disposable implements ISearchService { - _serviceBrand: any; + + _serviceBrand!: ServiceIdentifier; protected diskSearch: ISearchResultProvider; private readonly fileSearchProviders = new Map(); diff --git a/src/vs/workbench/test/common/notifications.test.ts b/src/vs/workbench/test/common/notifications.test.ts index 30312d509e3..4c81c67b61a 100644 --- a/src/vs/workbench/test/common/notifications.test.ts +++ b/src/vs/workbench/test/common/notifications.test.ts @@ -103,7 +103,7 @@ suite('Notifications', () => { // Error with Action let item6 = NotificationViewItem.create({ severity: Severity.Error, message: createErrorWithActions('Hello Error', { actions: [new Action('id', 'label')] }) })!; - assert.equal(item6.actions.primary!.length, 1); + assert.equal(item6.actions!.primary!.length, 1); // Links let item7 = NotificationViewItem.create({ severity: Severity.Info, message: 'Unable to [Link 1](http://link1.com) open [Link 2](command:open.me "Open This") and [Link 3](command:without.title) and [Invalid Link4](ftp://link4.com)' })!; @@ -219,4 +219,4 @@ suite('Notifications', () => { disposable3.dispose(); assert.ok(!model.statusMessage); }); -}); \ No newline at end of file +}); From 244789293fd4710331c18576318981ef12acf010 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 7 Aug 2019 12:31:57 +0200 Subject: [PATCH 291/861] you are not the chosen one --- .../platform/environment/test/node/environmentService.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/environment/test/node/environmentService.test.ts b/src/vs/platform/environment/test/node/environmentService.test.ts index 8a69fb2d740..39d83f414b3 100644 --- a/src/vs/platform/environment/test/node/environmentService.test.ts +++ b/src/vs/platform/environment/test/node/environmentService.test.ts @@ -54,7 +54,7 @@ suite('EnvironmentService', () => { }); // https://github.com/microsoft/vscode/issues/78440 - test.only('careful with boolean file names', function () { + test('careful with boolean file names', function () { let actual = parseArgs(['-r', 'arg.txt']); assert(actual['reuse-window']); assert.deepEqual(actual._, ['arg.txt']); From b0fc3e69904e2163a24f95f4501c1fa11f2d8564 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 7 Aug 2019 12:51:56 +0200 Subject: [PATCH 292/861] use vscode-minimist in remote --- remote/package.json | 2 +- remote/yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/remote/package.json b/remote/package.json index 5f851213c9d..b3159ed308e 100644 --- a/remote/package.json +++ b/remote/package.json @@ -9,7 +9,6 @@ "https-proxy-agent": "^2.2.1", "iconv-lite": "0.5.0", "jschardet": "1.6.0", - "minimist": "1.2.0", "native-watchdog": "1.0.0", "node-pty": "0.9.0-beta19", "nsfw": "1.2.5", @@ -17,6 +16,7 @@ "semver-umd": "^5.5.3", "spdlog": "^0.9.0", "vscode-chokidar": "2.1.7", + "vscode-minimist": "^1.2.1", "vscode-proxy-agent": "0.4.0", "vscode-ripgrep": "^1.5.5", "vscode-textmate": "^4.2.2", diff --git a/remote/yarn.lock b/remote/yarn.lock index 019b237911f..04ebe491f01 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -660,11 +660,6 @@ minimist@0.0.8: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= -minimist@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - mixin-deep@^1.2.0: version "1.3.2" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" @@ -1113,6 +1108,11 @@ vscode-fsevents@1.2.12: dependencies: nan "^2.14.0" +vscode-minimist@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/vscode-minimist/-/vscode-minimist-1.2.1.tgz#e63d3f4a9bf3680dcb8f9304eed612323fd6926a" + integrity sha512-cmB72+qDoiCFJ1UKnGUBdGYfXzdpJ3bQM/D/+XhkVk5v7uZgLbYiCz5JcwVyk7NC7hSi5VGtQ4wihzmi12NeXw== + vscode-proxy-agent@0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/vscode-proxy-agent/-/vscode-proxy-agent-0.4.0.tgz#574833e65405c6333f350f1b9fef9909deccb6b5" From ca6f0a795cfb870aa97aeb9cd87748b4bba174c8 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 7 Aug 2019 12:53:27 +0200 Subject: [PATCH 293/861] distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 02390ee4179..92120342a16 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "4694b56986953df2562df7cc65b4d7806e46c138", + "distro": "1413fa0e8982b468bc452d742bbd60c36b0cb45e", "author": { "name": "Microsoft Corporation" }, From c9066d26cd90380646297eebc4eb35cb652cc223 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 7 Aug 2019 14:34:26 +0200 Subject: [PATCH 294/861] Fixes #75704: Stop rendering indent guides after the wrapping column --- .../browser/viewParts/indentGuides/indentGuides.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/browser/viewParts/indentGuides/indentGuides.ts b/src/vs/editor/browser/viewParts/indentGuides/indentGuides.ts index 323a8097cec..ea713746e0d 100644 --- a/src/vs/editor/browser/viewParts/indentGuides/indentGuides.ts +++ b/src/vs/editor/browser/viewParts/indentGuides/indentGuides.ts @@ -21,6 +21,7 @@ export class IndentGuidesOverlay extends DynamicViewOverlay { private _renderResult: string[] | null; private _enabled: boolean; private _activeIndentEnabled: boolean; + private _maxIndentLeft: number; constructor(context: ViewContext) { super(); @@ -30,6 +31,9 @@ export class IndentGuidesOverlay extends DynamicViewOverlay { this._spaceWidth = this._context.configuration.editor.fontInfo.spaceWidth; this._enabled = this._context.configuration.editor.viewInfo.renderIndentGuides; this._activeIndentEnabled = this._context.configuration.editor.viewInfo.highlightActiveIndentGuide; + const wrappingColumn = this._context.configuration.editor.wrappingInfo.wrappingColumn; + this._maxIndentLeft = wrappingColumn === -1 ? -1 : (wrappingColumn * this._context.configuration.editor.fontInfo.typicalHalfwidthCharacterWidth); + this._renderResult = null; this._context.addEventHandler(this); @@ -54,6 +58,10 @@ export class IndentGuidesOverlay extends DynamicViewOverlay { this._enabled = this._context.configuration.editor.viewInfo.renderIndentGuides; this._activeIndentEnabled = this._context.configuration.editor.viewInfo.highlightActiveIndentGuide; } + if (e.wrappingInfo || e.fontInfo) { + const wrappingColumn = this._context.configuration.editor.wrappingInfo.wrappingColumn; + this._maxIndentLeft = wrappingColumn === -1 ? -1 : (wrappingColumn * this._context.configuration.editor.fontInfo.typicalHalfwidthCharacterWidth); + } return true; } public onCursorStateChanged(e: viewEvents.ViewCursorStateChangedEvent): boolean { @@ -133,7 +141,7 @@ export class IndentGuidesOverlay extends DynamicViewOverlay { const className = (containsActiveIndentGuide && i === activeIndentLevel ? 'cigra' : 'cigr'); result += `
`; left += indentWidth; - if (left > scrollWidth) { + if (left > scrollWidth || (this._maxIndentLeft > 0 && left > this._maxIndentLeft)) { break; } } From 280be12a3a90f40949d345d94894d4af6b782c6d Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 7 Aug 2019 14:51:00 +0200 Subject: [PATCH 295/861] fix zsh completions --- resources/completions/zsh/_code | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/completions/zsh/_code b/resources/completions/zsh/_code index 4c069c40011..25dfe7ca984 100644 --- a/resources/completions/zsh/_code +++ b/resources/completions/zsh/_code @@ -14,7 +14,7 @@ arguments=( '--user-data-dir[specify the directory that user data is kept in]:directory:_directories' '(- *)'{-v,--version}'[print version]' '(- *)'{-h,--help}'[print usage]' - '(- *)'{--telemetry}'[Shows all telemetry events which VS code collects.]' + '--telemetry[show all telemetry events which VS code collects]' '--extensions-dir[set the root path for extensions]:root path:_directories' '--list-extensions[list the installed extensions]' '--category[filters instaled extension list by category, when using --list-extension]' From e0f41ea7c9df1c681b50ca94db71c53260b82ec3 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 7 Aug 2019 15:03:59 +0200 Subject: [PATCH 296/861] move the textarea with the cursor, workaround no longer needed fixes #7394 --- src/vs/editor/browser/controller/textAreaHandler.ts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/vs/editor/browser/controller/textAreaHandler.ts b/src/vs/editor/browser/controller/textAreaHandler.ts index f0358188c86..c1a41a4981f 100644 --- a/src/vs/editor/browser/controller/textAreaHandler.ts +++ b/src/vs/editor/browser/controller/textAreaHandler.ts @@ -446,14 +446,8 @@ export class TextAreaHandler extends ViewPart { private _primaryCursorVisibleRange: HorizontalRange | null = null; public prepareRender(ctx: RenderingContext): void { - if (this._accessibilitySupport === AccessibilitySupport.Enabled) { - // Do not move the textarea with the cursor, as this generates accessibility events that might confuse screen readers - // See https://github.com/Microsoft/vscode/issues/26730 - this._primaryCursorVisibleRange = null; - } else { - const primaryCursorPosition = new Position(this._selections[0].positionLineNumber, this._selections[0].positionColumn); - this._primaryCursorVisibleRange = ctx.visibleRangeForPosition(primaryCursorPosition); - } + const primaryCursorPosition = new Position(this._selections[0].positionLineNumber, this._selections[0].positionColumn); + this._primaryCursorVisibleRange = ctx.visibleRangeForPosition(primaryCursorPosition); } public render(ctx: RestrictedRenderingContext): void { From fa91dfbdad51e055387aae44ba6cc4851942d260 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 7 Aug 2019 15:21:22 +0200 Subject: [PATCH 297/861] :lipstick: screencast css --- .../browser/actions/developerActions.ts | 38 ++---------------- .../browser/actions/media/screencast.css | 39 +++++++++++++++++++ 2 files changed, 43 insertions(+), 34 deletions(-) create mode 100644 src/vs/workbench/browser/actions/media/screencast.css diff --git a/src/vs/workbench/browser/actions/developerActions.ts b/src/vs/workbench/browser/actions/developerActions.ts index 82eca471acc..59300a71c50 100644 --- a/src/vs/workbench/browser/actions/developerActions.ts +++ b/src/vs/workbench/browser/actions/developerActions.ts @@ -3,6 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import 'vs/css!./media/screencast'; + import { Action } from 'vs/base/common/actions'; import { IWindowService } from 'vs/platform/windows/common/windows'; import * as nls from 'vs/nls'; @@ -110,19 +112,7 @@ export class ToggleScreencastModeAction extends Action { const container = this.layoutService.getWorkbenchElement(); - const mouseMarker = append(container, $('div')); - mouseMarker.style.position = 'absolute'; - mouseMarker.style.border = '2px solid red'; - mouseMarker.style.borderRadius = '20px'; - mouseMarker.style.width = '20px'; - mouseMarker.style.height = '20px'; - mouseMarker.style.top = '0'; - mouseMarker.style.left = '0'; - mouseMarker.style.zIndex = '100000'; - mouseMarker.style.content = ' '; - mouseMarker.style.pointerEvents = 'none'; - mouseMarker.style.display = 'none'; - + const mouseMarker = append(container, $('.screencast-mouse')); const onMouseDown = domEvent(container, 'mousedown', true); const onMouseUp = domEvent(container, 'mouseup', true); const onMouseMove = domEvent(container, 'mousemove', true); @@ -143,25 +133,7 @@ export class ToggleScreencastModeAction extends Action { }); }); - const keyboardMarker = append(container, $('div')); - keyboardMarker.style.position = 'absolute'; - keyboardMarker.style.backgroundColor = 'rgba(0, 0, 0 ,0.5)'; - keyboardMarker.style.width = '100%'; - keyboardMarker.style.height = '100px'; - keyboardMarker.style.bottom = '20%'; - keyboardMarker.style.left = '0'; - keyboardMarker.style.zIndex = '100000'; - keyboardMarker.style.pointerEvents = 'none'; - keyboardMarker.style.color = 'white'; - keyboardMarker.style.lineHeight = '100px'; - keyboardMarker.style.textAlign = 'center'; - keyboardMarker.style.fontSize = '56px'; - keyboardMarker.style.overflow = 'hidden'; - keyboardMarker.style.transitionProperty = 'opacity'; - keyboardMarker.style.transitionDuration = '0.3s'; - keyboardMarker.style.transitionTimingFunction = 'ease-out'; - keyboardMarker.style.opacity = '0'; - + const keyboardMarker = append(container, $('.screencast-keyboard')); const onKeyDown = domEvent(container, 'keydown', true); let keyboardTimeout: IDisposable = Disposable.None; let length = 0; @@ -184,7 +156,6 @@ export class ToggleScreencastModeAction extends Action { length++; keyboardMarker.textContent! += label; - keyboardMarker.style.opacity = '1'; const promise = timeout(800); keyboardTimeout = toDisposable(() => promise.cancel()); @@ -192,7 +163,6 @@ export class ToggleScreencastModeAction extends Action { promise.then(() => { keyboardMarker.textContent = ''; length = 0; - keyboardMarker.style.opacity = '0'; }); }); diff --git a/src/vs/workbench/browser/actions/media/screencast.css b/src/vs/workbench/browser/actions/media/screencast.css new file mode 100644 index 00000000000..6ef46acb284 --- /dev/null +++ b/src/vs/workbench/browser/actions/media/screencast.css @@ -0,0 +1,39 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +.vs .monaco-workbench .screencast-mouse { + position: absolute; + border: 2px solid red; + border-radius: 20px; + width: 20px; + height: 20px; + top: 0; + left: 0; + z-index: 100000; + content: ' '; + pointer-events: none; + display: none; +} + +.vs .monaco-workbench .screencast-keyboard { + position: absolute; + background-color: rgba(0, 0, 0 ,0.5); + width: 100%; + height: 100px; + bottom: 20%; + left: 0; + z-index: 100000; + pointer-events: none; + color: white; + line-height: 100px; + text-align: center; + font-size: 56px; + overflow: hidden; + transition: opacity 0.3s ease-out; +} + +.vs .monaco-workbench .screencast-keyboard:empty { + opacity: 0; +} From ebe2aeef8ff98a3b5e592eaddec0af0222c3af7c Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 7 Aug 2019 15:22:30 +0200 Subject: [PATCH 298/861] fix #78500 --- .../backup/common/backupFileService.ts | 15 ++++++++---- .../test/node/backupFileService.test.ts | 23 +++++++++++++++++++ .../textfile/common/textFileEditorModel.ts | 2 +- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/services/backup/common/backupFileService.ts b/src/vs/workbench/services/backup/common/backupFileService.ts index 65af4c1ee30..6725c5e2bb9 100644 --- a/src/vs/workbench/services/backup/common/backupFileService.ts +++ b/src/vs/workbench/services/backup/common/backupFileService.ts @@ -334,7 +334,7 @@ class BackupFileServiceImpl implements IBackupFileService { return contents.substr(0, newLineIndex); } - throw new Error(`Could not find ${JSON.stringify(matchingString)} in first ${maximumBytesToRead} bytes of ${file}`); + throw new Error(`Backup: Could not find ${JSON.stringify(matchingString)} in first ${maximumBytesToRead} bytes of ${file}`); } async resolveBackupContent(backup: URI): Promise> { @@ -368,9 +368,7 @@ class BackupFileServiceImpl implements IBackupFileService { const content = await this.fileService.readFileStream(backup); const factory = await createTextBufferFactoryFromStream(content.value, metaPreambleFilter); - // Trigger read for meta data extraction from the filter above - factory.getFirstLineText(1); - + // Extract meta data (if any) let meta: T | undefined; const metaStartIndex = metaRaw.indexOf(BackupFileServiceImpl.PREAMBLE_META_SEPARATOR); if (metaStartIndex !== -1) { @@ -381,6 +379,15 @@ class BackupFileServiceImpl implements IBackupFileService { } } + // We have seen reports (e.g. https://github.com/microsoft/vscode/issues/78500) where + // if VSCode goes down while writing the backup file, the file can turn empty because + // it always first gets truncated and then written to. In this case, we will not find + // the meta-end marker ('\n') and as such the backup can only be invalid. We bail out + // here if that is the case. + if (!metaEndFound) { + throw new Error(`Backup: Could not find meta end marker in ${backup}. The file is probably corrupt.`); + } + return { value: factory, meta }; } diff --git a/src/vs/workbench/services/backup/test/node/backupFileService.test.ts b/src/vs/workbench/services/backup/test/node/backupFileService.test.ts index 990d688b3cc..b4f37b1b276 100644 --- a/src/vs/workbench/services/backup/test/node/backupFileService.test.ts +++ b/src/vs/workbench/services/backup/test/node/backupFileService.test.ts @@ -27,6 +27,7 @@ import { IFileService } from 'vs/platform/files/common/files'; import { hashPath, BackupFileService } from 'vs/workbench/services/backup/node/backupFileService'; import { BACKUPS } from 'vs/platform/environment/common/environment'; import { FileUserDataProvider } from 'vs/workbench/services/userData/common/fileUserDataProvider'; +import { VSBuffer } from 'vs/base/common/buffer'; const userdataDir = getRandomTestPath(os.tmpdir(), 'vsctests', 'backupfileservice'); const appSettingsHome = path.join(userdataDir, 'User'); @@ -479,6 +480,28 @@ suite('BackupFileService', () => { await testResolveBackup(fooBarFile, contents, meta, null); }); + test('should throw an error when restoring invalid backup', async () => { + const contents = 'test\nand more stuff'; + + await service.backupResource(fooBarFile, createTextBufferFactory(contents).create(DefaultEndOfLine.LF).createSnapshot(false), 1); + + const backup = await service.loadBackupResource(fooBarFile); + if (!backup) { + throw new Error('Unexpected missing backup'); + } + + await service.fileService.writeFile(backup, VSBuffer.fromString('')); + + let err: Error; + try { + await service.resolveBackupContent(backup); + } catch (error) { + err = error; + } + + assert.ok(err!); + }); + async function testResolveBackup(resource: URI, contents: string, meta?: IBackupTestMetaData, expectedMeta?: IBackupTestMetaData | null) { if (typeof expectedMeta === 'undefined') { expectedMeta = meta; diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index 819e2a1fc08..3ece543b7d3 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -308,7 +308,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil try { return await this.loadFromBackup(backup, options); } catch (error) { - // ignore error and continue to load as file below + this.logService.error(error); // ignore error and continue to load as file below } } } From 3a85597845d0f5a48505a5d19a9829f2bada47d0 Mon Sep 17 00:00:00 2001 From: Christopher Strack Date: Wed, 7 Aug 2019 15:23:11 +0200 Subject: [PATCH 299/861] Normalize paths when matching problems (#77875) Fixes #77804 --- src/vs/workbench/contrib/tasks/common/problemMatcher.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/tasks/common/problemMatcher.ts b/src/vs/workbench/contrib/tasks/common/problemMatcher.ts index 1c4f457c5b9..18b98f751f0 100644 --- a/src/vs/workbench/contrib/tasks/common/problemMatcher.ts +++ b/src/vs/workbench/contrib/tasks/common/problemMatcher.ts @@ -8,7 +8,7 @@ import { localize } from 'vs/nls'; import * as Objects from 'vs/base/common/objects'; import * as Strings from 'vs/base/common/strings'; import * as Assert from 'vs/base/common/assert'; -import { join } from 'vs/base/common/path'; +import { join, normalize } from 'vs/base/common/path'; import * as Types from 'vs/base/common/types'; import * as UUID from 'vs/base/common/uuid'; import * as Platform from 'vs/base/common/platform'; @@ -220,6 +220,7 @@ export async function getResource(filename: string, matcher: ProblemMatcher, fil if (fullPath[0] !== '/') { fullPath = '/' + fullPath; } + fullPath = normalize(fullPath); if (matcher.uriProvider !== undefined) { return matcher.uriProvider(fullPath); } else { From 977a82fba3f30bf9b5516d28f6a083902707b9fa Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 7 Aug 2019 06:50:46 -0700 Subject: [PATCH 300/861] Disable terminal tests that depend on terminal being hidden or shown in the past --- .../src/singlefolder-tests/terminal.test.ts | 92 +++++++++---------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts index b008ecb1b0e..5291e7ab716 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts @@ -274,52 +274,52 @@ suite('window namespace tests', () => { const terminal = window.createTerminal({ name: 'foo', pty }); }); - test('should not provide dimensions on start as the terminal has not been shown yet', (done) => { - const reg1 = window.onDidOpenTerminal(term => { - equal(terminal, term); - reg1.dispose(); - }); - const pty: Pseudoterminal = { - onDidWrite: new EventEmitter().event, - open: (dimensions) => { - equal(dimensions, undefined); - const reg3 = window.onDidCloseTerminal(() => { - reg3.dispose(); - done(); - }); - // Show a terminal and wait a brief period before dispose, this will cause - // the panel to init it's dimenisons and be provided to following terminals. - // The following test depends on this. - terminal.show(); - setTimeout(() => terminal.dispose(), 200); - }, - close: () => {} - }; - const terminal = window.createTerminal({ name: 'foo', pty }); - }); - - test('should provide dimensions on start as the terminal has been shown', (done) => { - const reg1 = window.onDidOpenTerminal(term => { - equal(terminal, term); - reg1.dispose(); - }); - const pty: Pseudoterminal = { - onDidWrite: new EventEmitter().event, - open: (dimensions) => { - // This test depends on Terminal.show being called some time before such - // that the panel dimensions are initialized and cached. - ok(dimensions!.columns > 0); - ok(dimensions!.rows > 0); - const reg3 = window.onDidCloseTerminal(() => { - reg3.dispose(); - done(); - }); - terminal.dispose(); - }, - close: () => {} - }; - const terminal = window.createTerminal({ name: 'foo', pty }); - }); + // The below tests depend on global UI state and each other + // test('should not provide dimensions on start as the terminal has not been shown yet', (done) => { + // const reg1 = window.onDidOpenTerminal(term => { + // equal(terminal, term); + // reg1.dispose(); + // }); + // const pty: Pseudoterminal = { + // onDidWrite: new EventEmitter().event, + // open: (dimensions) => { + // equal(dimensions, undefined); + // const reg3 = window.onDidCloseTerminal(() => { + // reg3.dispose(); + // done(); + // }); + // // Show a terminal and wait a brief period before dispose, this will cause + // // the panel to init it's dimenisons and be provided to following terminals. + // // The following test depends on this. + // terminal.show(); + // setTimeout(() => terminal.dispose(), 200); + // }, + // close: () => {} + // }; + // const terminal = window.createTerminal({ name: 'foo', pty }); + // }); + // test('should provide dimensions on start as the terminal has been shown', (done) => { + // const reg1 = window.onDidOpenTerminal(term => { + // equal(terminal, term); + // reg1.dispose(); + // }); + // const pty: Pseudoterminal = { + // onDidWrite: new EventEmitter().event, + // open: (dimensions) => { + // // This test depends on Terminal.show being called some time before such + // // that the panel dimensions are initialized and cached. + // ok(dimensions!.columns > 0); + // ok(dimensions!.rows > 0); + // const reg3 = window.onDidCloseTerminal(() => { + // reg3.dispose(); + // done(); + // }); + // terminal.dispose(); + // }, + // close: () => {} + // }; + // const terminal = window.createTerminal({ name: 'foo', pty }); + // }); test('should respect dimension overrides', (done) => { const reg1 = window.onDidOpenTerminal(term => { From ebd96071d1b4182e29036f9d30c120a43cef720d Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 7 Aug 2019 16:11:00 +0200 Subject: [PATCH 301/861] make extHost-things services, setup injector --- .../workbench/api/common/extHostCommands.ts | 15 +++- .../api/common/extHostConfiguration.ts | 18 +++- .../api/common/extHostContextService.ts | 24 +++++ .../api/common/extHostDecorations.ts | 16 +++- .../api/common/extHostDocumentsAndEditors.ts | 15 +++- src/vs/workbench/api/common/extHostOutput.ts | 88 +++++++++---------- .../api/common/extHostTerminalService.ts | 30 +++++++ .../workbench/api/common/extHostWorkspace.ts | 23 +++-- src/vs/workbench/api/node/extHost.api.impl.ts | 31 +++---- src/vs/workbench/api/node/extHost.services.ts | 24 +++++ .../api/node/extHostExtensionService.ts | 42 ++++----- .../api/node/extHostOutputService.ts | 34 ++++--- src/vs/workbench/api/node/extHostTask.ts | 6 +- .../api/node/extHostTerminalService.ts | 24 ++--- .../extensions/node/extensionHostMain.ts | 25 +++--- .../node/extensionHostProcessSetup.ts | 1 + .../api/extHostApiCommands.test.ts | 10 ++- .../api/extHostCommands.test.ts | 13 ++- .../api/extHostConfiguration.test.ts | 20 +++-- .../extHostDocumentSaveParticipant.test.ts | 6 +- .../api/extHostDocumentsAndEditors.test.ts | 13 ++- .../api/extHostLanguageFeatures.test.ts | 9 +- .../api/extHostTextEditors.test.ts | 6 +- .../api/extHostTreeViews.test.ts | 8 +- .../api/extHostWorkspace.test.ts | 8 +- 25 files changed, 338 insertions(+), 171 deletions(-) create mode 100644 src/vs/workbench/api/common/extHostContextService.ts create mode 100644 src/vs/workbench/api/common/extHostTerminalService.ts create mode 100644 src/vs/workbench/api/node/extHost.services.ts diff --git a/src/vs/workbench/api/common/extHostCommands.ts b/src/vs/workbench/api/common/extHostCommands.ts index 6576c56192b..3ab2fdbf2fc 100644 --- a/src/vs/workbench/api/common/extHostCommands.ts +++ b/src/vs/workbench/api/common/extHostCommands.ts @@ -8,7 +8,7 @@ import { ICommandHandlerDescription, ICommandEvent } from 'vs/platform/commands/ import * as extHostTypes from 'vs/workbench/api/common/extHostTypes'; import * as extHostTypeConverter from 'vs/workbench/api/common/extHostTypeConverters'; import { cloneAndChange } from 'vs/base/common/objects'; -import { MainContext, MainThreadCommandsShape, ExtHostCommandsShape, ObjectIdentifier, IMainContext, ICommandDto } from './extHost.protocol'; +import { MainContext, MainThreadCommandsShape, ExtHostCommandsShape, ObjectIdentifier, ICommandDto } from './extHost.protocol'; import { isNonEmptyArray } from 'vs/base/common/arrays'; import * as modes from 'vs/editor/common/modes'; import * as vscode from 'vscode'; @@ -19,6 +19,8 @@ import { Position } from 'vs/editor/common/core/position'; import { URI } from 'vs/base/common/uri'; import { Event, Emitter } from 'vs/base/common/event'; import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; +import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; interface CommandHandler { callback: Function; @@ -32,6 +34,8 @@ export interface ArgumentProcessor { export class ExtHostCommands implements ExtHostCommandsShape { + readonly _serviceBrand: any; + private readonly _onDidExecuteCommand: Emitter; readonly onDidExecuteCommand: Event; @@ -42,10 +46,10 @@ export class ExtHostCommands implements ExtHostCommandsShape { private readonly _argumentProcessors: ArgumentProcessor[]; constructor( - mainContext: IMainContext, - logService: ILogService + @IExtHostContextService extHostContext: IExtHostContextService, + @ILogService logService: ILogService ) { - this._proxy = mainContext.getProxy(MainContext.MainThreadCommands); + this._proxy = extHostContext.rpc.getProxy(MainContext.MainThreadCommands); this._onDidExecuteCommand = new Emitter({ onFirstListenerDidAdd: () => this._proxy.$registerCommandListener(), onLastListenerRemove: () => this._proxy.$unregisterCommandListener(), @@ -282,3 +286,6 @@ export class CommandsConverter { } } + +export interface IExtHostCommands extends ExtHostCommands { } +export const IExtHostCommands = createDecorator('IExtHostCommands'); diff --git a/src/vs/workbench/api/common/extHostConfiguration.ts b/src/vs/workbench/api/common/extHostConfiguration.ts index 4f19d1f59e4..32f8db76d64 100644 --- a/src/vs/workbench/api/common/extHostConfiguration.ts +++ b/src/vs/workbench/api/common/extHostConfiguration.ts @@ -7,8 +7,8 @@ import { mixin, deepClone } from 'vs/base/common/objects'; import { URI } from 'vs/base/common/uri'; import { Event, Emitter } from 'vs/base/common/event'; import * as vscode from 'vscode'; -import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; -import { ExtHostConfigurationShape, MainThreadConfigurationShape, IWorkspaceConfigurationChangeEventData, IConfigurationInitData } from './extHost.protocol'; +import { ExtHostWorkspace, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; +import { ExtHostConfigurationShape, MainThreadConfigurationShape, IWorkspaceConfigurationChangeEventData, IConfigurationInitData, MainContext } from './extHost.protocol'; import { ConfigurationTarget as ExtHostConfigurationTarget } from './extHostTypes'; import { IConfigurationData, ConfigurationTarget, IConfigurationModel } from 'vs/platform/configuration/common/configuration'; import { Configuration, ConfigurationChangeEvent, ConfigurationModel } from 'vs/platform/configuration/common/configurationModels'; @@ -18,6 +18,8 @@ import { ConfigurationScope, OVERRIDE_PROPERTY_PATTERN } from 'vs/platform/confi import { isObject } from 'vs/base/common/types'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { Barrier } from 'vs/base/common/async'; +import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; function lookUp(tree: any, key: string) { if (key) { @@ -40,13 +42,18 @@ type ConfigurationInspect = { export class ExtHostConfiguration implements ExtHostConfigurationShape { + readonly _serviceBrand: any; + private readonly _proxy: MainThreadConfigurationShape; private readonly _extHostWorkspace: ExtHostWorkspace; private readonly _barrier: Barrier; private _actual: ExtHostConfigProvider | null; - constructor(proxy: MainThreadConfigurationShape, extHostWorkspace: ExtHostWorkspace) { - this._proxy = proxy; + constructor( + @IExtHostContextService extHostContext: IExtHostContextService, + @IExtHostWorkspace extHostWorkspace: IExtHostWorkspace + ) { + this._proxy = extHostContext.rpc.getProxy(MainContext.MainThreadConfiguration); this._extHostWorkspace = extHostWorkspace; this._barrier = new Barrier(); this._actual = null; @@ -274,3 +281,6 @@ export class ExtHostConfigProvider { return new ConfigurationModel(model.contents, model.keys, model.overrides).freeze(); } } + +export const IExtHostConfiguration = createDecorator('IExtHostConfiguration'); +export interface IExtHostConfiguration extends ExtHostConfiguration { } diff --git a/src/vs/workbench/api/common/extHostContextService.ts b/src/vs/workbench/api/common/extHostContextService.ts new file mode 100644 index 00000000000..77094e73009 --- /dev/null +++ b/src/vs/workbench/api/common/extHostContextService.ts @@ -0,0 +1,24 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IMainContext, IInitData } from './extHost.protocol'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; + +export const IExtHostContextService = createDecorator('IExtHostContextService'); + +export interface IExtHostContextService { + _serviceBrand: undefined; + + readonly rpc: IMainContext; + readonly initData: IInitData; +} + +export class ExtHostContextService implements IExtHostContextService { + _serviceBrand: any; + constructor( + readonly rpc: IMainContext, + readonly initData: IInitData + ) { } +} diff --git a/src/vs/workbench/api/common/extHostDecorations.ts b/src/vs/workbench/api/common/extHostDecorations.ts index 0c176afc362..6d964143779 100644 --- a/src/vs/workbench/api/common/extHostDecorations.ts +++ b/src/vs/workbench/api/common/extHostDecorations.ts @@ -5,26 +5,31 @@ import * as vscode from 'vscode'; import { URI } from 'vs/base/common/uri'; -import { MainContext, IMainContext, ExtHostDecorationsShape, MainThreadDecorationsShape, DecorationData, DecorationRequest, DecorationReply } from 'vs/workbench/api/common/extHost.protocol'; +import { MainContext, ExtHostDecorationsShape, MainThreadDecorationsShape, DecorationData, DecorationRequest, DecorationReply } from 'vs/workbench/api/common/extHost.protocol'; import { Disposable } from 'vs/workbench/api/common/extHostTypes'; import { CancellationToken } from 'vs/base/common/cancellation'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { asArray } from 'vs/base/common/arrays'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; interface ProviderData { provider: vscode.DecorationProvider; extensionId: ExtensionIdentifier; } -export class ExtHostDecorations implements ExtHostDecorationsShape { +export class ExtHostDecorations implements IExtHostDecorations { private static _handlePool = 0; + readonly _serviceBrand: undefined; private readonly _provider = new Map(); private readonly _proxy: MainThreadDecorationsShape; - constructor(mainContext: IMainContext) { - this._proxy = mainContext.getProxy(MainContext.MainThreadDecorations); + constructor( + @IExtHostContextService contextService: IExtHostContextService, + ) { + this._proxy = contextService.rpc.getProxy(MainContext.MainThreadDecorations); } registerDecorationProvider(provider: vscode.DecorationProvider, extensionId: ExtensionIdentifier): vscode.Disposable { @@ -70,3 +75,6 @@ export class ExtHostDecorations implements ExtHostDecorationsShape { }); } } + +export const IExtHostDecorations = createDecorator('IExtHostDecorations'); +export interface IExtHostDecorations extends ExtHostDecorations, ExtHostDecorationsShape { } diff --git a/src/vs/workbench/api/common/extHostDocumentsAndEditors.ts b/src/vs/workbench/api/common/extHostDocumentsAndEditors.ts index 98002f78c71..0f31898cb3a 100644 --- a/src/vs/workbench/api/common/extHostDocumentsAndEditors.ts +++ b/src/vs/workbench/api/common/extHostDocumentsAndEditors.ts @@ -7,14 +7,18 @@ import * as assert from 'vs/base/common/assert'; import { Emitter, Event } from 'vs/base/common/event'; import { dispose } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; -import { ExtHostDocumentsAndEditorsShape, IDocumentsAndEditorsDelta, IMainContext, MainContext } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostDocumentsAndEditorsShape, IDocumentsAndEditorsDelta, MainContext } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostDocumentData } from 'vs/workbench/api/common/extHostDocumentData'; import { ExtHostTextEditor } from 'vs/workbench/api/common/extHostTextEditor'; import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters'; import { Disposable } from 'vs/workbench/api/common/extHostTypes'; +import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsShape { + readonly _serviceBrand: any; + private _disposables: Disposable[] = []; private _activeEditorId: string | null = null; @@ -33,7 +37,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha readonly onDidChangeActiveTextEditor: Event = this._onDidChangeActiveTextEditor.event; constructor( - private readonly _mainContext: IMainContext, + @IExtHostContextService private readonly _ctx: IExtHostContextService, ) { } dispose() { @@ -64,7 +68,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha assert.ok(!this._documents.has(resource.toString()), `document '${resource} already exists!'`); const documentData = new ExtHostDocumentData( - this._mainContext.getProxy(MainContext.MainThreadDocuments), + this._ctx.rpc.getProxy(MainContext.MainThreadDocuments), resource, data.lines, data.EOL, @@ -95,7 +99,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha const documentData = this._documents.get(resource.toString())!; const editor = new ExtHostTextEditor( - this._mainContext.getProxy(MainContext.MainThreadTextEditors), + this._ctx.rpc.getProxy(MainContext.MainThreadTextEditors), data.id, documentData, data.selections.map(typeConverters.Selection.to), @@ -159,3 +163,6 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha return result; } } + +export interface IExtHostDocumentsAndEditors extends ExtHostDocumentsAndEditors { } +export const IExtHostDocumentsAndEditors = createDecorator('IExtHostDocumentsAndEditors'); diff --git a/src/vs/workbench/api/common/extHostOutput.ts b/src/vs/workbench/api/common/extHostOutput.ts index 3580d0e6679..91466ccaf92 100644 --- a/src/vs/workbench/api/common/extHostOutput.ts +++ b/src/vs/workbench/api/common/extHostOutput.ts @@ -3,12 +3,14 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { MainContext, MainThreadOutputServiceShape, IMainContext, ExtHostOutputServiceShape } from './extHost.protocol'; +import { MainContext, MainThreadOutputServiceShape, ExtHostOutputServiceShape } from './extHost.protocol'; import * as vscode from 'vscode'; import { URI } from 'vs/base/common/uri'; import { Event, Emitter } from 'vs/base/common/event'; -import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { VSBuffer } from 'vs/base/common/buffer'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; export abstract class AbstractExtHostOutputChannel extends Disposable implements vscode.OutputChannel { @@ -106,38 +108,50 @@ class ExtHostLogFileOutputChannel extends AbstractExtHostOutputChannel { } } -export interface IOutputChannelFactory { - createOutputChannel(name: string, logsLocation: URI, proxy: MainThreadOutputServiceShape): Promise; -} +export class LazyOutputChannel implements vscode.OutputChannel { -export const PushOutputChannelFactory = new class implements IOutputChannelFactory { - async createOutputChannel(name: string, _logsLocation: URI, proxy: MainThreadOutputServiceShape): Promise { - return new ExtHostPushOutputChannel(name, proxy); + constructor( + readonly name: string, + private readonly _channel: Promise + ) { } + + append(value: string): void { + this._channel.then(channel => channel.append(value)); } -}; + appendLine(value: string): void { + this._channel.then(channel => channel.appendLine(value)); + } + clear(): void { + this._channel.then(channel => channel.clear()); + } + show(columnOrPreserveFocus?: vscode.ViewColumn | boolean, preserveFocus?: boolean): void { + this._channel.then(channel => channel.show(columnOrPreserveFocus, preserveFocus)); + } + hide(): void { + this._channel.then(channel => channel.hide()); + } + dispose(): void { + this._channel.then(channel => channel.dispose()); + } +} export class ExtHostOutputService implements ExtHostOutputServiceShape { - private readonly _factory: IOutputChannelFactory; - private readonly _logsLocation: URI; - private readonly _proxy: MainThreadOutputServiceShape; - private readonly _channels: Map = new Map(); - private _visibleChannelDisposable?: IDisposable; + readonly _serviceBrand: any; - constructor(factory: IOutputChannelFactory, logsLocation: URI, mainContext: IMainContext) { - this._factory = factory; - this._logsLocation = logsLocation; - this._proxy = mainContext.getProxy(MainContext.MainThreadOutputService); + protected readonly _proxy: MainThreadOutputServiceShape; + protected readonly _channels: Map = new Map(); + protected readonly _visibleChannelDisposable = new MutableDisposable(); + + constructor(@IExtHostContextService extHostContext: IExtHostContextService) { + this._proxy = extHostContext.rpc.getProxy(MainContext.MainThreadOutputService); } $setVisibleChannel(channelId: string): void { - if (this._visibleChannelDisposable) { - this._visibleChannelDisposable = dispose(this._visibleChannelDisposable); - } if (channelId) { const channel = this._channels.get(channelId); if (channel) { - this._visibleChannelDisposable = channel.onDidAppend(() => channel.update()); + this._visibleChannelDisposable.value = channel.onDidAppend(() => channel.update()); } } } @@ -146,33 +160,8 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape { name = name.trim(); if (!name) { throw new Error('illegal argument `name`. must not be falsy'); - } else { - const extHostOutputChannel = this._factory.createOutputChannel(name, this._logsLocation, this._proxy); - extHostOutputChannel.then(channel => channel._id.then(id => this._channels.set(id, channel))); - return { - get name(): string { - return name; - }, - append(value: string): void { - extHostOutputChannel.then(channel => channel.append(value)); - }, - appendLine(value: string): void { - extHostOutputChannel.then(channel => channel.appendLine(value)); - }, - clear(): void { - extHostOutputChannel.then(channel => channel.clear()); - }, - show(columnOrPreserveFocus?: vscode.ViewColumn | boolean, preserveFocus?: boolean): void { - extHostOutputChannel.then(channel => channel.show(columnOrPreserveFocus, preserveFocus)); - }, - hide(): void { - extHostOutputChannel.then(channel => channel.hide()); - }, - dispose(): void { - extHostOutputChannel.then(channel => channel.dispose()); - } - }; } + return new ExtHostPushOutputChannel(name, this._proxy); } createOutputChannelFromLogFile(name: string, file: URI): vscode.OutputChannel { @@ -186,3 +175,6 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape { return new ExtHostLogFileOutputChannel(name, file, this._proxy); } } + +export interface IExtHostOutputService extends ExtHostOutputService { } +export const IExtHostOutputService = createDecorator('IExtHostOutputService'); diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts new file mode 100644 index 00000000000..9a0552a89ba --- /dev/null +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -0,0 +1,30 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; +import { Event } from 'vs/base/common/event'; +import { ExtHostTerminalServiceShape } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; + +export interface IExtHostTerminalService extends ExtHostTerminalServiceShape { + + activeTerminal: vscode.Terminal | undefined; + terminals: vscode.Terminal[]; + + onDidCloseTerminal: Event; + onDidOpenTerminal: Event; + onDidChangeActiveTerminal: Event; + onDidChangeTerminalDimensions: Event; + onDidWriteTerminalData: Event; + + createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal; + createTerminalFromOptions(options: vscode.TerminalOptions): vscode.Terminal; + createExtensionTerminal(options: vscode.ExtensionTerminalOptions): vscode.Terminal; + attachPtyToTerminal(id: number, pty: vscode.Pseudoterminal): void; + getDefaultShell(configProvider: ExtHostConfigProvider): string; +} + +export const IExtHostTerminalService = createDecorator('IExtHostTerminalService'); diff --git a/src/vs/workbench/api/common/extHostWorkspace.ts b/src/vs/workbench/api/common/extHostWorkspace.ts index 3c176107270..fa066e18686 100644 --- a/src/vs/workbench/api/common/extHostWorkspace.ts +++ b/src/vs/workbench/api/common/extHostWorkspace.ts @@ -20,11 +20,13 @@ import { Workspace, WorkspaceFolder } from 'vs/platform/workspace/common/workspa import { Range, RelativePattern } from 'vs/workbench/api/common/extHostTypes'; import { ITextQueryBuilderOptions } from 'vs/workbench/contrib/search/common/queryBuilder'; import * as vscode from 'vscode'; -import { ExtHostWorkspaceShape, IWorkspaceData, MainThreadMessageServiceShape, MainThreadWorkspaceShape, IMainContext, MainContext, IStaticWorkspaceData } from './extHost.protocol'; +import { ExtHostWorkspaceShape, IWorkspaceData, MainThreadMessageServiceShape, MainThreadWorkspaceShape, MainContext } from './extHost.protocol'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { Barrier } from 'vs/base/common/async'; import { Schemas } from 'vs/base/common/network'; import { withUndefinedAsNull } from 'vs/base/common/types'; +import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; export interface IExtHostWorkspaceProvider { getWorkspaceFolder2(uri: vscode.Uri, resolveParent?: boolean): Promise; @@ -153,6 +155,8 @@ class ExtHostWorkspaceImpl extends Workspace { export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspaceProvider { + readonly _serviceBrand: any; + private readonly _onDidChangeWorkspace = new Emitter(); readonly onDidChangeWorkspace: Event = this._onDidChangeWorkspace.event; @@ -169,20 +173,20 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac private readonly _activeSearchCallbacks: ((match: IRawFileMatch2) => any)[] = []; constructor( - mainContext: IMainContext, - logService: ILogService, - data?: IStaticWorkspaceData + @IExtHostContextService extHostContext: IExtHostContextService, + @ILogService logService: ILogService, ) { this._logService = logService; this._requestIdProvider = new Counter(); this._barrier = new Barrier(); - this._proxy = mainContext.getProxy(MainContext.MainThreadWorkspace); - this._messageService = mainContext.getProxy(MainContext.MainThreadMessageService); + this._proxy = extHostContext.rpc.getProxy(MainContext.MainThreadWorkspace); + this._messageService = extHostContext.rpc.getProxy(MainContext.MainThreadMessageService); + const data = extHostContext.initData.workspace; this._confirmedWorkspace = data ? new ExtHostWorkspaceImpl(data.id, data.name, [], data.configuration ? URI.revive(data.configuration) : null, !!data.isUntitled) : undefined; } - $initializeWorkspace(data: IWorkspaceData): void { + $initializeWorkspace(data: IWorkspaceData | null): void { this.$acceptWorkspaceData(data); this._barrier.open(); } @@ -389,7 +393,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac } } - $acceptWorkspaceData(data: IWorkspaceData): void { + $acceptWorkspaceData(data: IWorkspaceData | null): void { const { workspace, added, removed } = ExtHostWorkspaceImpl.toExtHostWorkspace(data, this._confirmedWorkspace, this._unconfirmedWorkspace); @@ -545,3 +549,6 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac return this._proxy.$resolveProxy(url); } } + +export const IExtHostWorkspace = createDecorator('IExtHostWorkspace'); +export interface IExtHostWorkspace extends ExtHostWorkspace, ExtHostWorkspaceShape, IExtHostWorkspaceProvider { } diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index acf5138be85..d9ceabda83b 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -18,17 +18,16 @@ import * as files from 'vs/platform/files/common/files'; import { ExtHostContext, IInitData, IMainContext, MainContext } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostApiCommands } from 'vs/workbench/api/common/extHostApiCommands'; import { ExtHostClipboard } from 'vs/workbench/api/common/extHostClipboard'; -import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; +import { IExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; import { ExtHostComments } from 'vs/workbench/api/common/extHostComments'; import { ExtHostConfiguration, ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration'; import { ExtHostDebugService } from 'vs/workbench/api/node/extHostDebugService'; -import { ExtHostDecorations } from 'vs/workbench/api/common/extHostDecorations'; import { ExtHostDiagnostics } from 'vs/workbench/api/common/extHostDiagnostics'; import { ExtHostDialogs } from 'vs/workbench/api/common/extHostDialogs'; import { ExtHostDocumentContentProvider } from 'vs/workbench/api/common/extHostDocumentContentProviders'; import { ExtHostDocumentSaveParticipant } from 'vs/workbench/api/common/extHostDocumentSaveParticipant'; import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments'; -import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; +import { IExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { ExtensionActivatedByAPI } from 'vs/workbench/api/common/extHostExtensionActivator'; import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService'; import { ExtHostFileSystem } from 'vs/workbench/api/common/extHostFileSystem'; @@ -37,8 +36,7 @@ import { ExtHostLanguageFeatures } from 'vs/workbench/api/common/extHostLanguage import { ExtHostLanguages } from 'vs/workbench/api/common/extHostLanguages'; import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; import { ExtHostMessageService } from 'vs/workbench/api/common/extHostMessageService'; -import { ExtHostOutputService } from 'vs/workbench/api/common/extHostOutput'; -import { LogOutputChannelFactory } from 'vs/workbench/api/node/extHostOutputService'; +import { IExtHostOutputService } from 'vs/workbench/api/common/extHostOutput'; import { ExtHostProgress } from 'vs/workbench/api/common/extHostProgress'; import { ExtHostQuickOpen } from 'vs/workbench/api/common/extHostQuickOpen'; import { ExtHostSCM } from 'vs/workbench/api/common/extHostSCM'; @@ -46,7 +44,7 @@ import { ExtHostSearch, registerEHSearchProviders } from 'vs/workbench/api/node/ import { ExtHostStatusBar } from 'vs/workbench/api/common/extHostStatusBar'; import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; import { ExtHostTask } from 'vs/workbench/api/node/extHostTask'; -import { ExtHostTerminalService } from 'vs/workbench/api/node/extHostTerminalService'; +import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; import { ExtHostEditors } from 'vs/workbench/api/common/extHostTextEditors'; import { ExtHostTreeViews } from 'vs/workbench/api/common/extHostTreeViews'; import { ExtHostDownloadService } from 'vs/workbench/api/node/extHostDownloadService'; @@ -68,10 +66,9 @@ import { Schemas } from 'vs/base/common/network'; import { IURITransformer } from 'vs/base/common/uriIpc'; import { ExtHostEditorInsets } from 'vs/workbench/api/common/extHostCodeInsets'; import { ExtHostLabelService } from 'vs/workbench/api/common/extHostLabelService'; -import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; -import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; -import { getSingletonServiceDescriptors } from 'vs/platform/instantiation/common/extensions'; import { getRemoteName } from 'vs/platform/remote/common/remoteHosts'; +import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IExtHostDecorations } from 'vs/workbench/api/common/extHostDecorations'; export interface IExtensionApiFactory { (extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode; @@ -89,6 +86,7 @@ function proposedApiFunction(extension: IExtensionDescription, fn: T): T { * This method instantiates and returns the extension API surface */ export function createApiFactory( + accessor: ServicesAccessor, initData: IInitData, rpcProtocol: IMainContext, extHostWorkspace: ExtHostWorkspace, @@ -99,21 +97,20 @@ export function createApiFactory( uriTransformer: IURITransformer | null ): IExtensionApiFactory { - // bootstrap services - const services = new ServiceCollection(...getSingletonServiceDescriptors()); - const instaService = new InstantiationService(services); + // services + const instaService = accessor.get(IInstantiationService); // Addressable instances rpcProtocol.set(ExtHostContext.ExtHostLogService, extHostLogService); - const extHostDecorations = rpcProtocol.set(ExtHostContext.ExtHostDecorations, new ExtHostDecorations(rpcProtocol)); + const extHostDecorations = rpcProtocol.set(ExtHostContext.ExtHostDecorations, accessor.get(IExtHostDecorations)); const extHostWebviews = rpcProtocol.set(ExtHostContext.ExtHostWebviews, new ExtHostWebviews(rpcProtocol, initData.environment)); const extHostUrls = rpcProtocol.set(ExtHostContext.ExtHostUrls, new ExtHostUrls(rpcProtocol)); - const extHostDocumentsAndEditors = rpcProtocol.set(ExtHostContext.ExtHostDocumentsAndEditors, new ExtHostDocumentsAndEditors(rpcProtocol)); + const extHostDocumentsAndEditors = rpcProtocol.set(ExtHostContext.ExtHostDocumentsAndEditors, accessor.get(IExtHostDocumentsAndEditors)); const extHostDocuments = rpcProtocol.set(ExtHostContext.ExtHostDocuments, new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors)); const extHostDocumentContentProviders = rpcProtocol.set(ExtHostContext.ExtHostDocumentContentProviders, new ExtHostDocumentContentProvider(rpcProtocol, extHostDocumentsAndEditors, extHostLogService)); const extHostDocumentSaveParticipant = rpcProtocol.set(ExtHostContext.ExtHostDocumentSaveParticipant, new ExtHostDocumentSaveParticipant(extHostLogService, extHostDocuments, rpcProtocol.getProxy(MainContext.MainThreadTextEditors))); const extHostEditors = rpcProtocol.set(ExtHostContext.ExtHostEditors, new ExtHostEditors(rpcProtocol, extHostDocumentsAndEditors)); - const extHostCommands = rpcProtocol.set(ExtHostContext.ExtHostCommands, new ExtHostCommands(rpcProtocol, extHostLogService)); + const extHostCommands = rpcProtocol.set(ExtHostContext.ExtHostCommands, accessor.get(IExtHostCommands)); const extHostTreeViews = rpcProtocol.set(ExtHostContext.ExtHostTreeViews, new ExtHostTreeViews(rpcProtocol.getProxy(MainContext.MainThreadTreeViews), extHostCommands, extHostLogService)); rpcProtocol.set(ExtHostContext.ExtHostDownloadService, new ExtHostDownloadService(rpcProtocol.getProxy(MainContext.MainThreadDownloadService), extHostCommands)); rpcProtocol.set(ExtHostContext.ExtHostWorkspace, extHostWorkspace); @@ -124,7 +121,7 @@ export function createApiFactory( const extHostFileSystem = rpcProtocol.set(ExtHostContext.ExtHostFileSystem, new ExtHostFileSystem(rpcProtocol, extHostLanguageFeatures)); const extHostFileSystemEvent = rpcProtocol.set(ExtHostContext.ExtHostFileSystemEventService, new ExtHostFileSystemEventService(rpcProtocol, extHostDocumentsAndEditors)); const extHostQuickOpen = rpcProtocol.set(ExtHostContext.ExtHostQuickOpen, new ExtHostQuickOpen(rpcProtocol, extHostWorkspace, extHostCommands)); - const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(rpcProtocol, extHostConfiguration, extHostWorkspace, extHostDocumentsAndEditors, extHostLogService)); + const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, accessor.get(IExtHostTerminalService)); const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, instaService.createInstance(ExtHostDebugService, rpcProtocol, extHostWorkspace, extensionService, extHostDocumentsAndEditors, extHostConfiguration, extHostTerminalService, extHostCommands)); const extHostSCM = rpcProtocol.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(rpcProtocol, extHostCommands, extHostLogService)); const extHostComment = rpcProtocol.set(ExtHostContext.ExtHostComments, new ExtHostComments(rpcProtocol, extHostCommands, extHostDocuments)); @@ -133,7 +130,7 @@ export function createApiFactory( const extHostWindow = rpcProtocol.set(ExtHostContext.ExtHostWindow, new ExtHostWindow(rpcProtocol)); rpcProtocol.set(ExtHostContext.ExtHostExtensionService, extensionService); const extHostProgress = rpcProtocol.set(ExtHostContext.ExtHostProgress, new ExtHostProgress(rpcProtocol.getProxy(MainContext.MainThreadProgress))); - const extHostOutputService = rpcProtocol.set(ExtHostContext.ExtHostOutputService, new ExtHostOutputService(LogOutputChannelFactory, initData.logsLocation, rpcProtocol)); + const extHostOutputService = rpcProtocol.set(ExtHostContext.ExtHostOutputService, accessor.get(IExtHostOutputService)); rpcProtocol.set(ExtHostContext.ExtHostStorage, extHostStorage); const extHostLabelService = rpcProtocol.set(ExtHostContext.ExtHosLabelService, new ExtHostLabelService(rpcProtocol)); diff --git a/src/vs/workbench/api/node/extHost.services.ts b/src/vs/workbench/api/node/extHost.services.ts new file mode 100644 index 00000000000..ff8a01bd9f8 --- /dev/null +++ b/src/vs/workbench/api/node/extHost.services.ts @@ -0,0 +1,24 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IExtHostOutputService } from 'vs/workbench/api/common/extHostOutput'; +import { ExtHostOutputService2 } from 'vs/workbench/api/node/extHostOutputService'; +import { IExtHostWorkspace, ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; +import { IExtHostDecorations, ExtHostDecorations } from 'vs/workbench/api/common/extHostDecorations'; +import { IExtHostConfiguration, ExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; +import { IExtHostCommands, ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; +import { IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; +import { ExtHostTerminalService } from 'vs/workbench/api/node/extHostTerminalService'; +import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; + +// register singleton services +registerSingleton(IExtHostOutputService, ExtHostOutputService2); +registerSingleton(IExtHostWorkspace, ExtHostWorkspace); +registerSingleton(IExtHostDecorations, ExtHostDecorations); +registerSingleton(IExtHostConfiguration, ExtHostConfiguration); +registerSingleton(IExtHostCommands, ExtHostCommands); +registerSingleton(IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors); +registerSingleton(IExtHostTerminalService, ExtHostTerminalService); diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 2ee2b919b1d..faafb11b7fe 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -13,12 +13,12 @@ import { URI } from 'vs/base/common/uri'; import { ILogService } from 'vs/platform/log/common/log'; import { createApiFactory, IExtensionApiFactory } from 'vs/workbench/api/node/extHost.api.impl'; import { NodeModuleRequireInterceptor, VSCodeNodeModuleFactory, KeytarNodeModuleFactory, OpenNodeModuleFactory } from 'vs/workbench/api/node/extHostRequireInterceptor'; -import { ExtHostExtensionServiceShape, IEnvironment, IInitData, IMainContext, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape, IResolveAuthorityResult } from 'vs/workbench/api/common/extHost.protocol'; -import { ExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; +import { ExtHostExtensionServiceShape, IInitData, IMainContext, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape, IResolveAuthorityResult } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostConfiguration, IExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionModule, HostExtension, ExtensionActivationTimesFragment } from 'vs/workbench/api/common/extHostExtensionActivator'; import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; -import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; +import { ExtHostWorkspace, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import { ExtensionActivationError } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; import { connectProxyResolver } from 'vs/workbench/services/extensions/node/proxyResolver'; @@ -34,6 +34,8 @@ import { ExtensionStoragePaths } from 'vs/workbench/api/node/extHostStoragePaths import { RemoteAuthorityResolverError, ExtensionExecutionContext } from 'vs/workbench/api/common/extHostTypes'; import { IURITransformer } from 'vs/base/common/uriIpc'; import { ResolvedAuthority, ResolvedOptions } from 'vs/platform/remote/common/remoteAuthorityResolver'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; interface ITestRunner { /** Old test runner API, as exported from `vscode/lib/testrunner` */ @@ -70,9 +72,10 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { private readonly _extHostContext: IMainContext; private readonly _extHostWorkspace: ExtHostWorkspace; private readonly _extHostConfiguration: ExtHostConfiguration; - private readonly _environment: IEnvironment; private readonly _extHostLogService: ExtHostLogService; + private readonly _instaService: IInstantiationService; + private readonly _mainThreadWorkspaceProxy: MainThreadWorkspaceShape; private readonly _mainThreadTelemetryProxy: MainThreadTelemetryShape; private readonly _mainThreadExtensionsProxy: MainThreadExtensionServiceShape; @@ -95,20 +98,19 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { constructor( hostUtils: IHostUtils, - initData: IInitData, - extHostContext: IMainContext, - extHostWorkspace: ExtHostWorkspace, - extHostConfiguration: ExtHostConfiguration, - environment: IEnvironment, - extHostLogService: ExtHostLogService, - uriTransformer: IURITransformer | null + uriTransformer: IURITransformer | null, + @IInstantiationService instaService: IInstantiationService, + @IExtHostContextService extHostContext: IExtHostContextService, + @IExtHostWorkspace extHostWorkspace: IExtHostWorkspace, + @IExtHostConfiguration extHostConfiguration: IExtHostConfiguration, + @ILogService extHostLogService: ExtHostLogService, ) { this._hostUtils = hostUtils; - this._initData = initData; - this._extHostContext = extHostContext; + this._initData = extHostContext.initData; + this._extHostContext = extHostContext.rpc; + this._instaService = instaService; this._extHostWorkspace = extHostWorkspace; this._extHostConfiguration = extHostConfiguration; - this._environment = environment; this._extHostLogService = extHostLogService; this._disposables = new DisposableStore(); @@ -119,14 +121,14 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { this._almostReadyToRunExtensions = new Barrier(); this._readyToStartExtensionHost = new Barrier(); this._readyToRunExtensions = new Barrier(); - this._registry = new ExtensionDescriptionRegistry(initData.extensions); + this._registry = new ExtensionDescriptionRegistry(this._initData.extensions); this._storage = new ExtHostStorage(this._extHostContext); - this._storagePath = new ExtensionStoragePaths(withNullAsUndefined(initData.workspace), initData.environment); + this._storagePath = new ExtensionStoragePaths(withNullAsUndefined(this._initData.workspace), this._initData.environment); const hostExtensions = new Set(); - initData.hostExtensions.forEach((extensionId) => hostExtensions.add(ExtensionIdentifier.toKey(extensionId))); + this._initData.hostExtensions.forEach((extensionId) => hostExtensions.add(ExtensionIdentifier.toKey(extensionId))); - this._activator = new ExtensionsActivator(this._registry, initData.resolvedExtensions, initData.hostExtensions, { + this._activator = new ExtensionsActivator(this._registry, this._initData.resolvedExtensions, this._initData.hostExtensions, { onExtensionActivationError: (extensionId: ExtensionIdentifier, error: ExtensionActivationError): void => { this._mainThreadExtensionsProxy.$onExtensionActivationError(extensionId, error); }, @@ -144,7 +146,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { this._extensionPathIndex = null; // initialize API first (i.e. do not release barrier until the API is initialized) - this._extensionApiFactory = createApiFactory( + this._extensionApiFactory = this._instaService.invokeFunction(createApiFactory, this._initData, this._extHostContext, this._extHostWorkspace, @@ -171,7 +173,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { const configProvider = await this._extHostConfiguration.getConfigProvider(); const extensionPaths = await this.getExtensionPathIndex(); NodeModuleRequireInterceptor.INSTANCE.register(new VSCodeNodeModuleFactory(this._extensionApiFactory, extensionPaths, this._registry, configProvider)); - NodeModuleRequireInterceptor.INSTANCE.register(new KeytarNodeModuleFactory(this._extHostContext.getProxy(MainContext.MainThreadKeytar), this._environment)); + NodeModuleRequireInterceptor.INSTANCE.register(new KeytarNodeModuleFactory(this._extHostContext.getProxy(MainContext.MainThreadKeytar), this._initData.environment)); if (this._initData.remote.isRemote) { NodeModuleRequireInterceptor.INSTANCE.register(new OpenNodeModuleFactory( this._extHostContext.getProxy(MainContext.MainThreadWindow), diff --git a/src/vs/workbench/api/node/extHostOutputService.ts b/src/vs/workbench/api/node/extHostOutputService.ts index e06299a5a32..9a228497d4e 100644 --- a/src/vs/workbench/api/node/extHostOutputService.ts +++ b/src/vs/workbench/api/node/extHostOutputService.ts @@ -10,7 +10,8 @@ import { join } from 'vs/base/common/path'; import { OutputAppender } from 'vs/workbench/services/output/node/outputAppender'; import { toLocalISOString } from 'vs/base/common/date'; import { dirExists, mkdirp } from 'vs/base/node/pfs'; -import { AbstractExtHostOutputChannel, IOutputChannelFactory, ExtHostPushOutputChannel } from 'vs/workbench/api/common/extHostOutput'; +import { AbstractExtHostOutputChannel, ExtHostPushOutputChannel, ExtHostOutputService, LazyOutputChannel } from 'vs/workbench/api/common/extHostOutput'; +import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; export class ExtHostOutputChannelBackedByFile extends AbstractExtHostOutputChannel { @@ -43,23 +44,36 @@ export class ExtHostOutputChannelBackedByFile extends AbstractExtHostOutputChann } } -export const LogOutputChannelFactory = new class implements IOutputChannelFactory { +export class ExtHostOutputService2 extends ExtHostOutputService { - _namePool = 1; + private _logsLocation: URI; + private _namePool: number = 1; - async createOutputChannel(name: string, logsLocation: URI, proxy: MainThreadOutputServiceShape): Promise { + constructor(@IExtHostContextService extHostContext: IExtHostContextService) { + super(extHostContext); + this._logsLocation = extHostContext.initData.logsLocation; + } + + createOutputChannel(name: string): vscode.OutputChannel { + name = name.trim(); + if (!name) { + throw new Error('illegal argument `name`. must not be falsy'); + } + return new LazyOutputChannel(name, this._doCreateOutChannel(name)); + } + + private async _doCreateOutChannel(name: string): Promise { try { - const outputDirPath = join(logsLocation.fsPath, `output_logging_${toLocalISOString(new Date()).replace(/-|:|\.\d+Z$/g, '')}`); - const outputDir = await dirExists(outputDirPath).then(exists => exists ? exists : mkdirp(outputDirPath).then(() => true)).then(() => outputDirPath); + const outputDirPath = join(this._logsLocation.fsPath, `output_logging_${toLocalISOString(new Date()).replace(/-|:|\.\d+Z$/g, '')}`); + const outputDir = await dirExists(outputDirPath).then(exists => exists || mkdirp(outputDirPath).then(() => true)).then(() => outputDirPath); const fileName = `${this._namePool++}-${name.replace(/[\\/:\*\?"<>\|]/g, '')}`; const file = URI.file(join(outputDir, `${fileName}.log`)); const appender = new OutputAppender(fileName, file.fsPath); - return new ExtHostOutputChannelBackedByFile(name, appender, proxy); + return new ExtHostOutputChannelBackedByFile(name, appender, this._proxy); } catch (error) { // Do not crash if logger cannot be created console.log(error); - return new ExtHostPushOutputChannel(name, proxy); + return new ExtHostPushOutputChannel(name, this._proxy); } } -}; - +} diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index b34f0ea8b95..de5c164f00d 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -27,10 +27,10 @@ import { import { ExtHostVariableResolverService } from 'vs/workbench/api/node/extHostDebugService'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { ExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; -import { ExtHostTerminalService } from 'vs/workbench/api/node/extHostTerminalService'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { CancellationToken } from 'vs/base/common/cancellation'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; namespace TaskDefinitionDTO { export function from(value: vscode.TaskDefinition): TaskDefinitionDTO | undefined { @@ -358,7 +358,7 @@ export class ExtHostTask implements ExtHostTaskShape { private _workspaceProvider: IExtHostWorkspaceProvider; private _editorService: ExtHostDocumentsAndEditors; private _configurationService: ExtHostConfiguration; - private _terminalService: ExtHostTerminalService; + private _terminalService: IExtHostTerminalService; private _handleCounter: number; private _handlers: Map; private _taskExecutions: Map; @@ -376,7 +376,7 @@ export class ExtHostTask implements ExtHostTaskShape { workspaceService: ExtHostWorkspace, editorService: ExtHostDocumentsAndEditors, configurationService: ExtHostConfiguration, - extHostTerminalService: ExtHostTerminalService) { + extHostTerminalService: IExtHostTerminalService) { this._proxy = mainContext.getProxy(MainContext.MainThreadTask); this._workspaceProvider = workspaceService; this._editorService = editorService; diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index b4aa39cce9a..3d88152da0c 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -10,19 +10,21 @@ import { URI, UriComponents } from 'vs/base/common/uri'; import * as platform from 'vs/base/common/platform'; import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { Event, Emitter } from 'vs/base/common/event'; -import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, IMainContext, IShellLaunchConfigDto, IShellDefinitionDto, IShellAndArgsDto, ITerminalDimensionsDto } from 'vs/workbench/api/common/extHost.protocol'; -import { ExtHostConfiguration, ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration'; +import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, IShellLaunchConfigDto, IShellDefinitionDto, IShellAndArgsDto, ITerminalDimensionsDto } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostConfiguration, ExtHostConfigProvider, IExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; import { ILogService } from 'vs/platform/log/common/log'; import { EXT_HOST_CREATION_DELAY, IShellLaunchConfig, ITerminalEnvironment, ITerminalChildProcess, ITerminalDimensions } from 'vs/workbench/contrib/terminal/common/terminal'; import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProcess'; import { timeout } from 'vs/base/common/async'; -import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; +import { ExtHostWorkspace, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { ExtHostVariableResolverService } from 'vs/workbench/api/node/extHostDebugService'; -import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; +import { ExtHostDocumentsAndEditors, IExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { getSystemShell, detectAvailableShells } from 'vs/workbench/contrib/terminal/node/terminal'; import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; import { IDisposable } from 'vs/base/common/lifecycle'; +import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; +import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; export class BaseExtHostTerminal { public _id: number | undefined; @@ -196,7 +198,7 @@ export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Termi } } -export class ExtHostTerminalService implements ExtHostTerminalServiceShape { +export class ExtHostTerminalService implements IExtHostTerminalService, ExtHostTerminalServiceShape { private _proxy: MainThreadTerminalServiceShape; private _activeTerminal: ExtHostTerminal | undefined; private _terminals: ExtHostTerminal[] = []; @@ -223,13 +225,13 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { public get onDidWriteTerminalData(): Event { return this._onDidWriteTerminalData && this._onDidWriteTerminalData.event; } constructor( - mainContext: IMainContext, - private _extHostConfiguration: ExtHostConfiguration, - private _extHostWorkspace: ExtHostWorkspace, - private _extHostDocumentsAndEditors: ExtHostDocumentsAndEditors, - private _logService: ILogService + @IExtHostContextService extHostContext: IExtHostContextService, + @IExtHostConfiguration private _extHostConfiguration: ExtHostConfiguration, + @IExtHostWorkspace private _extHostWorkspace: ExtHostWorkspace, + @IExtHostDocumentsAndEditors private _extHostDocumentsAndEditors: ExtHostDocumentsAndEditors, + @ILogService private _logService: ILogService ) { - this._proxy = mainContext.getProxy(MainContext.MainThreadTerminalService); + this._proxy = extHostContext.rpc.getProxy(MainContext.MainThreadTerminalService); this._onDidWriteTerminalData = new Emitter({ onFirstListenerAdd: () => this._proxy.$startSendingDataEvents(), onLastListenerRemove: () => this._proxy.$stopSendingDataEvents() diff --git a/src/vs/workbench/services/extensions/node/extensionHostMain.ts b/src/vs/workbench/services/extensions/node/extensionHostMain.ts index 6cf41ef0492..18b294ad091 100644 --- a/src/vs/workbench/services/extensions/node/extensionHostMain.ts +++ b/src/vs/workbench/services/extensions/node/extensionHostMain.ts @@ -10,14 +10,16 @@ import { URI, setUriThrowOnMissingScheme } from 'vs/base/common/uri'; import { IURITransformer } from 'vs/base/common/uriIpc'; import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; import { IInitData, MainContext, MainThreadConsoleShape } from 'vs/workbench/api/common/extHost.protocol'; -import { ExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; import { ExtHostExtensionService, IHostUtils } from 'vs/workbench/api/node/extHostExtensionService'; import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; -import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import { RPCProtocol } from 'vs/workbench/services/extensions/common/rpcProtocol'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; -import { withNullAsUndefined } from 'vs/base/common/types'; import { ILogService } from 'vs/platform/log/common/log'; +import { getSingletonServiceDescriptors } from 'vs/platform/instantiation/common/extensions'; +import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; +import { IExtHostContextService, ExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; +import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; // we don't (yet) throw when extensions parse // uris that have no scheme @@ -64,20 +66,19 @@ export class ExtensionHostMain { const extHostLogService = new ExtHostLogService(logServiceFn(initData), initData.logsLocation.fsPath); this._disposables.add(extHostLogService); - const extHostWorkspace = new ExtHostWorkspace(rpcProtocol, extHostLogService, withNullAsUndefined(initData.workspace)); + // bootstrap services + const services = new ServiceCollection(...getSingletonServiceDescriptors()); + services.set(IExtHostContextService, new ExtHostContextService(rpcProtocol, initData)); + services.set(ILogService, extHostLogService); + + const instaService: IInstantiationService = new InstantiationService(services); extHostLogService.info('extension host started'); extHostLogService.trace('initData', initData); - const extHostConfiguraiton = new ExtHostConfiguration(rpcProtocol.getProxy(MainContext.MainThreadConfiguration), extHostWorkspace); - this._extensionService = new ExtHostExtensionService( + this._extensionService = instaService.createInstance( + ExtHostExtensionService, hostUtils, - initData, - rpcProtocol, - extHostWorkspace, - extHostConfiguraiton, - initData.environment, - extHostLogService, uriTransformer ); diff --git a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts index 1a5822e645f..75b8c4c16a0 100644 --- a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts +++ b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts @@ -22,6 +22,7 @@ import { exists } from 'vs/base/node/pfs'; import { realpath } from 'vs/base/node/extpath'; import { IHostUtils } from 'vs/workbench/api/node/extHostExtensionService'; import { SpdLogService } from 'vs/platform/log/node/spdlogService'; +import 'vs/workbench/api/node/extHost.services'; interface ParsedExtHostArgs { uriTransformerPath?: string; diff --git a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts index 779c40e9656..ea33dffbd70 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts @@ -21,7 +21,7 @@ import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; import { MainThreadCommands } from 'vs/workbench/api/browser/mainThreadCommands'; import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; -import { MainContext, ExtHostContext } from 'vs/workbench/api/common/extHost.protocol'; +import { MainContext, ExtHostContext, IInitData } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostDiagnostics } from 'vs/workbench/api/common/extHostDiagnostics'; import * as vscode from 'vscode'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -30,6 +30,8 @@ import { NullLogService } from 'vs/platform/log/common/log'; import { ITextModel } from 'vs/editor/common/model'; import { nullExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; import { dispose } from 'vs/base/common/lifecycle'; +import { ExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; +import { mock } from 'vs/workbench/test/electron-browser/api/mock'; const defaultSelector = { scheme: 'far' }; const model: ITextModel = EditorModel.createFromString( @@ -93,7 +95,9 @@ suite('ExtHostLanguageFeatureCommands', function () { inst = instantiationService; } - const extHostDocumentsAndEditors = new ExtHostDocumentsAndEditors(rpcProtocol); + const extHostContext = new ExtHostContextService(rpcProtocol, new class extends mock() { }); + + const extHostDocumentsAndEditors = new ExtHostDocumentsAndEditors(extHostContext); extHostDocumentsAndEditors.$acceptDocumentsAndEditorsDelta({ addedDocuments: [{ isDirty: false, @@ -107,7 +111,7 @@ suite('ExtHostLanguageFeatureCommands', function () { const extHostDocuments = new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors); rpcProtocol.set(ExtHostContext.ExtHostDocuments, extHostDocuments); - commands = new ExtHostCommands(rpcProtocol, new NullLogService()); + commands = new ExtHostCommands(extHostContext, new NullLogService()); rpcProtocol.set(ExtHostContext.ExtHostCommands, commands); rpcProtocol.set(MainContext.MainThreadCommands, inst.createInstance(MainThreadCommands, rpcProtocol)); ExtHostApiCommands.register(commands); diff --git a/src/vs/workbench/test/electron-browser/api/extHostCommands.test.ts b/src/vs/workbench/test/electron-browser/api/extHostCommands.test.ts index d0cf59f320e..0f4769ae329 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostCommands.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostCommands.test.ts @@ -5,11 +5,12 @@ import * as assert from 'assert'; import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; -import { MainThreadCommandsShape } from 'vs/workbench/api/common/extHost.protocol'; +import { MainThreadCommandsShape, IInitData } from 'vs/workbench/api/common/extHost.protocol'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { SingleProxyRPCProtocol } from './testRPCProtocol'; import { mock } from 'vs/workbench/test/electron-browser/api/mock'; import { NullLogService } from 'vs/platform/log/common/log'; +import { ExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; suite('ExtHostCommands', function () { @@ -26,7 +27,10 @@ suite('ExtHostCommands', function () { } }; - const commands = new ExtHostCommands(SingleProxyRPCProtocol(shape), new NullLogService()); + const commands = new ExtHostCommands( + new ExtHostContextService(SingleProxyRPCProtocol(shape), new class extends mock() { }), + new NullLogService() + ); commands.registerCommand(true, 'foo', (): any => { }).dispose(); assert.equal(lastUnregister!, 'foo'); assert.equal(CommandsRegistry.getCommand('foo'), undefined); @@ -46,7 +50,10 @@ suite('ExtHostCommands', function () { } }; - const commands = new ExtHostCommands(SingleProxyRPCProtocol(shape), new NullLogService()); + const commands = new ExtHostCommands( + new ExtHostContextService(SingleProxyRPCProtocol(shape), new class extends mock() { }), + new NullLogService() + ); const reg = commands.registerCommand(true, 'foo', (): any => { }); reg.dispose(); reg.dispose(); diff --git a/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts b/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts index 3104b573b5c..4e2f172115a 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts @@ -7,7 +7,7 @@ import * as assert from 'assert'; import { URI, UriComponents } from 'vs/base/common/uri'; import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import { ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration'; -import { MainThreadConfigurationShape, IConfigurationInitData } from 'vs/workbench/api/common/extHost.protocol'; +import { MainThreadConfigurationShape, IConfigurationInitData, IInitData } from 'vs/workbench/api/common/extHost.protocol'; import { ConfigurationModel } from 'vs/platform/configuration/common/configurationModels'; import { TestRPCProtocol } from './testRPCProtocol'; import { mock } from 'vs/workbench/test/electron-browser/api/mock'; @@ -26,11 +26,19 @@ suite('ExtHostConfiguration', function () { } } + function createExtHostWorkspace(): ExtHostWorkspace { + return new ExtHostWorkspace({ + _serviceBrand: undefined, + rpc: new TestRPCProtocol(), + initData: new class extends mock() { } + }, new NullLogService()); + } + function createExtHostConfiguration(contents: any = Object.create(null), shape?: MainThreadConfigurationShape) { if (!shape) { shape = new class extends mock() { }; } - return new ExtHostConfigProvider(shape, new ExtHostWorkspace(new TestRPCProtocol(), new NullLogService()), createConfigurationData(contents)); + return new ExtHostConfigProvider(shape, createExtHostWorkspace(), createConfigurationData(contents)); } function createConfigurationData(contents: any): IConfigurationInitData { @@ -263,7 +271,7 @@ suite('ExtHostConfiguration', function () { test('inspect in no workspace context', function () { const testObject = new ExtHostConfigProvider( new class extends mock() { }, - new ExtHostWorkspace(new TestRPCProtocol(), new NullLogService()), + createExtHostWorkspace(), { defaults: new ConfigurationModel({ 'editor': { @@ -303,7 +311,7 @@ suite('ExtHostConfiguration', function () { } }, ['editor.wordWrap']); folders.push([workspaceUri, workspace]); - const extHostWorkspace = new ExtHostWorkspace(new TestRPCProtocol(), new NullLogService()); + const extHostWorkspace = createExtHostWorkspace(); extHostWorkspace.$initializeWorkspace({ 'id': 'foo', 'folders': [aWorkspaceFolder(URI.file('foo'), 0)], @@ -378,7 +386,7 @@ suite('ExtHostConfiguration', function () { }, ['editor.wordWrap'])]); folders.push([thirdRoot, new ConfigurationModel({}, [])]); - const extHostWorkspace = new ExtHostWorkspace(new TestRPCProtocol(), new NullLogService()); + const extHostWorkspace = createExtHostWorkspace(); extHostWorkspace.$initializeWorkspace({ 'id': 'foo', 'folders': [aWorkspaceFolder(firstRoot, 0), aWorkspaceFolder(secondRoot, 1)], @@ -588,7 +596,7 @@ suite('ExtHostConfiguration', function () { test('configuration change event', (done) => { const workspaceFolder = aWorkspaceFolder(URI.file('folder1'), 0); - const extHostWorkspace = new ExtHostWorkspace(new TestRPCProtocol(), new NullLogService()); + const extHostWorkspace = createExtHostWorkspace(); extHostWorkspace.$initializeWorkspace({ 'id': 'foo', 'folders': [workspaceFolder], diff --git a/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts b/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts index d85eae55ebf..bf67278fb60 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts @@ -7,7 +7,7 @@ import { URI } from 'vs/base/common/uri'; import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { TextDocumentSaveReason, TextEdit, Position, EndOfLine } from 'vs/workbench/api/common/extHostTypes'; -import { MainThreadTextEditorsShape, IWorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol'; +import { MainThreadTextEditorsShape, IWorkspaceEditDto, IInitData } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostDocumentSaveParticipant } from 'vs/workbench/api/common/extHostDocumentSaveParticipant'; import { SingleProxyRPCProtocol } from './testRPCProtocol'; import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles'; @@ -17,6 +17,7 @@ import { NullLogService } from 'vs/platform/log/common/log'; import { isResourceTextEdit, ResourceTextEdit } from 'vs/editor/common/modes'; import { timeout } from 'vs/base/common/async'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { ExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; suite('ExtHostDocumentSaveParticipant', () => { @@ -37,7 +38,8 @@ suite('ExtHostDocumentSaveParticipant', () => { }; setup(() => { - const documentsAndEditors = new ExtHostDocumentsAndEditors(SingleProxyRPCProtocol(null)); + const extHostContext = new ExtHostContextService(SingleProxyRPCProtocol(null), new class extends mock() { }); + const documentsAndEditors = new ExtHostDocumentsAndEditors(extHostContext); documentsAndEditors.$acceptDocumentsAndEditorsDelta({ addedDocuments: [{ isDirty: false, diff --git a/src/vs/workbench/test/electron-browser/api/extHostDocumentsAndEditors.test.ts b/src/vs/workbench/test/electron-browser/api/extHostDocumentsAndEditors.test.ts index 67916da33da..8eb015f77dc 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostDocumentsAndEditors.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostDocumentsAndEditors.test.ts @@ -6,16 +6,23 @@ import * as assert from 'assert'; import { URI } from 'vs/base/common/uri'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; +import { mock } from 'vs/workbench/test/electron-browser/api/mock'; +import { IInitData } from 'vs/workbench/api/common/extHost.protocol'; suite('ExtHostDocumentsAndEditors', () => { let editors: ExtHostDocumentsAndEditors; setup(function () { + editors = new ExtHostDocumentsAndEditors({ - getProxy: () => { return undefined!; }, - set: undefined!, - assertRegistered: undefined! + _serviceBrand: undefined, + rpc: { + getProxy: () => { return undefined!; }, + set: undefined!, + assertRegistered: undefined! + }, + initData: new class extends mock() { } }); }); diff --git a/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts b/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts index 18ecedc673b..b31cebfb56d 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts @@ -34,7 +34,7 @@ import { provideSignatureHelp } from 'vs/editor/contrib/parameterHints/provideSi import { provideSuggestionItems, CompletionOptions } from 'vs/editor/contrib/suggest/suggest'; import { getDocumentFormattingEditsUntilResult, getDocumentRangeFormattingEditsUntilResult, getOnTypeFormattingEdits } from 'vs/editor/contrib/format/format'; import { getLinks } from 'vs/editor/contrib/links/getLinks'; -import { MainContext, ExtHostContext } from 'vs/workbench/api/common/extHost.protocol'; +import { MainContext, ExtHostContext, IInitData } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostDiagnostics } from 'vs/workbench/api/common/extHostDiagnostics'; import * as vscode from 'vscode'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -48,6 +48,7 @@ import { mock } from 'vs/workbench/test/electron-browser/api/mock'; import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService'; import { dispose } from 'vs/base/common/lifecycle'; import { withNullAsUndefined } from 'vs/base/common/types'; +import { ExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; const defaultSelector = { scheme: 'far' }; const model: ITextModel = EditorModel.createFromString( @@ -85,7 +86,9 @@ suite('ExtHostLanguageFeatures', function () { originalErrorHandler = errorHandler.getUnexpectedErrorHandler(); setUnexpectedErrorHandler(() => { }); - const extHostDocumentsAndEditors = new ExtHostDocumentsAndEditors(rpcProtocol); + const extHostContext = new ExtHostContextService(rpcProtocol, new class extends mock() { }); + + const extHostDocumentsAndEditors = new ExtHostDocumentsAndEditors(extHostContext); extHostDocumentsAndEditors.$acceptDocumentsAndEditorsDelta({ addedDocuments: [{ isDirty: false, @@ -99,7 +102,7 @@ suite('ExtHostLanguageFeatures', function () { const extHostDocuments = new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors); rpcProtocol.set(ExtHostContext.ExtHostDocuments, extHostDocuments); - const commands = new ExtHostCommands(rpcProtocol, new NullLogService()); + const commands = new ExtHostCommands(extHostContext, new NullLogService()); rpcProtocol.set(ExtHostContext.ExtHostCommands, commands); rpcProtocol.set(MainContext.MainThreadCommands, inst.createInstance(MainThreadCommands, rpcProtocol)); diff --git a/src/vs/workbench/test/electron-browser/api/extHostTextEditors.test.ts b/src/vs/workbench/test/electron-browser/api/extHostTextEditors.test.ts index a66b5b43b9f..3690ff5519f 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostTextEditors.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostTextEditors.test.ts @@ -4,13 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as extHostTypes from 'vs/workbench/api/common/extHostTypes'; -import { MainContext, MainThreadTextEditorsShape, IWorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol'; +import { MainContext, MainThreadTextEditorsShape, IWorkspaceEditDto, IInitData } from 'vs/workbench/api/common/extHost.protocol'; import { URI } from 'vs/base/common/uri'; import { mock } from 'vs/workbench/test/electron-browser/api/mock'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { SingleProxyRPCProtocol, TestRPCProtocol } from 'vs/workbench/test/electron-browser/api/testRPCProtocol'; import { ExtHostEditors } from 'vs/workbench/api/common/extHostTextEditors'; import { ResourceTextEdit } from 'vs/editor/common/modes'; +import { ExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; suite('ExtHostTextEditors.applyWorkspaceEdit', () => { @@ -28,7 +29,8 @@ suite('ExtHostTextEditors.applyWorkspaceEdit', () => { return Promise.resolve(true); } }); - const documentsAndEditors = new ExtHostDocumentsAndEditors(SingleProxyRPCProtocol(null)); + const extHostContext = new ExtHostContextService(SingleProxyRPCProtocol(null), new class extends mock() { }); + const documentsAndEditors = new ExtHostDocumentsAndEditors(extHostContext); documentsAndEditors.$acceptDocumentsAndEditorsDelta({ addedDocuments: [{ isDirty: false, diff --git a/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts b/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts index 5f05a9bc453..f0e702295d8 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts @@ -8,7 +8,7 @@ import * as sinon from 'sinon'; import { Emitter } from 'vs/base/common/event'; import { ExtHostTreeViews } from 'vs/workbench/api/common/extHostTreeViews'; import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; -import { MainThreadTreeViewsShape, MainContext } from 'vs/workbench/api/common/extHost.protocol'; +import { MainThreadTreeViewsShape, MainContext, IInitData } from 'vs/workbench/api/common/extHost.protocol'; import { TreeDataProvider, TreeItem } from 'vscode'; import { TestRPCProtocol } from './testRPCProtocol'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; @@ -18,6 +18,7 @@ import { mock } from 'vs/workbench/test/electron-browser/api/mock'; import { TreeItemCollapsibleState, ITreeItem } from 'vs/workbench/common/views'; import { NullLogService } from 'vs/platform/log/common/log'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { ExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; suite('ExtHostTreeView', function () { @@ -71,7 +72,10 @@ suite('ExtHostTreeView', function () { rpcProtocol.set(MainContext.MainThreadCommands, inst.createInstance(MainThreadCommands, rpcProtocol)); target = new RecordingShape(); - testObject = new ExtHostTreeViews(target, new ExtHostCommands(rpcProtocol, new NullLogService()), new NullLogService()); + testObject = new ExtHostTreeViews(target, new ExtHostCommands( + new ExtHostContextService(rpcProtocol, new class extends mock() { }), + new NullLogService() + ), new NullLogService()); onDidChangeTreeNode = new Emitter<{ key: string }>(); onDidChangeTreeNodeWithId = new Emitter<{ key: string }>(); testObject.createTreeView('testNodeTreeProvider', { treeDataProvider: aNodeTreeDataProvider() }, { enableProposedApi: true } as IExtensionDescription); diff --git a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts index 0441b998625..833b6dbc7a9 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts @@ -11,14 +11,18 @@ import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensio import { ILogService, NullLogService } from 'vs/platform/log/common/log'; import { IWorkspaceFolderData } from 'vs/platform/workspace/common/workspace'; import { MainThreadWorkspace } from 'vs/workbench/api/browser/mainThreadWorkspace'; -import { IMainContext, IWorkspaceData, MainContext } from 'vs/workbench/api/common/extHost.protocol'; +import { IMainContext, IWorkspaceData, MainContext, IInitData } from 'vs/workbench/api/common/extHost.protocol'; import { RelativePattern } from 'vs/workbench/api/common/extHostTypes'; import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import { mock } from 'vs/workbench/test/electron-browser/api/mock'; import { TestRPCProtocol } from './testRPCProtocol'; function createExtHostWorkspace(mainContext: IMainContext, data: IWorkspaceData, logService: ILogService): ExtHostWorkspace { - const result = new ExtHostWorkspace(mainContext, logService); + const result = new ExtHostWorkspace({ + _serviceBrand: undefined, + rpc: mainContext, + initData: new class extends mock() { workspace = data; } + }, logService); result.$initializeWorkspace(data); return result; } From 2cf97fc2e54f43b2f67c5b359081aac835412f04 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 7 Aug 2019 16:19:25 +0200 Subject: [PATCH 302/861] add service brand to terminal service --- src/vs/workbench/api/common/extHostTerminalService.ts | 2 ++ src/vs/workbench/api/node/extHostTerminalService.ts | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index 9a0552a89ba..7c6907caa26 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -11,6 +11,8 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' export interface IExtHostTerminalService extends ExtHostTerminalServiceShape { + _serviceBrand: any; + activeTerminal: vscode.Terminal | undefined; terminals: vscode.Terminal[]; diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 3d88152da0c..d6f5694833a 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -199,6 +199,9 @@ export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Termi } export class ExtHostTerminalService implements IExtHostTerminalService, ExtHostTerminalServiceShape { + + readonly _serviceBrand: any; + private _proxy: MainThreadTerminalServiceShape; private _activeTerminal: ExtHostTerminal | undefined; private _terminals: ExtHostTerminal[] = []; From cb67fbacab18c398578eed9798e4edcb4d1ff15c Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 7 Aug 2019 17:14:13 +0200 Subject: [PATCH 303/861] remove bad css --- src/vs/workbench/browser/actions/media/screencast.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/browser/actions/media/screencast.css b/src/vs/workbench/browser/actions/media/screencast.css index c6b888c6bf2..b4b71b36726 100644 --- a/src/vs/workbench/browser/actions/media/screencast.css +++ b/src/vs/workbench/browser/actions/media/screencast.css @@ -34,7 +34,6 @@ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - direction: rtl; } .monaco-workbench .screencast-keyboard:empty { From 78ddcdcd5cf33c0fc015ea5be6b4289f3233cc86 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 7 Aug 2019 17:26:09 +0200 Subject: [PATCH 304/861] Fixes #75494: do not break between surrogate pairs --- .../common/viewModel/characterHardWrappingLineMapper.ts | 7 +++++++ .../viewModel/characterHardWrappingLineMapper.test.ts | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/src/vs/editor/common/viewModel/characterHardWrappingLineMapper.ts b/src/vs/editor/common/viewModel/characterHardWrappingLineMapper.ts index 9833c7c50c1..74b236d4b78 100644 --- a/src/vs/editor/common/viewModel/characterHardWrappingLineMapper.ts +++ b/src/vs/editor/common/viewModel/characterHardWrappingLineMapper.ts @@ -136,6 +136,13 @@ export class CharacterHardWrappingLineMapperFactory implements ILineMapperFactor let charCodeIsTab = (charCode === CharCode.Tab); let charCodeClass = classifier.get(charCode); + if (strings.isLowSurrogate(charCode)/* && i + 1 < len */) { + // A surrogate pair must always be considered as a single unit, so it is never to be broken + // => advance visibleColumn by 1 and advance to next char code... + visibleColumn = visibleColumn + 1; + continue; + } + if (charCodeClass === CharacterClass.BREAK_BEFORE) { // This is a character that indicates that a break should happen before it // Since we are certain the character before `i` fits, there's no extra checking needed, diff --git a/src/vs/editor/test/common/viewModel/characterHardWrappingLineMapper.test.ts b/src/vs/editor/test/common/viewModel/characterHardWrappingLineMapper.test.ts index 47538e39437..aec12368fa1 100644 --- a/src/vs/editor/test/common/viewModel/characterHardWrappingLineMapper.test.ts +++ b/src/vs/editor/test/common/viewModel/characterHardWrappingLineMapper.test.ts @@ -114,6 +114,11 @@ suite('Editor ViewModel - CharacterHardWrappingLineMapper', () => { assert.equal(mapper!.getWrappedLinesIndent(), ' \t'); }); + test('issue #75494: surrogate pairs', () => { + let factory = new CharacterHardWrappingLineMapperFactory('', ' ', ''); + assertLineMapping(factory, 4, 49, '🐇👬🌖🌞🏇🍼🐇👬🌖🌞🏇🍼🐇👬🌖🌞🏇🍼🐇👬🌖🌞🏇🍼🐇|👬🌖🌞🏇🍼🐇👬🌖🌞🏇🍼🐇👬🌖🌞🏇🍼🐇👬🌖🌞🏇🍼🐇👬', WrappingIndent.Same); + }); + test('CharacterHardWrappingLineMapper - WrappingIndent.DeepIndent', () => { let factory = new CharacterHardWrappingLineMapperFactory('', ' ', ''); let mapper = assertLineMapping(factory, 4, 26, ' W e A r e T e s t |i n g D e |e p I n d |e n t a t |i o n', WrappingIndent.DeepIndent); From 59e3396c27f6fe1c44bdd7d9aea0402f0c8117e9 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 7 Aug 2019 17:37:44 +0200 Subject: [PATCH 305/861] use add instead of stage --- extensions/git/src/commands.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 060ab53250a..0977442e527 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1249,7 +1249,7 @@ export class CommandCenter { if (pick === saveAndCommit) { await Promise.all(unsavedTextDocuments.map(d => d.save())); - await Promise.all(unsavedTextDocuments.map(d => repository.stage(d.uri, d.getText()))); + await repository.add(unsavedTextDocuments.map(d => d.uri)); await repository.status(); } else if (pick !== commit) { return false; // do not commit on cancel From adb3edaa460e190dc5613f92f171988d080f61f7 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 7 Aug 2019 08:06:18 -0700 Subject: [PATCH 306/861] xterm@3.15.0-beta93 Diff: https://github.com/xtermjs/xterm.js/compare/d20068c...58e1b0d Changes: - Add mouse report tests - Fix shift+click throwing - Fix DECSTBM Fixes #78614 Fixes #78355 --- package.json | 4 ++-- remote/package.json | 2 +- remote/yarn.lock | 8 ++++---- yarn.lock | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 92120342a16..24d656cb88e 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "vscode-ripgrep": "^1.5.5", "vscode-sqlite3": "4.0.8", "vscode-textmate": "^4.2.2", - "xterm": "3.15.0-beta90", + "xterm": "3.15.0-beta93", "xterm-addon-search": "0.2.0-beta3", "xterm-addon-web-links": "0.1.0-beta10", "yauzl": "^2.9.2", @@ -157,4 +157,4 @@ "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} \ No newline at end of file +} diff --git a/remote/package.json b/remote/package.json index b3159ed308e..82324d430aa 100644 --- a/remote/package.json +++ b/remote/package.json @@ -20,7 +20,7 @@ "vscode-proxy-agent": "0.4.0", "vscode-ripgrep": "^1.5.5", "vscode-textmate": "^4.2.2", - "xterm": "3.15.0-beta90", + "xterm": "3.15.0-beta93", "xterm-addon-search": "0.2.0-beta3", "xterm-addon-web-links": "0.1.0-beta10", "yauzl": "^2.9.2", diff --git a/remote/yarn.lock b/remote/yarn.lock index 04ebe491f01..0467f0810c3 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -1159,10 +1159,10 @@ xterm-addon-web-links@0.1.0-beta10: resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23" integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg== -xterm@3.15.0-beta90: - version "3.15.0-beta90" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta90.tgz#e1732c2914584c86cffa797ba762c482f21ce182" - integrity sha512-eixIA5brfoez+Y8bJPCcIw8Q7LgOvxRX3cPBaGmo7ozUASx9IEGOmvIRQX1ozTUmxEiXPnAxOfl/isQ+yNlaww== +xterm@3.15.0-beta93: + version "3.15.0-beta93" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta93.tgz#ba1d5e4588f07be9bb36c70082a0e034f9bad565" + integrity sha512-MgzlwBOOwa/xYmWnLiTmqVOk3v/YRxzlPej940zpcp/chXW+ErsSPW6sehy68wedO9TWbR3oBUe8agfLH0uOuA== yauzl@^2.9.2: version "2.10.0" diff --git a/yarn.lock b/yarn.lock index 70b8c2fcdf7..b872c14415e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9888,10 +9888,10 @@ xterm-addon-web-links@0.1.0-beta10: resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23" integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg== -xterm@3.15.0-beta90: - version "3.15.0-beta90" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta90.tgz#e1732c2914584c86cffa797ba762c482f21ce182" - integrity sha512-eixIA5brfoez+Y8bJPCcIw8Q7LgOvxRX3cPBaGmo7ozUASx9IEGOmvIRQX1ozTUmxEiXPnAxOfl/isQ+yNlaww== +xterm@3.15.0-beta93: + version "3.15.0-beta93" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta93.tgz#ba1d5e4588f07be9bb36c70082a0e034f9bad565" + integrity sha512-MgzlwBOOwa/xYmWnLiTmqVOk3v/YRxzlPej940zpcp/chXW+ErsSPW6sehy68wedO9TWbR3oBUe8agfLH0uOuA== y18n@^3.2.1: version "3.2.1" From f8463cbab5a914962b7bc94b7186c4700f154504 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 7 Aug 2019 09:18:36 -0700 Subject: [PATCH 307/861] Update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 24d656cb88e..fe64037080b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "1413fa0e8982b468bc452d742bbd60c36b0cb45e", + "distro": "fffc03749d2060757cd83580d67a15ded244c2af", "author": { "name": "Microsoft Corporation" }, From 383a3d8759e49d02b1b5b46a4077fe74b8c0a049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Wed, 7 Aug 2019 18:25:08 +0200 Subject: [PATCH 308/861] Use grid descriptors for workbench grid layout (#78550) * grid: getViewCachedVisibleSize fixes #78228 * wip: grid hydration first steps * use more layout state * grid: remember sidebar position * layout: remove layoutGrid * splitview: fix moveView invisible preservation * grid: addViewAt, moveViewTo * layout: handle sidebar position * layout: remove unnecessary layout call * layout: panel position * restore strange loop * layout: status bar and activity bar parts * :lipstick: * fix missing calls to setViewVisible * lipstick * fix titlebar visibility * fix editor visibility * doc * cleanup todos and use Parts enum --- src/vs/base/browser/ui/grid/grid.ts | 55 ++- src/vs/base/browser/ui/grid/gridview.ts | 29 +- src/vs/base/browser/ui/splitview/splitview.ts | 5 +- src/vs/workbench/browser/layout.ts | 361 +++++++++--------- 4 files changed, 246 insertions(+), 204 deletions(-) diff --git a/src/vs/base/browser/ui/grid/grid.ts b/src/vs/base/browser/ui/grid/grid.ts index eb8476e1b8b..a35f9b2cdf4 100644 --- a/src/vs/base/browser/ui/grid/grid.ts +++ b/src/vs/base/browser/ui/grid/grid.ts @@ -277,6 +277,24 @@ export class Grid extends Disposable { this._addView(newView, viewSize, location); } + addViewAt(newView: T, size: number | DistributeSizing | InvisibleSizing, location: number[]): void { + if (this.views.has(newView)) { + throw new Error('Can\'t add same view twice'); + } + + let viewSize: number | GridViewSizing; + + if (typeof size === 'number') { + viewSize = size; + } else if (size.type === 'distribute') { + viewSize = GridViewSizing.Distribute; + } else { + viewSize = size; + } + + this._addView(newView, viewSize, location); + } + protected _addView(newView: T, size: number | GridViewSizing, location: number[]): void { this.views.set(newView, newView.element); this.gridview.addView(newView, size, location); @@ -308,6 +326,26 @@ export class Grid extends Disposable { } } + moveViewTo(view: T, location: number[]): void { + const sourceLocation = this.getViewLocation(view); + const [sourceParentLocation, from] = tail(sourceLocation); + const [targetParentLocation, to] = tail(location); + + if (equals(sourceParentLocation, targetParentLocation)) { + this.gridview.moveView(sourceParentLocation, from, to); + } else { + const size = this.getViewSize(view); + const orientation = getLocationOrientation(this.gridview.orientation, sourceLocation); + const cachedViewSize = this.getViewCachedVisibleSize(view); + const sizing = typeof cachedViewSize === 'undefined' + ? (orientation === Orientation.HORIZONTAL ? size.width : size.height) + : Sizing.Invisible(cachedViewSize); + + this.removeView(view); + this.addViewAt(view, sizing, location); + } + } + swapViews(from: T, to: T): void { const fromLocation = this.getViewLocation(from); const toLocation = this.getViewLocation(to); @@ -319,11 +357,20 @@ export class Grid extends Disposable { return this.gridview.resizeView(location, size); } - getViewSize(view: T): IViewSize { + getViewSize(view?: T): IViewSize { + if (!view) { + return this.gridview.getViewSize(); + } + const location = this.getViewLocation(view); return this.gridview.getViewSize(location); } + getViewCachedVisibleSize(view: T): number | undefined { + const location = this.getViewLocation(view); + return this.gridview.getViewCachedVisibleSize(location); + } + maximizeViewSize(view: T): void { const location = this.getViewLocation(view); this.gridview.maximizeViewSize(location); @@ -373,7 +420,7 @@ export class Grid extends Disposable { .map(node => node.view); } - private getViewLocation(view: T): number[] { + getViewLocation(view: T): number[] { const element = this.views.get(view); if (!element) { @@ -422,7 +469,7 @@ export interface ISerializableView extends IView { } export interface IViewDeserializer { - fromJSON(json: object | null): T; + fromJSON(json: any): T; } interface InitialLayoutContext { @@ -433,7 +480,7 @@ interface InitialLayoutContext { export interface ISerializedLeafNode { type: 'leaf'; - data: object | null; + data: any; size: number; visible?: boolean; } diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts index 7ec49f3b343..497678cee41 100644 --- a/src/vs/base/browser/ui/grid/gridview.ts +++ b/src/vs/base/browser/ui/grid/gridview.ts @@ -11,6 +11,7 @@ import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle' import { $ } from 'vs/base/browser/dom'; import { tail2 as tail } from 'vs/base/common/arrays'; import { Color } from 'vs/base/common/color'; +import { clamp } from 'vs/base/common/numbers'; export { Sizing, LayoutPriority } from 'vs/base/browser/ui/splitview/splitview'; export { Orientation } from 'vs/base/browser/ui/sash/sash'; @@ -277,9 +278,7 @@ class BranchNode implements ISplitView, IDisposable { throw new Error('Invalid from index'); } - if (to < 0 || to > this.children.length) { - throw new Error('Invalid to index'); - } + to = clamp(to, 0, this.children.length); if (from < to) { to--; @@ -300,9 +299,7 @@ class BranchNode implements ISplitView, IDisposable { throw new Error('Invalid from index'); } - if (to < 0 || to >= this.children.length) { - throw new Error('Invalid to index'); - } + to = clamp(to, 0, this.children.length); this.splitview.swapViews(from, to); [this.children[from].orthogonalStartSash, this.children[from].orthogonalEndSash, this.children[to].orthogonalStartSash, this.children[to].orthogonalEndSash] = [this.children[to].orthogonalStartSash, this.children[to].orthogonalEndSash, this.children[from].orthogonalStartSash, this.children[from].orthogonalEndSash]; @@ -765,6 +762,7 @@ export class GridView implements IDisposable { const [, parentIndex] = tail(rest); const sibling = parent.children[0]; + const isSiblingVisible = parent.isChildVisible(0); parent.removeChild(0); const sizes = grandParent.children.map((_, i) => grandParent.getChildSize(i)); @@ -779,7 +777,8 @@ export class GridView implements IDisposable { } } else { const newSibling = new LeafNode(sibling.view, orthogonal(sibling.orientation), this.layoutController, sibling.size); - grandParent.addChild(newSibling, sibling.orthogonalSize, parentIndex); + const sizing = isSiblingVisible ? sibling.orthogonalSize : Sizing.Invisible(sibling.orthogonalSize); + grandParent.addChild(newSibling, sizing, parentIndex); } for (let i = 0; i < sizes.length; i++) { @@ -868,11 +867,25 @@ export class GridView implements IDisposable { } } - getViewSize(location: number[]): IViewSize { + getViewSize(location?: number[]): IViewSize { + if (!location) { + return { width: this.root.width, height: this.root.height }; + } + const [, node] = this.getNode(location); return { width: node.width, height: node.height }; } + getViewCachedVisibleSize(location: number[]): number | undefined { + const [, node] = this.getNode(location); + + if (!(node instanceof LeafNode)) { + throw new Error('Invalid node'); + } + + return node.cachedVisibleSize; + } + maximizeViewSize(location: number[]): void { const [ancestors, node] = this.getNode(location); diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index 07f860ecb57..37d44dbaad9 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -414,9 +414,10 @@ export class SplitView extends Disposable { throw new Error('Cant modify splitview'); } - const size = this.getViewSize(from); + const cachedVisibleSize = this.getViewCachedVisibleSize(from); + const sizing = typeof cachedVisibleSize === 'undefined' ? this.getViewSize(from) : Sizing.Invisible(cachedVisibleSize); const view = this.removeView(from); - this.addView(view, size, to); + this.addView(view, sizing, to); } swapViews(from: number, to: number): void { diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 89d9dca6b46..3ca0bb99b63 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -27,7 +27,7 @@ import { IWindowService, MenuBarVisibility, getTitleBarStyle } from 'vs/platform import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; -import { Sizing, Direction, Grid, SerializableGrid, ISerializableView, ISerializedGrid, GridBranchNode, GridLeafNode, isGridBranchNode } from 'vs/base/browser/ui/grid/grid'; +import { Grid, SerializableGrid, ISerializableView, ISerializedGrid, Orientation, ISerializedNode, ISerializedLeafNode, Direction } from 'vs/base/browser/ui/grid/grid'; import { WorkbenchLegacyLayout } from 'vs/workbench/browser/legacyLayout'; import { IDimension } from 'vs/platform/layout/browser/layoutService'; import { Part } from 'vs/workbench/browser/part'; @@ -50,15 +50,19 @@ enum Settings { enum Storage { SIDEBAR_HIDDEN = 'workbench.sidebar.hidden', + SIDEBAR_SIZE = 'workbench.sidebar.size', PANEL_HIDDEN = 'workbench.panel.hidden', PANEL_POSITION = 'workbench.panel.location', + PANEL_SIZE = 'workbench.panel.size', PANEL_SIZE_BEFORE_MAXIMIZED = 'workbench.panel.sizeBeforeMaximized', ZEN_MODE_ENABLED = 'workbench.zenmode.active', CENTERED_LAYOUT_ENABLED = 'workbench.centerededitorlayout.active', - GRID_LAYOUT = 'workbench.grid.layout' + GRID_LAYOUT = 'workbench.grid.layout', + GRID_WIDTH = 'workbench.grid.width', + GRID_HEIGHT = 'workbench.grid.height' } export abstract class Layout extends Disposable implements IWorkbenchLayoutService { @@ -233,6 +237,11 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi if (this.state.fullscreen && (this.state.menuBar.visibility === 'toggle' || this.state.menuBar.visibility === 'default')) { this._onTitleBarVisibilityChange.fire(); + + if (this.workbenchGrid instanceof SerializableGrid) { + this.workbenchGrid.setViewVisible(this.titleBarPartView, this.isVisible(Parts.TITLEBAR_PART)); + } + this.layout(); } } @@ -255,6 +264,11 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi // Changing fullscreen state of the window has an impact on custom title bar visibility, so we need to update if (getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') { this._onTitleBarVisibilityChange.fire(); + + if (this.workbenchGrid instanceof SerializableGrid) { + this.workbenchGrid.setViewVisible(this.titleBarPartView, this.isVisible(Parts.TITLEBAR_PART)); + } + this.layout(); // handle title bar when fullscreen changes } @@ -298,11 +312,6 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi const activityBar = this.getPart(Parts.ACTIVITYBAR_PART); const sideBar = this.getPart(Parts.SIDEBAR_PART); const wasHidden = this.state.sideBar.hidden; - - if (this.state.sideBar.hidden) { - this.setSideBarHidden(false, true /* Skip Layout */); - } - const newPositionValue = (position === Position.LEFT) ? 'left' : 'right'; const oldPositionValue = (this.state.sideBar.position === Position.LEFT) ? 'left' : 'right'; this.state.sideBar.position = position; @@ -323,11 +332,12 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi this.state.sideBar.width = this.workbenchGrid.getViewSize(this.sideBarPartView).width; } - this.workbenchGrid.removeView(this.sideBarPartView); - this.workbenchGrid.removeView(this.activityBarPartView); - - if (!this.state.panel.hidden && this.state.panel.position === Position.BOTTOM) { - this.workbenchGrid.removeView(this.panelPartView); + if (position === Position.LEFT) { + this.workbenchGrid.moveViewTo(this.activityBarPartView, [1, 0]); + this.workbenchGrid.moveViewTo(this.sideBarPartView, [1, 1]); + } else { + this.workbenchGrid.moveViewTo(this.sideBarPartView, [1, 4]); + this.workbenchGrid.moveViewTo(this.activityBarPartView, [1, 4]); } this.layout(); @@ -698,11 +708,14 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi removeClass(this.container, 'nostatusbar'); } + // Propagate to grid + if (this.workbenchGrid instanceof Grid) { + this.workbenchGrid.setViewVisible(this.statusBarPartView, !hidden); + } + // Layout if (!skipLayout) { - if (this.workbenchGrid instanceof Grid) { - this.layout(); - } else { + if (!(this.workbenchGrid instanceof Grid)) { this.workbenchGrid.layout(); } } @@ -726,64 +739,21 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi this.panelPartView = panelPart; this.statusBarPartView = statusBar; - let workbenchGrid: SerializableGrid | undefined; + const viewMap = { + [Parts.ACTIVITYBAR_PART]: this.activityBarPartView, + [Parts.TITLEBAR_PART]: this.titleBarPartView, + [Parts.EDITOR_PART]: this.editorPartView, + [Parts.PANEL_PART]: this.panelPartView, + [Parts.SIDEBAR_PART]: this.sideBarPartView, + [Parts.STATUSBAR_PART]: this.statusBarPartView + }; - const savedGrid = this.storageService.get(Storage.GRID_LAYOUT, StorageScope.GLOBAL, undefined); - if (savedGrid) { - const parsedGrid: ISerializedGrid = JSON.parse(savedGrid); - - const fromJSON = (serializedPart: { type: Parts } | null) => { - if (serializedPart && serializedPart.type) { - switch (serializedPart.type) { - case Parts.ACTIVITYBAR_PART: - return this.activityBarPartView; - case Parts.TITLEBAR_PART: - return this.titleBarPartView; - case Parts.EDITOR_PART: - return this.editorPartView; - case Parts.PANEL_PART: - return this.panelPartView; - case Parts.SIDEBAR_PART: - return this.sideBarPartView; - case Parts.STATUSBAR_PART: - return this.statusBarPartView; - default: - return this.editorPartView; - } - } else { - return this.editorPartView; - } - }; - - try { - workbenchGrid = SerializableGrid.deserialize(parsedGrid, { fromJSON }, { proportionalLayout: false }); - - const root = workbenchGrid.getViews(); - const titleBarSection = root.children[0]; - - if (isGridBranchNode(titleBarSection) || titleBarSection.view !== this.titleBarPartView) { - throw new Error('Bad grid'); - } - - const middleSection = root.children[1] as GridBranchNode; - const sideBarPosition = (middleSection.children[0] as GridLeafNode).view === this.activityBarPartView ? Position.LEFT : Position.RIGHT; - if (sideBarPosition !== this.state.sideBar.position) { - throw new Error('Bad Grid'); - } - - const panelPosition = isGridBranchNode(middleSection.children[2]) || isGridBranchNode(middleSection.children[0]) ? Position.BOTTOM : Position.RIGHT; - if (panelPosition !== this.state.panel.position) { - throw new Error('Bad Grid'); - } - } catch (err) { - workbenchGrid = undefined; - console.error(err); - } - } - - if (!workbenchGrid) { - workbenchGrid = new SerializableGrid(this.editorPartView, { proportionalLayout: false }); - } + const fromJSON = ({ type }: { type: Parts }) => viewMap[type]; + const workbenchGrid = SerializableGrid.deserialize( + this.createGridDescriptor(), + { fromJSON }, + { proportionalLayout: false } + ); this.container.prepend(workbenchGrid.element); this.workbenchGrid = workbenchGrid; @@ -802,9 +772,22 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi this._register(this.storageService.onWillSaveState(() => { const grid = this.workbenchGrid as SerializableGrid; - const serializedGrid = grid.serialize(); - this.storageService.store(Storage.GRID_LAYOUT, JSON.stringify(serializedGrid), StorageScope.GLOBAL); + const sideBarSize = this.state.sideBar.hidden + ? grid.getViewCachedVisibleSize(this.sideBarPartView) + : grid.getViewSize(this.sideBarPartView).width; + + this.storageService.store(Storage.SIDEBAR_SIZE, sideBarSize, StorageScope.GLOBAL); + + const panelSize = this.state.panel.hidden + ? grid.getViewCachedVisibleSize(this.panelPartView) + : (this.state.panel.position === Position.BOTTOM ? grid.getViewSize(this.panelPartView).height : grid.getViewSize(this.panelPartView).width); + + this.storageService.store(Storage.PANEL_SIZE, panelSize, StorageScope.GLOBAL); + + const gridSize = grid.getViewSize(); + this.storageService.store(Storage.GRID_WIDTH, gridSize.width, StorageScope.GLOBAL); + this.storageService.store(Storage.GRID_HEIGHT, gridSize.height, StorageScope.GLOBAL); })); } else { this.workbenchGrid = instantiationService.createInstance( @@ -833,9 +816,6 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi // Layout the grid widget this.workbenchGrid.layout(this._dimension.width, this._dimension.height); - - // Layout grid views - this.layoutGrid(); } else { this.workbenchGrid.layout(options); } @@ -845,95 +825,6 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi } } - private layoutGrid(): void { - if (!(this.workbenchGrid instanceof Grid)) { - return; - } - - let panelInGrid = this.workbenchGrid.hasView(this.panelPartView); - let sidebarInGrid = this.workbenchGrid.hasView(this.sideBarPartView); - let activityBarInGrid = this.workbenchGrid.hasView(this.activityBarPartView); - let statusBarInGrid = this.workbenchGrid.hasView(this.statusBarPartView); - let titlebarInGrid = this.workbenchGrid.hasView(this.titleBarPartView); - - // Add parts to grid - if (!statusBarInGrid) { - this.workbenchGrid.addView(this.statusBarPartView, Sizing.Split, this.editorPartView, Direction.Down); - statusBarInGrid = true; - } - - if (!titlebarInGrid) { - this.workbenchGrid.addView(this.titleBarPartView, Sizing.Split, this.editorPartView, Direction.Up); - - titlebarInGrid = true; - } - - if (!activityBarInGrid) { - this.workbenchGrid.addView(this.activityBarPartView, Sizing.Split, panelInGrid && this.state.sideBar.position === this.state.panel.position ? this.panelPartView : this.editorPartView, this.state.sideBar.position === Position.RIGHT ? Direction.Right : Direction.Left); - activityBarInGrid = true; - } - - if (!sidebarInGrid) { - this.workbenchGrid.addView(this.sideBarPartView, this.state.sideBar.width !== undefined ? this.state.sideBar.width : Sizing.Split, this.activityBarPartView, this.state.sideBar.position === Position.LEFT ? Direction.Right : Direction.Left); - sidebarInGrid = true; - } - - if (!panelInGrid) { - this.workbenchGrid.addView(this.panelPartView, Sizing.Split, this.editorPartView, this.state.panel.position === Position.BOTTOM ? Direction.Down : Direction.Right); - panelInGrid = true; - } - - // Hide parts - if (this.state.panel.hidden) { - this.workbenchGrid.setViewVisible(this.panelPartView, false); - } - - if (this.state.statusBar.hidden) { - this.workbenchGrid.setViewVisible(this.statusBarPartView, false); - } - - if (titlebarInGrid && !this.isVisible(Parts.TITLEBAR_PART)) { - this.workbenchGrid.setViewVisible(this.titleBarPartView, false); - } - - if (this.state.activityBar.hidden) { - this.workbenchGrid.setViewVisible(this.activityBarPartView, false); - } - - if (this.state.sideBar.hidden) { - this.workbenchGrid.setViewVisible(this.sideBarPartView, false); - } - - if (this.state.editor.hidden) { - this.workbenchGrid.setViewVisible(this.editorPartView, false); - } - - // Show visible parts - if (!this.state.editor.hidden) { - this.workbenchGrid.setViewVisible(this.editorPartView, true); - } - - if (!this.state.statusBar.hidden) { - this.workbenchGrid.setViewVisible(this.statusBarPartView, true); - } - - if (this.isVisible(Parts.TITLEBAR_PART)) { - this.workbenchGrid.setViewVisible(this.titleBarPartView, true); - } - - if (!this.state.activityBar.hidden) { - this.workbenchGrid.setViewVisible(this.activityBarPartView, true); - } - - if (!this.state.sideBar.hidden) { - this.workbenchGrid.setViewVisible(this.sideBarPartView, true); - } - - if (!this.state.panel.hidden) { - this.workbenchGrid.setViewVisible(this.panelPartView, true); - } - } - isEditorLayoutCentered(): boolean { return this.state.editor.centered; } @@ -1024,30 +915,32 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi setActivityBarHidden(hidden: boolean, skipLayout?: boolean): void { this.state.activityBar.hidden = hidden; + // Propagate to grid + if (this.workbenchGrid instanceof Grid) { + this.workbenchGrid.setViewVisible(this.activityBarPartView, !hidden); + } + // Layout if (!skipLayout) { - if (this.workbenchGrid instanceof Grid) { - this.layout(); - } else { + if (!(this.workbenchGrid instanceof Grid)) { this.workbenchGrid.layout(); } } } setEditorHidden(hidden: boolean, skipLayout?: boolean): void { - if (!(this.workbenchGrid instanceof Grid) || hidden === this.state.editor.hidden) { + if (!(this.workbenchGrid instanceof Grid)) { return; } this.state.editor.hidden = hidden; - // The editor and the panel cannot be hidden at the same time - if (this.state.editor.hidden && this.state.panel.hidden) { - this.setPanelHidden(false, true); - } + // Propagate to grid + this.workbenchGrid.setViewVisible(this.editorPartView, !hidden); - if (!skipLayout) { - this.layout(); + // The editor and panel cannot be hidden at the same time + if (hidden && this.state.panel.hidden) { + this.setPanelHidden(false, true); } } @@ -1085,6 +978,11 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi } } + // Propagate to grid + if (this.workbenchGrid instanceof Grid) { + this.workbenchGrid.setViewVisible(this.sideBarPartView, !hidden); + } + // Remember in settings const defaultHidden = this.contextService.getWorkbenchState() === WorkbenchState.EMPTY; if (hidden !== defaultHidden) { @@ -1095,9 +993,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi // Layout if (!skipLayout) { - if (this.workbenchGrid instanceof Grid) { - this.layout(); - } else { + if (!(this.workbenchGrid instanceof Grid)) { this.workbenchGrid.layout(); } } @@ -1128,6 +1024,11 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi } } + // Propagate to grid + if (this.workbenchGrid instanceof Grid) { + this.workbenchGrid.setViewVisible(this.panelPartView, !hidden); + } + // Remember in settings if (!hidden) { this.storageService.store(Storage.PANEL_HIDDEN, 'false', StorageScope.WORKSPACE); @@ -1142,9 +1043,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi // Layout if (!skipLayout) { - if (this.workbenchGrid instanceof Grid) { - this.layout(); - } else { + if (!(this.workbenchGrid instanceof Grid)) { this.workbenchGrid.layout(); } } @@ -1216,8 +1115,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi // Layout if (!skipLayout) { if (this.workbenchGrid instanceof Grid) { - const dimensions = getClientArea(this.parent); - this.workbenchGrid.layout(dimensions.width, dimensions.height); + this.workbenchGrid.setViewVisible(this.titleBarPartView, this.isVisible(Parts.TITLEBAR_PART)); } else { this.workbenchGrid.layout(); } @@ -1233,13 +1131,12 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi return this.state.panel.position; } - setPanelPosition(position: Position): void { - const panelPart = this.getPart(Parts.PANEL_PART); - + setPanelPosition(position: Position.BOTTOM | Position.RIGHT): void { if (this.state.panel.hidden) { - this.setPanelHidden(false, true /* Skip Layout */); + this.setPanelHidden(false); } + const panelPart = this.getPart(Parts.PANEL_PART); const newPositionValue = (position === Position.BOTTOM) ? 'bottom' : 'right'; const oldPositionValue = (this.state.panel.position === Position.BOTTOM) ? 'bottom' : 'right'; this.state.panel.position = position; @@ -1263,8 +1160,13 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi // Layout if (this.workbenchGrid instanceof Grid) { - this.workbenchGrid.removeView(this.panelPartView); - this.layout(); + const size = this.workbenchGrid.getViewSize(this.panelPartView); + + if (position === Position.BOTTOM) { + this.workbenchGrid.moveView(this.panelPartView, this.state.editor.hidden ? size.height : size.width, this.editorPartView, Direction.Down); + } else { + this.workbenchGrid.moveView(this.panelPartView, this.state.editor.hidden ? size.width : size.height, this.editorPartView, Direction.Right); + } } else { this.workbenchGrid.layout(); } @@ -1272,9 +1174,88 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi this._onPanelPositionChange.fire(positionToString(this.state.panel.position)); } + private createGridDescriptor(): ISerializedGrid { + const width = this.storageService.getNumber(Storage.GRID_WIDTH, StorageScope.GLOBAL, 600); + const height = this.storageService.getNumber(Storage.GRID_HEIGHT, StorageScope.GLOBAL, 400); + const sideBarSize = this.storageService.getNumber(Storage.SIDEBAR_SIZE, StorageScope.GLOBAL, 300); + const panelSize = this.storageService.getNumber(Storage.PANEL_SIZE, StorageScope.GLOBAL, 300); + + const titleBarHeight = this.titleBarPartView.minimumHeight; + const statusBarHeight = this.statusBarPartView.minimumHeight; + const activityBarWidth = this.activityBarPartView.minimumWidth; + const middleSectionHeight = height - titleBarHeight - statusBarHeight; + const editorSectionWidth = width - (this.state.activityBar.hidden ? 0 : activityBarWidth) - (this.state.sideBar.hidden ? 0 : sideBarSize); + + const activityBarNode: ISerializedLeafNode = { + type: 'leaf', + data: { type: Parts.ACTIVITYBAR_PART }, + size: activityBarWidth, + visible: !this.state.activityBar.hidden + }; + + const sideBarNode: ISerializedLeafNode = { + type: 'leaf', + data: { type: Parts.SIDEBAR_PART }, + size: sideBarSize, + visible: !this.state.sideBar.hidden + }; + + const editorNode: ISerializedLeafNode = { + type: 'leaf', + data: { type: Parts.EDITOR_PART }, + size: this.state.panel.position === Position.BOTTOM ? middleSectionHeight - (this.state.panel.hidden ? 0 : panelSize) : editorSectionWidth - (this.state.panel.hidden ? 0 : panelSize) + }; + + const panelNode: ISerializedLeafNode = { + type: 'leaf', + data: { type: Parts.PANEL_PART }, + size: panelSize, + visible: !this.state.panel.hidden + }; + + const editorSectionNode: ISerializedNode[] = this.state.panel.position === Position.BOTTOM + ? [{ type: 'branch', data: [editorNode, panelNode], size: editorSectionWidth }] + : [editorNode, panelNode]; + + const middleSection: ISerializedNode[] = this.state.sideBar.position === Position.LEFT + ? [activityBarNode, sideBarNode, ...editorSectionNode] + : [...editorSectionNode, sideBarNode, activityBarNode]; + + const result: ISerializedGrid = { + root: { + type: 'branch', + size: width, + data: [ + { + type: 'leaf', + data: { type: Parts.TITLEBAR_PART }, + size: titleBarHeight + }, + { + type: 'branch', + data: middleSection, + size: middleSectionHeight + }, + { + type: 'leaf', + data: { type: Parts.STATUSBAR_PART }, + size: statusBarHeight, + visible: !this.state.statusBar.hidden + } + ] + }, + orientation: Orientation.VERTICAL, + width, + height + }; + + return result; + } + dispose(): void { super.dispose(); this.disposed = true; } } + From 0083b8d2738f289fae4b585e9ebe8fcac97fbffd Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 7 Aug 2019 10:21:01 -0700 Subject: [PATCH 309/861] Re #78168 Zone Widget --- .../editor/contrib/zoneWidget/zoneWidget.ts | 46 +++++++++++-------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/src/vs/editor/contrib/zoneWidget/zoneWidget.ts b/src/vs/editor/contrib/zoneWidget/zoneWidget.ts index 34ed306c947..2e7073d55a6 100644 --- a/src/vs/editor/contrib/zoneWidget/zoneWidget.ts +++ b/src/vs/editor/contrib/zoneWidget/zoneWidget.ts @@ -51,7 +51,7 @@ const WIDGET_ID = 'vs.editor.contrib.zoneWidget'; export class ViewZoneDelegate implements IViewZone { public domNode: HTMLElement; - public id: number; + public id: number = 0; // A valid zone id should be greater than 0 public afterLineNumber: number; public afterColumn: number; public heightInLines: number; @@ -109,8 +109,8 @@ class Arrow { private readonly _ruleName = Arrow._IdGenerator.nextId(); private _decorations: string[] = []; - private _color: string; - private _height: number; + private _color: string | null = null; + private _height: number = -1; constructor( private readonly _editor: ICodeEditor @@ -159,15 +159,15 @@ class Arrow { export abstract class ZoneWidget implements IHorizontalSashLayoutProvider { - private _arrow: Arrow; - private _overlayWidget: OverlayWidgetDelegate | null; - private _resizeSash: Sash; + private _arrow: Arrow | null = null; + private _overlayWidget: OverlayWidgetDelegate | null = null; + private _resizeSash: Sash | null = null; private _positionMarkerId: string[] = []; - protected _viewZone: ViewZoneDelegate | null; + protected _viewZone: ViewZoneDelegate | null = null; protected readonly _disposables = new DisposableStore(); - public container: HTMLElement; + public container: HTMLElement | null = null; public domNode: HTMLElement; public editor: ICodeEditor; public options: IOptions; @@ -273,12 +273,16 @@ export abstract class ZoneWidget implements IHorizontalSashLayoutProvider { private _onViewZoneHeight(height: number): void { this.domNode.style.height = `${height}px`; - let containerHeight = height - this._decoratingElementsHeight(); - this.container.style.height = `${containerHeight}px`; - const layoutInfo = this.editor.getLayoutInfo(); - this._doLayout(containerHeight, this._getWidth(layoutInfo)); + if (this.container) { + let containerHeight = height - this._decoratingElementsHeight(); + this.container.style.height = `${containerHeight}px`; + const layoutInfo = this.editor.getLayoutInfo(); + this._doLayout(containerHeight, this._getWidth(layoutInfo)); + } - this._resizeSash.layout(); + if (this._resizeSash) { + this._resizeSash.layout(); + } } public get position(): Position | undefined { @@ -373,7 +377,7 @@ export abstract class ZoneWidget implements IHorizontalSashLayoutProvider { let frameThickness = 0; // Render the arrow one 1/3 of an editor line height - if (this.options.showArrow) { + if (this._arrow && this.options.showArrow) { arrowHeight = Math.round(lineHeight / 3); this._arrow.height = arrowHeight; this._arrow.show(position); @@ -407,17 +411,19 @@ export abstract class ZoneWidget implements IHorizontalSashLayoutProvider { this.editor.addOverlayWidget(this._overlayWidget); }); - if (this.options.showFrame) { + if (this.container && this.options.showFrame) { const width = this.options.frameWidth ? this.options.frameWidth : frameThickness; this.container.style.borderTopWidth = width + 'px'; this.container.style.borderBottomWidth = width + 'px'; } let containerHeight = heightInLines * lineHeight - this._decoratingElementsHeight(); - this.container.style.top = arrowHeight + 'px'; - this.container.style.height = containerHeight + 'px'; - this.container.style.overflow = 'hidden'; + if (this.container) { + this.container.style.top = arrowHeight + 'px'; + this.container.style.height = containerHeight + 'px'; + this.container.style.overflow = 'hidden'; + } this._doLayout(containerHeight, width); @@ -438,6 +444,10 @@ export abstract class ZoneWidget implements IHorizontalSashLayoutProvider { } protected setCssClass(className: string, classToReplace?: string): void { + if (!this.container) { + return; + } + if (classToReplace) { this.container.classList.remove(classToReplace); } From 6f63733348c3a0e19bea98f5f4b6f84208b6fce6 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 7 Aug 2019 10:23:58 -0700 Subject: [PATCH 310/861] remove scrollOff from top level editor options --- src/vs/editor/common/config/editorOptions.ts | 4 ---- src/vs/monaco.d.ts | 2 -- 2 files changed, 6 deletions(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 86e32ad30b3..7ff1b4a5d31 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -1098,7 +1098,6 @@ export class InternalEditorOptions { readonly pixelRatio: number; readonly editorClassName: string; readonly lineHeight: number; - readonly scrollOff: number; readonly readOnly: boolean; /** * @internal @@ -1191,7 +1190,6 @@ export class InternalEditorOptions { && this.pixelRatio === other.pixelRatio && this.editorClassName === other.editorClassName && this.lineHeight === other.lineHeight - && this.scrollOff === other.scrollOff && this.readOnly === other.readOnly && this.accessibilitySupport === other.accessibilitySupport && this.multiCursorModifier === other.multiCursorModifier @@ -1224,7 +1222,6 @@ export class InternalEditorOptions { pixelRatio: (this.pixelRatio !== newOpts.pixelRatio), editorClassName: (this.editorClassName !== newOpts.editorClassName), lineHeight: (this.lineHeight !== newOpts.lineHeight), - scrollOff: (this.scrollOff !== newOpts.scrollOff), readOnly: (this.readOnly !== newOpts.readOnly), accessibilitySupport: (this.accessibilitySupport !== newOpts.accessibilitySupport), multiCursorModifier: (this.multiCursorModifier !== newOpts.multiCursorModifier), @@ -1630,7 +1627,6 @@ export interface IConfigurationChangedEvent { readonly pixelRatio: boolean; readonly editorClassName: boolean; readonly lineHeight: boolean; - readonly scrollOff: boolean; readonly readOnly: boolean; readonly accessibilitySupport: boolean; readonly multiCursorModifier: boolean; diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 8c7eaf0e598..64a44cefc6e 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -3378,7 +3378,6 @@ declare namespace monaco.editor { readonly pixelRatio: number; readonly editorClassName: string; readonly lineHeight: number; - readonly scrollOff: number; readonly readOnly: boolean; readonly multiCursorModifier: 'altKey' | 'ctrlKey' | 'metaKey'; readonly multiCursorMergeOverlapping: boolean; @@ -3520,7 +3519,6 @@ declare namespace monaco.editor { readonly pixelRatio: boolean; readonly editorClassName: boolean; readonly lineHeight: boolean; - readonly scrollOff: boolean; readonly readOnly: boolean; readonly accessibilitySupport: boolean; readonly multiCursorModifier: boolean; From bcc7f1219fefd5ff74a47b19aa9b261c0b1c449d Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Mon, 5 Aug 2019 09:29:50 -0700 Subject: [PATCH 311/861] Update services for #78285 --- extensions/css-language-features/server/package.json | 2 +- extensions/css-language-features/server/yarn.lock | 8 ++++---- extensions/html-language-features/server/package.json | 2 +- extensions/html-language-features/server/yarn.lock | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/extensions/css-language-features/server/package.json b/extensions/css-language-features/server/package.json index c6e8600d2ae..b27fb14aef7 100644 --- a/extensions/css-language-features/server/package.json +++ b/extensions/css-language-features/server/package.json @@ -9,7 +9,7 @@ }, "main": "./out/cssServerMain", "dependencies": { - "vscode-css-languageservice": "^4.0.3-next.1", + "vscode-css-languageservice": "^4.0.3-next.3", "vscode-languageserver": "^5.3.0-next.8" }, "devDependencies": { diff --git a/extensions/css-language-features/server/yarn.lock b/extensions/css-language-features/server/yarn.lock index d93eec392c7..1f3a45c0844 100644 --- a/extensions/css-language-features/server/yarn.lock +++ b/extensions/css-language-features/server/yarn.lock @@ -781,10 +781,10 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -vscode-css-languageservice@^4.0.3-next.1: - version "4.0.3-next.1" - resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-4.0.3-next.1.tgz#e89d01ce0d79b3e6c2642f5e3ad73cb8160d38d9" - integrity sha512-Zrm5TeraVUJ8vRikWhFt259dQu+WK+Ie3K5UA8BB4kqcanoM+1mcnIt8fPkTXlZLbiEWElrkJ9yuYbDNkufeBg== +vscode-css-languageservice@^4.0.3-next.3: + version "4.0.3-next.3" + resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-4.0.3-next.3.tgz#eb7f642f2785d388d74a1a98fd14f7736a11e316" + integrity sha512-6j/y9ccecrq7/APLPEijx+uWHsEdTFH5ZQHG4ZMKjZx6euny27B1wvLCjpxKnZCWcHgmi7cMDLWpUdElvHjjPQ== dependencies: vscode-languageserver-types "^3.15.0-next.2" vscode-nls "^4.1.1" diff --git a/extensions/html-language-features/server/package.json b/extensions/html-language-features/server/package.json index 95a97f1110f..9b26165edbd 100644 --- a/extensions/html-language-features/server/package.json +++ b/extensions/html-language-features/server/package.json @@ -9,7 +9,7 @@ }, "main": "./out/htmlServerMain", "dependencies": { - "vscode-css-languageservice": "^4.0.3-next.1", + "vscode-css-languageservice": "^4.0.3-next.3", "vscode-html-languageservice": "^3.0.4-next.0", "vscode-languageserver": "^5.3.0-next.8", "vscode-languageserver-types": "3.15.0-next.2", diff --git a/extensions/html-language-features/server/yarn.lock b/extensions/html-language-features/server/yarn.lock index 9ea59b6077c..f8687c97f63 100644 --- a/extensions/html-language-features/server/yarn.lock +++ b/extensions/html-language-features/server/yarn.lock @@ -229,10 +229,10 @@ supports-color@5.4.0: dependencies: has-flag "^3.0.0" -vscode-css-languageservice@^4.0.3-next.1: - version "4.0.3-next.1" - resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-4.0.3-next.1.tgz#e89d01ce0d79b3e6c2642f5e3ad73cb8160d38d9" - integrity sha512-Zrm5TeraVUJ8vRikWhFt259dQu+WK+Ie3K5UA8BB4kqcanoM+1mcnIt8fPkTXlZLbiEWElrkJ9yuYbDNkufeBg== +vscode-css-languageservice@^4.0.3-next.3: + version "4.0.3-next.3" + resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-4.0.3-next.3.tgz#eb7f642f2785d388d74a1a98fd14f7736a11e316" + integrity sha512-6j/y9ccecrq7/APLPEijx+uWHsEdTFH5ZQHG4ZMKjZx6euny27B1wvLCjpxKnZCWcHgmi7cMDLWpUdElvHjjPQ== dependencies: vscode-languageserver-types "^3.15.0-next.2" vscode-nls "^4.1.1" From 2420d4c505bc37a8e6224a6a50b30e9bdd3edb82 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 7 Aug 2019 19:51:28 +0200 Subject: [PATCH 312/861] separate rpc and init data into separate services --- .../workbench/api/common/extHostCommands.ts | 6 ++--- .../api/common/extHostConfiguration.ts | 6 ++--- .../api/common/extHostDecorations.ts | 6 ++--- .../api/common/extHostDocumentsAndEditors.ts | 8 +++--- ...xtService.ts => extHostInitDataService.ts} | 16 +++--------- src/vs/workbench/api/common/extHostOutput.ts | 6 ++--- .../workbench/api/common/extHostWorkspace.ts | 12 +++++---- src/vs/workbench/api/common/rpcService.ts | 25 +++++++++++++++++++ .../api/node/extHostExtensionService.ts | 9 ++++--- .../api/node/extHostOutputService.ts | 12 ++++++--- src/vs/workbench/api/node/extHostTask.ts | 25 ++++++++++--------- .../api/node/extHostTerminalService.ts | 6 ++--- .../extensions/node/extensionHostMain.ts | 11 +++++--- .../api/extHostApiCommands.test.ts | 18 ++++++------- .../api/extHostCommands.test.ts | 7 +++--- .../api/extHostConfiguration.test.ts | 9 +++---- .../extHostDocumentSaveParticipant.test.ts | 6 ++--- .../api/extHostDocumentsAndEditors.test.ts | 14 ++--------- .../api/extHostLanguageFeatures.test.ts | 9 +++---- .../api/extHostTextEditors.test.ts | 6 ++--- .../api/extHostTreeViews.test.ts | 5 ++-- .../api/extHostWorkspace.test.ts | 14 ++++++----- .../electron-browser/api/testRPCProtocol.ts | 7 ++++-- 23 files changed, 124 insertions(+), 119 deletions(-) rename src/vs/workbench/api/common/{extHostContextService.ts => extHostInitDataService.ts} (51%) create mode 100644 src/vs/workbench/api/common/rpcService.ts diff --git a/src/vs/workbench/api/common/extHostCommands.ts b/src/vs/workbench/api/common/extHostCommands.ts index 3ab2fdbf2fc..b0219c67096 100644 --- a/src/vs/workbench/api/common/extHostCommands.ts +++ b/src/vs/workbench/api/common/extHostCommands.ts @@ -19,8 +19,8 @@ import { Position } from 'vs/editor/common/core/position'; import { URI } from 'vs/base/common/uri'; import { Event, Emitter } from 'vs/base/common/event'; import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; -import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; interface CommandHandler { callback: Function; @@ -46,10 +46,10 @@ export class ExtHostCommands implements ExtHostCommandsShape { private readonly _argumentProcessors: ArgumentProcessor[]; constructor( - @IExtHostContextService extHostContext: IExtHostContextService, + @IExtHostRpcService extHostRpc: IExtHostRpcService, @ILogService logService: ILogService ) { - this._proxy = extHostContext.rpc.getProxy(MainContext.MainThreadCommands); + this._proxy = extHostRpc.getProxy(MainContext.MainThreadCommands); this._onDidExecuteCommand = new Emitter({ onFirstListenerDidAdd: () => this._proxy.$registerCommandListener(), onLastListenerRemove: () => this._proxy.$unregisterCommandListener(), diff --git a/src/vs/workbench/api/common/extHostConfiguration.ts b/src/vs/workbench/api/common/extHostConfiguration.ts index 32f8db76d64..bebd81571fc 100644 --- a/src/vs/workbench/api/common/extHostConfiguration.ts +++ b/src/vs/workbench/api/common/extHostConfiguration.ts @@ -18,8 +18,8 @@ import { ConfigurationScope, OVERRIDE_PROPERTY_PATTERN } from 'vs/platform/confi import { isObject } from 'vs/base/common/types'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { Barrier } from 'vs/base/common/async'; -import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; function lookUp(tree: any, key: string) { if (key) { @@ -50,10 +50,10 @@ export class ExtHostConfiguration implements ExtHostConfigurationShape { private _actual: ExtHostConfigProvider | null; constructor( - @IExtHostContextService extHostContext: IExtHostContextService, + @IExtHostRpcService extHostRpc: IExtHostRpcService, @IExtHostWorkspace extHostWorkspace: IExtHostWorkspace ) { - this._proxy = extHostContext.rpc.getProxy(MainContext.MainThreadConfiguration); + this._proxy = extHostRpc.getProxy(MainContext.MainThreadConfiguration); this._extHostWorkspace = extHostWorkspace; this._barrier = new Barrier(); this._actual = null; diff --git a/src/vs/workbench/api/common/extHostDecorations.ts b/src/vs/workbench/api/common/extHostDecorations.ts index 6d964143779..37b57b9de13 100644 --- a/src/vs/workbench/api/common/extHostDecorations.ts +++ b/src/vs/workbench/api/common/extHostDecorations.ts @@ -11,7 +11,7 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { asArray } from 'vs/base/common/arrays'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; interface ProviderData { provider: vscode.DecorationProvider; @@ -27,9 +27,9 @@ export class ExtHostDecorations implements IExtHostDecorations { private readonly _proxy: MainThreadDecorationsShape; constructor( - @IExtHostContextService contextService: IExtHostContextService, + @IExtHostRpcService extHostRpc: IExtHostRpcService, ) { - this._proxy = contextService.rpc.getProxy(MainContext.MainThreadDecorations); + this._proxy = extHostRpc.getProxy(MainContext.MainThreadDecorations); } registerDecorationProvider(provider: vscode.DecorationProvider, extensionId: ExtensionIdentifier): vscode.Disposable { diff --git a/src/vs/workbench/api/common/extHostDocumentsAndEditors.ts b/src/vs/workbench/api/common/extHostDocumentsAndEditors.ts index 0f31898cb3a..6a5762373ec 100644 --- a/src/vs/workbench/api/common/extHostDocumentsAndEditors.ts +++ b/src/vs/workbench/api/common/extHostDocumentsAndEditors.ts @@ -12,8 +12,8 @@ import { ExtHostDocumentData } from 'vs/workbench/api/common/extHostDocumentData import { ExtHostTextEditor } from 'vs/workbench/api/common/extHostTextEditor'; import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters'; import { Disposable } from 'vs/workbench/api/common/extHostTypes'; -import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsShape { @@ -37,7 +37,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha readonly onDidChangeActiveTextEditor: Event = this._onDidChangeActiveTextEditor.event; constructor( - @IExtHostContextService private readonly _ctx: IExtHostContextService, + @IExtHostRpcService private readonly _extHostRpc: IExtHostRpcService, ) { } dispose() { @@ -68,7 +68,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha assert.ok(!this._documents.has(resource.toString()), `document '${resource} already exists!'`); const documentData = new ExtHostDocumentData( - this._ctx.rpc.getProxy(MainContext.MainThreadDocuments), + this._extHostRpc.getProxy(MainContext.MainThreadDocuments), resource, data.lines, data.EOL, @@ -99,7 +99,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha const documentData = this._documents.get(resource.toString())!; const editor = new ExtHostTextEditor( - this._ctx.rpc.getProxy(MainContext.MainThreadTextEditors), + this._extHostRpc.getProxy(MainContext.MainThreadTextEditors), data.id, documentData, data.selections.map(typeConverters.Selection.to), diff --git a/src/vs/workbench/api/common/extHostContextService.ts b/src/vs/workbench/api/common/extHostInitDataService.ts similarity index 51% rename from src/vs/workbench/api/common/extHostContextService.ts rename to src/vs/workbench/api/common/extHostInitDataService.ts index 77094e73009..2f0acd57a3c 100644 --- a/src/vs/workbench/api/common/extHostContextService.ts +++ b/src/vs/workbench/api/common/extHostInitDataService.ts @@ -3,22 +3,12 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IMainContext, IInitData } from './extHost.protocol'; +import { IInitData } from './extHost.protocol'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -export const IExtHostContextService = createDecorator('IExtHostContextService'); +export const IExtHostInitDataService = createDecorator('IExtHostInitDataService'); -export interface IExtHostContextService { +export interface IExtHostInitDataService extends Readonly { _serviceBrand: undefined; - - readonly rpc: IMainContext; - readonly initData: IInitData; } -export class ExtHostContextService implements IExtHostContextService { - _serviceBrand: any; - constructor( - readonly rpc: IMainContext, - readonly initData: IInitData - ) { } -} diff --git a/src/vs/workbench/api/common/extHostOutput.ts b/src/vs/workbench/api/common/extHostOutput.ts index 91466ccaf92..78aca487bf8 100644 --- a/src/vs/workbench/api/common/extHostOutput.ts +++ b/src/vs/workbench/api/common/extHostOutput.ts @@ -10,7 +10,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { VSBuffer } from 'vs/base/common/buffer'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; export abstract class AbstractExtHostOutputChannel extends Disposable implements vscode.OutputChannel { @@ -143,8 +143,8 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape { protected readonly _channels: Map = new Map(); protected readonly _visibleChannelDisposable = new MutableDisposable(); - constructor(@IExtHostContextService extHostContext: IExtHostContextService) { - this._proxy = extHostContext.rpc.getProxy(MainContext.MainThreadOutputService); + constructor(@IExtHostRpcService extHostRpc: IExtHostRpcService) { + this._proxy = extHostRpc.getProxy(MainContext.MainThreadOutputService); } $setVisibleChannel(channelId: string): void { diff --git a/src/vs/workbench/api/common/extHostWorkspace.ts b/src/vs/workbench/api/common/extHostWorkspace.ts index fa066e18686..e0b0b2006d6 100644 --- a/src/vs/workbench/api/common/extHostWorkspace.ts +++ b/src/vs/workbench/api/common/extHostWorkspace.ts @@ -25,8 +25,9 @@ import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensio import { Barrier } from 'vs/base/common/async'; import { Schemas } from 'vs/base/common/network'; import { withUndefinedAsNull } from 'vs/base/common/types'; -import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; +import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; export interface IExtHostWorkspaceProvider { getWorkspaceFolder2(uri: vscode.Uri, resolveParent?: boolean): Promise; @@ -173,16 +174,17 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac private readonly _activeSearchCallbacks: ((match: IRawFileMatch2) => any)[] = []; constructor( - @IExtHostContextService extHostContext: IExtHostContextService, + @IExtHostRpcService extHostRpc: IExtHostRpcService, + @IExtHostInitDataService initData: IExtHostInitDataService, @ILogService logService: ILogService, ) { this._logService = logService; this._requestIdProvider = new Counter(); this._barrier = new Barrier(); - this._proxy = extHostContext.rpc.getProxy(MainContext.MainThreadWorkspace); - this._messageService = extHostContext.rpc.getProxy(MainContext.MainThreadMessageService); - const data = extHostContext.initData.workspace; + this._proxy = extHostRpc.getProxy(MainContext.MainThreadWorkspace); + this._messageService = extHostRpc.getProxy(MainContext.MainThreadMessageService); + const data = initData.workspace; this._confirmedWorkspace = data ? new ExtHostWorkspaceImpl(data.id, data.name, [], data.configuration ? URI.revive(data.configuration) : null, !!data.isUntitled) : undefined; } diff --git a/src/vs/workbench/api/common/rpcService.ts b/src/vs/workbench/api/common/rpcService.ts new file mode 100644 index 00000000000..5cff20d4006 --- /dev/null +++ b/src/vs/workbench/api/common/rpcService.ts @@ -0,0 +1,25 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IMainContext } from 'vs/workbench/api/common/extHost.protocol'; +import { ProxyIdentifier } from 'vs/workbench/services/extensions/common/proxyIdentifier'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; + +export const IExtHostRpcService = createDecorator('IExtHostRpcService'); + +export interface IExtHostRpcService { + _serviceBrand: any; + getProxy(identifier: ProxyIdentifier): T; +} + +export class ExtHostRpcService implements IExtHostRpcService { + readonly _serviceBrand: any; + + constructor(private readonly _mainContext: IMainContext) { } + + getProxy(identifier: ProxyIdentifier): T { + return this._mainContext.getProxy(identifier); + } +} diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index faafb11b7fe..0d1c9447fc6 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -35,7 +35,7 @@ import { RemoteAuthorityResolverError, ExtensionExecutionContext } from 'vs/work import { IURITransformer } from 'vs/base/common/uriIpc'; import { ResolvedAuthority, ResolvedOptions } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; +import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; interface ITestRunner { /** Old test runner API, as exported from `vscode/lib/testrunner` */ @@ -99,15 +99,16 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { constructor( hostUtils: IHostUtils, uriTransformer: IURITransformer | null, + extHostContext: IMainContext, @IInstantiationService instaService: IInstantiationService, - @IExtHostContextService extHostContext: IExtHostContextService, @IExtHostWorkspace extHostWorkspace: IExtHostWorkspace, @IExtHostConfiguration extHostConfiguration: IExtHostConfiguration, @ILogService extHostLogService: ExtHostLogService, + @IExtHostInitDataService initData: IExtHostInitDataService ) { this._hostUtils = hostUtils; - this._initData = extHostContext.initData; - this._extHostContext = extHostContext.rpc; + this._extHostContext = extHostContext; + this._initData = initData; this._instaService = instaService; this._extHostWorkspace = extHostWorkspace; this._extHostConfiguration = extHostConfiguration; diff --git a/src/vs/workbench/api/node/extHostOutputService.ts b/src/vs/workbench/api/node/extHostOutputService.ts index 9a228497d4e..5ad2047201a 100644 --- a/src/vs/workbench/api/node/extHostOutputService.ts +++ b/src/vs/workbench/api/node/extHostOutputService.ts @@ -11,7 +11,8 @@ import { OutputAppender } from 'vs/workbench/services/output/node/outputAppender import { toLocalISOString } from 'vs/base/common/date'; import { dirExists, mkdirp } from 'vs/base/node/pfs'; import { AbstractExtHostOutputChannel, ExtHostPushOutputChannel, ExtHostOutputService, LazyOutputChannel } from 'vs/workbench/api/common/extHostOutput'; -import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; +import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; export class ExtHostOutputChannelBackedByFile extends AbstractExtHostOutputChannel { @@ -49,9 +50,12 @@ export class ExtHostOutputService2 extends ExtHostOutputService { private _logsLocation: URI; private _namePool: number = 1; - constructor(@IExtHostContextService extHostContext: IExtHostContextService) { - super(extHostContext); - this._logsLocation = extHostContext.initData.logsLocation; + constructor( + @IExtHostRpcService extHostRpc: IExtHostRpcService, + @IExtHostInitDataService initData: IExtHostInitDataService, + ) { + super(extHostRpc); + this._logsLocation = initData.logsLocation; } createOutputChannel(name: string): vscode.OutputChannel { diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index de5c164f00d..cd5e36c82dc 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -15,7 +15,7 @@ import { win32 } from 'vs/base/node/processes'; import { MainContext, MainThreadTaskShape, ExtHostTaskShape, IMainContext } from 'vs/workbench/api/common/extHost.protocol'; import * as types from 'vs/workbench/api/common/extHostTypes'; -import { ExtHostWorkspace, IExtHostWorkspaceProvider } from 'vs/workbench/api/common/extHostWorkspace'; +import { IExtHostWorkspaceProvider, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import * as vscode from 'vscode'; import { TaskDefinitionDTO, TaskExecutionDTO, TaskPresentationOptionsDTO, @@ -25,8 +25,8 @@ import { TaskDTO, TaskHandleDTO, TaskFilterDTO, TaskProcessStartedDTO, TaskProcessEndedDTO, TaskSystemInfoDTO, TaskSetDTO } from '../common/shared/tasks'; import { ExtHostVariableResolverService } from 'vs/workbench/api/node/extHostDebugService'; -import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; -import { ExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; +import { IExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; +import { IExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { CancellationToken } from 'vs/base/common/cancellation'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; @@ -354,11 +354,11 @@ interface HandlerData { export class ExtHostTask implements ExtHostTaskShape { - private _proxy: MainThreadTaskShape; - private _workspaceProvider: IExtHostWorkspaceProvider; - private _editorService: ExtHostDocumentsAndEditors; - private _configurationService: ExtHostConfiguration; - private _terminalService: IExtHostTerminalService; + private readonly _proxy: MainThreadTaskShape; + private readonly _workspaceProvider: IExtHostWorkspaceProvider; + private readonly _editorService: IExtHostDocumentsAndEditors; + private readonly _configurationService: IExtHostConfiguration; + private readonly _terminalService: IExtHostTerminalService; private _handleCounter: number; private _handlers: Map; private _taskExecutions: Map; @@ -373,10 +373,11 @@ export class ExtHostTask implements ExtHostTaskShape { constructor( mainContext: IMainContext, - workspaceService: ExtHostWorkspace, - editorService: ExtHostDocumentsAndEditors, - configurationService: ExtHostConfiguration, - extHostTerminalService: IExtHostTerminalService) { + @IExtHostWorkspace workspaceService: IExtHostWorkspace, + @IExtHostDocumentsAndEditors editorService: IExtHostDocumentsAndEditors, + @IExtHostConfiguration configurationService: IExtHostConfiguration, + @IExtHostTerminalService extHostTerminalService: IExtHostTerminalService + ) { this._proxy = mainContext.getProxy(MainContext.MainThreadTask); this._workspaceProvider = workspaceService; this._editorService = editorService; diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index d6f5694833a..f1d27d99781 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -23,8 +23,8 @@ import { ExtHostDocumentsAndEditors, IExtHostDocumentsAndEditors } from 'vs/work import { getSystemShell, detectAvailableShells } from 'vs/workbench/contrib/terminal/node/terminal'; import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; import { IDisposable } from 'vs/base/common/lifecycle'; -import { IExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; export class BaseExtHostTerminal { public _id: number | undefined; @@ -228,13 +228,13 @@ export class ExtHostTerminalService implements IExtHostTerminalService, ExtHostT public get onDidWriteTerminalData(): Event { return this._onDidWriteTerminalData && this._onDidWriteTerminalData.event; } constructor( - @IExtHostContextService extHostContext: IExtHostContextService, + @IExtHostRpcService extHostRpc: IExtHostRpcService, @IExtHostConfiguration private _extHostConfiguration: ExtHostConfiguration, @IExtHostWorkspace private _extHostWorkspace: ExtHostWorkspace, @IExtHostDocumentsAndEditors private _extHostDocumentsAndEditors: ExtHostDocumentsAndEditors, @ILogService private _logService: ILogService ) { - this._proxy = extHostContext.rpc.getProxy(MainContext.MainThreadTerminalService); + this._proxy = extHostRpc.getProxy(MainContext.MainThreadTerminalService); this._onDidWriteTerminalData = new Emitter({ onFirstListenerAdd: () => this._proxy.$startSendingDataEvents(), onLastListenerRemove: () => this._proxy.$stopSendingDataEvents() diff --git a/src/vs/workbench/services/extensions/node/extensionHostMain.ts b/src/vs/workbench/services/extensions/node/extensionHostMain.ts index 18b294ad091..9a35343785c 100644 --- a/src/vs/workbench/services/extensions/node/extensionHostMain.ts +++ b/src/vs/workbench/services/extensions/node/extensionHostMain.ts @@ -17,9 +17,10 @@ import { IExtensionDescription } from 'vs/platform/extensions/common/extensions' import { ILogService } from 'vs/platform/log/common/log'; import { getSingletonServiceDescriptors } from 'vs/platform/instantiation/common/extensions'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; -import { IExtHostContextService, ExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; +import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IExtHostRpcService, ExtHostRpcService } from 'vs/workbench/api/common/rpcService'; // we don't (yet) throw when extensions parse // uris that have no scheme @@ -68,10 +69,11 @@ export class ExtensionHostMain { // bootstrap services const services = new ServiceCollection(...getSingletonServiceDescriptors()); - services.set(IExtHostContextService, new ExtHostContextService(rpcProtocol, initData)); + services.set(IExtHostInitDataService, { _serviceBrand: undefined, ...initData }); + services.set(IExtHostRpcService, new ExtHostRpcService(rpcProtocol)); services.set(ILogService, extHostLogService); - const instaService: IInstantiationService = new InstantiationService(services); + const instaService: IInstantiationService = new InstantiationService(services, true); extHostLogService.info('extension host started'); extHostLogService.trace('initData', initData); @@ -79,7 +81,8 @@ export class ExtensionHostMain { this._extensionService = instaService.createInstance( ExtHostExtensionService, hostUtils, - uriTransformer + uriTransformer, + rpcProtocol ); // error forwarding and stack trace scanning diff --git a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts index ea33dffbd70..02dbd2c7852 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts @@ -21,7 +21,7 @@ import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; import { MainThreadCommands } from 'vs/workbench/api/browser/mainThreadCommands'; import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; -import { MainContext, ExtHostContext, IInitData } from 'vs/workbench/api/common/extHost.protocol'; +import { MainContext, ExtHostContext } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostDiagnostics } from 'vs/workbench/api/common/extHostDiagnostics'; import * as vscode from 'vscode'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -30,8 +30,6 @@ import { NullLogService } from 'vs/platform/log/common/log'; import { ITextModel } from 'vs/editor/common/model'; import { nullExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; import { dispose } from 'vs/base/common/lifecycle'; -import { ExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; -import { mock } from 'vs/workbench/test/electron-browser/api/mock'; const defaultSelector = { scheme: 'far' }; const model: ITextModel = EditorModel.createFromString( @@ -95,9 +93,7 @@ suite('ExtHostLanguageFeatureCommands', function () { inst = instantiationService; } - const extHostContext = new ExtHostContextService(rpcProtocol, new class extends mock() { }); - - const extHostDocumentsAndEditors = new ExtHostDocumentsAndEditors(extHostContext); + const extHostDocumentsAndEditors = new ExtHostDocumentsAndEditors(rpcProtocol); extHostDocumentsAndEditors.$acceptDocumentsAndEditorsDelta({ addedDocuments: [{ isDirty: false, @@ -111,7 +107,7 @@ suite('ExtHostLanguageFeatureCommands', function () { const extHostDocuments = new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors); rpcProtocol.set(ExtHostContext.ExtHostDocuments, extHostDocuments); - commands = new ExtHostCommands(extHostContext, new NullLogService()); + commands = new ExtHostCommands(rpcProtocol, new NullLogService()); rpcProtocol.set(ExtHostContext.ExtHostCommands, commands); rpcProtocol.set(MainContext.MainThreadCommands, inst.createInstance(MainThreadCommands, rpcProtocol)); ExtHostApiCommands.register(commands); @@ -185,7 +181,7 @@ suite('ExtHostLanguageFeatureCommands', function () { test('executeWorkspaceSymbolProvider should accept empty string, #39522', async function () { disposables.push(extHost.registerWorkspaceSymbolProvider(nullExtensionDescription, { - provideWorkspaceSymbols(query): vscode.SymbolInformation[] { + provideWorkspaceSymbols(): vscode.SymbolInformation[] { return [new types.SymbolInformation('hello', types.SymbolKind.Array, new types.Range(0, 0, 0, 0), URI.parse('foo:bar')) as vscode.SymbolInformation]; } })); @@ -316,7 +312,7 @@ suite('ExtHostLanguageFeatureCommands', function () { test('reference search, back and forth', function () { disposables.push(extHost.registerReferenceProvider(nullExtensionDescription, defaultSelector, { - provideReferences(doc: any) { + provideReferences() { return [ new types.Location(URI.parse('some:uri/path'), new types.Range(0, 1, 0, 5)) ]; @@ -392,7 +388,7 @@ suite('ExtHostLanguageFeatureCommands', function () { test('Suggest, back and forth', function () { disposables.push(extHost.registerCompletionItemProvider(nullExtensionDescription, defaultSelector, { - provideCompletionItems(doc, pos): any { + provideCompletionItems(): any { let a = new types.CompletionItem('item1'); let b = new types.CompletionItem('item2'); b.textEdit = types.TextEdit.replace(new types.Range(0, 4, 0, 8), 'foo'); // overwite after @@ -728,7 +724,7 @@ suite('ExtHostLanguageFeatureCommands', function () { provideDocumentColors(): vscode.ColorInformation[] { return [new types.ColorInformation(new types.Range(0, 0, 0, 20), new types.Color(0.1, 0.2, 0.3, 0.4))]; }, - provideColorPresentations(color: vscode.Color, context: { range: vscode.Range, document: vscode.TextDocument }): vscode.ColorPresentation[] { + provideColorPresentations(): vscode.ColorPresentation[] { const cp = new types.ColorPresentation('#ABC'); cp.textEdit = types.TextEdit.replace(new types.Range(1, 0, 1, 20), '#ABC'); cp.additionalTextEdits = [types.TextEdit.insert(new types.Position(2, 20), '*')]; diff --git a/src/vs/workbench/test/electron-browser/api/extHostCommands.test.ts b/src/vs/workbench/test/electron-browser/api/extHostCommands.test.ts index 0f4769ae329..cbf97988142 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostCommands.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostCommands.test.ts @@ -5,12 +5,11 @@ import * as assert from 'assert'; import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; -import { MainThreadCommandsShape, IInitData } from 'vs/workbench/api/common/extHost.protocol'; +import { MainThreadCommandsShape } from 'vs/workbench/api/common/extHost.protocol'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { SingleProxyRPCProtocol } from './testRPCProtocol'; import { mock } from 'vs/workbench/test/electron-browser/api/mock'; import { NullLogService } from 'vs/platform/log/common/log'; -import { ExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; suite('ExtHostCommands', function () { @@ -28,7 +27,7 @@ suite('ExtHostCommands', function () { }; const commands = new ExtHostCommands( - new ExtHostContextService(SingleProxyRPCProtocol(shape), new class extends mock() { }), + SingleProxyRPCProtocol(shape), new NullLogService() ); commands.registerCommand(true, 'foo', (): any => { }).dispose(); @@ -51,7 +50,7 @@ suite('ExtHostCommands', function () { }; const commands = new ExtHostCommands( - new ExtHostContextService(SingleProxyRPCProtocol(shape), new class extends mock() { }), + SingleProxyRPCProtocol(shape), new NullLogService() ); const reg = commands.registerCommand(true, 'foo', (): any => { }); diff --git a/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts b/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts index 4e2f172115a..c2bfcdd6605 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostConfiguration.test.ts @@ -7,7 +7,7 @@ import * as assert from 'assert'; import { URI, UriComponents } from 'vs/base/common/uri'; import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import { ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration'; -import { MainThreadConfigurationShape, IConfigurationInitData, IInitData } from 'vs/workbench/api/common/extHost.protocol'; +import { MainThreadConfigurationShape, IConfigurationInitData } from 'vs/workbench/api/common/extHost.protocol'; import { ConfigurationModel } from 'vs/platform/configuration/common/configurationModels'; import { TestRPCProtocol } from './testRPCProtocol'; import { mock } from 'vs/workbench/test/electron-browser/api/mock'; @@ -15,6 +15,7 @@ import { IWorkspaceFolder, WorkspaceFolder } from 'vs/platform/workspace/common/ import { ConfigurationTarget, IConfigurationModel } from 'vs/platform/configuration/common/configuration'; import { NullLogService } from 'vs/platform/log/common/log'; import { assign } from 'vs/base/common/objects'; +import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; suite('ExtHostConfiguration', function () { @@ -27,11 +28,7 @@ suite('ExtHostConfiguration', function () { } function createExtHostWorkspace(): ExtHostWorkspace { - return new ExtHostWorkspace({ - _serviceBrand: undefined, - rpc: new TestRPCProtocol(), - initData: new class extends mock() { } - }, new NullLogService()); + return new ExtHostWorkspace(new TestRPCProtocol(), new class extends mock() { }, new NullLogService()); } function createExtHostConfiguration(contents: any = Object.create(null), shape?: MainThreadConfigurationShape) { diff --git a/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts b/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts index bf67278fb60..d85eae55ebf 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostDocumentSaveParticipant.test.ts @@ -7,7 +7,7 @@ import { URI } from 'vs/base/common/uri'; import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { TextDocumentSaveReason, TextEdit, Position, EndOfLine } from 'vs/workbench/api/common/extHostTypes'; -import { MainThreadTextEditorsShape, IWorkspaceEditDto, IInitData } from 'vs/workbench/api/common/extHost.protocol'; +import { MainThreadTextEditorsShape, IWorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostDocumentSaveParticipant } from 'vs/workbench/api/common/extHostDocumentSaveParticipant'; import { SingleProxyRPCProtocol } from './testRPCProtocol'; import { SaveReason } from 'vs/workbench/services/textfile/common/textfiles'; @@ -17,7 +17,6 @@ import { NullLogService } from 'vs/platform/log/common/log'; import { isResourceTextEdit, ResourceTextEdit } from 'vs/editor/common/modes'; import { timeout } from 'vs/base/common/async'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; -import { ExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; suite('ExtHostDocumentSaveParticipant', () => { @@ -38,8 +37,7 @@ suite('ExtHostDocumentSaveParticipant', () => { }; setup(() => { - const extHostContext = new ExtHostContextService(SingleProxyRPCProtocol(null), new class extends mock() { }); - const documentsAndEditors = new ExtHostDocumentsAndEditors(extHostContext); + const documentsAndEditors = new ExtHostDocumentsAndEditors(SingleProxyRPCProtocol(null)); documentsAndEditors.$acceptDocumentsAndEditorsDelta({ addedDocuments: [{ isDirty: false, diff --git a/src/vs/workbench/test/electron-browser/api/extHostDocumentsAndEditors.test.ts b/src/vs/workbench/test/electron-browser/api/extHostDocumentsAndEditors.test.ts index 8eb015f77dc..ce9209f9344 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostDocumentsAndEditors.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostDocumentsAndEditors.test.ts @@ -6,24 +6,14 @@ import * as assert from 'assert'; import { URI } from 'vs/base/common/uri'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; -import { mock } from 'vs/workbench/test/electron-browser/api/mock'; -import { IInitData } from 'vs/workbench/api/common/extHost.protocol'; +import { TestRPCProtocol } from 'vs/workbench/test/electron-browser/api/testRPCProtocol'; suite('ExtHostDocumentsAndEditors', () => { let editors: ExtHostDocumentsAndEditors; setup(function () { - - editors = new ExtHostDocumentsAndEditors({ - _serviceBrand: undefined, - rpc: { - getProxy: () => { return undefined!; }, - set: undefined!, - assertRegistered: undefined! - }, - initData: new class extends mock() { } - }); + editors = new ExtHostDocumentsAndEditors(new TestRPCProtocol()); }); test('The value of TextDocument.isClosed is incorrect when a text document is closed, #27949', () => { diff --git a/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts b/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts index b31cebfb56d..18ecedc673b 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostLanguageFeatures.test.ts @@ -34,7 +34,7 @@ import { provideSignatureHelp } from 'vs/editor/contrib/parameterHints/provideSi import { provideSuggestionItems, CompletionOptions } from 'vs/editor/contrib/suggest/suggest'; import { getDocumentFormattingEditsUntilResult, getDocumentRangeFormattingEditsUntilResult, getOnTypeFormattingEdits } from 'vs/editor/contrib/format/format'; import { getLinks } from 'vs/editor/contrib/links/getLinks'; -import { MainContext, ExtHostContext, IInitData } from 'vs/workbench/api/common/extHost.protocol'; +import { MainContext, ExtHostContext } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostDiagnostics } from 'vs/workbench/api/common/extHostDiagnostics'; import * as vscode from 'vscode'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -48,7 +48,6 @@ import { mock } from 'vs/workbench/test/electron-browser/api/mock'; import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService'; import { dispose } from 'vs/base/common/lifecycle'; import { withNullAsUndefined } from 'vs/base/common/types'; -import { ExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; const defaultSelector = { scheme: 'far' }; const model: ITextModel = EditorModel.createFromString( @@ -86,9 +85,7 @@ suite('ExtHostLanguageFeatures', function () { originalErrorHandler = errorHandler.getUnexpectedErrorHandler(); setUnexpectedErrorHandler(() => { }); - const extHostContext = new ExtHostContextService(rpcProtocol, new class extends mock() { }); - - const extHostDocumentsAndEditors = new ExtHostDocumentsAndEditors(extHostContext); + const extHostDocumentsAndEditors = new ExtHostDocumentsAndEditors(rpcProtocol); extHostDocumentsAndEditors.$acceptDocumentsAndEditorsDelta({ addedDocuments: [{ isDirty: false, @@ -102,7 +99,7 @@ suite('ExtHostLanguageFeatures', function () { const extHostDocuments = new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors); rpcProtocol.set(ExtHostContext.ExtHostDocuments, extHostDocuments); - const commands = new ExtHostCommands(extHostContext, new NullLogService()); + const commands = new ExtHostCommands(rpcProtocol, new NullLogService()); rpcProtocol.set(ExtHostContext.ExtHostCommands, commands); rpcProtocol.set(MainContext.MainThreadCommands, inst.createInstance(MainThreadCommands, rpcProtocol)); diff --git a/src/vs/workbench/test/electron-browser/api/extHostTextEditors.test.ts b/src/vs/workbench/test/electron-browser/api/extHostTextEditors.test.ts index 3690ff5519f..a66b5b43b9f 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostTextEditors.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostTextEditors.test.ts @@ -4,14 +4,13 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as extHostTypes from 'vs/workbench/api/common/extHostTypes'; -import { MainContext, MainThreadTextEditorsShape, IWorkspaceEditDto, IInitData } from 'vs/workbench/api/common/extHost.protocol'; +import { MainContext, MainThreadTextEditorsShape, IWorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol'; import { URI } from 'vs/base/common/uri'; import { mock } from 'vs/workbench/test/electron-browser/api/mock'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { SingleProxyRPCProtocol, TestRPCProtocol } from 'vs/workbench/test/electron-browser/api/testRPCProtocol'; import { ExtHostEditors } from 'vs/workbench/api/common/extHostTextEditors'; import { ResourceTextEdit } from 'vs/editor/common/modes'; -import { ExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; suite('ExtHostTextEditors.applyWorkspaceEdit', () => { @@ -29,8 +28,7 @@ suite('ExtHostTextEditors.applyWorkspaceEdit', () => { return Promise.resolve(true); } }); - const extHostContext = new ExtHostContextService(SingleProxyRPCProtocol(null), new class extends mock() { }); - const documentsAndEditors = new ExtHostDocumentsAndEditors(extHostContext); + const documentsAndEditors = new ExtHostDocumentsAndEditors(SingleProxyRPCProtocol(null)); documentsAndEditors.$acceptDocumentsAndEditorsDelta({ addedDocuments: [{ isDirty: false, diff --git a/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts b/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts index f0e702295d8..bc50a3dd00a 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts @@ -8,7 +8,7 @@ import * as sinon from 'sinon'; import { Emitter } from 'vs/base/common/event'; import { ExtHostTreeViews } from 'vs/workbench/api/common/extHostTreeViews'; import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; -import { MainThreadTreeViewsShape, MainContext, IInitData } from 'vs/workbench/api/common/extHost.protocol'; +import { MainThreadTreeViewsShape, MainContext } from 'vs/workbench/api/common/extHost.protocol'; import { TreeDataProvider, TreeItem } from 'vscode'; import { TestRPCProtocol } from './testRPCProtocol'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; @@ -18,7 +18,6 @@ import { mock } from 'vs/workbench/test/electron-browser/api/mock'; import { TreeItemCollapsibleState, ITreeItem } from 'vs/workbench/common/views'; import { NullLogService } from 'vs/platform/log/common/log'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; -import { ExtHostContextService } from 'vs/workbench/api/common/extHostContextService'; suite('ExtHostTreeView', function () { @@ -73,7 +72,7 @@ suite('ExtHostTreeView', function () { rpcProtocol.set(MainContext.MainThreadCommands, inst.createInstance(MainThreadCommands, rpcProtocol)); target = new RecordingShape(); testObject = new ExtHostTreeViews(target, new ExtHostCommands( - new ExtHostContextService(rpcProtocol, new class extends mock() { }), + rpcProtocol, new NullLogService() ), new NullLogService()); onDidChangeTreeNode = new Emitter<{ key: string }>(); diff --git a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts index 833b6dbc7a9..285ac356774 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts @@ -11,18 +11,20 @@ import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensio import { ILogService, NullLogService } from 'vs/platform/log/common/log'; import { IWorkspaceFolderData } from 'vs/platform/workspace/common/workspace'; import { MainThreadWorkspace } from 'vs/workbench/api/browser/mainThreadWorkspace'; -import { IMainContext, IWorkspaceData, MainContext, IInitData } from 'vs/workbench/api/common/extHost.protocol'; +import { IMainContext, IWorkspaceData, MainContext } from 'vs/workbench/api/common/extHost.protocol'; import { RelativePattern } from 'vs/workbench/api/common/extHostTypes'; import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import { mock } from 'vs/workbench/test/electron-browser/api/mock'; import { TestRPCProtocol } from './testRPCProtocol'; +import { ExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; function createExtHostWorkspace(mainContext: IMainContext, data: IWorkspaceData, logService: ILogService): ExtHostWorkspace { - const result = new ExtHostWorkspace({ - _serviceBrand: undefined, - rpc: mainContext, - initData: new class extends mock() { workspace = data; } - }, logService); + const result = new ExtHostWorkspace( + new ExtHostRpcService(mainContext), + new class extends mock() { workspace = data; }, + logService + ); result.$initializeWorkspace(data); return result; } diff --git a/src/vs/workbench/test/electron-browser/api/testRPCProtocol.ts b/src/vs/workbench/test/electron-browser/api/testRPCProtocol.ts index 64fa203834f..a51c4feb788 100644 --- a/src/vs/workbench/test/electron-browser/api/testRPCProtocol.ts +++ b/src/vs/workbench/test/electron-browser/api/testRPCProtocol.ts @@ -7,9 +7,11 @@ import { ProxyIdentifier } from 'vs/workbench/services/extensions/common/proxyId import { CharCode } from 'vs/base/common/charCode'; import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol'; import { isThenable } from 'vs/base/common/async'; +import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; -export function SingleProxyRPCProtocol(thing: any): IExtHostContext { +export function SingleProxyRPCProtocol(thing: any): IExtHostContext & IExtHostRpcService { return { + _serviceBrand: undefined, remoteAuthority: null!, getProxy(): T { return thing; @@ -21,8 +23,9 @@ export function SingleProxyRPCProtocol(thing: any): IExtHostContext { }; } -export class TestRPCProtocol implements IExtHostContext { +export class TestRPCProtocol implements IExtHostContext, IExtHostRpcService { + public _serviceBrand = undefined; public remoteAuthority = null!; private _callCountValue: number = 0; From b72129dc4de74e26033ad75a8194a22af6d3fc7d Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Wed, 7 Aug 2019 10:27:13 -0700 Subject: [PATCH 313/861] fixes #78176 --- src/vs/workbench/browser/layout.ts | 4 ++++ src/vs/workbench/browser/parts/sidebar/sidebarPart.ts | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 3ca0bb99b63..08fbdd94d74 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -1161,12 +1161,16 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi // Layout if (this.workbenchGrid instanceof Grid) { const size = this.workbenchGrid.getViewSize(this.panelPartView); + const sideBarSize = this.workbenchGrid.getViewSize(this.sideBarPartView); if (position === Position.BOTTOM) { this.workbenchGrid.moveView(this.panelPartView, this.state.editor.hidden ? size.height : size.width, this.editorPartView, Direction.Down); } else { this.workbenchGrid.moveView(this.panelPartView, this.state.editor.hidden ? size.width : size.height, this.editorPartView, Direction.Right); } + + // Reset sidebar to original size before shifting the panel + this.workbenchGrid.resizeView(this.sideBarPartView, sideBarSize); } else { this.workbenchGrid.layout(); } diff --git a/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts b/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts index b2a2c74ca93..66650e527f7 100644 --- a/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts +++ b/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts @@ -31,6 +31,7 @@ import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/c import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { LayoutPriority } from 'vs/base/browser/ui/grid/grid'; export class SidebarPart extends CompositePart implements IViewletService { @@ -45,6 +46,8 @@ export class SidebarPart extends CompositePart implements IViewletServi readonly minimumHeight: number = 0; readonly maximumHeight: number = Number.POSITIVE_INFINITY; + readonly priority: LayoutPriority = LayoutPriority.Low; + readonly snap = true; get preferredWidth(): number | undefined { From c2f2b855029f4c078ee11431411982811abd7181 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 7 Aug 2019 20:07:32 +0200 Subject: [PATCH 314/861] register ExtHostTask as service --- src/vs/workbench/api/common/extHostTask.ts | 30 +++++++++++++++++++ src/vs/workbench/api/node/extHost.api.impl.ts | 4 +-- src/vs/workbench/api/node/extHost.services.ts | 3 ++ src/vs/workbench/api/node/extHostTask.ts | 9 ++++-- 4 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 src/vs/workbench/api/common/extHostTask.ts diff --git a/src/vs/workbench/api/common/extHostTask.ts b/src/vs/workbench/api/common/extHostTask.ts new file mode 100644 index 00000000000..e6233ae01a6 --- /dev/null +++ b/src/vs/workbench/api/common/extHostTask.ts @@ -0,0 +1,30 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Event } from 'vs/base/common/event'; +import { ExtHostTaskShape } from 'vs/workbench/api/common/extHost.protocol'; +import * as vscode from 'vscode'; +import { TaskSystemInfoDTO } from '../common/shared/tasks'; +import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; + +export interface IExtHostTask extends ExtHostTaskShape { + + readonly _serviceBrand: any; + + taskExecutions: vscode.TaskExecution[]; + onDidStartTask: Event; + onDidEndTask: Event; + onDidStartTaskProcess: Event; + onDidEndTaskProcess: Event; + + registerTaskProvider(extension: IExtensionDescription, type: string, provider: vscode.TaskProvider): vscode.Disposable; + registerTaskSystem(scheme: string, info: TaskSystemInfoDTO): void; + fetchTasks(filter?: vscode.TaskFilter): Promise; + executeTask(extension: IExtensionDescription, task: vscode.Task): Promise; + terminateTask(execution: vscode.TaskExecution): Promise; +} + +export const IExtHostTask = createDecorator('IExtHostTask'); diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index d9ceabda83b..4f324cacaeb 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -43,7 +43,6 @@ import { ExtHostSCM } from 'vs/workbench/api/common/extHostSCM'; import { ExtHostSearch, registerEHSearchProviders } from 'vs/workbench/api/node/extHostSearch'; import { ExtHostStatusBar } from 'vs/workbench/api/common/extHostStatusBar'; import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; -import { ExtHostTask } from 'vs/workbench/api/node/extHostTask'; import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; import { ExtHostEditors } from 'vs/workbench/api/common/extHostTextEditors'; import { ExtHostTreeViews } from 'vs/workbench/api/common/extHostTreeViews'; @@ -69,6 +68,7 @@ import { ExtHostLabelService } from 'vs/workbench/api/common/extHostLabelService import { getRemoteName } from 'vs/platform/remote/common/remoteHosts'; import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IExtHostDecorations } from 'vs/workbench/api/common/extHostDecorations'; +import { IExtHostTask } from 'vs/workbench/api/common/extHostTask'; export interface IExtensionApiFactory { (extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode; @@ -126,7 +126,7 @@ export function createApiFactory( const extHostSCM = rpcProtocol.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(rpcProtocol, extHostCommands, extHostLogService)); const extHostComment = rpcProtocol.set(ExtHostContext.ExtHostComments, new ExtHostComments(rpcProtocol, extHostCommands, extHostDocuments)); const extHostSearch = rpcProtocol.set(ExtHostContext.ExtHostSearch, new ExtHostSearch(rpcProtocol, uriTransformer, extHostLogService)); - const extHostTask = rpcProtocol.set(ExtHostContext.ExtHostTask, new ExtHostTask(rpcProtocol, extHostWorkspace, extHostDocumentsAndEditors, extHostConfiguration, extHostTerminalService)); + const extHostTask = rpcProtocol.set(ExtHostContext.ExtHostTask, accessor.get(IExtHostTask)); const extHostWindow = rpcProtocol.set(ExtHostContext.ExtHostWindow, new ExtHostWindow(rpcProtocol)); rpcProtocol.set(ExtHostContext.ExtHostExtensionService, extensionService); const extHostProgress = rpcProtocol.set(ExtHostContext.ExtHostProgress, new ExtHostProgress(rpcProtocol.getProxy(MainContext.MainThreadProgress))); diff --git a/src/vs/workbench/api/node/extHost.services.ts b/src/vs/workbench/api/node/extHost.services.ts index ff8a01bd9f8..3e5f9b5c3c1 100644 --- a/src/vs/workbench/api/node/extHost.services.ts +++ b/src/vs/workbench/api/node/extHost.services.ts @@ -13,6 +13,8 @@ import { IExtHostCommands, ExtHostCommands } from 'vs/workbench/api/common/extHo import { IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { ExtHostTerminalService } from 'vs/workbench/api/node/extHostTerminalService'; import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; +import { IExtHostTask } from 'vs/workbench/api/common/extHostTask'; +import { ExtHostTask } from 'vs/workbench/api/node/extHostTask'; // register singleton services registerSingleton(IExtHostOutputService, ExtHostOutputService2); @@ -22,3 +24,4 @@ registerSingleton(IExtHostConfiguration, ExtHostConfiguration); registerSingleton(IExtHostCommands, ExtHostCommands); registerSingleton(IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors); registerSingleton(IExtHostTerminalService, ExtHostTerminalService); +registerSingleton(IExtHostTask, ExtHostTask); diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index cd5e36c82dc..5e31d4eaa61 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -12,7 +12,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { win32 } from 'vs/base/node/processes'; -import { MainContext, MainThreadTaskShape, ExtHostTaskShape, IMainContext } from 'vs/workbench/api/common/extHost.protocol'; +import { MainContext, MainThreadTaskShape, ExtHostTaskShape } from 'vs/workbench/api/common/extHost.protocol'; import * as types from 'vs/workbench/api/common/extHostTypes'; import { IExtHostWorkspaceProvider, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; @@ -31,6 +31,7 @@ import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { CancellationToken } from 'vs/base/common/cancellation'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; namespace TaskDefinitionDTO { export function from(value: vscode.TaskDefinition): TaskDefinitionDTO | undefined { @@ -354,6 +355,8 @@ interface HandlerData { export class ExtHostTask implements ExtHostTaskShape { + readonly _serviceBrand: any; + private readonly _proxy: MainThreadTaskShape; private readonly _workspaceProvider: IExtHostWorkspaceProvider; private readonly _editorService: IExtHostDocumentsAndEditors; @@ -372,13 +375,13 @@ export class ExtHostTask implements ExtHostTaskShape { private readonly _onDidTaskProcessEnded: Emitter = new Emitter(); constructor( - mainContext: IMainContext, + @IExtHostRpcService extHostRpc: IExtHostRpcService, @IExtHostWorkspace workspaceService: IExtHostWorkspace, @IExtHostDocumentsAndEditors editorService: IExtHostDocumentsAndEditors, @IExtHostConfiguration configurationService: IExtHostConfiguration, @IExtHostTerminalService extHostTerminalService: IExtHostTerminalService ) { - this._proxy = mainContext.getProxy(MainContext.MainThreadTask); + this._proxy = extHostRpc.getProxy(MainContext.MainThreadTask); this._workspaceProvider = workspaceService; this._editorService = editorService; this._configurationService = configurationService; From 36135bd2eec1aa6c1caaba6e53399425d5434655 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 7 Aug 2019 21:20:51 +0200 Subject: [PATCH 315/861] add debug and extension service to injector --- .../api/common/extHostDebugService.ts | 34 +++++++++++++++++ .../api/common/extHostExtensionService.ts | 22 +++++++++++ src/vs/workbench/api/node/extHost.api.impl.ts | 15 ++++---- src/vs/workbench/api/node/extHost.services.ts | 3 ++ .../workbench/api/node/extHostDebugService.ts | 37 +++++++++++-------- .../api/node/extHostExtensionService.ts | 19 +++++++--- .../extensions/node/extensionHostMain.ts | 3 +- 7 files changed, 102 insertions(+), 31 deletions(-) create mode 100644 src/vs/workbench/api/common/extHostDebugService.ts create mode 100644 src/vs/workbench/api/common/extHostExtensionService.ts diff --git a/src/vs/workbench/api/common/extHostDebugService.ts b/src/vs/workbench/api/common/extHostDebugService.ts new file mode 100644 index 00000000000..02b3c423f87 --- /dev/null +++ b/src/vs/workbench/api/common/extHostDebugService.ts @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Event } from 'vs/base/common/event'; +import { ExtHostDebugServiceShape } from 'vs/workbench/api/common/extHost.protocol'; +import * as vscode from 'vscode'; +import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; + +export const IExtHostDebugService = createDecorator('IExtHostDebugService'); + +export interface IExtHostDebugService extends ExtHostDebugServiceShape { + + readonly _serviceBrand: any; + + onDidStartDebugSession: Event; + onDidTerminateDebugSession: Event; + onDidChangeActiveDebugSession: Event; + activeDebugSession: vscode.DebugSession | undefined; + activeDebugConsole: vscode.DebugConsole; + onDidReceiveDebugSessionCustomEvent: Event; + onDidChangeBreakpoints: Event; + breakpoints: vscode.Breakpoint[]; + + addBreakpoints(breakpoints0: vscode.Breakpoint[]): Promise; + removeBreakpoints(breakpoints0: vscode.Breakpoint[]): Promise; + startDebugging(folder: vscode.WorkspaceFolder | undefined, nameOrConfig: string | vscode.DebugConfiguration, parentSession?: vscode.DebugSession): Promise; + registerDebugConfigurationProvider(type: string, provider: vscode.DebugConfigurationProvider): vscode.Disposable; + registerDebugAdapterDescriptorFactory(extension: IExtensionDescription, type: string, factory: vscode.DebugAdapterDescriptorFactory): vscode.Disposable; + registerDebugAdapterTrackerFactory(type: string, factory: vscode.DebugAdapterTrackerFactory): vscode.Disposable; +} + diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts new file mode 100644 index 00000000000..0833e6f7e83 --- /dev/null +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -0,0 +1,22 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ExtHostExtensionServiceShape } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtensionActivationReason, IExtensionAPI } from 'vs/workbench/api/common/extHostExtensionActivator'; +import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; +import * as vscode from 'vscode'; +import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; + +export const IExtHostExtensionService = createDecorator('IExtHostExtensionService'); + +export interface IExtHostExtensionService extends ExtHostExtensionServiceShape { + _serviceBrand: any; + isActivated(extensionId: ExtensionIdentifier): boolean; + activateByIdWithErrors(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise; + getExtensionExports(extensionId: ExtensionIdentifier): IExtensionAPI | null | undefined; + getExtensionRegistry(): Promise; + registerRemoteAuthorityResolver(authorityPrefix: string, resolver: vscode.RemoteAuthorityResolver): vscode.Disposable; +} diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 4f324cacaeb..8870ae9a0cf 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -21,7 +21,6 @@ import { ExtHostClipboard } from 'vs/workbench/api/common/extHostClipboard'; import { IExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; import { ExtHostComments } from 'vs/workbench/api/common/extHostComments'; import { ExtHostConfiguration, ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration'; -import { ExtHostDebugService } from 'vs/workbench/api/node/extHostDebugService'; import { ExtHostDiagnostics } from 'vs/workbench/api/common/extHostDiagnostics'; import { ExtHostDialogs } from 'vs/workbench/api/common/extHostDialogs'; import { ExtHostDocumentContentProvider } from 'vs/workbench/api/common/extHostDocumentContentProviders'; @@ -29,7 +28,7 @@ import { ExtHostDocumentSaveParticipant } from 'vs/workbench/api/common/extHostD import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments'; import { IExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { ExtensionActivatedByAPI } from 'vs/workbench/api/common/extHostExtensionActivator'; -import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService'; +import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; import { ExtHostFileSystem } from 'vs/workbench/api/common/extHostFileSystem'; import { ExtHostFileSystemEventService } from 'vs/workbench/api/common/extHostFileSystemEventService'; import { ExtHostLanguageFeatures } from 'vs/workbench/api/common/extHostLanguageFeatures'; @@ -66,9 +65,10 @@ import { IURITransformer } from 'vs/base/common/uriIpc'; import { ExtHostEditorInsets } from 'vs/workbench/api/common/extHostCodeInsets'; import { ExtHostLabelService } from 'vs/workbench/api/common/extHostLabelService'; import { getRemoteName } from 'vs/platform/remote/common/remoteHosts'; -import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IExtHostDecorations } from 'vs/workbench/api/common/extHostDecorations'; import { IExtHostTask } from 'vs/workbench/api/common/extHostTask'; +import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService'; export interface IExtensionApiFactory { (extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode; @@ -91,14 +91,13 @@ export function createApiFactory( rpcProtocol: IMainContext, extHostWorkspace: ExtHostWorkspace, extHostConfiguration: ExtHostConfiguration, - extensionService: ExtHostExtensionService, extHostLogService: ExtHostLogService, extHostStorage: ExtHostStorage, uriTransformer: IURITransformer | null ): IExtensionApiFactory { // services - const instaService = accessor.get(IInstantiationService); + const extensionService = accessor.get(IExtHostExtensionService); // Addressable instances rpcProtocol.set(ExtHostContext.ExtHostLogService, extHostLogService); @@ -122,7 +121,7 @@ export function createApiFactory( const extHostFileSystemEvent = rpcProtocol.set(ExtHostContext.ExtHostFileSystemEventService, new ExtHostFileSystemEventService(rpcProtocol, extHostDocumentsAndEditors)); const extHostQuickOpen = rpcProtocol.set(ExtHostContext.ExtHostQuickOpen, new ExtHostQuickOpen(rpcProtocol, extHostWorkspace, extHostCommands)); const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, accessor.get(IExtHostTerminalService)); - const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, instaService.createInstance(ExtHostDebugService, rpcProtocol, extHostWorkspace, extensionService, extHostDocumentsAndEditors, extHostConfiguration, extHostTerminalService, extHostCommands)); + const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, accessor.get(IExtHostDebugService)); const extHostSCM = rpcProtocol.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(rpcProtocol, extHostCommands, extHostLogService)); const extHostComment = rpcProtocol.set(ExtHostContext.ExtHostComments, new ExtHostComments(rpcProtocol, extHostCommands, extHostDocuments)); const extHostSearch = rpcProtocol.set(ExtHostContext.ExtHostSearch, new ExtHostSearch(rpcProtocol, uriTransformer, extHostLogService)); @@ -908,7 +907,7 @@ export function createApiFactory( class Extension implements vscode.Extension { - private _extensionService: ExtHostExtensionService; + private _extensionService: IExtHostExtensionService; private _identifier: ExtensionIdentifier; readonly id: string; @@ -916,7 +915,7 @@ class Extension implements vscode.Extension { readonly packageJSON: IExtensionDescription; readonly extensionKind: vscode.ExtensionKind; - constructor(extensionService: ExtHostExtensionService, description: IExtensionDescription, kind: extHostTypes.ExtensionKind) { + constructor(extensionService: IExtHostExtensionService, description: IExtensionDescription, kind: extHostTypes.ExtensionKind) { this._extensionService = extensionService; this._identifier = description.identifier; this.id = description.identifier.value; diff --git a/src/vs/workbench/api/node/extHost.services.ts b/src/vs/workbench/api/node/extHost.services.ts index 3e5f9b5c3c1..4a8176170d7 100644 --- a/src/vs/workbench/api/node/extHost.services.ts +++ b/src/vs/workbench/api/node/extHost.services.ts @@ -15,6 +15,8 @@ import { ExtHostTerminalService } from 'vs/workbench/api/node/extHostTerminalSer import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; import { IExtHostTask } from 'vs/workbench/api/common/extHostTask'; import { ExtHostTask } from 'vs/workbench/api/node/extHostTask'; +import { ExtHostDebugService } from 'vs/workbench/api/node/extHostDebugService'; +import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService'; // register singleton services registerSingleton(IExtHostOutputService, ExtHostOutputService2); @@ -25,3 +27,4 @@ registerSingleton(IExtHostCommands, ExtHostCommands); registerSingleton(IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors); registerSingleton(IExtHostTerminalService, ExtHostTerminalService); registerSingleton(IExtHostTask, ExtHostTask); +registerSingleton(IExtHostDebugService, ExtHostDebugService); diff --git a/src/vs/workbench/api/node/extHostDebugService.ts b/src/vs/workbench/api/node/extHostDebugService.ts index 9b26206924d..cf179f59a6f 100644 --- a/src/vs/workbench/api/node/extHostDebugService.ts +++ b/src/vs/workbench/api/node/extHostDebugService.ts @@ -11,33 +11,37 @@ import { asPromise } from 'vs/base/common/async'; import * as nls from 'vs/nls'; import { MainContext, MainThreadDebugServiceShape, ExtHostDebugServiceShape, DebugSessionUUID, - IMainContext, IBreakpointsDeltaDto, ISourceMultiBreakpointDto, IFunctionBreakpointDto, IDebugSessionDto + IBreakpointsDeltaDto, ISourceMultiBreakpointDto, IFunctionBreakpointDto, IDebugSessionDto } from 'vs/workbench/api/common/extHost.protocol'; import * as vscode from 'vscode'; import { Disposable, Position, Location, SourceBreakpoint, FunctionBreakpoint, DebugAdapterServer, DebugAdapterExecutable } from 'vs/workbench/api/common/extHostTypes'; import { ExecutableDebugAdapter, SocketDebugAdapter } from 'vs/workbench/contrib/debug/node/debugAdapter'; import { AbstractDebugAdapter } from 'vs/workbench/contrib/debug/common/abstractDebugAdapter'; -import { IExtHostWorkspaceProvider } from 'vs/workbench/api/common/extHostWorkspace'; -import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService'; -import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; +import { IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; +import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; +import { ExtHostDocumentsAndEditors, IExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { IDebuggerContribution, IConfig, IDebugAdapter, IDebugAdapterServer, IDebugAdapterExecutable, IAdapterDescriptor } from 'vs/workbench/contrib/debug/common/debug'; import { hasChildProcesses, prepareCommand, runInExternalTerminal } from 'vs/workbench/contrib/debug/node/terminals'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { AbstractVariableResolverService } from 'vs/workbench/services/configurationResolver/common/variableResolver'; -import { ExtHostConfiguration, ExtHostConfigProvider } from '../common/extHostConfiguration'; +import { ExtHostConfigProvider, IExtHostConfiguration } from '../common/extHostConfiguration'; import { convertToVSCPaths, convertToDAPaths, isDebuggerMainContribution } from 'vs/workbench/contrib/debug/common/debugUtils'; -import { ExtHostTerminalService } from 'vs/workbench/api/node/extHostTerminalService'; import { IDisposable } from 'vs/base/common/lifecycle'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { CancellationToken } from 'vs/base/common/cancellation'; -import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; +import { IExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; import { IProcessEnvironment } from 'vs/base/common/platform'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { SignService } from 'vs/platform/sign/node/signService'; import { ISignService } from 'vs/platform/sign/common/sign'; +import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService'; -export class ExtHostDebugService implements ExtHostDebugServiceShape { +export class ExtHostDebugService implements IExtHostDebugService, ExtHostDebugServiceShape { + + readonly _serviceBrand: any; private _configProviderHandleCounter: number; private _configProviders: ConfigProviderTuple[]; @@ -86,13 +90,14 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { private _signService: ISignService; - constructor(mainContext: IMainContext, - private _workspaceService: IExtHostWorkspaceProvider, - private _extensionService: ExtHostExtensionService, - private _editorsService: ExtHostDocumentsAndEditors, - private _configurationService: ExtHostConfiguration, - private _terminalService: ExtHostTerminalService, - private _commandService: ExtHostCommands + constructor( + @IExtHostRpcService extHostRpcService: IExtHostRpcService, + @IExtHostWorkspace private _workspaceService: IExtHostWorkspace, + @IExtHostExtensionService private _extensionService: IExtHostExtensionService, + @IExtHostDocumentsAndEditors private _editorsService: IExtHostDocumentsAndEditors, + @IExtHostConfiguration private _configurationService: IExtHostConfiguration, + @IExtHostTerminalService private _terminalService: IExtHostTerminalService, + @IExtHostCommands private _commandService: IExtHostCommands ) { this._configProviderHandleCounter = 0; this._configProviders = []; @@ -112,7 +117,7 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { this._onDidChangeActiveDebugSession = new Emitter(); this._onDidReceiveDebugSessionCustomEvent = new Emitter(); - this._debugServiceProxy = mainContext.getProxy(MainContext.MainThreadDebugService); + this._debugServiceProxy = extHostRpcService.getProxy(MainContext.MainThreadDebugService); this._onDidChangeBreakpoints = new Emitter({ onFirstListenerAdd: () => { diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 0d1c9447fc6..237223240e2 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -36,6 +36,8 @@ import { IURITransformer } from 'vs/base/common/uriIpc'; import { ResolvedAuthority, ResolvedOptions } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; +import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; +import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; interface ITestRunner { /** Old test runner API, as exported from `vscode/lib/testrunner` */ @@ -63,7 +65,9 @@ type TelemetryActivationEventFragment = { reason: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; }; -export class ExtHostExtensionService implements ExtHostExtensionServiceShape { +export class ExtHostExtensionService implements IExtHostExtensionService, ExtHostExtensionServiceShape { + + readonly _serviceBrand: any; private static readonly WORKSPACE_CONTAINS_TIMEOUT = 7000; @@ -74,8 +78,6 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { private readonly _extHostConfiguration: ExtHostConfiguration; private readonly _extHostLogService: ExtHostLogService; - private readonly _instaService: IInstantiationService; - private readonly _mainThreadWorkspaceProxy: MainThreadWorkspaceShape; private readonly _mainThreadTelemetryProxy: MainThreadTelemetryShape; private readonly _mainThreadExtensionsProxy: MainThreadExtensionServiceShape; @@ -100,6 +102,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { hostUtils: IHostUtils, uriTransformer: IURITransformer | null, extHostContext: IMainContext, + services: ServiceCollection, @IInstantiationService instaService: IInstantiationService, @IExtHostWorkspace extHostWorkspace: IExtHostWorkspace, @IExtHostConfiguration extHostConfiguration: IExtHostConfiguration, @@ -109,7 +112,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { this._hostUtils = hostUtils; this._extHostContext = extHostContext; this._initData = initData; - this._instaService = instaService; + this._extHostWorkspace = extHostWorkspace; this._extHostConfiguration = extHostConfiguration; this._extHostLogService = extHostLogService; @@ -146,13 +149,17 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { }); this._extensionPathIndex = null; + // todo@joh this is a hack! + // the problem is that this service doesn't create the insta-service + // but downlevel things it creates depend on this service... + services.set(IExtHostExtensionService, this); + // initialize API first (i.e. do not release barrier until the API is initialized) - this._extensionApiFactory = this._instaService.invokeFunction(createApiFactory, + this._extensionApiFactory = instaService.invokeFunction(createApiFactory, this._initData, this._extHostContext, this._extHostWorkspace, this._extHostConfiguration, - this, this._extHostLogService, this._storage, uriTransformer diff --git a/src/vs/workbench/services/extensions/node/extensionHostMain.ts b/src/vs/workbench/services/extensions/node/extensionHostMain.ts index 9a35343785c..89ce6ba8bc0 100644 --- a/src/vs/workbench/services/extensions/node/extensionHostMain.ts +++ b/src/vs/workbench/services/extensions/node/extensionHostMain.ts @@ -82,7 +82,8 @@ export class ExtensionHostMain { ExtHostExtensionService, hostUtils, uriTransformer, - rpcProtocol + rpcProtocol, + services, // todo@joh hack! ); // error forwarding and stack trace scanning From 6a225f9a869b7903555cd57fb3a92019230b3db4 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Wed, 7 Aug 2019 15:54:45 -0700 Subject: [PATCH 316/861] Fix #78657, update padding for quick fixes --- src/vs/editor/contrib/hover/hover.css | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/hover/hover.css b/src/vs/editor/contrib/hover/hover.css index 62da9b51907..06639005192 100644 --- a/src/vs/editor/contrib/hover/hover.css +++ b/src/vs/editor/contrib/hover/hover.css @@ -84,13 +84,14 @@ .monaco-editor-hover .hover-row.status-bar .actions { display: flex; + padding: 0px 8px; } .monaco-editor-hover .hover-row.status-bar .actions .action-container { - margin: 0px 8px; + margin-right: 16px; cursor: pointer; } .monaco-editor-hover .hover-row.status-bar .actions .action-container .action .icon { padding-right: 4px; -} \ No newline at end of file +} From fe3669fe3b8c2344563751a6bcc294ec5c01de66 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Wed, 7 Aug 2019 16:18:27 -0700 Subject: [PATCH 317/861] Show minimap decorations for global search as well, fixes #78236 --- .../workbench/contrib/search/common/searchModel.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/search/common/searchModel.ts b/src/vs/workbench/contrib/search/common/searchModel.ts index 9c4d170c1d5..3887c7dc71e 100644 --- a/src/vs/workbench/contrib/search/common/searchModel.ts +++ b/src/vs/workbench/contrib/search/common/searchModel.ts @@ -14,7 +14,7 @@ import * as objects from 'vs/base/common/objects'; import { lcut } from 'vs/base/common/strings'; import { URI } from 'vs/base/common/uri'; import { Range } from 'vs/editor/common/core/range'; -import { FindMatch, IModelDeltaDecoration, ITextModel, OverviewRulerLane, TrackedRangeStickiness } from 'vs/editor/common/model'; +import { FindMatch, IModelDeltaDecoration, ITextModel, OverviewRulerLane, TrackedRangeStickiness, MinimapPosition } from 'vs/editor/common/model'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; import { IModelService } from 'vs/editor/common/services/modelService'; import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -22,7 +22,7 @@ import { IProgress, IProgressStep } from 'vs/platform/progress/common/progress'; import { ReplacePattern } from 'vs/workbench/services/search/common/replace'; import { IFileMatch, IPatternInfo, ISearchComplete, ISearchProgressItem, ISearchService, ITextQuery, ITextSearchPreviewOptions, ITextSearchMatch, ITextSearchStats, resultIsMatch, ISearchRange, OneLineRange } from 'vs/workbench/services/search/common/search'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { overviewRulerFindMatchForeground } from 'vs/platform/theme/common/colorRegistry'; +import { overviewRulerFindMatchForeground, minimapFindMatch } from 'vs/platform/theme/common/colorRegistry'; import { themeColorFromId } from 'vs/platform/theme/common/themeService'; import { IReplaceService } from 'vs/workbench/contrib/search/common/replace'; import { editorMatchesToTextSearchResults } from 'vs/workbench/services/search/common/searchHelpers'; @@ -155,6 +155,10 @@ export class FileMatch extends Disposable implements IFileMatch { overviewRuler: { color: themeColorFromId(overviewRulerFindMatchForeground), position: OverviewRulerLane.Center + }, + minimap: { + color: themeColorFromId(minimapFindMatch), + position: MinimapPosition.Inline } }); @@ -164,6 +168,10 @@ export class FileMatch extends Disposable implements IFileMatch { overviewRuler: { color: themeColorFromId(overviewRulerFindMatchForeground), position: OverviewRulerLane.Center + }, + minimap: { + color: themeColorFromId(minimapFindMatch), + position: MinimapPosition.Inline } }); From d9e833bc7e543e783d60867694d57fbc7f5c66aa Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 5 Aug 2019 09:26:43 -0700 Subject: [PATCH 318/861] SearchResult#remove must still handle FolderMatch Fix #78509 --- .../workbench/contrib/search/common/searchModel.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/search/common/searchModel.ts b/src/vs/workbench/contrib/search/common/searchModel.ts index 3887c7dc71e..96a532bcda2 100644 --- a/src/vs/workbench/contrib/search/common/searchModel.ts +++ b/src/vs/workbench/contrib/search/common/searchModel.ts @@ -721,11 +721,19 @@ export class SearchResult extends Disposable { this.disposeMatches(); } - remove(matches: FileMatch | FileMatch[]): void { + remove(matches: FileMatch | FolderMatch | (FileMatch | FolderMatch)[]): void { if (!Array.isArray(matches)) { matches = [matches]; } + matches.forEach(m => { + if (m instanceof FolderMatch) { + m.clear(); + } + }); + + matches = matches.filter(m => m instanceof FileMatch); + const { byFolder, other } = this.groupFilesByFolder(matches); byFolder.forEach(matches => { if (!matches.length) { @@ -740,10 +748,6 @@ export class SearchResult extends Disposable { } } - removeFolder(match: FolderMatch): void { - match.clear(); - } - replace(match: FileMatch): Promise { return this.getFolderMatch(match.resource).replace(match); } From 7fd022330ce95b2234323af6e3371b8e945d78a8 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 7 Aug 2019 16:30:29 -0700 Subject: [PATCH 319/861] Bump vscode-ripgrep --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index fe64037080b..98d73a82799 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "vscode-chokidar": "2.1.7", "vscode-minimist": "^1.2.1", "vscode-proxy-agent": "0.4.0", - "vscode-ripgrep": "^1.5.5", + "vscode-ripgrep": "^1.5.6", "vscode-sqlite3": "4.0.8", "vscode-textmate": "^4.2.2", "xterm": "3.15.0-beta93", diff --git a/yarn.lock b/yarn.lock index b872c14415e..35c0842584e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9574,10 +9574,10 @@ vscode-proxy-agent@0.4.0: https-proxy-agent "2.2.1" socks-proxy-agent "4.0.1" -vscode-ripgrep@^1.5.5: - version "1.5.5" - resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.5.5.tgz#24c0e9cb356cf889c98e15ecb58f9cf654a1d961" - integrity sha512-OrPrAmcun4+uZAuNcQvE6CCPskh+5AsjANod/Q3zRcJcGNxgoOSGlQN9RPtatkUNmkN8Nn8mZBnS1jMylu/dKg== +vscode-ripgrep@^1.5.6: + version "1.5.6" + resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.5.6.tgz#93bf5c99ca5f8248950a305e224f6ca153c30af4" + integrity sha512-WRIM9XpUj6dsfdAmuI3ANbmT1ysPUVsYy/2uCLDHJa9kbiB4T7uGvFnnc0Rgx2qQnyRAwL7PeWaFgUljPPxf2g== vscode-sqlite3@4.0.8: version "4.0.8" From 227576268470bdb178fbc46519780523d653750b Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 7 Aug 2019 16:33:14 -0700 Subject: [PATCH 320/861] Fix search perf regression on long lines, fix #77650 --- .../workbench/contrib/search/common/searchModel.ts | 2 ++ src/vs/workbench/services/search/common/search.ts | 13 ++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/search/common/searchModel.ts b/src/vs/workbench/contrib/search/common/searchModel.ts index 96a532bcda2..1c93ff5221c 100644 --- a/src/vs/workbench/contrib/search/common/searchModel.ts +++ b/src/vs/workbench/contrib/search/common/searchModel.ts @@ -27,6 +27,7 @@ import { themeColorFromId } from 'vs/platform/theme/common/themeService'; import { IReplaceService } from 'vs/workbench/contrib/search/common/replace'; import { editorMatchesToTextSearchResults } from 'vs/workbench/services/search/common/searchHelpers'; import { withNullAsUndefined } from 'vs/base/common/types'; +import { memoize } from 'vs/base/common/decorators'; export class Match { @@ -74,6 +75,7 @@ export class Match { return this._range; } + @memoize preview(): { before: string; inside: string; after: string; } { let before = this._oneLinePreviewText.substring(0, this._rangeInPreviewText.startColumn - 1), inside = this.getMatchString(), diff --git a/src/vs/workbench/services/search/common/search.ts b/src/vs/workbench/services/search/common/search.ts index f4e4e1ae243..da4e3edb333 100644 --- a/src/vs/workbench/services/search/common/search.ts +++ b/src/vs/workbench/services/search/common/search.ts @@ -251,20 +251,23 @@ export class TextSearchMatch implements ITextSearchMatch { constructor(text: string, range: ISearchRange | ISearchRange[], previewOptions?: ITextSearchPreviewOptions) { this.ranges = range; - if (previewOptions && previewOptions.matchLines === 1 && !Array.isArray(range)) { + if (previewOptions && previewOptions.matchLines === 1 && (!Array.isArray(range) || range.length === 1)) { + const oneRange = Array.isArray(range) ? range[0] : range; + // 1 line preview requested text = getNLines(text, previewOptions.matchLines); const leadingChars = Math.floor(previewOptions.charsPerLine / 5); - const previewStart = Math.max(range.startColumn - leadingChars, 0); + const previewStart = Math.max(oneRange.startColumn - leadingChars, 0); const previewText = text.substring(previewStart, previewOptions.charsPerLine + previewStart); - const endColInPreview = (range.endLineNumber - range.startLineNumber + 1) <= previewOptions.matchLines ? - Math.min(previewText.length, range.endColumn - previewStart) : // if number of match lines will not be trimmed by previewOptions + const endColInPreview = (oneRange.endLineNumber - oneRange.startLineNumber + 1) <= previewOptions.matchLines ? + Math.min(previewText.length, oneRange.endColumn - previewStart) : // if number of match lines will not be trimmed by previewOptions previewText.length; // if number of lines is trimmed + const oneLineRange = new OneLineRange(0, oneRange.startColumn - previewStart, endColInPreview); this.preview = { text: previewText, - matches: new OneLineRange(0, range.startColumn - previewStart, endColInPreview) + matches: Array.isArray(range) ? [oneLineRange] : oneLineRange }; } else { const firstMatchLine = Array.isArray(range) ? range[0].startLineNumber : range.startLineNumber; From fe5a70e3100b993b4a050c6defa948048216910a Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Wed, 7 Aug 2019 16:50:50 -0700 Subject: [PATCH 321/861] Fix build --- src/vs/editor/contrib/referenceSearch/referencesWidget.ts | 2 +- src/vs/workbench/contrib/debug/browser/exceptionWidget.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts index 78b59c046c2..67c49b7cdc1 100644 --- a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts +++ b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts @@ -469,7 +469,7 @@ export class ReferenceWidget extends PeekViewWidget { })); // make sure things are rendered - dom.addClass(this.container, 'results-loaded'); + dom.addClass(this.container!, 'results-loaded'); dom.show(this._treeContainer); dom.show(this._previewContainer); this._splitView.layout(this._dim.width); diff --git a/src/vs/workbench/contrib/debug/browser/exceptionWidget.ts b/src/vs/workbench/contrib/debug/browser/exceptionWidget.ts index 889cef64500..0d038ec13c9 100644 --- a/src/vs/workbench/contrib/debug/browser/exceptionWidget.ts +++ b/src/vs/workbench/contrib/debug/browser/exceptionWidget.ts @@ -63,8 +63,8 @@ export class ExceptionWidget extends ZoneWidget { this.setCssClass('exception-widget'); // Set the font size and line height to the one from the editor configuration. const fontInfo = this.editor.getConfiguration().fontInfo; - this.container.style.fontSize = `${fontInfo.fontSize}px`; - this.container.style.lineHeight = `${fontInfo.lineHeight}px`; + container.style.fontSize = `${fontInfo.fontSize}px`; + container.style.lineHeight = `${fontInfo.lineHeight}px`; let title = $('.title'); title.textContent = this.exceptionInfo.id ? nls.localize('exceptionThrownWithId', 'Exception has occurred: {0}', this.exceptionInfo.id) : nls.localize('exceptionThrown', 'Exception has occurred.'); @@ -87,11 +87,11 @@ export class ExceptionWidget extends ZoneWidget { protected _doLayout(_heightInPixel: number | undefined, _widthInPixel: number | undefined): void { // Reload the height with respect to the exception text content and relayout it to match the line count. - this.container.style.height = 'initial'; + this.container!.style.height = 'initial'; const lineHeight = this.editor.getConfiguration().lineHeight; const arrowHeight = Math.round(lineHeight / 3); - const computedLinesNumber = Math.ceil((this.container.offsetHeight + arrowHeight) / lineHeight); + const computedLinesNumber = Math.ceil((this.container!.offsetHeight + arrowHeight) / lineHeight); this._relayout(computedLinesNumber); } From bb27a11386906b272a98e3c730405fc30b98391b Mon Sep 17 00:00:00 2001 From: Yuya Tanaka Date: Sat, 27 Jul 2019 00:59:19 +0900 Subject: [PATCH 322/861] Fixes #77997: Let executeCodeActionProvider pass-through Selection obj. --- .../editor/contrib/codeAction/codeAction.ts | 16 +++++++++-- .../api/common/extHostApiCommands.ts | 8 ++++-- .../api/extHostApiCommands.test.ts | 28 +++++++++++++++++++ 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/codeAction.ts b/src/vs/editor/contrib/codeAction/codeAction.ts index 93873f17ffb..f706070a89b 100644 --- a/src/vs/editor/contrib/codeAction/codeAction.ts +++ b/src/vs/editor/contrib/codeAction/codeAction.ts @@ -117,8 +117,8 @@ function getCodeActionProviders( } registerLanguageCommand('_executeCodeActionProvider', async function (accessor, args): Promise> { - const { resource, range, kind } = args; - if (!(resource instanceof URI) || !Range.isIRange(range)) { + const { resource, rangeOrSelection, kind } = args; + if (!(resource instanceof URI)) { throw illegalArgument(); } @@ -127,9 +127,19 @@ registerLanguageCommand('_executeCodeActionProvider', async function (accessor, throw illegalArgument(); } + const validatedRangeOrSelection = Selection.isISelection(rangeOrSelection) + ? Selection.liftSelection(rangeOrSelection) + : Range.isIRange(rangeOrSelection) + ? model.validateRange(rangeOrSelection) + : undefined; + + if (!validatedRangeOrSelection) { + throw illegalArgument(); + } + const codeActionSet = await getCodeActions( model, - model.validateRange(range), + validatedRangeOrSelection, { type: 'manual', filter: { includeSourceActions: true, kind: kind && kind.value ? new CodeActionKind(kind.value) : undefined } }, CancellationToken.None); diff --git a/src/vs/workbench/api/common/extHostApiCommands.ts b/src/vs/workbench/api/common/extHostApiCommands.ts index ff2a106f427..2a95e81c5e1 100644 --- a/src/vs/workbench/api/common/extHostApiCommands.ts +++ b/src/vs/workbench/api/common/extHostApiCommands.ts @@ -135,7 +135,7 @@ export class ExtHostApiCommands { description: 'Execute code action provider.', args: [ { name: 'uri', description: 'Uri of a text document', constraint: URI }, - { name: 'range', description: 'Range in a text document', constraint: types.Range }, + { name: 'rangeOrSelection', description: 'Range in a text document. Some refactoring provider requires Selection object.', constraint: types.Range }, { name: 'kind', description: '(optional) Code action kind to return code actions for', constraint: (value: any) => !value || typeof value.value === 'string' }, ], returns: 'A promise that resolves to an array of Command-instances.' @@ -480,10 +480,12 @@ export class ExtHostApiCommands { }); } - private _executeCodeActionProvider(resource: URI, range: types.Range, kind?: string): Promise<(vscode.CodeAction | vscode.Command | undefined)[] | undefined> { + private _executeCodeActionProvider(resource: URI, rangeOrSelection: types.Range | types.Selection, kind?: string): Promise<(vscode.CodeAction | vscode.Command | undefined)[] | undefined> { const args = { resource, - range: typeConverters.Range.from(range), + rangeOrSelection: types.Selection.isSelection(rangeOrSelection) + ? typeConverters.Selection.from(rangeOrSelection) + : typeConverters.Range.from(rangeOrSelection), kind }; return this._commands.executeCommand('_executeCodeActionProvider', args) diff --git a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts index 779c40e9656..8e1bd39fdef 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts @@ -631,6 +631,34 @@ suite('ExtHostLanguageFeatureCommands', function () { }); }); + test('vscode.executeCodeActionProvider passes Range to provider although Selection is passed in #77997', function () { + disposables.push(extHost.registerCodeActionProvider(nullExtensionDescription, defaultSelector, { + provideCodeActions(document, rangeOrSelection): vscode.CodeAction[] { + return [{ + command: { + arguments: [document, rangeOrSelection], + command: 'command', + title: 'command_title', + }, + kind: types.CodeActionKind.Empty.append('foo'), + title: 'title', + }]; + } + })); + + const selection = new types.Selection(0, 0, 1, 1); + + return rpcProtocol.sync().then(() => { + return commands.executeCommand('vscode.executeCodeActionProvider', model.uri, selection).then(value => { + assert.equal(value.length, 1); + const [first] = value; + assert.ok(first.command); + assert.ok(first.command!.arguments![1] instanceof types.Selection); + assert.ok(first.command!.arguments![1].isEqual(selection)); + }); + }); + }); + // --- code lens test('CodeLens, back and forth', function () { From 46c702b118f59eefbf83104943d76266a8c0c809 Mon Sep 17 00:00:00 2001 From: Yuya Tanaka Date: Mon, 29 Jul 2019 23:20:40 +0900 Subject: [PATCH 323/861] Fixes #78098: Return isPreferred from vscode.executeCodeActionProvider --- .../api/common/extHostApiCommands.ts | 1 + src/vs/workbench/api/common/extHostTypes.ts | 2 ++ .../api/extHostApiCommands.test.ts | 27 +++++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/src/vs/workbench/api/common/extHostApiCommands.ts b/src/vs/workbench/api/common/extHostApiCommands.ts index 2a95e81c5e1..d84da000c3f 100644 --- a/src/vs/workbench/api/common/extHostApiCommands.ts +++ b/src/vs/workbench/api/common/extHostApiCommands.ts @@ -506,6 +506,7 @@ export class ExtHostApiCommands { if (codeAction.command) { ret.command = this._commands.converter.fromInternal(codeAction.command); } + ret.isPreferred = codeAction.isPreferred; return ret; } })); diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index 9ad1d38f66e..0f1da741909 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -1075,6 +1075,8 @@ export class CodeAction { kind?: CodeActionKind; + isPreferred?: boolean; + constructor(title: string, kind?: CodeActionKind) { this.title = title; this.kind = kind; diff --git a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts index 8e1bd39fdef..048070561f2 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts @@ -659,6 +659,33 @@ suite('ExtHostLanguageFeatureCommands', function () { }); }); + test('vscode.executeCodeActionProvider results seem to be missing their `isPreferred` property #78098', function () { + disposables.push(extHost.registerCodeActionProvider(nullExtensionDescription, defaultSelector, { + provideCodeActions(document, rangeOrSelection): vscode.CodeAction[] { + return [{ + command: { + arguments: [document, rangeOrSelection], + command: 'command', + title: 'command_title', + }, + kind: types.CodeActionKind.Empty.append('foo'), + title: 'title', + isPreferred: true + }]; + } + })); + + const selection = new types.Selection(0, 0, 1, 1); + + return rpcProtocol.sync().then(() => { + return commands.executeCommand('vscode.executeCodeActionProvider', model.uri, selection).then(value => { + assert.equal(value.length, 1); + const [first] = value; + assert.equal(first.isPreferred, true); + }); + }); + }); + // --- code lens test('CodeLens, back and forth', function () { From d3066ce7c50cc034f200efc4c7a29227d11794ed Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 8 Aug 2019 08:27:19 +0200 Subject: [PATCH 324/861] propagate editor part visibility (fix #68320) --- src/vs/workbench/browser/parts/editor/editor.ts | 3 +++ src/vs/workbench/browser/parts/editor/editorControl.ts | 6 ++++++ src/vs/workbench/browser/parts/editor/editorGroupView.ts | 9 +++++++++ 3 files changed, 18 insertions(+) diff --git a/src/vs/workbench/browser/parts/editor/editor.ts b/src/vs/workbench/browser/parts/editor/editor.ts index 6ad9ea42706..1408ae24e0e 100644 --- a/src/vs/workbench/browser/parts/editor/editor.ts +++ b/src/vs/workbench/browser/parts/editor/editor.ts @@ -81,12 +81,15 @@ export interface IEditorOpeningEvent extends IEditorIdentifier { } export interface IEditorGroupsAccessor { + readonly groups: IEditorGroupView[]; readonly activeGroup: IEditorGroupView; readonly partOptions: IEditorPartOptions; readonly onDidEditorPartOptionsChange: Event; + readonly onDidVisibilityChange: Event; + getGroup(identifier: GroupIdentifier): IEditorGroupView | undefined; getGroups(order: GroupsOrder): IEditorGroupView[]; diff --git a/src/vs/workbench/browser/parts/editor/editorControl.ts b/src/vs/workbench/browser/parts/editor/editorControl.ts index 726b84c97db..70d57bba5ad 100644 --- a/src/vs/workbench/browser/parts/editor/editorControl.ts +++ b/src/vs/workbench/browser/parts/editor/editorControl.ts @@ -221,6 +221,12 @@ export class EditorControl extends Disposable { } } + setVisible(visible: boolean): void { + if (this._activeControl) { + this._activeControl.setVisible(visible, this.groupView); + } + } + layout(dimension: Dimension): void { this.dimension = dimension; diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index e5cc3843429..91a216bc83f 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -468,6 +468,9 @@ export class EditorGroupView extends Themable implements IEditorGroupView { // Option Changes this._register(this.accessor.onDidEditorPartOptionsChange(e => this.onDidEditorPartOptionsChange(e))); + + // Visibility + this._register(this.accessor.onDidVisibilityChange(e => this.onDidVisibilityChange(e))); } private onDidEditorPin(editor: EditorInput): void { @@ -635,6 +638,12 @@ export class EditorGroupView extends Themable implements IEditorGroupView { this._onDidGroupChange.fire({ kind: GroupChangeKind.EDITOR_LABEL, editor }); } + private onDidVisibilityChange(visible: boolean): void { + + // Forward to editor control + this.editorControl.setVisible(visible); + } + //#endregion //region IEditorGroupView From 46ab5c00fd51395a7254925eb7d5ce3a4cae22fd Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 8 Aug 2019 08:51:43 +0200 Subject: [PATCH 325/861] fix #78679 --- .../workbench/browser/web.simpleservices.ts | 2 + .../relauncher.contribution.ts | 101 ++++++++++-------- src/vs/workbench/workbench.main.ts | 2 +- src/vs/workbench/workbench.web.main.ts | 2 +- 4 files changed, 59 insertions(+), 48 deletions(-) rename src/vs/workbench/contrib/relauncher/{electron-browser => common}/relauncher.contribution.ts (75%) diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index f9c7b18deee..61974d274ad 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -661,6 +661,8 @@ export class SimpleWindowsService implements IWindowsService { } relaunch(_options: { addArgs?: string[], removeArgs?: string[] }): Promise { + window.location.reload(); + return Promise.resolve(); } diff --git a/src/vs/workbench/contrib/relauncher/electron-browser/relauncher.contribution.ts b/src/vs/workbench/contrib/relauncher/common/relauncher.contribution.ts similarity index 75% rename from src/vs/workbench/contrib/relauncher/electron-browser/relauncher.contribution.ts rename to src/vs/workbench/contrib/relauncher/common/relauncher.contribution.ts index cae44658169..080e6d741e7 100644 --- a/src/vs/workbench/contrib/relauncher/electron-browser/relauncher.contribution.ts +++ b/src/vs/workbench/contrib/relauncher/common/relauncher.contribution.ts @@ -15,7 +15,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { RunOnceScheduler } from 'vs/base/common/async'; import { URI } from 'vs/base/common/uri'; import { isEqual } from 'vs/base/common/resources'; -import { isMacintosh } from 'vs/base/common/platform'; +import { isMacintosh, isNative } from 'vs/base/common/platform'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; @@ -57,48 +57,6 @@ export class SettingsChangeRelauncher extends Disposable implements IWorkbenchCo private onConfigurationChange(config: IConfiguration, notify: boolean): void { let changed = false; - // Titlebar style - if (config.window && config.window.titleBarStyle !== this.titleBarStyle && (config.window.titleBarStyle === 'native' || config.window.titleBarStyle === 'custom')) { - this.titleBarStyle = config.window.titleBarStyle; - changed = true; - } - - // macOS: Native tabs - if (isMacintosh && config.window && typeof config.window.nativeTabs === 'boolean' && config.window.nativeTabs !== this.nativeTabs) { - this.nativeTabs = config.window.nativeTabs; - changed = true; - } - - // macOS: Native fullscreen - if (isMacintosh && config.window && typeof config.window.nativeFullScreen === 'boolean' && config.window.nativeFullScreen !== this.nativeFullScreen) { - this.nativeFullScreen = config.window.nativeFullScreen; - changed = true; - } - - // macOS: Click through (accept first mouse) - if (isMacintosh && config.window && typeof config.window.clickThroughInactive === 'boolean' && config.window.clickThroughInactive !== this.clickThroughInactive) { - this.clickThroughInactive = config.window.clickThroughInactive; - changed = true; - } - - // Update channel - if (config.update && typeof config.update.mode === 'string' && config.update.mode !== this.updateMode) { - this.updateMode = config.update.mode; - changed = true; - } - - // Crash reporter - if (config.telemetry && typeof config.telemetry.enableCrashReporter === 'boolean' && config.telemetry.enableCrashReporter !== this.enableCrashReporter) { - this.enableCrashReporter = config.telemetry.enableCrashReporter; - changed = true; - } - - // macOS: Touchbar config - if (isMacintosh && config.keyboard && config.keyboard.touchbar && typeof config.keyboard.touchbar.enabled === 'boolean' && config.keyboard.touchbar.enabled !== this.touchbarEnabled) { - this.touchbarEnabled = config.keyboard.touchbar.enabled; - changed = true; - } - // Tree horizontal scrolling support if (config.workbench && config.workbench.list && typeof config.workbench.list.horizontalScrolling === 'boolean' && config.workbench.list.horizontalScrolling !== this.treeHorizontalScrolling) { this.treeHorizontalScrolling = config.workbench.list.horizontalScrolling; @@ -117,12 +75,63 @@ export class SettingsChangeRelauncher extends Disposable implements IWorkbenchCo changed = true; } + if (isNative) { + + // Titlebar style + if (config.window && config.window.titleBarStyle !== this.titleBarStyle && (config.window.titleBarStyle === 'native' || config.window.titleBarStyle === 'custom')) { + this.titleBarStyle = config.window.titleBarStyle; + changed = true; + } + + // macOS: Native tabs + if (isMacintosh && config.window && typeof config.window.nativeTabs === 'boolean' && config.window.nativeTabs !== this.nativeTabs) { + this.nativeTabs = config.window.nativeTabs; + changed = true; + } + + // macOS: Native fullscreen + if (isMacintosh && config.window && typeof config.window.nativeFullScreen === 'boolean' && config.window.nativeFullScreen !== this.nativeFullScreen) { + this.nativeFullScreen = config.window.nativeFullScreen; + changed = true; + } + + // macOS: Click through (accept first mouse) + if (isMacintosh && config.window && typeof config.window.clickThroughInactive === 'boolean' && config.window.clickThroughInactive !== this.clickThroughInactive) { + this.clickThroughInactive = config.window.clickThroughInactive; + changed = true; + } + + // Update channel + if (config.update && typeof config.update.mode === 'string' && config.update.mode !== this.updateMode) { + this.updateMode = config.update.mode; + changed = true; + } + + // Crash reporter + if (config.telemetry && typeof config.telemetry.enableCrashReporter === 'boolean' && config.telemetry.enableCrashReporter !== this.enableCrashReporter) { + this.enableCrashReporter = config.telemetry.enableCrashReporter; + changed = true; + } + + // macOS: Touchbar config + if (isMacintosh && config.keyboard && config.keyboard.touchbar && typeof config.keyboard.touchbar.enabled === 'boolean' && config.keyboard.touchbar.enabled !== this.touchbarEnabled) { + this.touchbarEnabled = config.keyboard.touchbar.enabled; + changed = true; + } + } + // Notify only when changed and we are the focused window (avoids notification spam across windows) if (notify && changed) { this.doConfirm( - localize('relaunchSettingMessage', "A setting has changed that requires a restart to take effect."), - localize('relaunchSettingDetail', "Press the restart button to restart {0} and enable the setting.", this.envService.appNameLong), - localize('restart', "&&Restart"), + isNative ? + localize('relaunchSettingMessage', "A setting has changed that requires a restart to take effect.") : + localize('relaunchSettingMessageWeb', "A setting has changed that requires a reload to take effect."), + isNative ? + localize('relaunchSettingDetail', "Press the restart button to restart {0} and enable the setting.", this.envService.appNameLong) : + localize('relaunchSettingDetailWeb', "Press the reload button to reload {0} and enable the setting.", this.envService.appNameLong), + isNative ? + localize('restart', "&&Restart") : + localize('restartWeb', "&&Reload"), () => this.windowsService.relaunch(Object.create(null)) ); } diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index ba1ea7a2075..840b1caa979 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -272,7 +272,7 @@ import 'vs/workbench/contrib/terminal/browser/terminalQuickOpen'; import 'vs/workbench/contrib/terminal/browser/terminalPanel'; // Relauncher -import 'vs/workbench/contrib/relauncher/electron-browser/relauncher.contribution'; +import 'vs/workbench/contrib/relauncher/common/relauncher.contribution'; // Tasks import 'vs/workbench/contrib/tasks/browser/task.contribution'; diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 4d5cf7bfbf9..ca799d9789a 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -283,7 +283,7 @@ registerSingleton(ITerminalNativeService, TerminalNativeService, true); registerSingleton(ITerminalInstanceService, TerminalInstanceService, true); // Relauncher -// import 'vs/workbench/contrib/relauncher/electron-browser/relauncher.contribution'; +import 'vs/workbench/contrib/relauncher/common/relauncher.contribution'; // Tasks import 'vs/workbench/contrib/tasks/browser/task.contribution'; From 2eee0e23c847a01f481c7a307aef716ce658f3eb Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 8 Aug 2019 09:20:49 +0200 Subject: [PATCH 326/861] build: add quality to compile cache key --- build/azure-pipelines/darwin/product-build-darwin.yml | 3 ++- .../linux/product-build-linux-multiarch.yml | 5 +++-- build/azure-pipelines/linux/product-build-linux.yml | 3 ++- build/azure-pipelines/product-compile.yml | 7 ++++--- build/azure-pipelines/web/product-build-web.yml | 3 ++- build/azure-pipelines/win32/product-build-win32.yml | 3 ++- 6 files changed, 15 insertions(+), 9 deletions(-) diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index b712e072849..c088bb8b457 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -2,11 +2,12 @@ steps: - script: | mkdir -p .build echo -n $BUILD_SOURCEVERSION > .build/commit + echo -n $VSCODE_QUALITY > .build/quality displayName: Prepare cache flag - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 inputs: - keyfile: 'build/.cachesalt, .build/commit' + keyfile: 'build/.cachesalt, .build/commit, .build/quality' targetfolder: '.build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min' vstsFeed: 'npm-vscode' platformIndependent: true diff --git a/build/azure-pipelines/linux/product-build-linux-multiarch.yml b/build/azure-pipelines/linux/product-build-linux-multiarch.yml index dff5ae2ceaf..d36c115be78 100644 --- a/build/azure-pipelines/linux/product-build-linux-multiarch.yml +++ b/build/azure-pipelines/linux/product-build-linux-multiarch.yml @@ -2,11 +2,12 @@ steps: - script: | mkdir -p .build echo -n $BUILD_SOURCEVERSION > .build/commit + echo -n $VSCODE_QUALITY > .build/quality displayName: Prepare cache flag - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 inputs: - keyfile: 'build/.cachesalt, .build/commit' + keyfile: 'build/.cachesalt, .build/commit, .build/quality' targetfolder: '.build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min' vstsFeed: 'npm-vscode' platformIndependent: true @@ -112,4 +113,4 @@ steps: - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 displayName: 'Component Detection' - continueOnError: true \ No newline at end of file + continueOnError: true diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index dee07a95d78..a6cc1c34965 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -2,11 +2,12 @@ steps: - script: | mkdir -p .build echo -n $BUILD_SOURCEVERSION > .build/commit + echo -n $VSCODE_QUALITY > .build/quality displayName: Prepare cache flag - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 inputs: - keyfile: 'build/.cachesalt, .build/commit' + keyfile: 'build/.cachesalt, .build/commit, .build/quality' targetfolder: '.build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min' vstsFeed: 'npm-vscode' platformIndependent: true diff --git a/build/azure-pipelines/product-compile.yml b/build/azure-pipelines/product-compile.yml index e5105326e7b..169dfe154fb 100644 --- a/build/azure-pipelines/product-compile.yml +++ b/build/azure-pipelines/product-compile.yml @@ -2,11 +2,12 @@ steps: - script: | mkdir -p .build echo -n $BUILD_SOURCEVERSION > .build/commit + echo -n $VSCODE_QUALITY > .build/quality displayName: Prepare cache flag - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 inputs: - keyfile: 'build/.cachesalt, .build/commit' + keyfile: 'build/.cachesalt, .build/commit, .build/quality' targetfolder: '.build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min' vstsFeed: 'npm-vscode' platformIndependent: true @@ -116,9 +117,9 @@ steps: - task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1 inputs: - keyfile: 'build/.cachesalt, .build/commit' + keyfile: 'build/.cachesalt, .build/commit, .build/quality' targetfolder: '.build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min' vstsFeed: 'npm-vscode' platformIndependent: true alias: 'Compilation' - condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) \ No newline at end of file + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) diff --git a/build/azure-pipelines/web/product-build-web.yml b/build/azure-pipelines/web/product-build-web.yml index 7c65dc982f0..d5851559d67 100644 --- a/build/azure-pipelines/web/product-build-web.yml +++ b/build/azure-pipelines/web/product-build-web.yml @@ -2,11 +2,12 @@ steps: - script: | mkdir -p .build echo -n $BUILD_SOURCEVERSION > .build/commit + echo -n $VSCODE_QUALITY > .build/quality displayName: Prepare cache flag - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 inputs: - keyfile: 'build/.cachesalt, .build/commit' + keyfile: 'build/.cachesalt, .build/commit, .build/quality' targetfolder: '.build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min' vstsFeed: 'npm-vscode' platformIndependent: true diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 7a72dcfb09b..71a47e63d45 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -2,11 +2,12 @@ steps: - powershell: | mkdir .build -ea 0 "$env:BUILD_SOURCEVERSION" | Out-File -Encoding ascii -NoNewLine .build\commit + "$env:VSCODE_QUALITY" | Out-File -Encoding ascii -NoNewLine .build\quality displayName: Prepare cache flag - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 inputs: - keyfile: 'build/.cachesalt, .build/commit' + keyfile: 'build/.cachesalt, .build/commit, .build/quality' targetfolder: '.build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min' vstsFeed: 'npm-vscode' platformIndependent: true From f47bf93da970733c23eba91afbf08aeaba192441 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 8 Aug 2019 10:08:57 +0200 Subject: [PATCH 327/861] add search to injector --- src/vs/workbench/api/common/extHostSearch.ts | 16 ++++++++ .../common/extHostUriTransformerService.ts | 37 ++++++++++++++++++ src/vs/workbench/api/node/extHost.api.impl.ts | 6 +-- src/vs/workbench/api/node/extHost.services.ts | 3 ++ src/vs/workbench/api/node/extHostSearch.ts | 38 ++++++++++++------- .../extensions/node/extensionHostMain.ts | 2 + .../api/extHostSearch.test.ts | 15 +++++++- 7 files changed, 98 insertions(+), 19 deletions(-) create mode 100644 src/vs/workbench/api/common/extHostSearch.ts create mode 100644 src/vs/workbench/api/common/extHostUriTransformerService.ts diff --git a/src/vs/workbench/api/common/extHostSearch.ts b/src/vs/workbench/api/common/extHostSearch.ts new file mode 100644 index 00000000000..efc6ca49825 --- /dev/null +++ b/src/vs/workbench/api/common/extHostSearch.ts @@ -0,0 +1,16 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IDisposable } from 'vs/base/common/lifecycle'; +import * as vscode from 'vscode'; +import { ExtHostSearchShape } from '../common/extHost.protocol'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; + +export interface IExtHostSearch extends ExtHostSearchShape { + registerTextSearchProvider(scheme: string, provider: vscode.TextSearchProvider): IDisposable; + registerFileSearchProvider(scheme: string, provider: vscode.FileSearchProvider): IDisposable; +} + +export const IExtHostSearch = createDecorator('IExtHostSearch'); diff --git a/src/vs/workbench/api/common/extHostUriTransformerService.ts b/src/vs/workbench/api/common/extHostUriTransformerService.ts new file mode 100644 index 00000000000..e9acd9bc5d6 --- /dev/null +++ b/src/vs/workbench/api/common/extHostUriTransformerService.ts @@ -0,0 +1,37 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IURITransformer } from 'vs/base/common/uriIpc'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { URI, UriComponents } from 'vs/base/common/uri'; + +export interface IURITransformerService extends IURITransformer { + _serviceBrand: any; +} + +export const IURITransformerService = createDecorator('IURITransformerService'); + +export class URITransformerService implements IURITransformerService { + _serviceBrand: any; + + transformIncoming: (uri: UriComponents) => UriComponents; + transformOutgoing: (uri: UriComponents) => UriComponents; + transformOutgoingURI: (uri: URI) => URI; + transformOutgoingScheme: (scheme: string) => string; + + constructor(delegate: IURITransformer | null) { + if (!delegate) { + this.transformIncoming = arg => arg; + this.transformOutgoing = arg => arg; + this.transformOutgoingURI = arg => arg; + this.transformOutgoingScheme = arg => arg; + } else { + this.transformIncoming = delegate.transformIncoming.bind(delegate); + this.transformOutgoing = delegate.transformOutgoing.bind(delegate); + this.transformOutgoingURI = delegate.transformOutgoingURI.bind(delegate); + this.transformOutgoingScheme = delegate.transformOutgoingScheme.bind(delegate); + } + } +} diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 8870ae9a0cf..52d3f877333 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -39,7 +39,6 @@ import { IExtHostOutputService } from 'vs/workbench/api/common/extHostOutput'; import { ExtHostProgress } from 'vs/workbench/api/common/extHostProgress'; import { ExtHostQuickOpen } from 'vs/workbench/api/common/extHostQuickOpen'; import { ExtHostSCM } from 'vs/workbench/api/common/extHostSCM'; -import { ExtHostSearch, registerEHSearchProviders } from 'vs/workbench/api/node/extHostSearch'; import { ExtHostStatusBar } from 'vs/workbench/api/common/extHostStatusBar'; import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; @@ -69,6 +68,7 @@ import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation import { IExtHostDecorations } from 'vs/workbench/api/common/extHostDecorations'; import { IExtHostTask } from 'vs/workbench/api/common/extHostTask'; import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService'; +import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch'; export interface IExtensionApiFactory { (extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode; @@ -124,7 +124,7 @@ export function createApiFactory( const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, accessor.get(IExtHostDebugService)); const extHostSCM = rpcProtocol.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(rpcProtocol, extHostCommands, extHostLogService)); const extHostComment = rpcProtocol.set(ExtHostContext.ExtHostComments, new ExtHostComments(rpcProtocol, extHostCommands, extHostDocuments)); - const extHostSearch = rpcProtocol.set(ExtHostContext.ExtHostSearch, new ExtHostSearch(rpcProtocol, uriTransformer, extHostLogService)); + const extHostSearch = rpcProtocol.set(ExtHostContext.ExtHostSearch, accessor.get(IExtHostSearch)); const extHostTask = rpcProtocol.set(ExtHostContext.ExtHostTask, accessor.get(IExtHostTask)); const extHostWindow = rpcProtocol.set(ExtHostContext.ExtHostWindow, new ExtHostWindow(rpcProtocol)); rpcProtocol.set(ExtHostContext.ExtHostExtensionService, extensionService); @@ -140,8 +140,6 @@ export function createApiFactory( platform: process.platform }); - registerEHSearchProviders(extHostSearch, extHostLogService); - const cliServer = new CLIServer(extHostCommands); process.env['VSCODE_IPC_HOOK_CLI'] = cliServer.ipcHandlePath; } diff --git a/src/vs/workbench/api/node/extHost.services.ts b/src/vs/workbench/api/node/extHost.services.ts index 4a8176170d7..434f8b170d8 100644 --- a/src/vs/workbench/api/node/extHost.services.ts +++ b/src/vs/workbench/api/node/extHost.services.ts @@ -17,6 +17,8 @@ import { IExtHostTask } from 'vs/workbench/api/common/extHostTask'; import { ExtHostTask } from 'vs/workbench/api/node/extHostTask'; import { ExtHostDebugService } from 'vs/workbench/api/node/extHostDebugService'; import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService'; +import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch'; +import { ExtHostSearch } from 'vs/workbench/api/node/extHostSearch'; // register singleton services registerSingleton(IExtHostOutputService, ExtHostOutputService2); @@ -28,3 +30,4 @@ registerSingleton(IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors); registerSingleton(IExtHostTerminalService, ExtHostTerminalService); registerSingleton(IExtHostTask, ExtHostTask); registerSingleton(IExtHostDebugService, ExtHostDebugService); +registerSingleton(IExtHostSearch, ExtHostSearch); diff --git a/src/vs/workbench/api/node/extHostSearch.ts b/src/vs/workbench/api/node/extHostSearch.ts index 5f6be2d3e60..ea1ee401e18 100644 --- a/src/vs/workbench/api/node/extHostSearch.ts +++ b/src/vs/workbench/api/node/extHostSearch.ts @@ -15,8 +15,10 @@ import { RipgrepSearchProvider } from 'vs/workbench/services/search/node/ripgrep import { OutputChannel } from 'vs/workbench/services/search/node/ripgrepSearchUtils'; import { TextSearchManager } from 'vs/workbench/services/search/node/textSearchManager'; import * as vscode from 'vscode'; -import { ExtHostSearchShape, IMainContext, MainContext, MainThreadSearchShape } from '../common/extHost.protocol'; -import { IURITransformer } from 'vs/base/common/uriIpc'; +import { ExtHostSearchShape, MainContext, MainThreadSearchShape } from '../common/extHost.protocol'; +import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IURITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService'; +import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; export class ExtHostSearch implements ExtHostSearchShape { @@ -32,16 +34,30 @@ export class ExtHostSearch implements ExtHostSearchShape { private _fileSearchManager: FileSearchManager; - constructor(mainContext: IMainContext, private _uriTransformer: IURITransformer | null, private _logService: ILogService, private _pfs = pfs) { - this._proxy = mainContext.getProxy(MainContext.MainThreadSearch); + protected _pfs: typeof pfs = pfs; // allow extending for tests + + constructor( + @IExtHostRpcService extHostRpc: IExtHostRpcService, + @IExtHostInitDataService initData: IExtHostInitDataService, + @IURITransformerService private _uriTransformer: IURITransformerService, + @ILogService private _logService: ILogService, + ) { + this._proxy = extHostRpc.getProxy(MainContext.MainThreadSearch); this._fileSearchManager = new FileSearchManager(); + + if (initData.remote.isRemote && initData.remote.authority) { + this._registerEHSearchProviders(); + } + } + + private _registerEHSearchProviders(): void { + const outputChannel = new OutputChannel(this._logService); + this.registerTextSearchProvider('file', new RipgrepSearchProvider(outputChannel)); + this.registerInternalFileSearchProvider('file', new SearchService()); } private _transformScheme(scheme: string): string { - if (this._uriTransformer) { - return this._uriTransformer.transformOutgoingScheme(scheme); - } - return scheme; + return this._uriTransformer.transformOutgoingScheme(scheme); } registerTextSearchProvider(scheme: string, provider: vscode.TextSearchProvider): IDisposable { @@ -148,12 +164,6 @@ export class ExtHostSearch implements ExtHostSearchShape { } } -export function registerEHSearchProviders(extHostSearch: ExtHostSearch, logService: ILogService): void { - const outputChannel = new OutputChannel(logService); - extHostSearch.registerTextSearchProvider('file', new RipgrepSearchProvider(outputChannel)); - extHostSearch.registerInternalFileSearchProvider('file', new SearchService()); -} - function reviveQuery(rawQuery: U): U extends IRawTextQuery ? ITextQuery : IFileQuery { return { ...rawQuery, // TODO diff --git a/src/vs/workbench/services/extensions/node/extensionHostMain.ts b/src/vs/workbench/services/extensions/node/extensionHostMain.ts index 89ce6ba8bc0..da8f9ff60aa 100644 --- a/src/vs/workbench/services/extensions/node/extensionHostMain.ts +++ b/src/vs/workbench/services/extensions/node/extensionHostMain.ts @@ -21,6 +21,7 @@ import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitData import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IExtHostRpcService, ExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IURITransformerService, URITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService'; // we don't (yet) throw when extensions parse // uris that have no scheme @@ -72,6 +73,7 @@ export class ExtensionHostMain { services.set(IExtHostInitDataService, { _serviceBrand: undefined, ...initData }); services.set(IExtHostRpcService, new ExtHostRpcService(rpcProtocol)); services.set(ILogService, extHostLogService); + services.set(IURITransformerService, new URITransformerService(uriTransformer)); const instaService: IInstantiationService = new InstantiationService(services, true); diff --git a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts index 0d15201d893..8dff457b408 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts @@ -18,6 +18,9 @@ import { IFileMatch, IFileQuery, IPatternInfo, IRawFileMatch2, ISearchCompleteSt import { TestRPCProtocol } from 'vs/workbench/test/electron-browser/api/testRPCProtocol'; import * as vscode from 'vscode'; import { NullLogService } from 'vs/platform/log/common/log'; +import { URITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService'; +import { mock } from 'vs/workbench/test/electron-browser/api/mock'; +import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; let rpcProtocol: TestRPCProtocol; let extHostSearch: ExtHostSearch; @@ -135,7 +138,17 @@ suite('ExtHostSearch', () => { rpcProtocol.set(MainContext.MainThreadSearch, mockMainThreadSearch); mockPFS = {}; - extHostSearch = new ExtHostSearch(rpcProtocol, null!, logService, mockPFS as any); + extHostSearch = new class extends ExtHostSearch { + constructor() { + super( + rpcProtocol, + new class extends mock() { remote = { isRemote: false, authority: undefined }; }, + new URITransformerService(null), + logService + ); + this._pfs = mockPFS as any; + } + }; }); teardown(() => { From 8ed1045e87f0b133eee9975d0df66dc36d8add3d Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 8 Aug 2019 10:09:19 +0200 Subject: [PATCH 328/861] fixes #78603 --- src/vs/workbench/contrib/scm/browser/scm.contribution.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/scm/browser/scm.contribution.ts b/src/vs/workbench/contrib/scm/browser/scm.contribution.ts index beef3cdc9fb..fc2dcc8b96e 100644 --- a/src/vs/workbench/contrib/scm/browser/scm.contribution.ts +++ b/src/vs/workbench/contrib/scm/browser/scm.contribution.ts @@ -16,7 +16,7 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { StatusUpdater, StatusBarController } from './scmActivity'; import { SCMViewlet } from 'vs/workbench/contrib/scm/browser/scmViewlet'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; -import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry'; +import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { ICommandService } from 'vs/platform/commands/common/commands'; @@ -69,6 +69,7 @@ Registry.as(ConfigurationExtensions.Configuration).regis order: 5, title: localize('scmConfigurationTitle', "SCM"), type: 'object', + scope: ConfigurationScope.RESOURCE, properties: { 'scm.alwaysShowProviders': { type: 'boolean', From bd30caa0d74d651f59e8532e183d0854a9eed0e3 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 8 Aug 2019 10:38:33 +0200 Subject: [PATCH 329/861] fix git count badge setting change update --- extensions/git/src/repository.ts | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index a9af9324db6..a4b37bebd5e 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -724,6 +724,10 @@ export class Repository implements Disposable { const progressManager = new ProgressManager(this); this.disposables.push(progressManager); + const onDidChangeCountBadge = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.countBadge', root)); + onDidChangeCountBadge(this.setCountBadge, this, this.disposables); + this.setCountBadge(); + this.updateCommitTemplate(); } @@ -1495,15 +1499,7 @@ export class Repository implements Disposable { this.workingTreeGroup.resourceStates = workingTree; // set count badge - const countBadge = workspace.getConfiguration('git').get('countBadge'); - let count = merge.length + index.length + workingTree.length; - - switch (countBadge) { - case 'off': count = 0; break; - case 'tracked': count = count - workingTree.filter(r => r.type === Status.UNTRACKED || r.type === Status.IGNORED).length; break; - } - - this._sourceControl.count = count; + this.setCountBadge(); // Disable `Discard All Changes` for "fresh" repositories // https://github.com/Microsoft/vscode/issues/43066 @@ -1517,6 +1513,18 @@ export class Repository implements Disposable { this._onDidChangeStatus.fire(); } + private setCountBadge(): void { + const countBadge = workspace.getConfiguration('git').get('countBadge'); + let count = this.mergeGroup.resourceStates.length + this.indexGroup.resourceStates.length + this.workingTreeGroup.resourceStates.length; + + switch (countBadge) { + case 'off': count = 0; break; + case 'tracked': count = count - this.workingTreeGroup.resourceStates.filter(r => r.type === Status.UNTRACKED || r.type === Status.IGNORED).length; break; + } + + this._sourceControl.count = count; + } + private async getRebaseCommit(): Promise { const rebaseHeadPath = path.join(this.repository.root, '.git', 'REBASE_HEAD'); const rebaseApplyPath = path.join(this.repository.root, '.git', 'rebase-apply'); From aef1a6c803c17434ba13d18c80bb5c9898b217fa Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 8 Aug 2019 10:38:46 +0200 Subject: [PATCH 330/861] add setting: scm.countBadge fixes #78610 --- .../contrib/scm/browser/scm.contribution.ts | 18 ++- .../contrib/scm/browser/scmActivity.ts | 118 ++++++++---------- 2 files changed, 63 insertions(+), 73 deletions(-) diff --git a/src/vs/workbench/contrib/scm/browser/scm.contribution.ts b/src/vs/workbench/contrib/scm/browser/scm.contribution.ts index fc2dcc8b96e..8385ae8124d 100644 --- a/src/vs/workbench/contrib/scm/browser/scm.contribution.ts +++ b/src/vs/workbench/contrib/scm/browser/scm.contribution.ts @@ -13,7 +13,7 @@ import { IWorkbenchActionRegistry, Extensions as WorkbenchActionExtensions } fro import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; -import { StatusUpdater, StatusBarController } from './scmActivity'; +import { SCMStatusController } from './scmActivity'; import { SCMViewlet } from 'vs/workbench/contrib/scm/browser/scmViewlet'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; @@ -47,10 +47,7 @@ Registry.as(ViewletExtensions.Viewlets).registerViewlet(new Vie )); Registry.as(WorkbenchExtensions.Workbench) - .registerWorkbenchContribution(StatusUpdater, LifecyclePhase.Restored); - -Registry.as(WorkbenchExtensions.Workbench) - .registerWorkbenchContribution(StatusBarController, LifecyclePhase.Restored); + .registerWorkbenchContribution(SCMStatusController, LifecyclePhase.Restored); // Register Action to Open Viewlet Registry.as(WorkbenchActionExtensions.WorkbenchActions).registerWorkbenchAction( @@ -97,6 +94,17 @@ Registry.as(ConfigurationExtensions.Configuration).regis type: 'boolean', description: localize('alwaysShowActions', "Controls whether inline actions are always visible in the Source Control view."), default: false + }, + 'scm.countBadge': { + type: 'string', + enum: ['all', 'focused', 'off'], + enumDescriptions: [ + localize('scm.countBadge.all', "Show the sum of all Source Control Providers count badges."), + localize('scm.countBadge.focused', "Show the count badge of the focused Source Control Provider."), + localize('scm.countBadge.off', "Disable the Source Control count badge.") + ], + description: localize('scm.countBadge', "Controls the Source Control count badge."), + default: 'all' } } }); diff --git a/src/vs/workbench/contrib/scm/browser/scmActivity.ts b/src/vs/workbench/contrib/scm/browser/scmActivity.ts index aaa9676f892..a76d60e0e0e 100644 --- a/src/vs/workbench/contrib/scm/browser/scmActivity.ts +++ b/src/vs/workbench/contrib/scm/browser/scmActivity.ts @@ -14,92 +14,45 @@ import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/c import { IStatusbarService, StatusbarAlignment as MainThreadStatusBarAlignment } from 'vs/platform/statusbar/common/statusbar'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { commonPrefixLength } from 'vs/base/common/strings'; -import { ILogService } from 'vs/platform/log/common/log'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -export class StatusUpdater implements IWorkbenchContribution { - - private readonly badgeDisposable = new MutableDisposable(); - private disposables: IDisposable[] = []; - - constructor( - @ISCMService private readonly scmService: ISCMService, - @IActivityService private readonly activityService: IActivityService, - @ILogService private readonly logService: ILogService - ) { - for (const repository of this.scmService.repositories) { - this.onDidAddRepository(repository); - } - - this.scmService.onDidAddRepository(this.onDidAddRepository, this, this.disposables); - this.render(); - } - - private onDidAddRepository(repository: ISCMRepository): void { - const provider = repository.provider; - const onDidChange = Event.any(provider.onDidChange, provider.onDidChangeResources); - const changeDisposable = onDidChange(() => this.render()); - - const onDidRemove = Event.filter(this.scmService.onDidRemoveRepository, e => e === repository); - const removeDisposable = onDidRemove(() => { - disposable.dispose(); - this.disposables = this.disposables.filter(d => d !== removeDisposable); - this.render(); - }); - - const disposable = combinedDisposable(changeDisposable, removeDisposable); - this.disposables.push(disposable); - } - - private render(): void { - this.badgeDisposable.clear(); - - const count = this.scmService.repositories.reduce((r, repository) => { - if (typeof repository.provider.count === 'number') { - return r + repository.provider.count; - } else { - return r + repository.provider.groups.elements.reduce((r, g) => r + g.elements.length, 0); - } - }, 0); - - // TODO@joao: remove - this.logService.trace('SCM#StatusUpdater.render', count); - - if (count > 0) { - const badge = new NumberBadge(count, num => localize('scmPendingChangesBadge', '{0} pending changes', num)); - this.badgeDisposable.value = this.activityService.showActivity(VIEWLET_ID, badge, 'scm-viewlet-label'); - } else { - this.badgeDisposable.clear(); - } - } - - dispose(): void { - this.badgeDisposable.dispose(); - this.disposables = dispose(this.disposables); +function getCount(repository: ISCMRepository): number { + if (typeof repository.provider.count === 'number') { + return repository.provider.count; + } else { + return repository.provider.groups.elements.reduce((r, g) => r + g.elements.length, 0); } } -export class StatusBarController implements IWorkbenchContribution { +export class SCMStatusController implements IWorkbenchContribution { private statusBarDisposable: IDisposable = Disposable.None; private focusDisposable: IDisposable = Disposable.None; private focusedRepository: ISCMRepository | undefined = undefined; private focusedProviderContextKey: IContextKey; + private readonly badgeDisposable = new MutableDisposable(); private disposables: IDisposable[] = []; constructor( @ISCMService private readonly scmService: ISCMService, @IStatusbarService private readonly statusbarService: IStatusbarService, - @IContextKeyService contextKeyService: IContextKeyService, - @IEditorService private readonly editorService: IEditorService + @IContextKeyService readonly contextKeyService: IContextKeyService, + @IActivityService private readonly activityService: IActivityService, + @IEditorService private readonly editorService: IEditorService, + @IConfigurationService private readonly configurationService: IConfigurationService ) { this.focusedProviderContextKey = contextKeyService.createKey('scmProvider', undefined); this.scmService.onDidAddRepository(this.onDidAddRepository, this, this.disposables); + const onDidChangeSCMCountBadge = Event.filter(configurationService.onDidChangeConfiguration, e => e.affectsConfiguration('scm.countBadge')); + onDidChangeSCMCountBadge(this.renderActivityCount, this, this.disposables); + for (const repository of this.scmService.repositories) { this.onDidAddRepository(repository); } editorService.onDidActiveEditorChange(this.onDidActiveEditorChange, this, this.disposables); + this.renderActivityCount(); } private onDidActiveEditorChange(): void { @@ -138,7 +91,11 @@ export class StatusBarController implements IWorkbenchContribution { } private onDidAddRepository(repository: ISCMRepository): void { - const changeDisposable = repository.onDidFocus(() => this.onDidFocusRepository(repository)); + const focusDisposable = repository.onDidFocus(() => this.onDidFocusRepository(repository)); + + const onDidChange = Event.any(repository.provider.onDidChange, repository.provider.onDidChangeResources); + const changeDisposable = onDidChange(() => this.renderActivityCount()); + const onDidRemove = Event.filter(this.scmService.onDidRemoveRepository, e => e === repository); const removeDisposable = onDidRemove(() => { disposable.dispose(); @@ -149,9 +106,11 @@ export class StatusBarController implements IWorkbenchContribution { } else if (this.focusedRepository === repository) { this.scmService.repositories[0].focus(); } + + this.renderActivityCount(); }); - const disposable = combinedDisposable(changeDisposable, removeDisposable); + const disposable = combinedDisposable(focusDisposable, changeDisposable, removeDisposable); this.disposables.push(disposable); if (!this.focusedRepository) { @@ -169,13 +128,14 @@ export class StatusBarController implements IWorkbenchContribution { this.focusDisposable.dispose(); if (repository && repository.provider.onDidChangeStatusBarCommands) { - this.focusDisposable = repository.provider.onDidChangeStatusBarCommands(() => this.render(repository)); + this.focusDisposable = repository.provider.onDidChangeStatusBarCommands(() => this.renderStatusBar(repository)); } - this.render(repository); + this.renderStatusBar(repository); + this.renderActivityCount(); } - private render(repository: ISCMRepository | undefined): void { + private renderStatusBar(repository: ISCMRepository | undefined): void { this.statusBarDisposable.dispose(); if (!repository) { @@ -200,9 +160,31 @@ export class StatusBarController implements IWorkbenchContribution { this.statusBarDisposable = disposables; } + private renderActivityCount(): void { + this.badgeDisposable.clear(); + + const countBadgeType = this.configurationService.getValue<'all' | 'focused' | 'off'>('scm.countBadge'); + + let count = 0; + + if (countBadgeType === 'all') { + count = this.scmService.repositories.reduce((r, repository) => r + getCount(repository), 0); + } else if (countBadgeType === 'focused' && this.focusedRepository) { + count = getCount(this.focusedRepository); + } + + if (count > 0) { + const badge = new NumberBadge(count, num => localize('scmPendingChangesBadge', '{0} pending changes', num)); + this.badgeDisposable.value = this.activityService.showActivity(VIEWLET_ID, badge, 'scm-viewlet-label'); + } else { + this.badgeDisposable.clear(); + } + } + dispose(): void { this.focusDisposable.dispose(); this.statusBarDisposable.dispose(); + this.badgeDisposable.dispose(); this.disposables = dispose(this.disposables); } } From c92430ca57ea152f4a10386ebfae12321ff95335 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 8 Aug 2019 10:44:19 +0200 Subject: [PATCH 331/861] web - prevent unload while writing state to storage service --- .../platform/storage/browser/storageService.ts | 17 +++++++++++++++-- src/vs/platform/storage/common/storage.ts | 15 +++++++++++++-- src/vs/workbench/browser/web.main.ts | 8 +++++++- src/vs/workbench/browser/workbench.ts | 6 +++++- .../textfile/browser/textFileService.ts | 3 ++- 5 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/vs/platform/storage/browser/storageService.ts b/src/vs/platform/storage/browser/storageService.ts index d7e7be28dd7..392ca58f2b8 100644 --- a/src/vs/platform/storage/browser/storageService.ts +++ b/src/vs/platform/storage/browser/storageService.ts @@ -28,11 +28,18 @@ export class BrowserStorageService extends Disposable implements IStorageService private globalStorage: IStorage; private workspaceStorage: IStorage; + private globalStorageDatabase: FileStorageDatabase; + private workspaceStorageDatabase: FileStorageDatabase; + private globalStorageFile: URI; private workspaceStorageFile: URI; private initializePromise: Promise; + get hasPendingUpdate(): boolean { + return this.globalStorageDatabase.hasPendingUpdate || this.workspaceStorageDatabase.hasPendingUpdate; + } + constructor( @IEnvironmentService private readonly environmentService: IEnvironmentService, @IFileService private readonly fileService: IFileService @@ -76,12 +83,14 @@ export class BrowserStorageService extends Disposable implements IStorageService // Workspace Storage this.workspaceStorageFile = joinPath(stateRoot, `${payload.id}.json`); - this.workspaceStorage = new Storage(this._register(new FileStorageDatabase(this.workspaceStorageFile, this.fileService))); + this.workspaceStorageDatabase = this._register(new FileStorageDatabase(this.workspaceStorageFile, this.fileService)); + this.workspaceStorage = new Storage(this.workspaceStorageDatabase); this._register(this.workspaceStorage.onDidChangeStorage(key => this._onDidChangeStorage.fire({ key, scope: StorageScope.WORKSPACE }))); // Global Storage this.globalStorageFile = joinPath(stateRoot, 'global.json'); - this.globalStorage = new Storage(this._register(new FileStorageDatabase(this.globalStorageFile, this.fileService))); + this.globalStorageDatabase = this._register(new FileStorageDatabase(this.globalStorageFile, this.fileService)); + this.globalStorage = new Storage(this.globalStorageDatabase); this._register(this.globalStorage.onDidChangeStorage(key => this._onDidChangeStorage.fire({ key, scope: StorageScope.GLOBAL }))); // Init both @@ -134,5 +143,9 @@ export class BrowserStorageService extends Disposable implements IStorageService // Signal as event so that clients can still store data this._onWillSaveState.fire({ reason: WillSaveStateReason.SHUTDOWN }); + + // Close DBs + this.globalStorage.close(); + this.workspaceStorage.close(); } } diff --git a/src/vs/platform/storage/common/storage.ts b/src/vs/platform/storage/common/storage.ts index 5f6e2b6673f..46fdd613d11 100644 --- a/src/vs/platform/storage/common/storage.ts +++ b/src/vs/platform/storage/common/storage.ts @@ -220,6 +220,11 @@ export class FileStorageDatabase extends Disposable implements IStorageDatabase private pendingUpdate: Promise = Promise.resolve(); + private _hasPendingUpdate = false; + get hasPendingUpdate(): boolean { + return this._hasPendingUpdate; + } + constructor( private readonly file: URI, private readonly fileService: IFileService @@ -260,7 +265,13 @@ export class FileStorageDatabase extends Disposable implements IStorageDatabase await this.pendingUpdate; - this.pendingUpdate = this.fileService.writeFile(this.file, VSBuffer.fromString(JSON.stringify(mapToSerializable(items)))).then(); + this._hasPendingUpdate = true; + + this.pendingUpdate = this.fileService.writeFile(this.file, VSBuffer.fromString(JSON.stringify(mapToSerializable(items)))) + .then(() => undefined) + .finally(() => { + this._hasPendingUpdate = false; + }); return this.pendingUpdate; } @@ -312,4 +323,4 @@ export async function logStorage(global: Map, workspace: Map workbench.layout())); // Workbench Lifecycle - this._register(workbench.onShutdown(() => this.dispose())); + this._register(workbench.onBeforeShutdown(event => { + if (services.storageService.hasPendingUpdate) { + console.warn('Unload prevented: pending storage update'); + event.veto(true); // prevent data loss from pending storage update + } + })); this._register(workbench.onWillShutdown(() => { services.storageService.close(); this.saveBaseTheme(); })); + this._register(workbench.onShutdown(() => this.dispose())); // Startup workbench.startup(); diff --git a/src/vs/workbench/browser/workbench.ts b/src/vs/workbench/browser/workbench.ts index c5757dd5423..336f7d97e97 100644 --- a/src/vs/workbench/browser/workbench.ts +++ b/src/vs/workbench/browser/workbench.ts @@ -25,7 +25,7 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; -import { LifecyclePhase, ILifecycleService, WillShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle'; +import { LifecyclePhase, ILifecycleService, WillShutdownEvent, BeforeShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { NotificationService } from 'vs/workbench/services/notification/common/notificationService'; import { NotificationsCenter } from 'vs/workbench/browser/parts/notifications/notificationsCenter'; @@ -47,6 +47,9 @@ import { Layout } from 'vs/workbench/browser/layout'; export class Workbench extends Layout { + private readonly _onBeforeShutdown = this._register(new Emitter()); + readonly onBeforeShutdown: Event = this._onBeforeShutdown.event; + private readonly _onShutdown = this._register(new Emitter()); readonly onShutdown: Event = this._onShutdown.event; @@ -225,6 +228,7 @@ export class Workbench extends Layout { ): void { // Lifecycle + this._register(lifecycleService.onBeforeShutdown(event => this._onBeforeShutdown.fire(event))); this._register(lifecycleService.onWillShutdown(event => this._onWillShutdown.fire(event))); this._register(lifecycleService.onShutdown(() => { this._onShutdown.fire(); diff --git a/src/vs/workbench/services/textfile/browser/textFileService.ts b/src/vs/workbench/services/textfile/browser/textFileService.ts index 9f0660e400c..ac16d811705 100644 --- a/src/vs/workbench/services/textfile/browser/textFileService.ts +++ b/src/vs/workbench/services/textfile/browser/textFileService.ts @@ -46,6 +46,7 @@ export class BrowserTextFileService extends TextFileService { } if (!hasBackup) { + console.warn('Unload prevented: pending backups'); return true; // dirty without backup: veto } } @@ -54,4 +55,4 @@ export class BrowserTextFileService extends TextFileService { } } -registerSingleton(ITextFileService, BrowserTextFileService); \ No newline at end of file +registerSingleton(ITextFileService, BrowserTextFileService); From 0920cd6ecbfd37f26974691f2147b39e52cf82ff Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 8 Aug 2019 10:45:03 +0200 Subject: [PATCH 332/861] move task registration depending on process into /node/ --- src/vs/workbench/api/node/extHost.api.impl.ts | 7 ------- src/vs/workbench/api/node/extHostTask.ts | 11 +++++++++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 52d3f877333..21c90b637fa 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -59,7 +59,6 @@ import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensio import { originalFSPath } from 'vs/base/common/resources'; import { CLIServer } from 'vs/workbench/api/node/extHostCLIServer'; import { values } from 'vs/base/common/collections'; -import { Schemas } from 'vs/base/common/network'; import { IURITransformer } from 'vs/base/common/uriIpc'; import { ExtHostEditorInsets } from 'vs/workbench/api/common/extHostCodeInsets'; import { ExtHostLabelService } from 'vs/workbench/api/common/extHostLabelService'; @@ -134,12 +133,6 @@ export function createApiFactory( const extHostLabelService = rpcProtocol.set(ExtHostContext.ExtHosLabelService, new ExtHostLabelService(rpcProtocol)); if (initData.remote.isRemote && initData.remote.authority) { - extHostTask.registerTaskSystem(Schemas.vscodeRemote, { - scheme: Schemas.vscodeRemote, - authority: initData.remote.authority, - platform: process.platform - }); - const cliServer = new CLIServer(extHostCommands); process.env['VSCODE_IPC_HOOK_CLI'] = cliServer.ipcHandlePath; } diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index 5e31d4eaa61..c826cccf633 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -32,6 +32,8 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; +import { Schemas } from 'vs/base/common/network'; namespace TaskDefinitionDTO { export function from(value: vscode.TaskDefinition): TaskDefinitionDTO | undefined { @@ -376,6 +378,7 @@ export class ExtHostTask implements ExtHostTaskShape { constructor( @IExtHostRpcService extHostRpc: IExtHostRpcService, + @IExtHostInitDataService initData: IExtHostInitDataService, @IExtHostWorkspace workspaceService: IExtHostWorkspace, @IExtHostDocumentsAndEditors editorService: IExtHostDocumentsAndEditors, @IExtHostConfiguration configurationService: IExtHostConfiguration, @@ -391,6 +394,14 @@ export class ExtHostTask implements ExtHostTaskShape { this._taskExecutions = new Map(); this._providedCustomExecutions2 = new Map(); this._activeCustomExecutions2 = new Map(); + + if (initData.remote.isRemote && initData.remote.authority) { + this.registerTaskSystem(Schemas.vscodeRemote, { + scheme: Schemas.vscodeRemote, + authority: initData.remote.authority, + platform: process.platform + }); + } } public registerTaskProvider(extension: IExtensionDescription, type: string, provider: vscode.TaskProvider): vscode.Disposable { From 6e9e6e912aadb5b69bb9d93ebb818258c632ff80 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 8 Aug 2019 10:54:14 +0200 Subject: [PATCH 333/861] extHostDownload isn't main thread addressable --- src/vs/workbench/api/common/extHost.protocol.ts | 4 ---- src/vs/workbench/api/node/extHost.api.impl.ts | 4 +++- src/vs/workbench/api/node/extHostDownloadService.ts | 12 +++++++++--- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 26f84014001..ea7865ddb0d 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -815,9 +815,6 @@ export interface ExtHostTreeViewsShape { $setVisible(treeViewId: string, visible: boolean): void; } -export interface ExtHostDownloadServiceShape { -} - export interface ExtHostWorkspaceShape { $initializeWorkspace(workspace: IWorkspaceData | null): void; $acceptWorkspaceData(workspace: IWorkspaceData | null): void; @@ -1354,7 +1351,6 @@ export const ExtHostContext = { ExtHostDocumentSaveParticipant: createExtId('ExtHostDocumentSaveParticipant'), ExtHostEditors: createExtId('ExtHostEditors'), ExtHostTreeViews: createExtId('ExtHostTreeViews'), - ExtHostDownloadService: createExtId('ExtHostDownloadService'), ExtHostFileSystem: createExtId('ExtHostFileSystem'), ExtHostFileSystemEventService: createExtId('ExtHostFileSystemEventService'), ExtHostLanguageFeatures: createExtId('ExtHostLanguageFeatures'), diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 21c90b637fa..353f7d39c76 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -110,7 +110,6 @@ export function createApiFactory( const extHostEditors = rpcProtocol.set(ExtHostContext.ExtHostEditors, new ExtHostEditors(rpcProtocol, extHostDocumentsAndEditors)); const extHostCommands = rpcProtocol.set(ExtHostContext.ExtHostCommands, accessor.get(IExtHostCommands)); const extHostTreeViews = rpcProtocol.set(ExtHostContext.ExtHostTreeViews, new ExtHostTreeViews(rpcProtocol.getProxy(MainContext.MainThreadTreeViews), extHostCommands, extHostLogService)); - rpcProtocol.set(ExtHostContext.ExtHostDownloadService, new ExtHostDownloadService(rpcProtocol.getProxy(MainContext.MainThreadDownloadService), extHostCommands)); rpcProtocol.set(ExtHostContext.ExtHostWorkspace, extHostWorkspace); rpcProtocol.set(ExtHostContext.ExtHostConfiguration, extHostConfiguration); const extHostEditorInsets = rpcProtocol.set(ExtHostContext.ExtHostEditorInsets, new ExtHostEditorInsets(rpcProtocol.getProxy(MainContext.MainThreadEditorInsets), extHostEditors, initData.environment)); @@ -155,6 +154,9 @@ export function createApiFactory( // Register API-ish commands ExtHostApiCommands.register(extHostCommands); + // Register Download command + ExtHostDownloadService.register(rpcProtocol.getProxy(MainContext.MainThreadDownloadService), extHostCommands); + return function (extension: IExtensionDescription, extensionRegistry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode { // Check document selectors for being overly generic. Technically this isn't a problem but diff --git a/src/vs/workbench/api/node/extHostDownloadService.ts b/src/vs/workbench/api/node/extHostDownloadService.ts index c86a8ecd8f9..ad43979716c 100644 --- a/src/vs/workbench/api/node/extHostDownloadService.ts +++ b/src/vs/workbench/api/node/extHostDownloadService.ts @@ -13,7 +13,14 @@ import { URI } from 'vs/base/common/uri'; export class ExtHostDownloadService extends Disposable { - constructor( + static register( + proxy: MainThreadDownloadServiceShape, + commands: ExtHostCommands + ) { + return new ExtHostDownloadService(proxy, commands); + } + + private constructor( proxy: MainThreadDownloadServiceShape, commands: ExtHostCommands ) { @@ -24,5 +31,4 @@ export class ExtHostDownloadService extends Disposable { return location; }); } - -} \ No newline at end of file +} From b8a7a8931f306b46f3cba6fd01bb7197ff1d0900 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 8 Aug 2019 10:56:39 +0200 Subject: [PATCH 334/861] web - enable sourcemaps (#78690) --- build/azure-pipelines/upload-sourcemaps.js | 34 +++++++++++++++---- .../azure-pipelines/web/product-build-web.yml | 9 +++++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/build/azure-pipelines/upload-sourcemaps.js b/build/azure-pipelines/upload-sourcemaps.js index ac3bd55a7f5..190023f40dc 100644 --- a/build/azure-pipelines/upload-sourcemaps.js +++ b/build/azure-pipelines/upload-sourcemaps.js @@ -13,19 +13,39 @@ const util = require('../lib/util'); const root = path.dirname(path.dirname(__dirname)); const commit = util.getVersion(root); -function main() { - const vs = vfs.src('out-vscode-min/**/*.map', { base: 'out-vscode-min' }) // client source-maps only +// optionally allow to pass in explicit base/maps to upload +const args = process.argv.slice(2); +const base = args[0]; +const maps = args[1]; + +const fetch = function (base, maps = `${base}/**/*.map`) { + return vfs.src(maps, { base }) .pipe(es.mapSync(f => { f.path = `${f.base}/core/${f.relative}`; return f; })); +}; - const extensionsOut = vfs.src(['.build/extensions/**/*.js.map', '!**/node_modules/**'], { base: '.build' }); +function main() { + const sources = []; - return es.merge(vs, extensionsOut) + // vscode client maps (default) + if (!base) { + const vs = fetch('out-vscode-min'); // client source-maps only + sources.push(vs); + + const extensionsOut = vfs.src(['.build/extensions/**/*.js.map', '!**/node_modules/**'], { base: '.build' }); + sources.push(extensionsOut); + } + + // specific client base/maps + else { + sources.push(fetch(base, maps)); + } + + return es.merge(...sources) .pipe(es.through(function (data) { - // debug - console.log('Uploading Sourcemap', data.relative); + console.log('Uploading Sourcemap', data.relative); // debug this.emit('data', data); })) .pipe(azure.upload({ @@ -36,4 +56,4 @@ function main() { })); } -main(); \ No newline at end of file +main(); diff --git a/build/azure-pipelines/web/product-build-web.yml b/build/azure-pipelines/web/product-build-web.yml index d5851559d67..fe5231dacc1 100644 --- a/build/azure-pipelines/web/product-build-web.yml +++ b/build/azure-pipelines/web/product-build-web.yml @@ -88,6 +88,15 @@ steps: yarn gulp vscode-web-min-ci displayName: Build + # upload only the workbench.web.api.js source maps because + # we just compiled these bits in the previous step and the + # general task to upload source maps has already been run +- script: | + set -e + AZURE_STORAGE_ACCESS_KEY="$(ticino-storage-key)" \ + node build/azure-pipelines/upload-sourcemaps out-vscode-web-min out-vscode-web-min/vs/workbench/workbench.web.api.js.map + displayName: Upload sourcemaps (Web) + - script: | set -e AZURE_DOCUMENTDB_MASTERKEY="$(builds-docdb-key-readwrite)" \ From 31c73988b9fe71ea10ebf881d0a178f3d8e14743 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 8 Aug 2019 11:06:14 +0200 Subject: [PATCH 335/861] Reinstante keybinding service check --- src/vs/editor/standalone/browser/standaloneCodeEditor.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/standalone/browser/standaloneCodeEditor.ts b/src/vs/editor/standalone/browser/standaloneCodeEditor.ts index 7a00d9f2291..31a3f56b704 100644 --- a/src/vs/editor/standalone/browser/standaloneCodeEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneCodeEditor.ts @@ -153,7 +153,7 @@ function createAriaDomNode() { */ export class StandaloneCodeEditor extends CodeEditorWidget implements IStandaloneCodeEditor { - private readonly _standaloneKeybindingService: StandaloneKeybindingService; + private readonly _standaloneKeybindingService: StandaloneKeybindingService | null; constructor( domElement: HTMLElement, @@ -176,7 +176,11 @@ export class StandaloneCodeEditor extends CodeEditorWidget implements IStandalon ); super(domElement, options, {}, instantiationService, codeEditorService, commandService, contextKeyService, themeService, notificationService, accessibilityService); - this._standaloneKeybindingService = keybindingService; + if (keybindingService instanceof StandaloneKeybindingService) { + this._standaloneKeybindingService = keybindingService; + } else { + this._standaloneKeybindingService = null; + } // Create the ARIA dom node as soon as the first editor is instantiated createAriaDomNode(); From 3ffd89239950a77b588a2c57f227b6ce081c9f72 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 8 Aug 2019 11:06:24 +0200 Subject: [PATCH 336/861] Fixes #59980 --- extensions/razor/language-configuration.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/extensions/razor/language-configuration.json b/extensions/razor/language-configuration.json index e2a49bcbd8e..55c5321e9a4 100644 --- a/extensions/razor/language-configuration.json +++ b/extensions/razor/language-configuration.json @@ -4,7 +4,6 @@ }, "brackets": [ [""], - ["<", ">"], ["{", "}"], ["(", ")"] ], @@ -20,4 +19,4 @@ { "open": "\"", "close": "\"" }, { "open": "<", "close": ">" } ] -} \ No newline at end of file +} From 44f176c74525957300486357d57761477676913e Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 8 Aug 2019 11:12:10 +0200 Subject: [PATCH 337/861] move cli server and download command registrations out of api.impl --- src/vs/workbench/api/node/extHost.api.impl.ts | 33 ++++++++----------- src/vs/workbench/api/node/extHostCLIServer.ts | 6 ++-- .../api/node/extHostDownloadService.ts | 21 +++++------- .../api/node/extHostExtensionService.ts | 20 ++++++++--- 4 files changed, 41 insertions(+), 39 deletions(-) diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 353f7d39c76..56efd7d8bba 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -20,7 +20,7 @@ import { ExtHostApiCommands } from 'vs/workbench/api/common/extHostApiCommands'; import { ExtHostClipboard } from 'vs/workbench/api/common/extHostClipboard'; import { IExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; import { ExtHostComments } from 'vs/workbench/api/common/extHostComments'; -import { ExtHostConfiguration, ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration'; +import { ExtHostConfigProvider, IExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; import { ExtHostDiagnostics } from 'vs/workbench/api/common/extHostDiagnostics'; import { ExtHostDialogs } from 'vs/workbench/api/common/extHostDialogs'; import { ExtHostDocumentContentProvider } from 'vs/workbench/api/common/extHostDocumentContentProviders'; @@ -44,20 +44,18 @@ import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; import { ExtHostEditors } from 'vs/workbench/api/common/extHostTextEditors'; import { ExtHostTreeViews } from 'vs/workbench/api/common/extHostTreeViews'; -import { ExtHostDownloadService } from 'vs/workbench/api/node/extHostDownloadService'; import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters'; import * as extHostTypes from 'vs/workbench/api/common/extHostTypes'; import { ExtHostUrls } from 'vs/workbench/api/common/extHostUrls'; import { ExtHostWebviews } from 'vs/workbench/api/common/extHostWebview'; import { ExtHostWindow } from 'vs/workbench/api/common/extHostWindow'; -import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; +import { IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import { throwProposedApiError, checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions'; import { ProxyIdentifier } from 'vs/workbench/services/extensions/common/proxyIdentifier'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; import * as vscode from 'vscode'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { originalFSPath } from 'vs/base/common/resources'; -import { CLIServer } from 'vs/workbench/api/node/extHostCLIServer'; import { values } from 'vs/base/common/collections'; import { IURITransformer } from 'vs/base/common/uriIpc'; import { ExtHostEditorInsets } from 'vs/workbench/api/common/extHostCodeInsets'; @@ -68,6 +66,7 @@ import { IExtHostDecorations } from 'vs/workbench/api/common/extHostDecorations' import { IExtHostTask } from 'vs/workbench/api/common/extHostTask'; import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService'; import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch'; +import { ILogService } from 'vs/platform/log/common/log'; export interface IExtensionApiFactory { (extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode; @@ -88,18 +87,24 @@ export function createApiFactory( accessor: ServicesAccessor, initData: IInitData, rpcProtocol: IMainContext, - extHostWorkspace: ExtHostWorkspace, - extHostConfiguration: ExtHostConfiguration, - extHostLogService: ExtHostLogService, extHostStorage: ExtHostStorage, uriTransformer: IURITransformer | null ): IExtensionApiFactory { // services const extensionService = accessor.get(IExtHostExtensionService); + const extHostWorkspace = accessor.get(IExtHostWorkspace); + const extHostConfiguration = accessor.get(IExtHostConfiguration); + const extHostLogService = accessor.get(ILogService); - // Addressable instances + // register addressable instances rpcProtocol.set(ExtHostContext.ExtHostLogService, extHostLogService); + rpcProtocol.set(ExtHostContext.ExtHostWorkspace, extHostWorkspace); + rpcProtocol.set(ExtHostContext.ExtHostConfiguration, extHostConfiguration); + rpcProtocol.set(ExtHostContext.ExtHostExtensionService, extensionService); + rpcProtocol.set(ExtHostContext.ExtHostStorage, extHostStorage); + + // create and register addressable instances const extHostDecorations = rpcProtocol.set(ExtHostContext.ExtHostDecorations, accessor.get(IExtHostDecorations)); const extHostWebviews = rpcProtocol.set(ExtHostContext.ExtHostWebviews, new ExtHostWebviews(rpcProtocol, initData.environment)); const extHostUrls = rpcProtocol.set(ExtHostContext.ExtHostUrls, new ExtHostUrls(rpcProtocol)); @@ -110,8 +115,6 @@ export function createApiFactory( const extHostEditors = rpcProtocol.set(ExtHostContext.ExtHostEditors, new ExtHostEditors(rpcProtocol, extHostDocumentsAndEditors)); const extHostCommands = rpcProtocol.set(ExtHostContext.ExtHostCommands, accessor.get(IExtHostCommands)); const extHostTreeViews = rpcProtocol.set(ExtHostContext.ExtHostTreeViews, new ExtHostTreeViews(rpcProtocol.getProxy(MainContext.MainThreadTreeViews), extHostCommands, extHostLogService)); - rpcProtocol.set(ExtHostContext.ExtHostWorkspace, extHostWorkspace); - rpcProtocol.set(ExtHostContext.ExtHostConfiguration, extHostConfiguration); const extHostEditorInsets = rpcProtocol.set(ExtHostContext.ExtHostEditorInsets, new ExtHostEditorInsets(rpcProtocol.getProxy(MainContext.MainThreadEditorInsets), extHostEditors, initData.environment)); const extHostDiagnostics = rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, new ExtHostDiagnostics(rpcProtocol)); const extHostLanguageFeatures = rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, new ExtHostLanguageFeatures(rpcProtocol, uriTransformer, extHostDocuments, extHostCommands, extHostDiagnostics, extHostLogService)); @@ -125,17 +128,10 @@ export function createApiFactory( const extHostSearch = rpcProtocol.set(ExtHostContext.ExtHostSearch, accessor.get(IExtHostSearch)); const extHostTask = rpcProtocol.set(ExtHostContext.ExtHostTask, accessor.get(IExtHostTask)); const extHostWindow = rpcProtocol.set(ExtHostContext.ExtHostWindow, new ExtHostWindow(rpcProtocol)); - rpcProtocol.set(ExtHostContext.ExtHostExtensionService, extensionService); const extHostProgress = rpcProtocol.set(ExtHostContext.ExtHostProgress, new ExtHostProgress(rpcProtocol.getProxy(MainContext.MainThreadProgress))); const extHostOutputService = rpcProtocol.set(ExtHostContext.ExtHostOutputService, accessor.get(IExtHostOutputService)); - rpcProtocol.set(ExtHostContext.ExtHostStorage, extHostStorage); const extHostLabelService = rpcProtocol.set(ExtHostContext.ExtHosLabelService, new ExtHostLabelService(rpcProtocol)); - if (initData.remote.isRemote && initData.remote.authority) { - const cliServer = new CLIServer(extHostCommands); - process.env['VSCODE_IPC_HOOK_CLI'] = cliServer.ipcHandlePath; - } - // Check that no named customers are missing const expected: ProxyIdentifier[] = values(ExtHostContext); rpcProtocol.assertRegistered(expected); @@ -154,9 +150,6 @@ export function createApiFactory( // Register API-ish commands ExtHostApiCommands.register(extHostCommands); - // Register Download command - ExtHostDownloadService.register(rpcProtocol.getProxy(MainContext.MainThreadDownloadService), extHostCommands); - return function (extension: IExtensionDescription, extensionRegistry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode { // Check document selectors for being overly generic. Technically this isn't a problem but diff --git a/src/vs/workbench/api/node/extHostCLIServer.ts b/src/vs/workbench/api/node/extHostCLIServer.ts index 3b06ea4c064..f923a36d324 100644 --- a/src/vs/workbench/api/node/extHostCLIServer.ts +++ b/src/vs/workbench/api/node/extHostCLIServer.ts @@ -6,7 +6,7 @@ import { generateRandomPipeName } from 'vs/base/parts/ipc/node/ipc.net'; import * as http from 'http'; import * as fs from 'fs'; -import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; +import { IExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; import { IURIToOpen, IOpenSettings } from 'vs/platform/windows/common/windows'; import { URI } from 'vs/base/common/uri'; import { hasWorkspaceFileExtension } from 'vs/platform/workspaces/common/workspaces'; @@ -38,7 +38,7 @@ export class CLIServer { private _server: http.Server; private _ipcHandlePath: string | undefined; - constructor(private _commands: ExtHostCommands) { + constructor(@IExtHostCommands private _commands: IExtHostCommands) { this._server = http.createServer((req, res) => this.onRequest(req, res)); this.setup().catch(err => { console.error(err); @@ -179,4 +179,4 @@ export class CLIServer { fs.unlinkSync(this._ipcHandlePath); } } -} \ No newline at end of file +} diff --git a/src/vs/workbench/api/node/extHostDownloadService.ts b/src/vs/workbench/api/node/extHostDownloadService.ts index ad43979716c..4bf43510397 100644 --- a/src/vs/workbench/api/node/extHostDownloadService.ts +++ b/src/vs/workbench/api/node/extHostDownloadService.ts @@ -6,25 +6,22 @@ import { join } from 'vs/base/common/path'; import { tmpdir } from 'os'; import { generateUuid } from 'vs/base/common/uuid'; -import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; +import { IExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; import { Disposable } from 'vs/base/common/lifecycle'; -import { MainThreadDownloadServiceShape } from 'vs/workbench/api/common/extHost.protocol'; +import { MainContext } from 'vs/workbench/api/common/extHost.protocol'; import { URI } from 'vs/base/common/uri'; +import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; export class ExtHostDownloadService extends Disposable { - static register( - proxy: MainThreadDownloadServiceShape, - commands: ExtHostCommands - ) { - return new ExtHostDownloadService(proxy, commands); - } - - private constructor( - proxy: MainThreadDownloadServiceShape, - commands: ExtHostCommands + constructor( + @IExtHostRpcService extHostRpc: IExtHostRpcService, + @IExtHostCommands commands: IExtHostCommands ) { super(); + + const proxy = extHostRpc.getProxy(MainContext.MainThreadDownloadService); + commands.registerCommand(false, '_workbench.downloadResource', async (resource: URI): Promise => { const location = URI.file(join(tmpdir(), generateUuid())); await proxy.$download(resource, location); diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 237223240e2..96285174fe6 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -38,6 +38,8 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; +import { ExtHostDownloadService } from 'vs/workbench/api/node/extHostDownloadService'; +import { CLIServer } from 'vs/workbench/api/node/extHostCLIServer'; interface ITestRunner { /** Old test runner API, as exported from `vscode/lib/testrunner` */ @@ -74,6 +76,7 @@ export class ExtHostExtensionService implements IExtHostExtensionService, ExtHos private readonly _hostUtils: IHostUtils; private readonly _initData: IInitData; private readonly _extHostContext: IMainContext; + private readonly _instaService: IInstantiationService; private readonly _extHostWorkspace: ExtHostWorkspace; private readonly _extHostConfiguration: ExtHostConfiguration; private readonly _extHostLogService: ExtHostLogService; @@ -113,6 +116,7 @@ export class ExtHostExtensionService implements IExtHostExtensionService, ExtHos this._extHostContext = extHostContext; this._initData = initData; + this._instaService = instaService; this._extHostWorkspace = extHostWorkspace; this._extHostConfiguration = extHostConfiguration; this._extHostLogService = extHostLogService; @@ -155,12 +159,9 @@ export class ExtHostExtensionService implements IExtHostExtensionService, ExtHos services.set(IExtHostExtensionService, this); // initialize API first (i.e. do not release barrier until the API is initialized) - this._extensionApiFactory = instaService.invokeFunction(createApiFactory, + this._extensionApiFactory = this._instaService.invokeFunction(createApiFactory, this._initData, this._extHostContext, - this._extHostWorkspace, - this._extHostConfiguration, - this._extHostLogService, this._storage, uriTransformer ); @@ -177,7 +178,18 @@ export class ExtHostExtensionService implements IExtHostExtensionService, ExtHos } private async _initialize(): Promise { + try { + // Register Download command + this._instaService.createInstance(ExtHostDownloadService); + + // Register CLI Server for ipc + if (this._initData.remote.isRemote && this._initData.remote.authority) { + const cliServer = this._instaService.createInstance(CLIServer); + process.env['VSCODE_IPC_HOOK_CLI'] = cliServer.ipcHandlePath; + } + + // Module loading tricks const configProvider = await this._extHostConfiguration.getConfigProvider(); const extensionPaths = await this.getExtensionPathIndex(); NodeModuleRequireInterceptor.INSTANCE.register(new VSCodeNodeModuleFactory(this._extensionApiFactory, extensionPaths, this._registry, configProvider)); From bc35789e146aa6da6bc9037de58474da054f1c7c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 8 Aug 2019 11:13:14 +0200 Subject: [PATCH 338/861] move api.impl to /common/ --- src/vs/workbench/api/{node => common}/extHost.api.impl.ts | 0 src/vs/workbench/api/node/extHostExtensionService.ts | 2 +- src/vs/workbench/api/node/extHostRequireInterceptor.ts | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/vs/workbench/api/{node => common}/extHost.api.impl.ts (100%) diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts similarity index 100% rename from src/vs/workbench/api/node/extHost.api.impl.ts rename to src/vs/workbench/api/common/extHost.api.impl.ts diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 96285174fe6..feac51cd37c 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -11,7 +11,7 @@ import { dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle import { TernarySearchTree } from 'vs/base/common/map'; import { URI } from 'vs/base/common/uri'; import { ILogService } from 'vs/platform/log/common/log'; -import { createApiFactory, IExtensionApiFactory } from 'vs/workbench/api/node/extHost.api.impl'; +import { createApiFactory, IExtensionApiFactory } from 'vs/workbench/api/common/extHost.api.impl'; import { NodeModuleRequireInterceptor, VSCodeNodeModuleFactory, KeytarNodeModuleFactory, OpenNodeModuleFactory } from 'vs/workbench/api/node/extHostRequireInterceptor'; import { ExtHostExtensionServiceShape, IInitData, IMainContext, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape, IResolveAuthorityResult } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostConfiguration, IExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; diff --git a/src/vs/workbench/api/node/extHostRequireInterceptor.ts b/src/vs/workbench/api/node/extHostRequireInterceptor.ts index 8633dc023bc..876d6716a67 100644 --- a/src/vs/workbench/api/node/extHostRequireInterceptor.ts +++ b/src/vs/workbench/api/node/extHostRequireInterceptor.ts @@ -12,7 +12,7 @@ import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/c import * as vscode from 'vscode'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { endsWith } from 'vs/base/common/strings'; -import { IExtensionApiFactory } from 'vs/workbench/api/node/extHost.api.impl'; +import { IExtensionApiFactory } from 'vs/workbench/api/common/extHost.api.impl'; interface LoadFunction { From f7fd6b34ba78cf611501a8ca4f768b0c6e3076d0 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 8 Aug 2019 11:22:52 +0200 Subject: [PATCH 339/861] git: improve promptToSaveFilesBeforeCommit message --- extensions/git/src/commands.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 3ff6be64541..2cdd0ebe8ff 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1242,7 +1242,7 @@ export class CommandCenter { if (documents.length > 0) { const message = documents.length === 1 - ? localize('unsaved files single', "The following staged file is unsaved: {0}.\n\nWould you like to save it before committing?", path.basename(documents[0].uri.fsPath)) + ? localize('unsaved files single', "The following staged file is unsaved and will not be included in the commit if you proceed: {0}.\n\nWould you like to save it before committing?", path.basename(documents[0].uri.fsPath)) : localize('unsaved files', "There are {0} unsaved staged files.\n\nWould you like to save them before committing?", documents.length); const saveAndCommit = localize('save and commit', "Save All & Commit"); const commit = localize('commit', "Commit Anyway"); From 3dd74959d4debfc05dbf5bd9183ba3b72933b1f9 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 8 Aug 2019 11:23:22 +0200 Subject: [PATCH 340/861] editor - switching between tab enablement is missing a layout call for title area --- .../browser/parts/editor/editorGroupView.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 91a216bc83f..54be65b6f03 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -594,8 +594,12 @@ export class EditorGroupView extends Themable implements IEditorGroupView { // Title control Switch between showing tabs <=> not showing tabs if (event.oldPartOptions.showTabs !== event.newPartOptions.showTabs) { - this.createTitleAreaControl(); + // Recreate and layout control + this.createTitleAreaControl(); + this.layoutTitleAreaControl(); + + // Ensure to show active editor if any if (this._group.activeEditor) { this.titleAreaControl.openEditor(this._group.activeEditor); } @@ -1449,10 +1453,14 @@ export class EditorGroupView extends Themable implements IEditorGroupView { this.editorContainer.style.height = `calc(100% - ${this.titleAreaControl.getPreferredHeight()}px)`; // Forward to controls - this.titleAreaControl.layout(new Dimension(this.dimension.width, this.titleAreaControl.getPreferredHeight())); + this.layoutTitleAreaControl(); this.editorControl.layout(new Dimension(this.dimension.width, this.dimension.height - this.titleAreaControl.getPreferredHeight())); } + private layoutTitleAreaControl(): void { + this.titleAreaControl.layout(new Dimension(this.dimension.width, this.titleAreaControl.getPreferredHeight())); + } + relayout(): void { if (this.dimension) { const { width, height } = this.dimension; @@ -1472,7 +1480,6 @@ export class EditorGroupView extends Themable implements IEditorGroupView { this._onWillDispose.fire(); this.titleAreaControl.dispose(); - // this.editorControl = null; super.dispose(); } From fa5c79386cb6052d3321755ca3ccd3785d223f96 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 8 Aug 2019 11:30:25 +0200 Subject: [PATCH 341/861] git: promptToSaveFilesBeforeCommit should have more options related to #66296 --- extensions/git/package.json | 14 ++++++++++++-- extensions/git/package.nls.json | 3 +++ extensions/git/src/commands.ts | 21 ++++++++++++++++----- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index 90064509397..aba696781b6 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1172,9 +1172,19 @@ "description": "%config.decorations.enabled%" }, "git.promptToSaveFilesBeforeCommit": { - "type": "boolean", + "type": "string", + "enum": [ + "always", + "staged", + "never" + ], + "enumDescriptions": [ + "%config.promptToSaveFilesBeforeCommit.always%", + "%config.promptToSaveFilesBeforeCommit.staged%", + "%config.promptToSaveFilesBeforeCommit.never%" + ], "scope": "resource", - "default": true, + "default": "always", "description": "%config.promptToSaveFilesBeforeCommit%" }, "git.postCommitCommand": { diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 4d8bccf4e0b..cddbdad605e 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -94,6 +94,9 @@ "config.discardAllScope": "Controls what changes are discarded by the `Discard all changes` command. `all` discards all changes. `tracked` discards only tracked files. `prompt` shows a prompt dialog every time the action is run.", "config.decorations.enabled": "Controls whether Git contributes colors and badges to the explorer and the open editors view.", "config.promptToSaveFilesBeforeCommit": "Controls whether Git should check for unsaved files before committing.", + "config.promptToSaveFilesBeforeCommit.always": "Check for any unsaved files.", + "config.promptToSaveFilesBeforeCommit.staged": "Check only for unsaved staged files.", + "config.promptToSaveFilesBeforeCommit.never": "Disable this check.", "config.postCommitCommand": "Runs a git command after a successful commit.", "config.postCommitCommand.none": "Don't run any command after a commit.", "config.postCommitCommand.push": "Run 'Git Push' after a successful commit.", diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 2cdd0ebe8ff..39b48f2c5e9 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1233,12 +1233,23 @@ export class CommandCenter { opts?: CommitOptions ): Promise { const config = workspace.getConfiguration('git', Uri.file(repository.root)); - const promptToSaveFilesBeforeCommit = config.get('promptToSaveFilesBeforeCommit') === true; + let promptToSaveFilesBeforeCommit = config.get<'always' | 'staged' | 'never'>('promptToSaveFilesBeforeCommit'); - if (promptToSaveFilesBeforeCommit) { - const documents = workspace.textDocuments - .filter(d => !d.isUntitled && d.isDirty && isDescendant(repository.root, d.uri.fsPath)) - .filter(d => repository.indexGroup.resourceStates.some(s => s.resourceUri.path === d.uri.fsPath)); + // migration + if (promptToSaveFilesBeforeCommit as any === true) { + promptToSaveFilesBeforeCommit = 'always'; + } else if (promptToSaveFilesBeforeCommit as any === false) { + promptToSaveFilesBeforeCommit = 'never'; + } + + if (promptToSaveFilesBeforeCommit !== 'never') { + let documents = workspace.textDocuments + .filter(d => !d.isUntitled && d.isDirty && isDescendant(repository.root, d.uri.fsPath)); + + if (promptToSaveFilesBeforeCommit === 'staged') { + documents = documents + .filter(d => repository.indexGroup.resourceStates.some(s => s.resourceUri.path === d.uri.fsPath)); + } if (documents.length > 0) { const message = documents.length === 1 From 79bb87943f64cb4ca829c3f76c24383f557be1f9 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 8 Aug 2019 11:40:09 +0200 Subject: [PATCH 342/861] fix #78077 --- .../contrib/welcome/overlay/browser/welcomeOverlay.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/welcome/overlay/browser/welcomeOverlay.ts b/src/vs/workbench/contrib/welcome/overlay/browser/welcomeOverlay.ts index a56cff41c02..2cfebd34775 100644 --- a/src/vs/workbench/contrib/welcome/overlay/browser/welcomeOverlay.ts +++ b/src/vs/workbench/contrib/welcome/overlay/browser/welcomeOverlay.ts @@ -9,7 +9,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { ShowAllCommandsAction } from 'vs/workbench/contrib/quickopen/browser/commandsHandler'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { Parts, IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { localize } from 'vs/nls'; import { Action } from 'vs/base/common/actions'; import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions'; @@ -168,10 +168,8 @@ class WelcomeOverlay extends Disposable { } private create(): void { - const container = this.layoutService.getContainer(Parts.EDITOR_PART)!; - const offset = this.layoutService.getTitleBarOffset(); - this._overlay = dom.append(container.parentElement!, $('.welcomeOverlay')); + this._overlay = dom.append(this.layoutService.getWorkbenchElement(), $('.welcomeOverlay')); this._overlay.style.top = `${offset}px`; this._overlay.style.height = `calc(100% - ${offset}px)`; this._overlay.style.display = 'none'; From 181759fe6ac34627c6c219a5750b4bfaf16c41e7 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 8 Aug 2019 11:55:13 +0200 Subject: [PATCH 343/861] add git.smartCommitChanges --- extensions/git/package.json | 20 +++++++++++++------ extensions/git/package.nls.json | 4 +++- extensions/git/src/commands.ts | 6 +++++- extensions/git/src/git.ts | 14 ++++++++++--- extensions/git/src/repository.ts | 34 +++++--------------------------- 5 files changed, 38 insertions(+), 40 deletions(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index be91d5e02d4..6a0e20b3eb3 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1148,6 +1148,20 @@ "description": "%config.enableSmartCommit%", "default": false }, + "git.smartCommitChanges": { + "type": "string", + "enum": [ + "all", + "tracked" + ], + "enumDescriptions": [ + "%config.smartCommitChanges.all%", + "%config.smartCommitChanges.tracked%" + ], + "scope": "resource", + "description": "%config.smartCommitChanges%", + "default": "all" + }, "git.suggestSmartCommit": { "type": "boolean", "scope": "resource", @@ -1254,12 +1268,6 @@ "default": false, "description": "%config.alwaysShowStagedChangesResourceGroup%" }, - "git.onlyTrackedFilesCanBeAutoStaged": { - "type": "boolean", - "scope": "resource", - "default": false, - "description": "%config.onlyTrackedFilesCanBeAutoStaged%" - }, "git.alwaysSignOff": { "type": "boolean", "scope": "resource", diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 9048bda6bb3..151b62d4458 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -89,6 +89,9 @@ "config.ignoreLimitWarning": "Ignores the warning when there are too many changes in a repository.", "config.defaultCloneDirectory": "The default location to clone a git repository.", "config.enableSmartCommit": "Commit all changes when there are no staged changes.", + "config.smartCommitChanges": "Control which changes are automatically staged by Smart Commit.", + "config.smartCommitChanges.all": "Automatically stage all changes.", + "config.smartCommitChanges.tracked": "Automatically staged tracked changes only.", "config.suggestSmartCommit": "Suggests to enable smart commit (commit all changes when there are no staged changes).", "config.enableCommitSigning": "Enables commit signing with GPG.", "config.discardAllScope": "Controls what changes are discarded by the `Discard all changes` command. `all` discards all changes. `tracked` discards only tracked files. `prompt` shows a prompt dialog every time the action is run.", @@ -109,7 +112,6 @@ "config.detectSubmodules": "Controls whether to automatically detect git submodules.", "config.detectSubmodulesLimit": "Controls the limit of git submodules detected.", "config.alwaysShowStagedChangesResourceGroup": "Always show the Staged Changes resource group.", - "config.onlyTrackedFilesCanBeAutoStaged": "Only tracked files can be auto staged", "config.alwaysSignOff": "Controls the signoff flag for all commits.", "config.ignoredRepositories": "List of git repositories to ignore.", "config.scanRepositories": "List of paths to search for git repositories in.", diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 39b48f2c5e9..036f152ee4d 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1275,8 +1275,8 @@ export class CommandCenter { // no changes, and the user has not configured to commit all in this case if (!noUnstagedChanges && noStagedChanges && !enableSmartCommit) { - const suggestSmartCommit = config.get('suggestSmartCommit') === true; + if (!suggestSmartCommit) { return false; } @@ -1330,6 +1330,10 @@ export class CommandCenter { return false; } + if (opts.all && config.get<'all' | 'tracked'>('smartCommitChanges') === 'tracked') { + opts.all = 'tracked'; + } + await repository.commit(message, opts); const postCommitCommand = config.get<'none' | 'push' | 'sync'>('postCommitCommand'); diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index b306cab1255..243bf2471c6 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -642,7 +642,7 @@ export function parseLsFiles(raw: string): LsFilesElement[] { } export interface CommitOptions { - all?: boolean; + all?: boolean | 'tracked'; amend?: boolean; signoff?: boolean; signCommit?: boolean; @@ -1081,8 +1081,16 @@ export class Repository { return result.stdout.trim(); } - async add(paths: string[]): Promise { - const args = ['add', '-A', '--']; + async add(paths: string[], opts?: { update?: boolean }): Promise { + const args = ['add']; + + if (opts && opts.update) { + args.push('-u'); + } else { + args.push('-A'); + } + + args.push('--'); if (paths && paths.length) { args.push.apply(args, paths); diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index e39e50e7dcb..7320c08eaea 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -907,22 +907,11 @@ export class Repository implements Disposable { } async commit(message: string, opts: CommitOptions = Object.create(null)): Promise { - const config = workspace.getConfiguration('git'); - const onlyTrackStagedFile = config.get('onlyTrackedFilesCanBeAutoStaged'); - if (this.rebaseCommit) { await this.run(Operation.RebaseContinue, async () => { if (opts.all) { - if (onlyTrackStagedFile) { - const unstageFiles = await this.trackedUnstagedFiles(); - if (unstageFiles.length === 0) { - window.showInformationMessage(localize('no changes', "There are no changes to commit.")); - return false; - } - await this.repository.add(unstageFiles); - } else { - await this.repository.add([]); - } + const addOpts = opts.all === 'tracked' ? { update: true } : {}; + await this.repository.add([], addOpts); } await this.repository.rebaseContinue(); @@ -930,18 +919,11 @@ export class Repository implements Disposable { } else { await this.run(Operation.Commit, async () => { if (opts.all) { - if (onlyTrackStagedFile) { - const unstageFiles = await this.trackedUnstagedFiles(); - if (unstageFiles.length === 0) { - window.showInformationMessage(localize('no changes', "There are no changes to commit.")); - return false; - } - await this.repository.add(unstageFiles); - } else { - await this.repository.add([]); - } + const addOpts = opts.all === 'tracked' ? { update: true } : {}; + await this.repository.add([], addOpts); } + delete opts.all; await this.repository.commit(message, opts); }); } @@ -1601,12 +1583,6 @@ export class Repository implements Disposable { this.eventuallyUpdateWhenIdleAndWait(); } - private async trackedUnstagedFiles(): Promise { - const rawChangedFiles = await this.repository.run(['ls-files', '.', '-m']); - const parsedFiles = rawChangedFiles.stdout.split('\n').filter(l => !!l); - return parsedFiles; - } - @debounce(1000) private eventuallyUpdateWhenIdleAndWait(): void { this.updateWhenIdleAndWait(); From 6af97c875608462195e43f4d4ed339a05d1791e4 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 8 Aug 2019 12:02:55 +0200 Subject: [PATCH 344/861] :lipstick: --- extensions/git/package.json | 5 +++-- extensions/git/package.nls.json | 2 +- extensions/git/src/statusbar.ts | 17 +++++++---------- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index 5ca55fe1aca..ffa34ca6efb 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1185,10 +1185,11 @@ "default": true, "description": "%config.decorations.enabled%" }, - "git.statusBarSync.enabled": { + "git.enableStatusBarSync": { "type": "boolean", "default": true, - "description": "%config.statusBarSync.enabled%" + "description": "%config.enableStatusBarSync%", + "scope": "resource" }, "git.promptToSaveFilesBeforeCommit": { "type": "string", diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index e4523b45744..367544c6cc3 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -96,7 +96,7 @@ "config.enableCommitSigning": "Enables commit signing with GPG.", "config.discardAllScope": "Controls what changes are discarded by the `Discard all changes` command. `all` discards all changes. `tracked` discards only tracked files. `prompt` shows a prompt dialog every time the action is run.", "config.decorations.enabled": "Controls whether Git contributes colors and badges to the explorer and the open editors view.", - "config.statusBarSync.enabled": "Controls whether Git sync appears in the status bar.", + "config.enableStatusBarSync": "Controls whether the Git Sync command appears in the status bar.", "config.promptToSaveFilesBeforeCommit": "Controls whether Git should check for unsaved files before committing.", "config.promptToSaveFilesBeforeCommit.always": "Check for any unsaved files.", "config.promptToSaveFilesBeforeCommit.staged": "Check only for unsaved staged files.", diff --git a/extensions/git/src/statusbar.ts b/extensions/git/src/statusbar.ts index e89e1ff9c9b..3b43e880090 100644 --- a/extensions/git/src/statusbar.ts +++ b/extensions/git/src/statusbar.ts @@ -39,7 +39,7 @@ class CheckoutStatusBar { } interface SyncStatusBarState { - isEnabled: boolean; + enabled: boolean; isSyncRunning: boolean; hasRemotes: boolean; HEAD: Branch | undefined; @@ -48,7 +48,7 @@ interface SyncStatusBarState { class SyncStatusBar { private static StartState: SyncStatusBarState = { - isEnabled: true, + enabled: true, isSyncRunning: false, hasRemotes: false, HEAD: undefined @@ -69,20 +69,17 @@ class SyncStatusBar { repository.onDidRunGitStatus(this.onModelChange, this, this.disposables); repository.onDidChangeOperations(this.onOperationsChange, this, this.disposables); - const onEnablementChange = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.statusBarSync.enabled')); + const onEnablementChange = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.enableStatusBarSync')); onEnablementChange(this.updateEnablement, this, this.disposables); this._onDidChange.fire(); } private updateEnablement(): void { - const isEnabled = workspace.getConfiguration('git').get('statusBarSync.enabled'); + const config = workspace.getConfiguration('git', Uri.file(this.repository.root)); + const enabled = config.get('enableStatusBarSync', true); - if (isEnabled) { - this.state = { ... this.state, isEnabled: true }; - } else { - this.state = { ... this.state, isEnabled: false }; - } + this.state = { ... this.state, enabled }; } private onOperationsChange(): void { @@ -102,7 +99,7 @@ class SyncStatusBar { } get command(): Command | undefined { - if (!this.state.isEnabled || !this.state.hasRemotes) { + if (!this.state.enabled || !this.state.hasRemotes) { return undefined; } From 4390e373216491546ef509e2cbda732b3617d086 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 8 Aug 2019 12:05:18 +0200 Subject: [PATCH 345/861] fix #67705 --- src/vs/workbench/browser/layout.ts | 8 +++++++- .../workbench/browser/parts/panel/media/panelpart.css | 10 +++++++++- src/vs/workbench/browser/workbench.ts | 1 + 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 08fbdd94d74..dcafef2d467 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -45,7 +45,6 @@ enum Settings { PANEL_POSITION = 'workbench.panel.defaultLocation', ZEN_MODE_RESTORE = 'zenMode.restore', - } enum Storage { @@ -935,6 +934,13 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi this.state.editor.hidden = hidden; + // Adjust CSS + if (hidden) { + addClass(this.container, 'noeditorarea'); + } else { + removeClass(this.container, 'noeditorarea'); + } + // Propagate to grid this.workbenchGrid.setViewVisible(this.editorPartView, !hidden); diff --git a/src/vs/workbench/browser/parts/panel/media/panelpart.css b/src/vs/workbench/browser/parts/panel/media/panelpart.css index 4839f8b0831..fb9a8f4bf2f 100644 --- a/src/vs/workbench/browser/parts/panel/media/panelpart.css +++ b/src/vs/workbench/browser/parts/panel/media/panelpart.css @@ -25,11 +25,19 @@ border-top-style: solid; } +.monaco-workbench.noeditorarea .part.panel.bottom .title { + border-top-width: 0; /* no border when editor area is hiden */ +} + .monaco-workbench .part.panel.right { border-left-width: 1px; border-left-style: solid; } +.monaco-workbench.noeditorarea .part.panel.right { + border-left-width: 0; /* no border when editor area is hiden */ +} + .monaco-workbench .part.panel > .title > .title-actions .monaco-action-bar .action-item .action-label { outline-offset: -2px; } @@ -181,4 +189,4 @@ .hc-black .monaco-workbench .panel.right .minimize-panel-action { background-image: url('chevron-right-hc.svg'); -} \ No newline at end of file +} diff --git a/src/vs/workbench/browser/workbench.ts b/src/vs/workbench/browser/workbench.ts index 336f7d97e97..f2e5d880dc8 100644 --- a/src/vs/workbench/browser/workbench.ts +++ b/src/vs/workbench/browser/workbench.ts @@ -299,6 +299,7 @@ export class Workbench extends Layout { platformClass, isWeb ? 'web' : undefined, this.state.sideBar.hidden ? 'nosidebar' : undefined, + this.state.editor.hidden ? 'noeditorarea' : undefined, this.state.panel.hidden ? 'nopanel' : undefined, this.state.statusBar.hidden ? 'nostatusbar' : undefined, this.state.fullscreen ? 'fullscreen' : undefined From 0ca4ce2065899070304fb70cc4dd93a2d2cf6712 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 8 Aug 2019 12:05:40 +0200 Subject: [PATCH 346/861] :lipstick: --- src/vs/editor/contrib/suggest/suggestWidget.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vs/editor/contrib/suggest/suggestWidget.ts b/src/vs/editor/contrib/suggest/suggestWidget.ts index 6817d5c8f51..826d8d9aa36 100644 --- a/src/vs/editor/contrib/suggest/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/suggestWidget.ts @@ -440,7 +440,6 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate; private readonly suggestWidgetMultipleSuggestions: IContextKey; - private readonly editorBlurTimeout = new TimeoutTimer(); private readonly showTimeout = new TimeoutTimer(); private readonly toDispose = new DisposableStore(); @@ -1157,7 +1156,6 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate Date: Thu, 8 Aug 2019 12:12:42 +0200 Subject: [PATCH 347/861] fix #71317 --- src/vs/editor/contrib/suggest/media/suggest.css | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/suggest/media/suggest.css b/src/vs/editor/contrib/suggest/media/suggest.css index 09594abb493..1fc61b27488 100644 --- a/src/vs/editor/contrib/suggest/media/suggest.css +++ b/src/vs/editor/contrib/suggest/media/suggest.css @@ -110,7 +110,9 @@ .monaco-editor .suggest-widget .details > .monaco-scrollable-element > .body > .header > .close { background-image: url('./close-light.svg'); - float: right; + position: absolute; + top: 0px; + right: 0px; margin-right: 5px; } @@ -251,7 +253,7 @@ text-overflow: ellipsis; opacity: 0.7; word-break: break-all; - margin: 0; + margin: 0px 24px 0 0; padding: 4px 0 12px 5px; } From 90f79e1a2a6b668815206d2c6beab619efef0ad9 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 8 Aug 2019 12:19:03 +0200 Subject: [PATCH 348/861] add storage paths to injector --- .../api/common/extHostStoragePaths.ts | 16 ++++++++++++++ src/vs/workbench/api/node/extHost.services.ts | 4 ++++ .../api/node/extHostExtensionService.ts | 10 ++++----- .../workbench/api/node/extHostStoragePaths.ts | 21 ++++++++++--------- 4 files changed, 36 insertions(+), 15 deletions(-) create mode 100644 src/vs/workbench/api/common/extHostStoragePaths.ts diff --git a/src/vs/workbench/api/common/extHostStoragePaths.ts b/src/vs/workbench/api/common/extHostStoragePaths.ts new file mode 100644 index 00000000000..0dcaba0f791 --- /dev/null +++ b/src/vs/workbench/api/common/extHostStoragePaths.ts @@ -0,0 +1,16 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; + +export const IExtensionStoragePaths = createDecorator('IExtensionStoragePaths'); + +export interface IExtensionStoragePaths { + _serviceBrand: any; + whenReady: Promise; + workspaceValue(extension: IExtensionDescription): string | undefined; + globalValue(extension: IExtensionDescription): string; +} diff --git a/src/vs/workbench/api/node/extHost.services.ts b/src/vs/workbench/api/node/extHost.services.ts index 434f8b170d8..392d12d48c7 100644 --- a/src/vs/workbench/api/node/extHost.services.ts +++ b/src/vs/workbench/api/node/extHost.services.ts @@ -19,6 +19,8 @@ import { ExtHostDebugService } from 'vs/workbench/api/node/extHostDebugService'; import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService'; import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch'; import { ExtHostSearch } from 'vs/workbench/api/node/extHostSearch'; +import { ExtensionStoragePaths } from 'vs/workbench/api/node/extHostStoragePaths'; +import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths'; // register singleton services registerSingleton(IExtHostOutputService, ExtHostOutputService2); @@ -31,3 +33,5 @@ registerSingleton(IExtHostTerminalService, ExtHostTerminalService); registerSingleton(IExtHostTask, ExtHostTask); registerSingleton(IExtHostDebugService, ExtHostDebugService); registerSingleton(IExtHostSearch, ExtHostSearch); +registerSingleton(IExtensionStoragePaths, ExtensionStoragePaths); + diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index feac51cd37c..1bfc691ab2c 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -27,10 +27,8 @@ import * as errors from 'vs/base/common/errors'; import * as vscode from 'vscode'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { Schemas } from 'vs/base/common/network'; -import { withNullAsUndefined } from 'vs/base/common/types'; import { VSBuffer } from 'vs/base/common/buffer'; import { ExtensionMemento } from 'vs/workbench/api/common/extHostMemento'; -import { ExtensionStoragePaths } from 'vs/workbench/api/node/extHostStoragePaths'; import { RemoteAuthorityResolverError, ExtensionExecutionContext } from 'vs/workbench/api/common/extHostTypes'; import { IURITransformer } from 'vs/base/common/uriIpc'; import { ResolvedAuthority, ResolvedOptions } from 'vs/platform/remote/common/remoteAuthorityResolver'; @@ -40,6 +38,7 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; import { ExtHostDownloadService } from 'vs/workbench/api/node/extHostDownloadService'; import { CLIServer } from 'vs/workbench/api/node/extHostCLIServer'; +import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths'; interface ITestRunner { /** Old test runner API, as exported from `vscode/lib/testrunner` */ @@ -90,7 +89,7 @@ export class ExtHostExtensionService implements IExtHostExtensionService, ExtHos private readonly _readyToRunExtensions: Barrier; private readonly _registry: ExtensionDescriptionRegistry; private readonly _storage: ExtHostStorage; - private readonly _storagePath: ExtensionStoragePaths; + private readonly _storagePath: IExtensionStoragePaths; private readonly _activator: ExtensionsActivator; private _extensionPathIndex: Promise> | null; private readonly _extensionApiFactory: IExtensionApiFactory; @@ -110,7 +109,8 @@ export class ExtHostExtensionService implements IExtHostExtensionService, ExtHos @IExtHostWorkspace extHostWorkspace: IExtHostWorkspace, @IExtHostConfiguration extHostConfiguration: IExtHostConfiguration, @ILogService extHostLogService: ExtHostLogService, - @IExtHostInitDataService initData: IExtHostInitDataService + @IExtHostInitDataService initData: IExtHostInitDataService, + @IExtensionStoragePaths storagePath: IExtensionStoragePaths ) { this._hostUtils = hostUtils; this._extHostContext = extHostContext; @@ -131,7 +131,7 @@ export class ExtHostExtensionService implements IExtHostExtensionService, ExtHos this._readyToRunExtensions = new Barrier(); this._registry = new ExtensionDescriptionRegistry(this._initData.extensions); this._storage = new ExtHostStorage(this._extHostContext); - this._storagePath = new ExtensionStoragePaths(withNullAsUndefined(this._initData.workspace), this._initData.environment); + this._storagePath = storagePath; const hostExtensions = new Set(); this._initData.hostExtensions.forEach((extensionId) => hostExtensions.add(ExtensionIdentifier.toKey(extensionId))); diff --git a/src/vs/workbench/api/node/extHostStoragePaths.ts b/src/vs/workbench/api/node/extHostStoragePaths.ts index 0adb497de02..5a301ad857c 100644 --- a/src/vs/workbench/api/node/extHostStoragePaths.ts +++ b/src/vs/workbench/api/node/extHostStoragePaths.ts @@ -8,23 +8,24 @@ import { URI } from 'vs/base/common/uri'; import * as pfs from 'vs/base/node/pfs'; import { IEnvironment, IStaticWorkspaceData } from 'vs/workbench/api/common/extHost.protocol'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths'; +import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; +import { withNullAsUndefined } from 'vs/base/common/types'; -export class ExtensionStoragePaths { +export class ExtensionStoragePaths implements IExtensionStoragePaths { + + readonly _serviceBrand: undefined; private readonly _workspace?: IStaticWorkspaceData; private readonly _environment: IEnvironment; - private readonly _ready: Promise; + readonly whenReady: Promise; private _value?: string; - constructor(workspace: IStaticWorkspaceData | undefined, environment: IEnvironment) { - this._workspace = workspace; - this._environment = environment; - this._ready = this._getOrCreateWorkspaceStoragePath().then(value => this._value = value); - } - - get whenReady(): Promise { - return this._ready; + constructor(@IExtHostInitDataService initData: IExtHostInitDataService) { + this._workspace = withNullAsUndefined(initData.workspace); + this._environment = initData.environment; + this.whenReady = this._getOrCreateWorkspaceStoragePath().then(value => this._value = value); } workspaceValue(extension: IExtensionDescription): string | undefined { From 753732c8ed2d1da6dafa7ca86dafce9fb0c2b6a3 Mon Sep 17 00:00:00 2001 From: Andy Hinkle Date: Thu, 8 Aug 2019 05:23:38 -0500 Subject: [PATCH 349/861] Check for updates only once at launch (#72169) * Check for updates only once at launch * Update Mode Fix * Add Start to enum config * Check For Updates on Startup --- .../update/electron-main/abstractUpdateService.ts | 9 +++++++-- .../platform/update/node/update.config.contribution.ts | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/vs/platform/update/electron-main/abstractUpdateService.ts b/src/vs/platform/update/electron-main/abstractUpdateService.ts index 2a1240b1eb9..bc2427bb7c8 100644 --- a/src/vs/platform/update/electron-main/abstractUpdateService.ts +++ b/src/vs/platform/update/electron-main/abstractUpdateService.ts @@ -81,8 +81,13 @@ export abstract class AbstractUpdateService implements IUpdateService { return; } - // Start checking for updates after 30 seconds - this.scheduleCheckForUpdates(30 * 1000).then(undefined, err => this.logService.error(err)); + if (updateMode === 'start') { + this.logService.info('update#ctor - startup checks only; automatic updates are disabled by user preference'); + this.checkForUpdates(null); + } else { + // Create schedule after checking for updates in 30 seconds + this.scheduleCheckForUpdates(30 * 1000).then(undefined, err => this.logService.error(err)); + } } private getProductQuality(updateMode: string): string | undefined { diff --git a/src/vs/platform/update/node/update.config.contribution.ts b/src/vs/platform/update/node/update.config.contribution.ts index b6ef43b29fa..2a7978bbcfd 100644 --- a/src/vs/platform/update/node/update.config.contribution.ts +++ b/src/vs/platform/update/node/update.config.contribution.ts @@ -17,7 +17,7 @@ configurationRegistry.registerConfiguration({ properties: { 'update.mode': { type: 'string', - enum: ['none', 'manual', 'default'], + enum: ['none', 'manual', 'start', 'default'], default: 'default', scope: ConfigurationScope.APPLICATION, description: localize('updateMode', "Configure whether you receive automatic updates. Requires a restart after change. The updates are fetched from a Microsoft online service."), @@ -25,6 +25,7 @@ configurationRegistry.registerConfiguration({ enumDescriptions: [ localize('none', "Disable updates."), localize('manual', "Disable automatic background update checks. Updates will be available if you manually check for updates."), + localize('start', "Code will check for updates on launch. Disable automatic background update checks. "), localize('default', "Enable automatic update checks. Code will check for updates automatically and periodically.") ] }, From 29c36ae95d5cecc2ae748934199ccb63913e3f76 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 8 Aug 2019 12:25:05 +0200 Subject: [PATCH 350/861] :lipstick: --- .../platform/update/electron-main/abstractUpdateService.ts | 6 ++++-- src/vs/platform/update/node/update.config.contribution.ts | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/vs/platform/update/electron-main/abstractUpdateService.ts b/src/vs/platform/update/electron-main/abstractUpdateService.ts index bc2427bb7c8..d789bf4e09b 100644 --- a/src/vs/platform/update/electron-main/abstractUpdateService.ts +++ b/src/vs/platform/update/electron-main/abstractUpdateService.ts @@ -83,9 +83,11 @@ export abstract class AbstractUpdateService implements IUpdateService { if (updateMode === 'start') { this.logService.info('update#ctor - startup checks only; automatic updates are disabled by user preference'); - this.checkForUpdates(null); + + // Check for updates only once after 30 seconds + setTimeout(() => this.checkForUpdates(null), 30 * 1000); } else { - // Create schedule after checking for updates in 30 seconds + // Start checking for updates after 30 seconds this.scheduleCheckForUpdates(30 * 1000).then(undefined, err => this.logService.error(err)); } } diff --git a/src/vs/platform/update/node/update.config.contribution.ts b/src/vs/platform/update/node/update.config.contribution.ts index 2a7978bbcfd..fe7b3cba8b2 100644 --- a/src/vs/platform/update/node/update.config.contribution.ts +++ b/src/vs/platform/update/node/update.config.contribution.ts @@ -25,7 +25,7 @@ configurationRegistry.registerConfiguration({ enumDescriptions: [ localize('none', "Disable updates."), localize('manual', "Disable automatic background update checks. Updates will be available if you manually check for updates."), - localize('start', "Code will check for updates on launch. Disable automatic background update checks. "), + localize('start', "Check for updates only on startup. Disable automatic background update checks."), localize('default', "Enable automatic update checks. Code will check for updates automatically and periodically.") ] }, From 72e3d3b45d6c3f7685a6559f024a1ae0fcad6146 Mon Sep 17 00:00:00 2001 From: Dan McCarthy Date: Thu, 8 Aug 2019 05:28:03 -0500 Subject: [PATCH 351/861] Updated branch tooltip to display full branch name instead of "checkout..." (#72275) Previously the tooltip displayed when hovering over a branch name in the git workflow simply said "Checkout...". However, this could be better used by displaying the full branch name since long branch names are concatenated and not shown in full. Therefore it has been updated to do so. --- extensions/git/src/statusbar.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/git/src/statusbar.ts b/extensions/git/src/statusbar.ts index 3b43e880090..fb89aca7264 100644 --- a/extensions/git/src/statusbar.ts +++ b/extensions/git/src/statusbar.ts @@ -27,7 +27,7 @@ class CheckoutStatusBar { return { command: 'git.checkout', - tooltip: localize('checkout', 'Checkout...'), + tooltip: `${this.repository.headLabel}`, title, arguments: [this.repository.sourceControl] }; From 0bb4cc3dafefc2f2787bd944168134c6b05b3ade Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 8 Aug 2019 12:42:56 +0200 Subject: [PATCH 352/861] remove misdirection --- extensions/git/src/commands.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 036f152ee4d..c8575ab880e 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1253,8 +1253,8 @@ export class CommandCenter { if (documents.length > 0) { const message = documents.length === 1 - ? localize('unsaved files single', "The following staged file is unsaved and will not be included in the commit if you proceed: {0}.\n\nWould you like to save it before committing?", path.basename(documents[0].uri.fsPath)) - : localize('unsaved files', "There are {0} unsaved staged files.\n\nWould you like to save them before committing?", documents.length); + ? localize('unsaved files single', "The following file is unsaved and will not be included in the commit if you proceed: {0}.\n\nWould you like to save it before committing?", path.basename(documents[0].uri.fsPath)) + : localize('unsaved files', "There are {0} unsaved files.\n\nWould you like to save them before committing?", documents.length); const saveAndCommit = localize('save and commit', "Save All & Commit"); const commit = localize('commit', "Commit Anyway"); const pick = await window.showWarningMessage(message, { modal: true }, saveAndCommit, commit); From 1556800102ab0d44f2dad97d59da0246fb4fb9c6 Mon Sep 17 00:00:00 2001 From: skprabhanjan Date: Thu, 8 Aug 2019 16:14:23 +0530 Subject: [PATCH 353/861] Fix fix-64077 With a setting --- extensions/git/package.json | 9 +++++++++ extensions/git/package.nls.json | 1 + extensions/git/src/git.ts | 11 +++++++++-- extensions/git/src/repository.ts | 7 +++++-- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index aba696781b6..3e0e7d2e4d4 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1334,6 +1334,15 @@ "scope": "resource", "default": false, "description": "%config.supportCancellation%" + }, + "git.sortOrderForBranch": { + "type": "string", + "enum": [ + "committerdate", + "alphabetically" + ], + "default": "committerdate", + "description": "%config.sortOrderForBranch%" } } }, diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index cddbdad605e..7086508a137 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -123,6 +123,7 @@ "config.confirmForcePush": "Controls whether to ask for confirmation before force-pushing.", "config.openDiffOnClick": "Controls whether the diff editor should be opened when clicking a change. Otherwise the regular editor will be opened.", "config.supportCancellation": "Controls whether a notification comes up when running the Sync action, which allows the user to cancel the operation.", + "config.sortOrderForBranch": "Controls the sort order for branches", "colors.added": "Color for added resources.", "colors.modified": "Color for modified resources.", "colors.deleted": "Color for deleted resources.", diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index b306cab1255..9b5ba8a9eca 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -1610,8 +1610,15 @@ export class Repository { .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']); + async getRefs(sortBranchListByCommitterDate?: Boolean): Promise { + const args = ['for-each-ref', '--format', '%(refname) %(objectname)']; + + if (sortBranchListByCommitterDate) { + args.push('--sort'); + args.push('-committerdate'); + } + + const result = await this.run(args); const fn = (line: string): Ref | null => { let match: RegExpExecArray | null; diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index a4b37bebd5e..ec81987241c 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -698,6 +698,9 @@ export class Repository implements Disposable { onConfigListener(updateIndexGroupVisibility, this, this.disposables); updateIndexGroupVisibility(); + const onConfigListenerForBranchSortOrder = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.sortOrderForBranch', root)); + onConfigListenerForBranchSortOrder(this.updateModelState, this, this.disposables); + this.mergeGroup.hideWhenEmpty = true; this.disposables.push(this.mergeGroup); @@ -1399,7 +1402,7 @@ export class Repository implements Disposable { const config = workspace.getConfiguration('git'); const shouldIgnore = config.get('ignoreLimitWarning') === true; const useIcons = !config.get('decorations.enabled', true); - + const sortBranchListByCommitterDate = config.get('sortOrderForBranch') === 'committerdate'; this.isRepositoryHuge = didHitLimit; if (didHitLimit && !shouldIgnore && !this.didWarnAboutLimit) { @@ -1449,7 +1452,7 @@ export class Repository implements Disposable { // noop } - const [refs, remotes, submodules, rebaseCommit] = await Promise.all([this.repository.getRefs(), this.repository.getRemotes(), this.repository.getSubmodules(), this.getRebaseCommit()]); + const [refs, remotes, submodules, rebaseCommit] = await Promise.all([this.repository.getRefs(sortBranchListByCommitterDate), this.repository.getRemotes(), this.repository.getSubmodules(), this.getRebaseCommit()]); this._HEAD = HEAD; this._refs = refs; From d3dbf5660f46f7efcc4dde9f367eb1c424063d02 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Thu, 8 Aug 2019 12:45:14 +0200 Subject: [PATCH 354/861] Command inputs should be consistent with keybindings (#73034) Fixes #72935 --- .../contrib/tasks/browser/abstractTaskService.ts | 4 ++-- .../common/configurationResolver.ts | 2 +- .../common/configurationResolverSchema.ts | 16 ++++++++++++++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index be59e276ec8..5451b8eb6f4 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -306,7 +306,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer }); CommandsRegistry.registerCommand('workbench.action.tasks.reRunTask', (accessor, arg) => { - this.reRunTaskCommand(arg); + this.reRunTaskCommand(); }); CommandsRegistry.registerCommand('workbench.action.tasks.restartTask', (accessor, arg) => { @@ -1810,7 +1810,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer }); } - private reRunTaskCommand(arg?: any): void { + private reRunTaskCommand(): void { if (!this.canRunCommand()) { return; } diff --git a/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts b/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts index fafa3c35e17..47281663ce9 100644 --- a/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts +++ b/src/vs/workbench/services/configurationResolver/common/configurationResolver.ts @@ -60,4 +60,4 @@ export interface CommandInputInfo { args?: any; } -export type ConfiguredInput = PromptStringInputInfo | PickStringInputInfo | CommandInputInfo; \ No newline at end of file +export type ConfiguredInput = PromptStringInputInfo | PickStringInputInfo | CommandInputInfo; diff --git a/src/vs/workbench/services/configurationResolver/common/configurationResolverSchema.ts b/src/vs/workbench/services/configurationResolver/common/configurationResolverSchema.ts index fa0e030188e..1fa8a4ca589 100644 --- a/src/vs/workbench/services/configurationResolver/common/configurationResolverSchema.ts +++ b/src/vs/workbench/services/configurationResolver/common/configurationResolverSchema.ts @@ -102,8 +102,20 @@ export const inputsSchema: IJSONSchema = { description: nls.localize('JsonSchema.input.command.command', "The command to execute for this input variable.") }, args: { - type: 'object', - description: nls.localize('JsonSchema.input.command.args', "Optional arguments passed to the command.") + oneOf: [ + { + type: 'object', + description: nls.localize('JsonSchema.input.command.args', "Optional arguments passed to the command.") + }, + { + type: 'array', + description: nls.localize('JsonSchema.input.command.args', "Optional arguments passed to the command.") + }, + { + type: 'string', + description: nls.localize('JsonSchema.input.command.args', "Optional arguments passed to the command.") + } + ] } } } From 2a829f92906b5836fb59a8a4140f43288eecdf07 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 8 Aug 2019 12:47:55 +0200 Subject: [PATCH 355/861] :lipstick: --- build/azure-pipelines/upload-sourcemaps.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/build/azure-pipelines/upload-sourcemaps.js b/build/azure-pipelines/upload-sourcemaps.js index 190023f40dc..8288129852d 100644 --- a/build/azure-pipelines/upload-sourcemaps.js +++ b/build/azure-pipelines/upload-sourcemaps.js @@ -14,9 +14,7 @@ const root = path.dirname(path.dirname(__dirname)); const commit = util.getVersion(root); // optionally allow to pass in explicit base/maps to upload -const args = process.argv.slice(2); -const base = args[0]; -const maps = args[1]; +const [base, maps] = process.argv.slice(2); const fetch = function (base, maps = `${base}/**/*.map`) { return vfs.src(maps, { base }) From 66b499a016241eb4c3b9b0e3febf95cf922ba242 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 8 Aug 2019 12:53:01 +0200 Subject: [PATCH 356/861] register ExtHostExtensionService as singleton --- .../workbench/api/common/extHost.api.impl.ts | 9 ++-- .../api/common/extHostExtensionService.ts | 6 ++- src/vs/workbench/api/common/extHostStorage.ts | 5 ++- src/vs/workbench/api/common/rpcService.ts | 15 ++++--- src/vs/workbench/api/node/extHost.services.ts | 3 ++ .../api/node/extHostExtensionService.ts | 44 +++++++------------ .../extensions/node/extensionHostMain.ts | 16 +++---- .../node/extensionHostProcessSetup.ts | 1 + 8 files changed, 50 insertions(+), 49 deletions(-) diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 56efd7d8bba..3b753c18fea 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -15,7 +15,7 @@ import { OverviewRulerLane } from 'vs/editor/common/model'; import * as languageConfiguration from 'vs/editor/common/modes/languageConfiguration'; import { score } from 'vs/editor/common/modes/languageSelector'; import * as files from 'vs/platform/files/common/files'; -import { ExtHostContext, IInitData, IMainContext, MainContext } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostContext, IInitData, MainContext } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostApiCommands } from 'vs/workbench/api/common/extHostApiCommands'; import { ExtHostClipboard } from 'vs/workbench/api/common/extHostClipboard'; import { IExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; @@ -57,7 +57,6 @@ import * as vscode from 'vscode'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { originalFSPath } from 'vs/base/common/resources'; import { values } from 'vs/base/common/collections'; -import { IURITransformer } from 'vs/base/common/uriIpc'; import { ExtHostEditorInsets } from 'vs/workbench/api/common/extHostCodeInsets'; import { ExtHostLabelService } from 'vs/workbench/api/common/extHostLabelService'; import { getRemoteName } from 'vs/platform/remote/common/remoteHosts'; @@ -67,6 +66,8 @@ import { IExtHostTask } from 'vs/workbench/api/common/extHostTask'; import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService'; import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch'; import { ILogService } from 'vs/platform/log/common/log'; +import { IURITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; export interface IExtensionApiFactory { (extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode; @@ -86,15 +87,15 @@ function proposedApiFunction(extension: IExtensionDescription, fn: T): T { export function createApiFactory( accessor: ServicesAccessor, initData: IInitData, - rpcProtocol: IMainContext, extHostStorage: ExtHostStorage, - uriTransformer: IURITransformer | null ): IExtensionApiFactory { // services const extensionService = accessor.get(IExtHostExtensionService); const extHostWorkspace = accessor.get(IExtHostWorkspace); const extHostConfiguration = accessor.get(IExtHostConfiguration); + const uriTransformer = accessor.get(IURITransformerService); + const rpcProtocol = accessor.get(IExtHostRpcService); const extHostLogService = accessor.get(ILogService); // register addressable instances diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts index 0833e6f7e83..5b296ee5390 100644 --- a/src/vs/workbench/api/common/extHostExtensionService.ts +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -7,16 +7,20 @@ import { ExtHostExtensionServiceShape } from 'vs/workbench/api/common/extHost.pr import { ExtensionActivationReason, IExtensionAPI } from 'vs/workbench/api/common/extHostExtensionActivator'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; import * as vscode from 'vscode'; -import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { TernarySearchTree } from 'vs/base/common/map'; export const IExtHostExtensionService = createDecorator('IExtHostExtensionService'); export interface IExtHostExtensionService extends ExtHostExtensionServiceShape { _serviceBrand: any; + initialize(): void; isActivated(extensionId: ExtensionIdentifier): boolean; activateByIdWithErrors(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise; + deactivateAll(): Promise; getExtensionExports(extensionId: ExtensionIdentifier): IExtensionAPI | null | undefined; getExtensionRegistry(): Promise; + getExtensionPathIndex(): Promise>; registerRemoteAuthorityResolver(authorityPrefix: string, resolver: vscode.RemoteAuthorityResolver): vscode.Disposable; } diff --git a/src/vs/workbench/api/common/extHostStorage.ts b/src/vs/workbench/api/common/extHostStorage.ts index 32df5a99877..72c6e02f6d4 100644 --- a/src/vs/workbench/api/common/extHostStorage.ts +++ b/src/vs/workbench/api/common/extHostStorage.ts @@ -3,8 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { MainContext, MainThreadStorageShape, IMainContext, ExtHostStorageShape } from './extHost.protocol'; +import { MainContext, MainThreadStorageShape, ExtHostStorageShape } from './extHost.protocol'; import { Emitter } from 'vs/base/common/event'; +import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; export interface IStorageChangeEvent { shared: boolean; @@ -19,7 +20,7 @@ export class ExtHostStorage implements ExtHostStorageShape { private _onDidChangeStorage = new Emitter(); readonly onDidChangeStorage = this._onDidChangeStorage.event; - constructor(mainContext: IMainContext) { + constructor(mainContext: IExtHostRpcService) { this._proxy = mainContext.getProxy(MainContext.MainThreadStorage); } diff --git a/src/vs/workbench/api/common/rpcService.ts b/src/vs/workbench/api/common/rpcService.ts index 5cff20d4006..ab2a788d52c 100644 --- a/src/vs/workbench/api/common/rpcService.ts +++ b/src/vs/workbench/api/common/rpcService.ts @@ -9,17 +9,22 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' export const IExtHostRpcService = createDecorator('IExtHostRpcService'); -export interface IExtHostRpcService { +export interface IExtHostRpcService extends IMainContext { _serviceBrand: any; - getProxy(identifier: ProxyIdentifier): T; } export class ExtHostRpcService implements IExtHostRpcService { readonly _serviceBrand: any; - constructor(private readonly _mainContext: IMainContext) { } + getProxy: (identifier: ProxyIdentifier) => T; + set: (identifier: ProxyIdentifier, instance: R) => R; + assertRegistered: (identifiers: ProxyIdentifier[]) => void; + + constructor(mainContext: IMainContext) { + this.getProxy = mainContext.getProxy.bind(mainContext); + this.set = mainContext.set.bind(mainContext); + this.assertRegistered = mainContext.assertRegistered.bind(mainContext); - getProxy(identifier: ProxyIdentifier): T { - return this._mainContext.getProxy(identifier); } + } diff --git a/src/vs/workbench/api/node/extHost.services.ts b/src/vs/workbench/api/node/extHost.services.ts index 392d12d48c7..f6896f19e04 100644 --- a/src/vs/workbench/api/node/extHost.services.ts +++ b/src/vs/workbench/api/node/extHost.services.ts @@ -21,6 +21,8 @@ import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch'; import { ExtHostSearch } from 'vs/workbench/api/node/extHostSearch'; import { ExtensionStoragePaths } from 'vs/workbench/api/node/extHostStoragePaths'; import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths'; +import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; +import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService'; // register singleton services registerSingleton(IExtHostOutputService, ExtHostOutputService2); @@ -34,4 +36,5 @@ registerSingleton(IExtHostTask, ExtHostTask); registerSingleton(IExtHostDebugService, ExtHostDebugService); registerSingleton(IExtHostSearch, ExtHostSearch); registerSingleton(IExtensionStoragePaths, ExtensionStoragePaths); +registerSingleton(IExtHostExtensionService, ExtHostExtensionService); diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 1bfc691ab2c..268e7ec0e55 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -11,9 +11,9 @@ import { dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle import { TernarySearchTree } from 'vs/base/common/map'; import { URI } from 'vs/base/common/uri'; import { ILogService } from 'vs/platform/log/common/log'; -import { createApiFactory, IExtensionApiFactory } from 'vs/workbench/api/common/extHost.api.impl'; +import { createApiFactory } from 'vs/workbench/api/common/extHost.api.impl'; import { NodeModuleRequireInterceptor, VSCodeNodeModuleFactory, KeytarNodeModuleFactory, OpenNodeModuleFactory } from 'vs/workbench/api/node/extHostRequireInterceptor'; -import { ExtHostExtensionServiceShape, IInitData, IMainContext, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape, IResolveAuthorityResult } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostExtensionServiceShape, IInitData, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape, IResolveAuthorityResult } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostConfiguration, IExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionModule, HostExtension, ExtensionActivationTimesFragment } from 'vs/workbench/api/common/extHostExtensionActivator'; import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; @@ -30,15 +30,14 @@ import { Schemas } from 'vs/base/common/network'; import { VSBuffer } from 'vs/base/common/buffer'; import { ExtensionMemento } from 'vs/workbench/api/common/extHostMemento'; import { RemoteAuthorityResolverError, ExtensionExecutionContext } from 'vs/workbench/api/common/extHostTypes'; -import { IURITransformer } from 'vs/base/common/uriIpc'; import { ResolvedAuthority, ResolvedOptions } from 'vs/platform/remote/common/remoteAuthorityResolver'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IInstantiationService, createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; -import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; import { ExtHostDownloadService } from 'vs/workbench/api/node/extHostDownloadService'; import { CLIServer } from 'vs/workbench/api/node/extHostCLIServer'; import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths'; +import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; interface ITestRunner { /** Old test runner API, as exported from `vscode/lib/testrunner` */ @@ -50,7 +49,10 @@ interface INewTestRunner { run(): Promise; } +export const IHostUtils = createDecorator('IHostUtils'); + export interface IHostUtils { + _serviceBrand: undefined; exit(code?: number): void; exists(path: string): Promise; realpath(path: string): Promise; @@ -74,7 +76,7 @@ export class ExtHostExtensionService implements IExtHostExtensionService, ExtHos private readonly _hostUtils: IHostUtils; private readonly _initData: IInitData; - private readonly _extHostContext: IMainContext; + private readonly _extHostContext: IExtHostRpcService; private readonly _instaService: IInstantiationService; private readonly _extHostWorkspace: ExtHostWorkspace; private readonly _extHostConfiguration: ExtHostConfiguration; @@ -92,7 +94,6 @@ export class ExtHostExtensionService implements IExtHostExtensionService, ExtHos private readonly _storagePath: IExtensionStoragePaths; private readonly _activator: ExtensionsActivator; private _extensionPathIndex: Promise> | null; - private readonly _extensionApiFactory: IExtensionApiFactory; private readonly _resolvers: { [authorityPrefix: string]: vscode.RemoteAuthorityResolver; }; @@ -101,11 +102,9 @@ export class ExtHostExtensionService implements IExtHostExtensionService, ExtHos private readonly _disposables: DisposableStore; constructor( - hostUtils: IHostUtils, - uriTransformer: IURITransformer | null, - extHostContext: IMainContext, - services: ServiceCollection, @IInstantiationService instaService: IInstantiationService, + @IHostUtils hostUtils: IHostUtils, + @IExtHostRpcService extHostContext: IExtHostRpcService, @IExtHostWorkspace extHostWorkspace: IExtHostWorkspace, @IExtHostConfiguration extHostConfiguration: IExtHostConfiguration, @ILogService extHostLogService: ExtHostLogService, @@ -152,26 +151,12 @@ export class ExtHostExtensionService implements IExtHostExtensionService, ExtHos } }); this._extensionPathIndex = null; - - // todo@joh this is a hack! - // the problem is that this service doesn't create the insta-service - // but downlevel things it creates depend on this service... - services.set(IExtHostExtensionService, this); - - // initialize API first (i.e. do not release barrier until the API is initialized) - this._extensionApiFactory = this._instaService.invokeFunction(createApiFactory, - this._initData, - this._extHostContext, - this._storage, - uriTransformer - ); - this._resolvers = Object.create(null); - this._started = false; + } + public initialize(): void { this._initialize(); - if (this._initData.autoStart) { this._startExtensionHost(); } @@ -180,6 +165,9 @@ export class ExtHostExtensionService implements IExtHostExtensionService, ExtHos private async _initialize(): Promise { try { + // initialize API + const extensionApiFactory = this._instaService.invokeFunction(createApiFactory, this._initData, this._storage); + // Register Download command this._instaService.createInstance(ExtHostDownloadService); @@ -192,7 +180,7 @@ export class ExtHostExtensionService implements IExtHostExtensionService, ExtHos // Module loading tricks const configProvider = await this._extHostConfiguration.getConfigProvider(); const extensionPaths = await this.getExtensionPathIndex(); - NodeModuleRequireInterceptor.INSTANCE.register(new VSCodeNodeModuleFactory(this._extensionApiFactory, extensionPaths, this._registry, configProvider)); + NodeModuleRequireInterceptor.INSTANCE.register(new VSCodeNodeModuleFactory(extensionApiFactory, extensionPaths, this._registry, configProvider)); NodeModuleRequireInterceptor.INSTANCE.register(new KeytarNodeModuleFactory(this._extHostContext.getProxy(MainContext.MainThreadKeytar), this._initData.environment)); if (this._initData.remote.isRemote) { NodeModuleRequireInterceptor.INSTANCE.register(new OpenNodeModuleFactory( diff --git a/src/vs/workbench/services/extensions/node/extensionHostMain.ts b/src/vs/workbench/services/extensions/node/extensionHostMain.ts index da8f9ff60aa..10a8ebd4e42 100644 --- a/src/vs/workbench/services/extensions/node/extensionHostMain.ts +++ b/src/vs/workbench/services/extensions/node/extensionHostMain.ts @@ -10,7 +10,7 @@ import { URI, setUriThrowOnMissingScheme } from 'vs/base/common/uri'; import { IURITransformer } from 'vs/base/common/uriIpc'; import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; import { IInitData, MainContext, MainThreadConsoleShape } from 'vs/workbench/api/common/extHost.protocol'; -import { ExtHostExtensionService, IHostUtils } from 'vs/workbench/api/node/extHostExtensionService'; +import { IHostUtils } from 'vs/workbench/api/node/extHostExtensionService'; import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; import { RPCProtocol } from 'vs/workbench/services/extensions/common/rpcProtocol'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; @@ -22,6 +22,7 @@ import { InstantiationService } from 'vs/platform/instantiation/common/instantia import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IExtHostRpcService, ExtHostRpcService } from 'vs/workbench/api/common/rpcService'; import { IURITransformerService, URITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService'; +import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; // we don't (yet) throw when extensions parse // uris that have no scheme @@ -43,7 +44,7 @@ export class ExtensionHostMain { private _isTerminating: boolean; private readonly _hostUtils: IHostUtils; - private readonly _extensionService: ExtHostExtensionService; + private readonly _extensionService: IExtHostExtensionService; private readonly _disposables = new DisposableStore(); constructor( @@ -74,19 +75,16 @@ export class ExtensionHostMain { services.set(IExtHostRpcService, new ExtHostRpcService(rpcProtocol)); services.set(ILogService, extHostLogService); services.set(IURITransformerService, new URITransformerService(uriTransformer)); + services.set(IHostUtils, hostUtils); const instaService: IInstantiationService = new InstantiationService(services, true); extHostLogService.info('extension host started'); extHostLogService.trace('initData', initData); - this._extensionService = instaService.createInstance( - ExtHostExtensionService, - hostUtils, - uriTransformer, - rpcProtocol, - services, // todo@joh hack! - ); + // todo@joh -> not soo nice... + this._extensionService = instaService.invokeFunction(accessor => accessor.get(IExtHostExtensionService)); + this._extensionService.initialize(); // error forwarding and stack trace scanning Error.stackTraceLimit = 100; // increase number of stack frames (from 10, https://github.com/v8/v8/wiki/Stack-Trace-API) diff --git a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts index 59a5bedde38..4a99e7dfd2d 100644 --- a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts +++ b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts @@ -313,6 +313,7 @@ export async function startExtensionHostProcess(): Promise { // host abstraction const hostUtils = new class NodeHost implements IHostUtils { + _serviceBrand: undefined; exit(code: number) { nativeExit(code); } exists(path: string) { return exists(path); } realpath(path: string) { return realpath(path); } From 419dc83a5d6b2e1dc19416ef975421a969682e9a Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 8 Aug 2019 13:16:14 +0200 Subject: [PATCH 357/861] less argumenst, more services in api factory --- src/vs/workbench/api/common/extHost.api.impl.ts | 5 +++-- src/vs/workbench/api/node/extHostExtensionService.ts | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 3b753c18fea..78cbeeb3182 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -15,7 +15,7 @@ import { OverviewRulerLane } from 'vs/editor/common/model'; import * as languageConfiguration from 'vs/editor/common/modes/languageConfiguration'; import { score } from 'vs/editor/common/modes/languageSelector'; import * as files from 'vs/platform/files/common/files'; -import { ExtHostContext, IInitData, MainContext } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostContext, MainContext } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostApiCommands } from 'vs/workbench/api/common/extHostApiCommands'; import { ExtHostClipboard } from 'vs/workbench/api/common/extHostClipboard'; import { IExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; @@ -68,6 +68,7 @@ import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch'; import { ILogService } from 'vs/platform/log/common/log'; import { IURITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService'; import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; export interface IExtensionApiFactory { (extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode; @@ -86,11 +87,11 @@ function proposedApiFunction(extension: IExtensionDescription, fn: T): T { */ export function createApiFactory( accessor: ServicesAccessor, - initData: IInitData, extHostStorage: ExtHostStorage, ): IExtensionApiFactory { // services + const initData = accessor.get(IExtHostInitDataService); const extensionService = accessor.get(IExtHostExtensionService); const extHostWorkspace = accessor.get(IExtHostWorkspace); const extHostConfiguration = accessor.get(IExtHostConfiguration); diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 268e7ec0e55..0de3f0f5974 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -166,7 +166,7 @@ export class ExtHostExtensionService implements IExtHostExtensionService, ExtHos try { // initialize API - const extensionApiFactory = this._instaService.invokeFunction(createApiFactory, this._initData, this._storage); + const extensionApiFactory = this._instaService.invokeFunction(createApiFactory, this._storage); // Register Download command this._instaService.createInstance(ExtHostDownloadService); From fdbe5eaa7e1d1bf224eaead078b6db5a37d60941 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Thu, 8 Aug 2019 13:04:24 +0200 Subject: [PATCH 358/861] move EH debug sevice to proper location --- .../workbench/browser/web.simpleservices.ts | 40 +------------ .../debug/browser/debugHelperService.ts | 21 ------- .../browser/extensionHostDebugService.ts | 57 +++++++++++++++++++ src/vs/workbench/workbench.web.main.ts | 3 +- 4 files changed, 59 insertions(+), 62 deletions(-) delete mode 100644 src/vs/workbench/contrib/debug/browser/debugHelperService.ts create mode 100644 src/vs/workbench/contrib/debug/browser/extensionHostDebugService.ts diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 61974d274ad..f60961dbdff 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -22,7 +22,6 @@ import { IRecentlyOpened, IRecent, isRecentFile, isRecentFolder } from 'vs/platf import { ISerializableCommandAction } from 'vs/platform/actions/common/actions'; import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing'; import { ITunnelService } from 'vs/platform/remote/common/tunnel'; -import { IExtensionHostDebugService } from 'vs/platform/debug/common/extensionHostDebug'; // tslint:disable-next-line: import-patterns import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { addDisposableListener, EventType } from 'vs/base/browser/dom'; @@ -30,13 +29,11 @@ import { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/co import { pathsToEditors } from 'vs/workbench/common/editor'; import { IFileService } from 'vs/platform/files/common/files'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { ParsedArgs, IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { ParsedArgs } from 'vs/platform/environment/common/environment'; import { IProcessEnvironment } from 'vs/base/common/platform'; import { toStoreData, restoreRecentlyOpened } from 'vs/platform/history/common/historyStorage'; -import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; // tslint:disable-next-line: import-patterns import { IExperimentService, IExperiment, ExperimentActionType, ExperimentState } from 'vs/workbench/contrib/experiments/common/experimentService'; -import { ExtensionHostDebugChannelClient, ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; //#region Extension Tips @@ -504,41 +501,6 @@ registerSingleton(IWindowService, SimpleWindowService); //#endregion -//#region ExtensionHostDebugService - -export class SimpleExtensionHostDebugService extends ExtensionHostDebugChannelClient { - - constructor( - @IRemoteAgentService remoteAgentService: IRemoteAgentService, - //@IWindowService windowService: IWindowService, - @IEnvironmentService environmentService: IEnvironmentService - ) { - const connection = remoteAgentService.getConnection(); - - if (!connection) { - throw new Error('Missing agent connection'); - } - - super(connection.getChannel(ExtensionHostDebugBroadcastChannel.ChannelName)); - - this._register(this.onReload(event => { - if (environmentService.isExtensionDevelopment && environmentService.debugExtensionHost.debugId === event.sessionId) { - //windowService.reloadWindow(); - window.location.reload(); - } - })); - this._register(this.onClose(event => { - if (environmentService.isExtensionDevelopment && environmentService.debugExtensionHost.debugId === event.sessionId) { - //this._windowService.closeWindow(); - window.close(); - } - })); - } -} -registerSingleton(IExtensionHostDebugService, SimpleExtensionHostDebugService); - -//#endregion - //#region Window export class SimpleWindowsService implements IWindowsService { diff --git a/src/vs/workbench/contrib/debug/browser/debugHelperService.ts b/src/vs/workbench/contrib/debug/browser/debugHelperService.ts deleted file mode 100644 index a0616866a48..00000000000 --- a/src/vs/workbench/contrib/debug/browser/debugHelperService.ts +++ /dev/null @@ -1,21 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; -import { IDebugHelperService } from 'vs/workbench/contrib/debug/common/debug'; -import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; - -export class BrowserDebugHelperService implements IDebugHelperService { - - _serviceBrand!: ServiceIdentifier; - - createTelemetryService(configurationService: IConfigurationService, args: string[]): TelemetryService | undefined { - return undefined; - } -} - -registerSingleton(IDebugHelperService, BrowserDebugHelperService); diff --git a/src/vs/workbench/contrib/debug/browser/extensionHostDebugService.ts b/src/vs/workbench/contrib/debug/browser/extensionHostDebugService.ts new file mode 100644 index 00000000000..3f5b703c4ce --- /dev/null +++ b/src/vs/workbench/contrib/debug/browser/extensionHostDebugService.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 { ExtensionHostDebugChannelClient, ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc'; +import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IExtensionHostDebugService } from 'vs/platform/debug/common/extensionHostDebug'; +import { IDebugHelperService } from 'vs/workbench/contrib/debug/common/debug'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; + +class BrowserExtensionHostDebugService extends ExtensionHostDebugChannelClient { + + constructor( + @IRemoteAgentService remoteAgentService: IRemoteAgentService, + //@IWindowService windowService: IWindowService, + @IEnvironmentService environmentService: IEnvironmentService + ) { + const connection = remoteAgentService.getConnection(); + + if (!connection) { + throw new Error('Missing agent connection'); + } + + super(connection.getChannel(ExtensionHostDebugBroadcastChannel.ChannelName)); + + this._register(this.onReload(event => { + if (environmentService.isExtensionDevelopment && environmentService.debugExtensionHost.debugId === event.sessionId) { + //windowService.reloadWindow(); + window.location.reload(); + } + })); + this._register(this.onClose(event => { + if (environmentService.isExtensionDevelopment && environmentService.debugExtensionHost.debugId === event.sessionId) { + //this._windowService.closeWindow(); + window.close(); + } + })); + } +} + +registerSingleton(IExtensionHostDebugService, BrowserExtensionHostDebugService); + +class BrowserDebugHelperService implements IDebugHelperService { + + _serviceBrand!: ServiceIdentifier; + + createTelemetryService(configurationService: IConfigurationService, args: string[]): TelemetryService | undefined { + return undefined; + } +} + +registerSingleton(IDebugHelperService, BrowserDebugHelperService); diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index ca799d9789a..1a11ef19d75 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -99,7 +99,6 @@ import 'vs/workbench/services/decorations/browser/decorationsService'; import 'vs/workbench/services/search/common/searchService'; import 'vs/workbench/services/progress/browser/progressService'; import 'vs/workbench/services/editor/browser/codeEditorService'; -// import 'vs/workbench/services/extensions/electron-browser/extensionHostDebugService'; import 'vs/workbench/services/preferences/browser/preferencesService'; import 'vs/workbench/services/output/common/outputChannelModelService'; import 'vs/workbench/services/configuration/common/jsonEditingService'; @@ -240,7 +239,7 @@ import 'vs/workbench/contrib/debug/browser/debugQuickOpen'; import 'vs/workbench/contrib/debug/browser/debugEditorContribution'; import 'vs/workbench/contrib/debug/browser/repl'; import 'vs/workbench/contrib/debug/browser/debugViewlet'; -import 'vs/workbench/contrib/debug/browser/debugHelperService'; +import 'vs/workbench/contrib/debug/browser/extensionHostDebugService'; // Markers import 'vs/workbench/contrib/markers/browser/markers.contribution'; From 42b5eb3bf3588381c3bdcc53497c0616be7ae407 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 8 Aug 2019 15:08:10 +0200 Subject: [PATCH 359/861] add ExtHostStorage to injector, rename 'createApiFactory' to 'createApiFactoryAndRegisterActors' --- src/vs/workbench/api/common/extHost.api.impl.ts | 8 +++----- .../api/common/extHostExtensionService.ts | 6 +++++- src/vs/workbench/api/common/extHostStorage.ts | 6 ++++++ src/vs/workbench/api/node/extHost.services.ts | 3 ++- .../workbench/api/node/extHostExtensionService.ts | 14 +++++++++----- 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 78cbeeb3182..1e096e0a6c2 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -40,7 +40,7 @@ import { ExtHostProgress } from 'vs/workbench/api/common/extHostProgress'; import { ExtHostQuickOpen } from 'vs/workbench/api/common/extHostQuickOpen'; import { ExtHostSCM } from 'vs/workbench/api/common/extHostSCM'; import { ExtHostStatusBar } from 'vs/workbench/api/common/extHostStatusBar'; -import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; +import { IExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; import { ExtHostEditors } from 'vs/workbench/api/common/extHostTextEditors'; import { ExtHostTreeViews } from 'vs/workbench/api/common/extHostTreeViews'; @@ -85,10 +85,7 @@ function proposedApiFunction(extension: IExtensionDescription, fn: T): T { /** * This method instantiates and returns the extension API surface */ -export function createApiFactory( - accessor: ServicesAccessor, - extHostStorage: ExtHostStorage, -): IExtensionApiFactory { +export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): IExtensionApiFactory { // services const initData = accessor.get(IExtHostInitDataService); @@ -97,6 +94,7 @@ export function createApiFactory( const extHostConfiguration = accessor.get(IExtHostConfiguration); const uriTransformer = accessor.get(IURITransformerService); const rpcProtocol = accessor.get(IExtHostRpcService); + const extHostStorage = accessor.get(IExtHostStorage); const extHostLogService = accessor.get(ILogService); // register addressable instances diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts index 5b296ee5390..57baf95adce 100644 --- a/src/vs/workbench/api/common/extHostExtensionService.ts +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -8,9 +8,13 @@ import { ExtensionActivationReason, IExtensionAPI } from 'vs/workbench/api/commo import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; import * as vscode from 'vscode'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { createDecorator, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { TernarySearchTree } from 'vs/base/common/map'; +export interface IInitializeParticipant { + (accessor: ServicesAccessor): Promise | void; +} + export const IExtHostExtensionService = createDecorator('IExtHostExtensionService'); export interface IExtHostExtensionService extends ExtHostExtensionServiceShape { diff --git a/src/vs/workbench/api/common/extHostStorage.ts b/src/vs/workbench/api/common/extHostStorage.ts index 72c6e02f6d4..f8669c45311 100644 --- a/src/vs/workbench/api/common/extHostStorage.ts +++ b/src/vs/workbench/api/common/extHostStorage.ts @@ -6,6 +6,7 @@ import { MainContext, MainThreadStorageShape, ExtHostStorageShape } from './extHost.protocol'; import { Emitter } from 'vs/base/common/event'; import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; export interface IStorageChangeEvent { shared: boolean; @@ -15,6 +16,8 @@ export interface IStorageChangeEvent { export class ExtHostStorage implements ExtHostStorageShape { + readonly _serviceBrand: any; + private _proxy: MainThreadStorageShape; private _onDidChangeStorage = new Emitter(); @@ -36,3 +39,6 @@ export class ExtHostStorage implements ExtHostStorageShape { this._onDidChangeStorage.fire({ shared, key, value }); } } + +export interface IExtHostStorage extends ExtHostStorage { } +export const IExtHostStorage = createDecorator('IExtHostStorage'); diff --git a/src/vs/workbench/api/node/extHost.services.ts b/src/vs/workbench/api/node/extHost.services.ts index f6896f19e04..153413e086e 100644 --- a/src/vs/workbench/api/node/extHost.services.ts +++ b/src/vs/workbench/api/node/extHost.services.ts @@ -23,6 +23,7 @@ import { ExtensionStoragePaths } from 'vs/workbench/api/node/extHostStoragePaths import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths'; import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService'; +import { IExtHostStorage, ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; // register singleton services registerSingleton(IExtHostOutputService, ExtHostOutputService2); @@ -37,4 +38,4 @@ registerSingleton(IExtHostDebugService, ExtHostDebugService); registerSingleton(IExtHostSearch, ExtHostSearch); registerSingleton(IExtensionStoragePaths, ExtensionStoragePaths); registerSingleton(IExtHostExtensionService, ExtHostExtensionService); - +registerSingleton(IExtHostStorage, ExtHostStorage); diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 0de3f0f5974..eb2fb4ae37b 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -11,13 +11,13 @@ import { dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle import { TernarySearchTree } from 'vs/base/common/map'; import { URI } from 'vs/base/common/uri'; import { ILogService } from 'vs/platform/log/common/log'; -import { createApiFactory } from 'vs/workbench/api/common/extHost.api.impl'; +import { createApiFactoryAndRegisterActors } from 'vs/workbench/api/common/extHost.api.impl'; import { NodeModuleRequireInterceptor, VSCodeNodeModuleFactory, KeytarNodeModuleFactory, OpenNodeModuleFactory } from 'vs/workbench/api/node/extHostRequireInterceptor'; import { ExtHostExtensionServiceShape, IInitData, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape, IResolveAuthorityResult } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostConfiguration, IExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionModule, HostExtension, ExtensionActivationTimesFragment } from 'vs/workbench/api/common/extHostExtensionActivator'; import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; -import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; +import { ExtHostStorage, IExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; import { ExtHostWorkspace, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import { ExtensionActivationError } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; @@ -38,6 +38,7 @@ import { ExtHostDownloadService } from 'vs/workbench/api/node/extHostDownloadSer import { CLIServer } from 'vs/workbench/api/node/extHostCLIServer'; import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths'; import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; interface ITestRunner { /** Old test runner API, as exported from `vscode/lib/testrunner` */ @@ -115,7 +116,6 @@ export class ExtHostExtensionService implements IExtHostExtensionService, ExtHos this._extHostContext = extHostContext; this._initData = initData; - this._instaService = instaService; this._extHostWorkspace = extHostWorkspace; this._extHostConfiguration = extHostConfiguration; this._extHostLogService = extHostLogService; @@ -132,6 +132,10 @@ export class ExtHostExtensionService implements IExtHostExtensionService, ExtHos this._storage = new ExtHostStorage(this._extHostContext); this._storagePath = storagePath; + this._instaService = instaService.createChild(new ServiceCollection( + [IExtHostStorage, this._storage] + )); + const hostExtensions = new Set(); this._initData.hostExtensions.forEach((extensionId) => hostExtensions.add(ExtensionIdentifier.toKey(extensionId))); @@ -165,8 +169,8 @@ export class ExtHostExtensionService implements IExtHostExtensionService, ExtHos private async _initialize(): Promise { try { - // initialize API - const extensionApiFactory = this._instaService.invokeFunction(createApiFactory, this._storage); + // initialize API and register actors + const extensionApiFactory = this._instaService.invokeFunction(createApiFactoryAndRegisterActors); // Register Download command this._instaService.createInstance(ExtHostDownloadService); From f9a6e04701600b385a536ae9a46af3afb063bdfa Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 8 Aug 2019 15:08:51 +0200 Subject: [PATCH 360/861] 1337 ES3000 --- build/azure-pipelines/upload-sourcemaps.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/azure-pipelines/upload-sourcemaps.js b/build/azure-pipelines/upload-sourcemaps.js index 8288129852d..b70335efe5b 100644 --- a/build/azure-pipelines/upload-sourcemaps.js +++ b/build/azure-pipelines/upload-sourcemaps.js @@ -14,7 +14,7 @@ const root = path.dirname(path.dirname(__dirname)); const commit = util.getVersion(root); // optionally allow to pass in explicit base/maps to upload -const [base, maps] = process.argv.slice(2); +const [, , base, maps] = process.argv; const fetch = function (base, maps = `${base}/**/*.map`) { return vfs.src(maps, { base }) From 1cb73a38a79e1d1b64fae056e586bf9643b02a9c Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 8 Aug 2019 15:12:24 +0200 Subject: [PATCH 361/861] Fixes #77935 --- src/vs/editor/common/config/editorOptions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 7ff1b4a5d31..38d27f4d44b 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -2200,7 +2200,7 @@ export class InternalEditorOptionsFactory { stopRenderingLineAfter: opts.viewInfo.stopRenderingLineAfter, renderWhitespace: (accessibilityIsOn ? 'none' : opts.viewInfo.renderWhitespace), // DISABLED WHEN SCREEN READER IS ATTACHED renderControlCharacters: (accessibilityIsOn ? false : opts.viewInfo.renderControlCharacters), // DISABLED WHEN SCREEN READER IS ATTACHED - fontLigatures: (accessibilityIsOn ? false : opts.viewInfo.fontLigatures), // DISABLED WHEN SCREEN READER IS ATTACHED + fontLigatures: opts.viewInfo.fontLigatures, renderIndentGuides: (accessibilityIsOn ? false : opts.viewInfo.renderIndentGuides), // DISABLED WHEN SCREEN READER IS ATTACHED highlightActiveIndentGuide: opts.viewInfo.highlightActiveIndentGuide, renderLineHighlight: opts.viewInfo.renderLineHighlight, From f084f2c7932d9f5ba877c6f60c76379bfb8e5336 Mon Sep 17 00:00:00 2001 From: Yisrael Veller <34338840+YisraelV@users.noreply.github.com> Date: Thu, 8 Aug 2019 16:47:15 +0300 Subject: [PATCH 362/861] Reuse never show again logic - work in progress (#73968) * Support never show again option in notification service * in notify put never show again as secondary * Allow customization of whether never show again is shown as secondary or primary * put never show again inside notification object * feedback * feedback --- build/lib/i18n.resources.json | 4 ++ .../notification/common/notification.ts | 22 +++++++ .../browser/largeFileOptimizations.ts | 17 +----- .../common/notificationService.ts | 61 ++++++++++++++++++- 4 files changed, 85 insertions(+), 19 deletions(-) diff --git a/build/lib/i18n.resources.json b/build/lib/i18n.resources.json index 32b0e6fb4c7..570d97669c7 100644 --- a/build/lib/i18n.resources.json +++ b/build/lib/i18n.resources.json @@ -269,6 +269,10 @@ { "name": "vs/workbench/services/preferences", "project": "vscode-preferences" + }, + { + "name": "vs/workbench/services/notification", + "project": "vscode-workbench" } ] } diff --git a/src/vs/platform/notification/common/notification.ts b/src/vs/platform/notification/common/notification.ts index 173b575822e..7c1b6dd5f56 100644 --- a/src/vs/platform/notification/common/notification.ts +++ b/src/vs/platform/notification/common/notification.ts @@ -29,6 +29,11 @@ export interface INotificationProperties { * catch some attention. */ silent?: boolean; + + /** + * Add a "never show again" action. If user selects the action, the notification will not appear again. + */ + neverShowAgainOptions?: INeverShowAgainOptions; } export interface INotification extends INotificationProperties { @@ -173,6 +178,23 @@ export interface IPromptOptions extends INotificationProperties { onCancel?: () => void; } + +export interface INeverShowAgainOptions { + /** + * Sending prompt id automatically adds a "never show again" action to the prompt. + * If user picks this option, future calls to 'prompt' with the same prompt id will be ignored. + * The id is used to persist the selection to storage + */ + id: string; + + /** + * + * Primary: The never show again action will show up as a button on the notificaion. + * Secondary The never show again action will show up under the gear icon. + */ + isSecondary?: boolean; +} + export interface IStatusMessageOptions { /** diff --git a/src/vs/workbench/contrib/codeEditor/browser/largeFileOptimizations.ts b/src/vs/workbench/contrib/codeEditor/browser/largeFileOptimizations.ts index 17369ff0b6c..4b635d33772 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/largeFileOptimizations.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/largeFileOptimizations.ts @@ -11,7 +11,6 @@ import { registerEditorContribution } from 'vs/editor/browser/editorExtensions'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; -import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; /** * Shows a message when opening a large file which has been memory optimized (and features disabled). @@ -20,26 +19,19 @@ export class LargeFileOptimizationsWarner extends Disposable implements IEditorC private static readonly ID = 'editor.contrib.largeFileOptimizationsWarner'; - private _isDisabled: boolean; - constructor( private readonly _editor: ICodeEditor, @INotificationService private readonly _notificationService: INotificationService, @IConfigurationService private readonly _configurationService: IConfigurationService, - @IStorageService private readonly _storageService: IStorageService, ) { super(); - this._isDisabled = Boolean(this._storageService.getBoolean('editor.neverPromptForLargeFiles', StorageScope.GLOBAL, false)); this._register(this._editor.onDidChangeModel((e) => { const model = this._editor.getModel(); if (!model) { return; } - if (this._isDisabled) { - return; - } if (model.isTooLargeForTokenization()) { const message = nls.localize( @@ -54,13 +46,6 @@ export class LargeFileOptimizationsWarner extends Disposable implements IEditorC ); this._notificationService.prompt(Severity.Info, message, [ - { - label: nls.localize('dontShowAgain', "Don't Show Again"), - run: () => { - this._isDisabled = true; - this._storageService.store('editor.neverPromptForLargeFiles', true, StorageScope.GLOBAL); - } - }, { label: nls.localize('removeOptimizations', "Forcefully enable features"), run: () => { @@ -71,7 +56,7 @@ export class LargeFileOptimizationsWarner extends Disposable implements IEditorC }); } } - ]); + ], { neverShowAgainOptions: { id: 'editor.contrib.largeFileOptimizationsWarner' } }); } })); } diff --git a/src/vs/workbench/services/notification/common/notificationService.ts b/src/vs/workbench/services/notification/common/notificationService.ts index 5db9ec24347..c0b286d0ea3 100644 --- a/src/vs/workbench/services/notification/common/notificationService.ts +++ b/src/vs/workbench/services/notification/common/notificationService.ts @@ -3,13 +3,15 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { INotificationService, INotification, INotificationHandle, Severity, NotificationMessage, INotificationActions, IPromptChoice, IPromptOptions, IStatusMessageOptions } from 'vs/platform/notification/common/notification'; +import { INotificationService, INotification, INotificationHandle, Severity, NotificationMessage, INotificationActions, IPromptChoice, IPromptOptions, IStatusMessageOptions, NoOpNotification } from 'vs/platform/notification/common/notification'; import { INotificationsModel, NotificationsModel, ChoiceAction } from 'vs/workbench/common/notifications'; import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; import { Event } from 'vs/base/common/event'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; -import { IAction } from 'vs/base/common/actions'; +import { IAction, Action } from 'vs/base/common/actions'; +import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; +import * as nls from 'vs/nls'; export class NotificationService extends Disposable implements INotificationService { @@ -21,6 +23,10 @@ export class NotificationService extends Disposable implements INotificationServ return this._model; } + constructor(@IStorageService private readonly storageService: IStorageService) { + super(); + } + info(message: NotificationMessage | NotificationMessage[]): void { if (Array.isArray(message)) { message.forEach(m => this.info(m)); @@ -52,12 +58,61 @@ export class NotificationService extends Disposable implements INotificationServ } notify(notification: INotification): INotificationHandle { - return this.model.addNotification(notification); + + let handle: INotificationHandle; + if (notification.neverShowAgainOptions) { + const id = notification.neverShowAgainOptions.id; + if (!!this.storageService.get(id, StorageScope.GLOBAL)) { + return new NoOpNotification(); + } + + const neverShowAction = new Action( + 'workbench.dialog.choice.neverShowAgain', + nls.localize('neverShowAgain', "Don't Show Again"), + undefined, true, () => { + handle.close(); + this.storageService.store(id, true, StorageScope.GLOBAL); + return Promise.resolve(); + }); + + notification.actions = notification.actions || {}; + if (notification.neverShowAgainOptions.isSecondary) { + notification.actions.secondary = notification.actions.secondary || []; + notification.actions.secondary = [...notification.actions.secondary, neverShowAction]; + } + else { + notification.actions.primary = notification.actions.primary || []; + notification.actions.primary = [neverShowAction, ...notification.actions.primary]; + } + } + + handle = this.model.addNotification(notification); + return handle; } prompt(severity: Severity, message: string, choices: IPromptChoice[], options?: IPromptOptions): INotificationHandle { const toDispose = new DisposableStore(); + + if (options && options.neverShowAgainOptions) { + const id = options.neverShowAgainOptions.id; + if (!!this.storageService.get(id, StorageScope.GLOBAL)) { + return new NoOpNotification(); + } + + const neverShowAgainChoice = { + label: nls.localize('neverShowAgain', "Don't Show Again"), + run: () => this.storageService.store(id, true, StorageScope.GLOBAL), + isSecondary: options.neverShowAgainOptions.isSecondary + }; + if (options.neverShowAgainOptions.isSecondary) { + choices = [...choices, neverShowAgainChoice]; + } + else { + choices = [neverShowAgainChoice, ...choices]; + } + } + let choiceClicked = false; let handle: INotificationHandle; From 1856b26bd680cf4a4e8242cdf34ffc7cf9c66996 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 8 Aug 2019 15:49:23 +0200 Subject: [PATCH 363/861] :lipstick: notifications --- .../notification/common/notification.ts | 38 +++++----- .../browser/largeFileOptimizations.ts | 2 +- .../common/notificationService.ts | 73 ++++++++++++------- 3 files changed, 65 insertions(+), 48 deletions(-) diff --git a/src/vs/platform/notification/common/notification.ts b/src/vs/platform/notification/common/notification.ts index 7c1b6dd5f56..2582047934e 100644 --- a/src/vs/platform/notification/common/notification.ts +++ b/src/vs/platform/notification/common/notification.ts @@ -31,9 +31,24 @@ export interface INotificationProperties { silent?: boolean; /** - * Add a "never show again" action. If user selects the action, the notification will not appear again. + * Adds an action to never show the notification again. The choice will be persisted + * such as future requests will not cause the notification to show again. */ - neverShowAgainOptions?: INeverShowAgainOptions; + neverShowAgain?: INeverShowAgainOptions; +} + +export interface INeverShowAgainOptions { + + /** + * The id is used to persist the selection of not showing the notification again. + */ + id: string; + + /** + * By default the action will show up as primary action. Setting this to true will + * make it a secondary action instead. + */ + isSecondary?: boolean; } export interface INotification extends INotificationProperties { @@ -178,23 +193,6 @@ export interface IPromptOptions extends INotificationProperties { onCancel?: () => void; } - -export interface INeverShowAgainOptions { - /** - * Sending prompt id automatically adds a "never show again" action to the prompt. - * If user picks this option, future calls to 'prompt' with the same prompt id will be ignored. - * The id is used to persist the selection to storage - */ - id: string; - - /** - * - * Primary: The never show again action will show up as a button on the notificaion. - * Secondary The never show again action will show up under the gear icon. - */ - isSecondary?: boolean; -} - export interface IStatusMessageOptions { /** @@ -292,4 +290,4 @@ export class NoOpProgress implements INotificationProgress { done(): void { } total(value: number): void { } worked(value: number): void { } -} \ No newline at end of file +} diff --git a/src/vs/workbench/contrib/codeEditor/browser/largeFileOptimizations.ts b/src/vs/workbench/contrib/codeEditor/browser/largeFileOptimizations.ts index 4b635d33772..551c3e4b86a 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/largeFileOptimizations.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/largeFileOptimizations.ts @@ -56,7 +56,7 @@ export class LargeFileOptimizationsWarner extends Disposable implements IEditorC }); } } - ], { neverShowAgainOptions: { id: 'editor.contrib.largeFileOptimizationsWarner' } }); + ], { neverShowAgain: { id: 'editor.contrib.largeFileOptimizationsWarner' } }); } })); } diff --git a/src/vs/workbench/services/notification/common/notificationService.ts b/src/vs/workbench/services/notification/common/notificationService.ts index c0b286d0ea3..81ba282a7c3 100644 --- a/src/vs/workbench/services/notification/common/notificationService.ts +++ b/src/vs/workbench/services/notification/common/notificationService.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import * as nls from 'vs/nls'; import { INotificationService, INotification, INotificationHandle, Severity, NotificationMessage, INotificationActions, IPromptChoice, IPromptOptions, IStatusMessageOptions, NoOpNotification } from 'vs/platform/notification/common/notification'; import { INotificationsModel, NotificationsModel, ChoiceAction } from 'vs/workbench/common/notifications'; import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; @@ -11,7 +12,6 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { IAction, Action } from 'vs/base/common/actions'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; -import * as nls from 'vs/nls'; export class NotificationService extends Disposable implements INotificationService { @@ -58,58 +58,77 @@ export class NotificationService extends Disposable implements INotificationServ } notify(notification: INotification): INotificationHandle { + const toDispose = new DisposableStore(); + // Handle neverShowAgain option accordingly let handle: INotificationHandle; - if (notification.neverShowAgainOptions) { - const id = notification.neverShowAgainOptions.id; - if (!!this.storageService.get(id, StorageScope.GLOBAL)) { + if (notification.neverShowAgain) { + + // If the user already picked to not show the notification + // again, we return with a no-op notification here + const id = notification.neverShowAgain.id; + if (this.storageService.getBoolean(id, StorageScope.GLOBAL)) { return new NoOpNotification(); } - const neverShowAction = new Action( - 'workbench.dialog.choice.neverShowAgain', + const neverShowAgainAction = toDispose.add(new Action( + 'workbench.notification.neverShowAgain', nls.localize('neverShowAgain', "Don't Show Again"), undefined, true, () => { - handle.close(); - this.storageService.store(id, true, StorageScope.GLOBAL); - return Promise.resolve(); - }); - notification.actions = notification.actions || {}; - if (notification.neverShowAgainOptions.isSecondary) { - notification.actions.secondary = notification.actions.secondary || []; - notification.actions.secondary = [...notification.actions.secondary, neverShowAction]; - } - else { - notification.actions.primary = notification.actions.primary || []; - notification.actions.primary = [neverShowAction, ...notification.actions.primary]; + // Close notification + handle.close(); + + // Remember choice + this.storageService.store(id, true, StorageScope.GLOBAL); + + return Promise.resolve(); + })); + + // Insert as primary or secondary action + const actions = notification.actions || { primary: [], secondary: [] }; + if (!notification.neverShowAgain.isSecondary) { + actions.primary = [neverShowAgainAction, ...(actions.primary || [])]; // action comes first + } else { + actions.secondary = [...(actions.secondary || []), neverShowAgainAction]; // actions comes last } + + notification.actions = actions; } + // Show notification handle = this.model.addNotification(notification); + + // Cleanup when notification gets disposed + Event.once(handle.onDidClose)(() => toDispose.dispose()); + return handle; } prompt(severity: Severity, message: string, choices: IPromptChoice[], options?: IPromptOptions): INotificationHandle { const toDispose = new DisposableStore(); + // Handle neverShowAgain option accordingly + if (options && options.neverShowAgain) { - if (options && options.neverShowAgainOptions) { - const id = options.neverShowAgainOptions.id; - if (!!this.storageService.get(id, StorageScope.GLOBAL)) { + // If the user already picked to not show the notification + // again, we return with a no-op notification here + const id = options.neverShowAgain.id; + if (this.storageService.getBoolean(id, StorageScope.GLOBAL)) { return new NoOpNotification(); } const neverShowAgainChoice = { label: nls.localize('neverShowAgain', "Don't Show Again"), run: () => this.storageService.store(id, true, StorageScope.GLOBAL), - isSecondary: options.neverShowAgainOptions.isSecondary + isSecondary: options.neverShowAgain.isSecondary }; - if (options.neverShowAgainOptions.isSecondary) { - choices = [...choices, neverShowAgainChoice]; - } - else { - choices = [neverShowAgainChoice, ...choices]; + + // Insert as primary or secondary action + if (!options.neverShowAgain.isSecondary) { + choices = [neverShowAgainChoice, ...choices]; // action comes first + } else { + choices = [...choices, neverShowAgainChoice]; // actions comes last } } From a912dff93216f1dd9519ac1426691273cc50d472 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 8 Aug 2019 16:18:56 +0200 Subject: [PATCH 364/861] :lipstick: layout classes --- src/vs/workbench/browser/layout.ts | 39 ++++++++++++++++++++------- src/vs/workbench/browser/workbench.ts | 6 +---- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index dcafef2d467..d928b4a6c6c 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -35,6 +35,7 @@ import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar'; import { IActivityBarService } from 'vs/workbench/services/activityBar/browser/activityBarService'; import { IFileService } from 'vs/platform/files/common/files'; import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; +import { coalesce } from 'vs/base/common/arrays'; enum Settings { MENUBAR_VISIBLE = 'window.menuBarVisibility', @@ -64,6 +65,14 @@ enum Storage { GRID_HEIGHT = 'workbench.grid.height' } +enum Classes { + SIDEBAR_HIDDEN = 'nosidebar', + EDITOR_HIDDEN = 'noeditorarea', + PANEL_HIDDEN = 'nopanel', + STATUSBAR_HIDDEN = 'nostatusbar', + FULLSCREEN = 'fullscreen' +} + export abstract class Layout extends Disposable implements IWorkbenchLayoutService { _serviceBrand!: ServiceIdentifier; @@ -251,9 +260,9 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi // Apply as CSS class if (this.state.fullscreen) { - addClass(this.container, 'fullscreen'); + addClass(this.container, Classes.FULLSCREEN); } else { - removeClass(this.container, 'fullscreen'); + removeClass(this.container, Classes.FULLSCREEN); if (this.state.zenMode.transitionedToFullScreen && this.state.zenMode.active) { this.toggleZenMode(); @@ -702,9 +711,9 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi // Adjust CSS if (hidden) { - addClass(this.container, 'nostatusbar'); + addClass(this.container, Classes.STATUSBAR_HIDDEN); } else { - removeClass(this.container, 'nostatusbar'); + removeClass(this.container, Classes.STATUSBAR_HIDDEN); } // Propagate to grid @@ -936,9 +945,9 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi // Adjust CSS if (hidden) { - addClass(this.container, 'noeditorarea'); + addClass(this.container, Classes.EDITOR_HIDDEN); } else { - removeClass(this.container, 'noeditorarea'); + removeClass(this.container, Classes.EDITOR_HIDDEN); } // Propagate to grid @@ -950,14 +959,24 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi } } + getLayoutClasses(): string[] { + return coalesce([ + this.state.sideBar.hidden ? Classes.SIDEBAR_HIDDEN : undefined, + this.state.editor.hidden ? Classes.EDITOR_HIDDEN : undefined, + this.state.panel.hidden ? Classes.PANEL_HIDDEN : undefined, + this.state.statusBar.hidden ? Classes.STATUSBAR_HIDDEN : undefined, + this.state.fullscreen ? Classes.FULLSCREEN : undefined + ]); + } + setSideBarHidden(hidden: boolean, skipLayout?: boolean): void { this.state.sideBar.hidden = hidden; // Adjust CSS if (hidden) { - addClass(this.container, 'nosidebar'); + addClass(this.container, Classes.SIDEBAR_HIDDEN); } else { - removeClass(this.container, 'nosidebar'); + removeClass(this.container, Classes.SIDEBAR_HIDDEN); } // If sidebar becomes hidden, also hide the current active Viewlet if any @@ -1010,9 +1029,9 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi // Adjust CSS if (hidden) { - addClass(this.container, 'nopanel'); + addClass(this.container, Classes.PANEL_HIDDEN); } else { - removeClass(this.container, 'nopanel'); + removeClass(this.container, Classes.PANEL_HIDDEN); } // If panel part becomes hidden, also hide the current active panel if any diff --git a/src/vs/workbench/browser/workbench.ts b/src/vs/workbench/browser/workbench.ts index f2e5d880dc8..014e2cb0686 100644 --- a/src/vs/workbench/browser/workbench.ts +++ b/src/vs/workbench/browser/workbench.ts @@ -298,11 +298,7 @@ export class Workbench extends Layout { 'monaco-workbench', platformClass, isWeb ? 'web' : undefined, - this.state.sideBar.hidden ? 'nosidebar' : undefined, - this.state.editor.hidden ? 'noeditorarea' : undefined, - this.state.panel.hidden ? 'nopanel' : undefined, - this.state.statusBar.hidden ? 'nostatusbar' : undefined, - this.state.fullscreen ? 'fullscreen' : undefined + ...this.getLayoutClasses() ]); addClasses(this.container, ...workbenchClasses); From f464c1de45e0092747ae8057696d493a21495c07 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 8 Aug 2019 16:24:55 +0200 Subject: [PATCH 365/861] cleanup scm input scrollbar --- src/vs/base/browser/ui/inputbox/inputBox.css | 9 ++- src/vs/base/browser/ui/inputbox/inputBox.ts | 74 +++++++++++-------- .../contrib/scm/browser/scmViewlet.ts | 36 +-------- 3 files changed, 54 insertions(+), 65 deletions(-) diff --git a/src/vs/base/browser/ui/inputbox/inputBox.css b/src/vs/base/browser/ui/inputbox/inputBox.css index 294ca475662..dc1240dfbc5 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.css +++ b/src/vs/base/browser/ui/inputbox/inputBox.css @@ -58,7 +58,12 @@ .monaco-inputbox > .wrapper > textarea.input { display: block; - overflow: hidden; + -ms-overflow-style: none; /* IE 10+ */ + overflow: -moz-scrollbars-none; /* Firefox */ +} + +.monaco-inputbox > .wrapper > textarea.input::-webkit-scrollbar { + display: none; } .monaco-inputbox > .wrapper > .mirror { @@ -116,4 +121,4 @@ background-repeat: no-repeat; width: 16px; height: 16px; -} \ No newline at end of file +} diff --git a/src/vs/base/browser/ui/inputbox/inputBox.ts b/src/vs/base/browser/ui/inputbox/inputBox.ts index 1313d1bc7cc..59d0c9900b9 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.ts +++ b/src/vs/base/browser/ui/inputbox/inputBox.ts @@ -19,6 +19,9 @@ import { Color } from 'vs/base/common/color'; import { mixin } from 'vs/base/common/objects'; import { HistoryNavigator } from 'vs/base/common/history'; import { IHistoryNavigationWidget } from 'vs/base/browser/history'; +import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; +import { ScrollbarVisibility } from 'vs/base/common/scrollable'; +import { domEvent } from 'vs/base/browser/event'; const $ = dom.$; @@ -28,6 +31,7 @@ export interface IInputOptions extends IInputBoxStyles { readonly type?: string; readonly validationOptions?: IInputValidationOptions; readonly flexibleHeight?: boolean; + readonly flexibleMaxHeight?: number; readonly actions?: ReadonlyArray; } @@ -86,7 +90,6 @@ export class InputBox extends Widget { private contextViewProvider?: IContextViewProvider; element: HTMLElement; private input: HTMLInputElement; - private mirror: HTMLElement | undefined; private actionbar?: ActionBar; private options: IInputOptions; private message: IMessage | null; @@ -94,8 +97,12 @@ export class InputBox extends Widget { private ariaLabel: string; private validation?: IInputValidator; private state: 'idle' | 'open' | 'closed' = 'idle'; - private cachedHeight: number | null; - private cachedScrollTop: number | null; + + private mirror: HTMLElement | undefined; + private cachedHeight: number | undefined; + private cachedContentHeight: number | undefined; + private maxHeight: number = Number.POSITIVE_INFINITY; + private scrollableElement: ScrollableElement | undefined; private inputBackground?: Color; private inputForeground?: Color; @@ -117,9 +124,6 @@ export class InputBox extends Widget { private _onDidHeightChange = this._register(new Emitter()); public readonly onDidHeightChange: Event = this._onDidHeightChange.event; - private _onDidScrollTopChange = this._register(new Emitter()); - public readonly onDidScrollTopChange: Event = this._onDidScrollTopChange.event; - constructor(container: HTMLElement, contextViewProvider: IContextViewProvider | undefined, options?: IInputOptions) { super(); @@ -127,7 +131,6 @@ export class InputBox extends Widget { this.options = options || Object.create(null); mixin(this.options, defaultOpts, false); this.message = null; - this.cachedHeight = null; this.placeholder = this.options.placeholder || ''; this.ariaLabel = this.options.ariaLabel || ''; @@ -163,8 +166,26 @@ export class InputBox extends Widget { this.onblur(this.input, () => dom.removeClass(this.element, 'synthetic-focus')); if (this.options.flexibleHeight) { + this.maxHeight = typeof this.options.flexibleMaxHeight === 'number' ? this.options.flexibleMaxHeight : Number.POSITIVE_INFINITY; + this.mirror = dom.append(wrapper, $('div.mirror')); this.mirror.innerHTML = ' '; + + this.scrollableElement = new ScrollableElement(this.element, { vertical: ScrollbarVisibility.Auto }); + dom.append(container, this.scrollableElement.getDomNode()); + this._register(this.scrollableElement); + + // from ScrollableElement to DOM + this._register(this.scrollableElement.onScroll(e => this.input.scrollTop = e.scrollTop)); + + const onSelectionChange = Event.filter(domEvent(document, 'selectionchange'), () => { + const selection = document.getSelection(); + return !!selection && selection.anchorNode === wrapper; + }); + + // from DOM to ScrollableElement + this._register(onSelectionChange(this.updateScrollDimensions, this)); + this._register(this.onDidHeightChange(this.updateScrollDimensions, this)); } else { this.input.type = this.options.type || 'text'; this.input.setAttribute('wrap', 'off'); @@ -181,7 +202,6 @@ export class InputBox extends Widget { this.oninput(this.input, () => this.onValueChange()); this.onblur(this.input, () => this.onBlur()); this.onfocus(this.input, () => this.onFocus()); - this.onkeydown(this.input, () => this.checkScrollTop()); // Add placeholder shim for IE because IE decides to hide the placeholder on focus (we dont want that!) if (this.placeholder && Bal.isIE) { @@ -216,14 +236,6 @@ export class InputBox extends Widget { this._showMessage(); } - private checkScrollTop(): void { - const scrollTop = this.element.scrollTop; - if (scrollTop !== this.cachedScrollTop) { - this.cachedScrollTop = scrollTop; - this._onDidScrollTopChange.fire(this.cachedScrollTop); - } - } - public setPlaceHolder(placeHolder: string): void { if (this.input) { this.input.setAttribute('placeholder', placeHolder); @@ -263,7 +275,7 @@ export class InputBox extends Widget { } public get height(): number { - return this.cachedHeight === null ? dom.getTotalHeight(this.element) : this.cachedHeight; + return typeof this.cachedHeight === 'number' ? this.cachedHeight : dom.getTotalHeight(this.element); } public focus(): void { @@ -314,8 +326,17 @@ export class InputBox extends Widget { } } - public get scrollTop(): number { - return this.cachedScrollTop === null ? this.element.scrollTop : this.cachedScrollTop; + private updateScrollDimensions(): void { + if (typeof this.cachedContentHeight !== 'number' || typeof this.cachedHeight !== 'number') { + return; + } + + const scrollHeight = this.cachedContentHeight; + const height = this.cachedHeight; + const scrollTop = this.input.scrollTop; + + this.scrollableElement!.setScrollDimensions({ scrollHeight, height }); + this.scrollableElement!.setScrollPosition({ scrollTop }); } public showMessage(message: IMessage, force?: boolean): void { @@ -527,18 +548,13 @@ export class InputBox extends Widget { return; } - const previousHeight = this.cachedHeight; - this.cachedHeight = dom.getTotalHeight(this.mirror); + const previousHeight = this.cachedContentHeight; + this.cachedContentHeight = dom.getTotalHeight(this.mirror); - if (previousHeight !== this.cachedHeight) { + if (previousHeight !== this.cachedContentHeight) { + this.cachedHeight = Math.min(this.cachedContentHeight, this.maxHeight); this.input.style.height = this.cachedHeight + 'px'; - this._onDidHeightChange.fire(this.cachedHeight); - - if (previousHeight) { - const scrollTop = this.cachedHeight - previousHeight + this.scrollTop; - this.cachedScrollTop = scrollTop; - this._onDidScrollTopChange.fire(this.cachedScrollTop); - } + this._onDidHeightChange.fire(this.cachedContentHeight); } } diff --git a/src/vs/workbench/contrib/scm/browser/scmViewlet.ts b/src/vs/workbench/contrib/scm/browser/scmViewlet.ts index bd6974358c7..5c596e9ef7d 100644 --- a/src/vs/workbench/contrib/scm/browser/scmViewlet.ts +++ b/src/vs/workbench/contrib/scm/browser/scmViewlet.ts @@ -49,8 +49,6 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IViewsRegistry, IViewDescriptor, Extensions } from 'vs/workbench/common/views'; import { Registry } from 'vs/platform/registry/common/platform'; -import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; -import { ScrollbarVisibility } from 'vs/base/common/scrollable'; export interface ISpliceEvent { index: number; @@ -713,7 +711,6 @@ export class RepositoryPanel extends ViewletPanel { private cachedScrollTop: number | undefined = undefined; private inputBoxContainer: HTMLElement; private inputBox: InputBox; - private scrollableElement: ScrollableElement; private listContainer: HTMLElement; private list: List; private listLabels: ResourceLabels; @@ -800,38 +797,13 @@ export class RepositoryPanel extends ViewletPanel { const triggerValidation = () => validationDelayer.trigger(validate); - this.inputBox = new InputBox(this.inputBoxContainer, this.contextViewService, { flexibleHeight: true }); + this.inputBox = new InputBox(this.inputBoxContainer, this.contextViewService, { flexibleHeight: true, flexibleMaxHeight: 134 }); this.inputBox.setEnabled(this.isBodyVisible()); this._register(attachInputBoxStyler(this.inputBox, this.themeService)); this._register(this.inputBox); this._register(this.inputBox.onDidChange(triggerValidation, null)); - this.scrollableElement = new ScrollableElement(this.inputBox.element, { - vertical: ScrollbarVisibility.Visible - }); - - this.disposables.push(this.scrollableElement); - - this.scrollableElement.onScroll((e) => { - this.scrollInput(e.scrollTop); - }); - - append(this.inputBoxContainer, this.scrollableElement.getDomNode()); - - const updateScrollDimensions = () => { - const scrollHeight = this.inputBox.height; - const height = scrollHeight > 134 ? 134 : scrollHeight; - const scrollTop = this.inputBox.scrollTop; - - this.scrollableElement.setScrollDimensions({ scrollHeight: scrollHeight, height: height }); - this.scrollableElement.setScrollPosition({ scrollTop: scrollTop }); - }; - - this.inputBox.element.style.maxHeight = '134px'; - this.inputBox.onDidHeightChange(updateScrollDimensions, null, this.disposables); - this.inputBox.onDidScrollTopChange(updateScrollDimensions, null, this.disposables); - const onKeyUp = domEvent(this.inputBox.inputElement, 'keyup'); const onMouseUp = domEvent(this.inputBox.inputElement, 'mouseup'); this._register(Event.any(onKeyUp, onMouseUp)(triggerValidation, null)); @@ -899,10 +871,6 @@ export class RepositoryPanel extends ViewletPanel { this.onDidChangeBodyVisibility(visible => this.inputBox.setEnabled(visible)); } - private scrollInput(scrollTop: number): void { - this.inputBox.element.scrollTop = scrollTop; - } - private onDidChangeVisibility(visible: boolean): void { if (visible) { const listSplicer = new ResourceGroupSplicer(this.repository.provider.groups, this.list); @@ -924,7 +892,7 @@ export class RepositoryPanel extends ViewletPanel { removeClass(this.inputBoxContainer, 'hidden'); this.inputBox.layout(); - const editorHeight = this.inputBox.height > 134 ? 134 : this.inputBox.height; + const editorHeight = this.inputBox.height; const listHeight = height - (editorHeight + 12 /* margin */); this.listContainer.style.height = `${listHeight}px`; this.list.layout(listHeight, width); From daf581da39aef66dd9dad353b9304ebb3301547e Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 8 Aug 2019 16:30:47 +0200 Subject: [PATCH 366/861] fixes #71258 --- extensions/git/src/git.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 661dc4d0b80..f71c75a250e 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -601,7 +601,7 @@ export function parseGitmodules(raw: string): Submodule[] { } export function parseGitCommit(raw: string): Commit | null { - const match = /^([0-9a-f]{40})\n(.*)\n(.*)\n([^]*)$/m.exec(raw.trim()); + const match = /^([0-9a-f]{40})\n(.*)\n(.*)(\n([^]*))?$/m.exec(raw.trim()); if (!match) { return null; } From 3dc832d088c3a3983ef7e924ca65a3be816d078d Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 8 Aug 2019 07:37:53 -0700 Subject: [PATCH 367/861] Remove unneeded queue from ExtHostPseudoterminal Fixes #78705 --- .../api/node/extHostTerminalService.ts | 28 ++----------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index b4aa39cce9a..fe7c524a423 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -22,7 +22,6 @@ import { ExtHostVariableResolverService } from 'vs/workbench/api/node/extHostDeb import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { getSystemShell, detectAvailableShells } from 'vs/workbench/contrib/terminal/node/terminal'; import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; -import { IDisposable } from 'vs/base/common/lifecycle'; export class BaseExtHostTerminal { public _id: number | undefined; @@ -687,9 +686,6 @@ class ApiRequest { } class ExtHostPseudoterminal implements ITerminalChildProcess { - private _queuedEvents: (IQueuedEvent | IQueuedEvent | IQueuedEvent<{ pid: number, cwd: string }> | IQueuedEvent)[] = []; - private _queueDisposables: IDisposable[] | undefined; - private readonly _onProcessData = new Emitter(); public readonly onProcessData: Event = this._onProcessData.event; private readonly _onProcessExit = new Emitter(); @@ -701,18 +697,7 @@ class ExtHostPseudoterminal implements ITerminalChildProcess { private readonly _onProcessOverrideDimensions = new Emitter(); public get onProcessOverrideDimensions(): Event { return this._onProcessOverrideDimensions.event; } - constructor( - private readonly _pty: vscode.Pseudoterminal - ) { - this._queueDisposables = []; - this._queueDisposables.push(this._pty.onDidWrite(e => this._queuedEvents.push({ emitter: this._onProcessData, data: e }))); - if (this._pty.onDidClose) { - this._queueDisposables.push(this._pty.onDidClose(e => this._queuedEvents.push({ emitter: this._onProcessExit, data: 0 }))); - } - if (this._pty.onDidOverrideDimensions) { - this._queueDisposables.push(this._pty.onDidOverrideDimensions(e => this._queuedEvents.push({ emitter: this._onProcessOverrideDimensions, data: e ? { cols: e.columns, rows: e.rows } : undefined }))); - } - } + constructor(private readonly _pty: vscode.Pseudoterminal) { } shutdown(): void { this._pty.close(); @@ -743,12 +728,7 @@ class ExtHostPseudoterminal implements ITerminalChildProcess { } startSendingEvents(initialDimensions: ITerminalDimensionsDto | undefined): void { - // Flush all buffered events - this._queuedEvents.forEach(e => (e.emitter.fire)(e.data)); - this._queuedEvents = []; - this._queueDisposables = undefined; - - // Attach the real listeners + // Attach the listeners this._pty.onDidWrite(e => this._onProcessData.fire(e)); if (this._pty.onDidClose) { this._pty.onDidClose(e => this._onProcessExit.fire(0)); @@ -761,7 +741,3 @@ class ExtHostPseudoterminal implements ITerminalChildProcess { } } -interface IQueuedEvent { - emitter: Emitter; - data: T; -} From 2c189f373f10bf8e9e6139690dd588876314f2d4 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 8 Aug 2019 16:38:33 +0200 Subject: [PATCH 368/861] fix capture group --- extensions/git/src/git.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index f71c75a250e..701ceded1c9 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -607,7 +607,7 @@ export function parseGitCommit(raw: string): Commit | null { } const parents = match[3] ? match[3].split(' ') : []; - return { hash: match[1], message: match[4], parents, authorEmail: match[2] }; + return { hash: match[1], message: match[5], parents, authorEmail: match[2] }; } interface LsTreeElement { From 079aef1ec5549171717decf30a9cb3e5b8aeee18 Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 8 Aug 2019 16:44:32 +0200 Subject: [PATCH 369/861] filesExplorer.openFilePreserveFocus fixes #28710 --- .../files/browser/fileActions.contribution.ts | 10 +++++++++- .../contrib/files/browser/fileActions.ts | 16 ++++++++++++++++ .../contrib/files/browser/fileCommands.ts | 2 +- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts b/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts index 8b29304e715..40a0ec28bf2 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts @@ -5,7 +5,7 @@ import * as nls from 'vs/nls'; import { Registry } from 'vs/platform/registry/common/platform'; -import { ToggleAutoSaveAction, GlobalNewUntitledFileAction, ShowOpenedFileInNewWindow, FocusFilesExplorer, GlobalCompareResourcesAction, SaveAllAction, ShowActiveFileInExplorer, CollapseExplorerView, RefreshExplorerView, CompareWithClipboardAction, NEW_FILE_COMMAND_ID, NEW_FILE_LABEL, NEW_FOLDER_COMMAND_ID, NEW_FOLDER_LABEL, TRIGGER_RENAME_LABEL, MOVE_FILE_TO_TRASH_LABEL, COPY_FILE_LABEL, PASTE_FILE_LABEL, FileCopiedContext, renameHandler, moveFileToTrashHandler, copyFileHandler, pasteFileHandler, deleteFileHandler, cutFileHandler, DOWNLOAD_COMMAND_ID } from 'vs/workbench/contrib/files/browser/fileActions'; +import { ToggleAutoSaveAction, GlobalNewUntitledFileAction, ShowOpenedFileInNewWindow, FocusFilesExplorer, GlobalCompareResourcesAction, SaveAllAction, ShowActiveFileInExplorer, CollapseExplorerView, RefreshExplorerView, CompareWithClipboardAction, NEW_FILE_COMMAND_ID, NEW_FILE_LABEL, NEW_FOLDER_COMMAND_ID, NEW_FOLDER_LABEL, TRIGGER_RENAME_LABEL, MOVE_FILE_TO_TRASH_LABEL, COPY_FILE_LABEL, PASTE_FILE_LABEL, FileCopiedContext, renameHandler, moveFileToTrashHandler, copyFileHandler, pasteFileHandler, deleteFileHandler, cutFileHandler, DOWNLOAD_COMMAND_ID, openFilePreserveFocusHandler } from 'vs/workbench/contrib/files/browser/fileActions'; import { revertLocalChangesCommand, acceptLocalChangesCommand, CONFLICT_RESOLUTION_CONTEXT } from 'vs/workbench/contrib/files/browser/saveErrorHandler'; import { SyncActionDescriptor, MenuId, MenuRegistry, ILocalizedString } from 'vs/platform/actions/common/actions'; import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; @@ -186,6 +186,14 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ } }); +KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: 'filesExplorer.openFilePreserveFocus', + weight: KeybindingWeight.WorkbenchContrib + explorerCommandsWeightBonus, + when: ContextKeyExpr.and(FilesExplorerFocusCondition, ExplorerFolderContext.toNegated()), + primary: KeyCode.Space, + handler: openFilePreserveFocusHandler +}); + const copyPathCommand = { id: COPY_PATH_COMMAND_ID, title: nls.localize('copyPath', "Copy Path") diff --git a/src/vs/workbench/contrib/files/browser/fileActions.ts b/src/vs/workbench/contrib/files/browser/fileActions.ts index 4bde241c886..cb9ac033e43 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.ts @@ -1059,3 +1059,19 @@ export const pasteFileHandler = async (accessor: ServicesAccessor) => { } } }; + +export const openFilePreserveFocusHandler = async (accessor: ServicesAccessor) => { + const listService = accessor.get(IListService); + const editorService = accessor.get(IEditorService); + + if (listService.lastFocusedList) { + const explorerContext = getContext(listService.lastFocusedList); + if (explorerContext.stat) { + const stats = explorerContext.selection.length > 1 ? explorerContext.selection : [explorerContext.stat]; + await editorService.openEditors(stats.filter(s => !s.isDirectory).map(s => ({ + resource: s.resource, + options: { preserveFocus: true } + }))); + } + } +}; diff --git a/src/vs/workbench/contrib/files/browser/fileCommands.ts b/src/vs/workbench/contrib/files/browser/fileCommands.ts index e94990d2390..38835200d54 100644 --- a/src/vs/workbench/contrib/files/browser/fileCommands.ts +++ b/src/vs/workbench/contrib/files/browser/fileCommands.ts @@ -578,7 +578,7 @@ CommandsRegistry.registerCommand({ CommandsRegistry.registerCommand({ id: SAVE_ALL_IN_GROUP_COMMAND_ID, - handler: (accessor, resource: URI | object, editorContext: IEditorCommandsContext) => { + handler: (accessor, _: URI | object, editorContext: IEditorCommandsContext) => { const contexts = getMultiSelectedEditorContexts(editorContext, accessor.get(IListService), accessor.get(IEditorGroupsService)); const editorGroupService = accessor.get(IEditorGroupsService); let saveAllArg: any; From 8e286cc353221d8d46c1a540931f3412dd10f266 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 8 Aug 2019 07:59:29 -0700 Subject: [PATCH 370/861] Only pass conptyInheritCursor for tasks Part of #76548 --- .../workbench/contrib/terminal/browser/terminalInstance.ts | 6 ++++++ src/vs/workbench/contrib/terminal/node/terminalProcess.ts | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 48edebe7c19..9d6decb1a34 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -1130,6 +1130,12 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } } + // HACK: Force initialText to be non-falsy for reused terminals such that the + // conptyInheritCursor flag is passed to the node-pty, this flag can cause a Window to hang + // in Windows 10 1903 so we only want to use it when something is definitely written to the + // terminal. + shell.initialText = ' '; + // Set the new shell launch config this._shellLaunchConfig = shell; // Must be done before calling _createProcess() diff --git a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts index b8ad7fd4c28..2fbc8a25e74 100644 --- a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts +++ b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts @@ -66,7 +66,8 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess cols, rows, experimentalUseConpty: useConpty, - conptyInheritCursor: true + // This option will force conpty to not redraw the whole viewport on launch + conptyInheritCursor: useConpty && !!shellLaunchConfig.initialText }; const cwdVerification = stat(cwd).then(async stat => { From 35cac93b97be6d1a4090ec9d46a3aa75bafb128c Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 8 Aug 2019 17:33:50 +0200 Subject: [PATCH 371/861] list.clear should clear both focus and selection in one go --- src/vs/workbench/browser/actions/listCommands.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/actions/listCommands.ts b/src/vs/workbench/browser/actions/listCommands.ts index 634dcd69599..e7c711e378b 100644 --- a/src/vs/workbench/browser/actions/listCommands.ts +++ b/src/vs/workbench/browser/actions/listCommands.ts @@ -751,7 +751,8 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ if (list.getSelection().length > 0) { list.setSelection([]); - } else if (list.getFocus().length > 0) { + } + if (list.getFocus().length > 0) { list.setFocus([]); } } @@ -763,7 +764,8 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ if (list.getSelection().length > 0) { list.setSelection([], fakeKeyboardEvent); - } else if (list.getFocus().length > 0) { + } + if (list.getFocus().length > 0) { list.setFocus([], fakeKeyboardEvent); } } @@ -774,7 +776,8 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ if (tree.getSelection().length) { tree.clearSelection({ origin: 'keyboard' }); - } else if (tree.getFocus()) { + } + if (tree.getFocus()) { tree.clearFocus({ origin: 'keyboard' }); } } From a02214a6a2be050044137dfaa046ae8ce67a5f6e Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 8 Aug 2019 17:44:41 +0200 Subject: [PATCH 372/861] explorer: do not support octicons fixes #77747 --- src/vs/workbench/contrib/files/browser/views/explorerViewer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index bffa827671f..a069bee3bf9 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -141,7 +141,7 @@ export class FilesRenderer implements ITreeRenderer Date: Thu, 8 Aug 2019 17:59:09 +0200 Subject: [PATCH 373/861] simplify --- .../workbench/browser/actions/listCommands.ts | 24 +++++-------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/browser/actions/listCommands.ts b/src/vs/workbench/browser/actions/listCommands.ts index e7c711e378b..a811aed2a82 100644 --- a/src/vs/workbench/browser/actions/listCommands.ts +++ b/src/vs/workbench/browser/actions/listCommands.ts @@ -749,12 +749,8 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ if (focused instanceof List || focused instanceof PagedList) { const list = focused; - if (list.getSelection().length > 0) { - list.setSelection([]); - } - if (list.getFocus().length > 0) { - list.setFocus([]); - } + list.setSelection([]); + list.setFocus([]); } // ObjectTree @@ -762,24 +758,16 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ const list = focused; const fakeKeyboardEvent = new KeyboardEvent('keydown'); - if (list.getSelection().length > 0) { - list.setSelection([], fakeKeyboardEvent); - } - if (list.getFocus().length > 0) { - list.setFocus([], fakeKeyboardEvent); - } + list.setSelection([], fakeKeyboardEvent); + list.setFocus([], fakeKeyboardEvent); } // Tree else if (focused) { const tree = focused; - if (tree.getSelection().length) { - tree.clearSelection({ origin: 'keyboard' }); - } - if (tree.getFocus()) { - tree.clearFocus({ origin: 'keyboard' }); - } + tree.clearSelection({ origin: 'keyboard' }); + tree.clearFocus({ origin: 'keyboard' }); } } }); From 8ebfa686ec8eafb4b25c7ee37a90bd21b59583dd Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 8 Aug 2019 18:18:18 +0200 Subject: [PATCH 374/861] fix #78715 --- .../workbench/browser/parts/editor/editor.ts | 4 +- .../browser/parts/editor/editorGroupView.ts | 28 +++++++------ .../browser/parts/editor/editorPart.ts | 41 +++++++------------ .../files/browser/views/openEditorsView.ts | 2 +- .../editor/common/editorGroupsService.ts | 10 ++++- .../test/browser/editorGroupsService.test.ts | 31 +++++++++++--- .../workbench/test/workbenchTestServices.ts | 3 +- 7 files changed, 72 insertions(+), 47 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editor.ts b/src/vs/workbench/browser/parts/editor/editor.ts index 1408ae24e0e..f36234ec441 100644 --- a/src/vs/workbench/browser/parts/editor/editor.ts +++ b/src/vs/workbench/browser/parts/editor/editor.ts @@ -118,7 +118,9 @@ export interface IEditorGroupView extends IDisposable, ISerializableView, IEdito isEmpty(): boolean; setActive(isActive: boolean): void; - setLabel(label: string): void; + + notifyIndexChanged(newIndex: number): void; + relayout(): void; } diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 54be65b6f03..6f575845305 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -54,16 +54,16 @@ export class EditorGroupView extends Themable implements IEditorGroupView { //#region factory - static createNew(accessor: IEditorGroupsAccessor, label: string, instantiationService: IInstantiationService): IEditorGroupView { - return instantiationService.createInstance(EditorGroupView, accessor, null, label); + static createNew(accessor: IEditorGroupsAccessor, index: number, instantiationService: IInstantiationService): IEditorGroupView { + return instantiationService.createInstance(EditorGroupView, accessor, null, index); } - static createFromSerialized(serialized: ISerializedEditorGroup, accessor: IEditorGroupsAccessor, label: string, instantiationService: IInstantiationService): IEditorGroupView { - return instantiationService.createInstance(EditorGroupView, accessor, serialized, label); + static createFromSerialized(serialized: ISerializedEditorGroup, accessor: IEditorGroupsAccessor, index: number, instantiationService: IInstantiationService): IEditorGroupView { + return instantiationService.createInstance(EditorGroupView, accessor, serialized, index); } - static createCopy(copyFrom: IEditorGroupView, accessor: IEditorGroupsAccessor, label: string, instantiationService: IInstantiationService): IEditorGroupView { - return instantiationService.createInstance(EditorGroupView, accessor, copyFrom, label); + static createCopy(copyFrom: IEditorGroupView, accessor: IEditorGroupsAccessor, index: number, instantiationService: IInstantiationService): IEditorGroupView { + return instantiationService.createInstance(EditorGroupView, accessor, copyFrom, index); } //#endregion @@ -119,7 +119,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { constructor( private accessor: IEditorGroupsAccessor, from: IEditorGroupView | ISerializedEditorGroup, - private _label: string, + private _index: number, @IInstantiationService private readonly instantiationService: IInstantiationService, @IContextKeyService private readonly contextKeyService: IContextKeyService, @IThemeService themeService: IThemeService, @@ -656,8 +656,12 @@ export class EditorGroupView extends Themable implements IEditorGroupView { return this._group; } + get index(): number { + return this._index; + } + get label(): string { - return this._label; + return localize('groupLabel', "Group {0}", this._index + 1); } get disposed(): boolean { @@ -668,10 +672,10 @@ export class EditorGroupView extends Themable implements IEditorGroupView { return this._whenRestored; } - setLabel(label: string): void { - if (this._label !== label) { - this._label = label; - this._onDidGroupChange.fire({ kind: GroupChangeKind.GROUP_LABEL }); + notifyIndexChanged(newIndex: number): void { + if (this._index !== newIndex) { + this._index = newIndex; + this._onDidGroupChange.fire({ kind: GroupChangeKind.GROUP_INDEX }); } } diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index 0d0ac0c7231..f4b7ce43846 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -24,7 +24,6 @@ import { assign } from 'vs/base/common/objects'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { ISerializedEditorGroup, isSerializedEditorGroup } from 'vs/workbench/common/editor/editorGroup'; import { EditorDropTarget } from 'vs/workbench/browser/parts/editor/editorDropTarget'; -import { localize } from 'vs/nls'; import { Color } from 'vs/base/common/color'; import { CenteredViewLayout } from 'vs/base/browser/ui/centered/centeredViewLayout'; import { onUnexpectedError } from 'vs/base/common/errors'; @@ -424,8 +423,8 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro } }); - // Update labels - this.updateGroupLabels(); + // Notify group index change given layout has changed + this.notifyGroupIndexChange(); // Restore focus as needed if (restoreFocus) { @@ -484,25 +483,22 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro // Event this._onDidAddGroup.fire(newGroupView); - // Update labels - this.updateGroupLabels(); + // Notify group index change given a new group was added + this.notifyGroupIndexChange(); return newGroupView; } private doCreateGroupView(from?: IEditorGroupView | ISerializedEditorGroup | null): IEditorGroupView { - // Label: just use the number of existing groups as label - const label = this.getGroupLabel(this.count + 1); - // Create group view let groupView: IEditorGroupView; if (from instanceof EditorGroupView) { - groupView = EditorGroupView.createCopy(from, this, label, this.instantiationService); + groupView = EditorGroupView.createCopy(from, this, this.count, this.instantiationService); } else if (isSerializedEditorGroup(from)) { - groupView = EditorGroupView.createFromSerialized(from, this, label, this.instantiationService); + groupView = EditorGroupView.createFromSerialized(from, this, this.count, this.instantiationService); } else { - groupView = EditorGroupView.createNew(this, label, this.instantiationService); + groupView = EditorGroupView.createNew(this, this.count, this.instantiationService); } // Keep in map @@ -643,8 +639,8 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro this._activeGroup.focus(); } - // Update labels - this.updateGroupLabels(); + // Notify group index change given a group was removed + this.notifyGroupIndexChange(); // Update container this.updateContainer(); @@ -675,6 +671,9 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro // Event this._onDidMoveGroup.fire(sourceView); + // Notify group index change given a group was moved + this.notifyGroupIndexChange(); + return sourceView; } @@ -784,6 +783,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro centerLayout(active: boolean): void { this.centeredLayoutWidget.activate(active); + this._activeGroup.focus(); } @@ -909,19 +909,8 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro toggleClass(this.container, 'empty', this.isEmpty()); } - private updateGroupLabels(): void { - - // Since our labels are created using the index of the - // group, adding/removing a group might produce gaps. - // So we iterate over all groups and reassign the label - // based on the index. - this.getGroups(GroupsOrder.GRID_APPEARANCE).forEach((group, index) => { - group.setLabel(this.getGroupLabel(index + 1)); - }); - } - - private getGroupLabel(index: number): string { - return localize('groupLabel', "Group {0}", index); + private notifyGroupIndexChange(): void { + this.getGroups(GroupsOrder.GRID_APPEARANCE).forEach((group, index) => group.notifyIndexChanged(index)); } private isEmpty(): boolean { diff --git a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts index 1f570dfa7ce..96be5e2659b 100644 --- a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts +++ b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts @@ -129,7 +129,7 @@ export class OpenEditorsView extends ViewletPanel { const index = this.getIndex(group, e.editor); switch (e.kind) { - case GroupChangeKind.GROUP_LABEL: { + case GroupChangeKind.GROUP_INDEX: { if (this.showGroups) { this.list.splice(index, 1, [group]); } diff --git a/src/vs/workbench/services/editor/common/editorGroupsService.ts b/src/vs/workbench/services/editor/common/editorGroupsService.ts index a9ab498cc98..78e852dd29c 100644 --- a/src/vs/workbench/services/editor/common/editorGroupsService.ts +++ b/src/vs/workbench/services/editor/common/editorGroupsService.ts @@ -343,7 +343,7 @@ export const enum GroupChangeKind { /* Group Changes */ GROUP_ACTIVE, - GROUP_LABEL, + GROUP_INDEX, /* Editor Changes */ EDITOR_OPEN, @@ -374,6 +374,14 @@ export interface IEditorGroup { */ readonly id: GroupIdentifier; + /** + * A number that indicates the position of this group in the visual + * order of groups from left to right and top to bottom. The lowest + * index will likely be top-left while the largest index in most + * cases should be bottom-right, but that depends on the grid. + */ + readonly index: number; + /** * A human readable label for the group. This label can change depending * on the layout of all editor groups. Clients should listen on the diff --git a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts index 477fdfc5bc7..35584c57600 100644 --- a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts @@ -254,28 +254,49 @@ suite('EditorGroupsService', () => { part.dispose(); }); - test('groups labels', function () { + test('groups index / labels', function () { const part = createPart(); const rootGroup = part.groups[0]; const rightGroup = part.addGroup(rootGroup, GroupDirection.RIGHT); const downGroup = part.addGroup(rightGroup, GroupDirection.DOWN); - let labelChangeCounter = 0; + let indexChangeCounter = 0; const labelChangeListener = downGroup.onDidGroupChange(e => { - if (e.kind === GroupChangeKind.GROUP_LABEL) { - labelChangeCounter++; + if (e.kind === GroupChangeKind.GROUP_INDEX) { + indexChangeCounter++; } }); + assert.equal(rootGroup.index, 0); + assert.equal(rightGroup.index, 1); + assert.equal(downGroup.index, 2); assert.equal(rootGroup.label, 'Group 1'); assert.equal(rightGroup.label, 'Group 2'); assert.equal(downGroup.label, 'Group 3'); part.removeGroup(rightGroup); + assert.equal(rootGroup.index, 0); + assert.equal(downGroup.index, 1); assert.equal(rootGroup.label, 'Group 1'); assert.equal(downGroup.label, 'Group 2'); - assert.equal(labelChangeCounter, 1); + assert.equal(indexChangeCounter, 1); + + part.moveGroup(downGroup, rootGroup, GroupDirection.UP); + assert.equal(downGroup.index, 0); + assert.equal(rootGroup.index, 1); + assert.equal(downGroup.label, 'Group 1'); + assert.equal(rootGroup.label, 'Group 2'); + assert.equal(indexChangeCounter, 2); + + const newFirstGroup = part.addGroup(downGroup, GroupDirection.UP); + assert.equal(newFirstGroup.index, 0); + assert.equal(downGroup.index, 1); + assert.equal(rootGroup.index, 2); + assert.equal(newFirstGroup.label, 'Group 1'); + assert.equal(downGroup.label, 'Group 2'); + assert.equal(rootGroup.label, 'Group 3'); + assert.equal(indexChangeCounter, 3); labelChangeListener.dispose(); diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 48ebaf8e296..3895ed64e2a 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -761,6 +761,7 @@ export class TestEditorGroup implements IEditorGroupView { disposed: boolean; editors: ReadonlyArray = []; label: string; + index: number; whenRestored: Promise = Promise.resolve(undefined); element: HTMLElement; minimumWidth: number; @@ -839,7 +840,7 @@ export class TestEditorGroup implements IEditorGroupView { isEmpty(): boolean { return true; } setActive(_isActive: boolean): void { } - setLabel(_label: string): void { } + notifyIndexChanged(_index: number): void { } dispose(): void { } toJSON(): object { return Object.create(null); } layout(_width: number, _height: number): void { } From 5e61e20fde9be6639be80f486616e1abc51f2d56 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Thu, 8 Aug 2019 18:14:26 +0200 Subject: [PATCH 375/861] node-debug@1.38.2 --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index a3483f451e2..3ae1ace01c1 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -1,7 +1,7 @@ [ { "name": "ms-vscode.node-debug", - "version": "1.35.3", + "version": "1.38.2", "repo": "https://github.com/Microsoft/vscode-node-debug", "metadata": { "id": "b6ded8fb-a0a0-4c1c-acbd-ab2a3bc995a6", From 8b85550c7d1ea44ddfdb647f5bbd962b67d7f030 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 8 Aug 2019 09:30:30 -0700 Subject: [PATCH 376/861] Revert "Remove unneeded queue from ExtHostPseudoterminal" This reverts commit 3dc832d088c3a3983ef7e924ca65a3be816d078d. This broke the tests --- .../api/node/extHostTerminalService.ts | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index fe7c524a423..b4aa39cce9a 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -22,6 +22,7 @@ import { ExtHostVariableResolverService } from 'vs/workbench/api/node/extHostDeb import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { getSystemShell, detectAvailableShells } from 'vs/workbench/contrib/terminal/node/terminal'; import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; +import { IDisposable } from 'vs/base/common/lifecycle'; export class BaseExtHostTerminal { public _id: number | undefined; @@ -686,6 +687,9 @@ class ApiRequest { } class ExtHostPseudoterminal implements ITerminalChildProcess { + private _queuedEvents: (IQueuedEvent | IQueuedEvent | IQueuedEvent<{ pid: number, cwd: string }> | IQueuedEvent)[] = []; + private _queueDisposables: IDisposable[] | undefined; + private readonly _onProcessData = new Emitter(); public readonly onProcessData: Event = this._onProcessData.event; private readonly _onProcessExit = new Emitter(); @@ -697,7 +701,18 @@ class ExtHostPseudoterminal implements ITerminalChildProcess { private readonly _onProcessOverrideDimensions = new Emitter(); public get onProcessOverrideDimensions(): Event { return this._onProcessOverrideDimensions.event; } - constructor(private readonly _pty: vscode.Pseudoterminal) { } + constructor( + private readonly _pty: vscode.Pseudoterminal + ) { + this._queueDisposables = []; + this._queueDisposables.push(this._pty.onDidWrite(e => this._queuedEvents.push({ emitter: this._onProcessData, data: e }))); + if (this._pty.onDidClose) { + this._queueDisposables.push(this._pty.onDidClose(e => this._queuedEvents.push({ emitter: this._onProcessExit, data: 0 }))); + } + if (this._pty.onDidOverrideDimensions) { + this._queueDisposables.push(this._pty.onDidOverrideDimensions(e => this._queuedEvents.push({ emitter: this._onProcessOverrideDimensions, data: e ? { cols: e.columns, rows: e.rows } : undefined }))); + } + } shutdown(): void { this._pty.close(); @@ -728,7 +743,12 @@ class ExtHostPseudoterminal implements ITerminalChildProcess { } startSendingEvents(initialDimensions: ITerminalDimensionsDto | undefined): void { - // Attach the listeners + // Flush all buffered events + this._queuedEvents.forEach(e => (e.emitter.fire)(e.data)); + this._queuedEvents = []; + this._queueDisposables = undefined; + + // Attach the real listeners this._pty.onDidWrite(e => this._onProcessData.fire(e)); if (this._pty.onDidClose) { this._pty.onDidClose(e => this._onProcessExit.fire(0)); @@ -741,3 +761,7 @@ class ExtHostPseudoterminal implements ITerminalChildProcess { } } +interface IQueuedEvent { + emitter: Emitter; + data: T; +} From b1bb36ba2e38681ae6ba2b5e57d8db633da97d17 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 8 Aug 2019 09:31:24 -0700 Subject: [PATCH 377/861] Revert "Revert "Remove unneeded queue from ExtHostPseudoterminal"" This reverts commit 8b85550c7d1ea44ddfdb647f5bbd962b67d7f030. --- .../api/node/extHostTerminalService.ts | 28 ++----------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index b4aa39cce9a..fe7c524a423 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -22,7 +22,6 @@ import { ExtHostVariableResolverService } from 'vs/workbench/api/node/extHostDeb import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; import { getSystemShell, detectAvailableShells } from 'vs/workbench/contrib/terminal/node/terminal'; import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; -import { IDisposable } from 'vs/base/common/lifecycle'; export class BaseExtHostTerminal { public _id: number | undefined; @@ -687,9 +686,6 @@ class ApiRequest { } class ExtHostPseudoterminal implements ITerminalChildProcess { - private _queuedEvents: (IQueuedEvent | IQueuedEvent | IQueuedEvent<{ pid: number, cwd: string }> | IQueuedEvent)[] = []; - private _queueDisposables: IDisposable[] | undefined; - private readonly _onProcessData = new Emitter(); public readonly onProcessData: Event = this._onProcessData.event; private readonly _onProcessExit = new Emitter(); @@ -701,18 +697,7 @@ class ExtHostPseudoterminal implements ITerminalChildProcess { private readonly _onProcessOverrideDimensions = new Emitter(); public get onProcessOverrideDimensions(): Event { return this._onProcessOverrideDimensions.event; } - constructor( - private readonly _pty: vscode.Pseudoterminal - ) { - this._queueDisposables = []; - this._queueDisposables.push(this._pty.onDidWrite(e => this._queuedEvents.push({ emitter: this._onProcessData, data: e }))); - if (this._pty.onDidClose) { - this._queueDisposables.push(this._pty.onDidClose(e => this._queuedEvents.push({ emitter: this._onProcessExit, data: 0 }))); - } - if (this._pty.onDidOverrideDimensions) { - this._queueDisposables.push(this._pty.onDidOverrideDimensions(e => this._queuedEvents.push({ emitter: this._onProcessOverrideDimensions, data: e ? { cols: e.columns, rows: e.rows } : undefined }))); - } - } + constructor(private readonly _pty: vscode.Pseudoterminal) { } shutdown(): void { this._pty.close(); @@ -743,12 +728,7 @@ class ExtHostPseudoterminal implements ITerminalChildProcess { } startSendingEvents(initialDimensions: ITerminalDimensionsDto | undefined): void { - // Flush all buffered events - this._queuedEvents.forEach(e => (e.emitter.fire)(e.data)); - this._queuedEvents = []; - this._queueDisposables = undefined; - - // Attach the real listeners + // Attach the listeners this._pty.onDidWrite(e => this._onProcessData.fire(e)); if (this._pty.onDidClose) { this._pty.onDidClose(e => this._onProcessExit.fire(0)); @@ -761,7 +741,3 @@ class ExtHostPseudoterminal implements ITerminalChildProcess { } } -interface IQueuedEvent { - emitter: Emitter; - data: T; -} From ced08707d1a87b080bbc319771aa9f24088a0f93 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 8 Aug 2019 09:34:34 -0700 Subject: [PATCH 378/861] Fix terminal integration test --- .../vscode-api-tests/src/singlefolder-tests/terminal.test.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts index 5291e7ab716..0905e90acb1 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts @@ -337,14 +337,15 @@ suite('window namespace tests', () => { }); terminal.dispose(); }); - overrideDimensionsEmitter.fire({ columns: 10, rows: 5 }); }); const writeEmitter = new EventEmitter(); const overrideDimensionsEmitter = new EventEmitter(); const pty: Pseudoterminal = { onDidWrite: writeEmitter.event, onDidOverrideDimensions: overrideDimensionsEmitter.event, - open: () => {}, + open: () => { + overrideDimensionsEmitter.fire({ columns: 10, rows: 5 }); + }, close: () => {} }; const terminal = window.createTerminal({ name: 'foo', pty }); From b8e29993945c00afe2cc927d5a200e1ae1a0030d Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 8 Aug 2019 19:10:26 +0200 Subject: [PATCH 379/861] move extHostMain to /common/, have base extension service in /common/ and extend in /node/ --- .../api/common/extHostExtensionService.ts | 778 +++++++++++++++- .../api/node/extHostExtensionService.ts | 840 +----------------- .../{node => common}/extensionHostMain.ts | 3 +- .../node/extensionHostProcessSetup.ts | 4 +- 4 files changed, 813 insertions(+), 812 deletions(-) rename src/vs/workbench/services/extensions/{node => common}/extensionHostMain.ts (97%) diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts index 57baf95adce..ab08b92dd80 100644 --- a/src/vs/workbench/api/common/extHostExtensionService.ts +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -3,23 +3,785 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ExtHostExtensionServiceShape } from 'vs/workbench/api/common/extHost.protocol'; -import { ExtensionActivationReason, IExtensionAPI } from 'vs/workbench/api/common/extHostExtensionActivator'; +import * as nls from 'vs/nls'; +import * as path from 'vs/base/common/path'; +import { originalFSPath } from 'vs/base/common/resources'; +import { Barrier } from 'vs/base/common/async'; +import { dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { TernarySearchTree } from 'vs/base/common/map'; +import { URI } from 'vs/base/common/uri'; +import { ILogService } from 'vs/platform/log/common/log'; +import { ExtHostExtensionServiceShape, IInitData, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape, IResolveAuthorityResult } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostConfiguration, IExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; +import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionModule, HostExtension, ExtensionActivationTimesFragment } from 'vs/workbench/api/common/extHostExtensionActivator'; +import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; +import { ExtHostStorage, IExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; +import { ExtHostWorkspace, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; +import { ExtensionActivationError } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; +import * as errors from 'vs/base/common/errors'; import * as vscode from 'vscode'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; -import { createDecorator, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { TernarySearchTree } from 'vs/base/common/map'; +import { Schemas } from 'vs/base/common/network'; +import { VSBuffer } from 'vs/base/common/buffer'; +import { ExtensionMemento } from 'vs/workbench/api/common/extHostMemento'; +import { RemoteAuthorityResolverError, ExtensionExecutionContext } from 'vs/workbench/api/common/extHostTypes'; +import { ResolvedAuthority, ResolvedOptions } from 'vs/platform/remote/common/remoteAuthorityResolver'; +import { IInstantiationService, createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; +import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths'; +import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; -export interface IInitializeParticipant { - (accessor: ServicesAccessor): Promise | void; +interface ITestRunner { + /** Old test runner API, as exported from `vscode/lib/testrunner` */ + run(testsRoot: string, clb: (error: Error, failures?: number) => void): void; } +interface INewTestRunner { + /** New test runner API, as explained in the extension test doc */ + run(): Promise; +} + +export const IHostUtils = createDecorator('IHostUtils'); + +export interface IHostUtils { + _serviceBrand: undefined; + exit(code?: number): void; + exists(path: string): Promise; + realpath(path: string): Promise; +} + +type TelemetryActivationEventFragment = { + id: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' }; + name: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' }; + extensionVersion: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' }; + publisherDisplayName: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; + activationEvents: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; + isBuiltin: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true }; + reason: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; +}; + +export abstract class AbstractExtHostExtensionService implements ExtHostExtensionServiceShape { + + readonly _serviceBrand: any; + + private static readonly WORKSPACE_CONTAINS_TIMEOUT = 7000; + + protected readonly _hostUtils: IHostUtils; + protected readonly _initData: IInitData; + protected readonly _extHostContext: IExtHostRpcService; + protected readonly _instaService: IInstantiationService; + protected readonly _extHostWorkspace: ExtHostWorkspace; + protected readonly _extHostConfiguration: ExtHostConfiguration; + protected readonly _extHostLogService: ExtHostLogService; + + protected readonly _mainThreadWorkspaceProxy: MainThreadWorkspaceShape; + protected readonly _mainThreadTelemetryProxy: MainThreadTelemetryShape; + protected readonly _mainThreadExtensionsProxy: MainThreadExtensionServiceShape; + + private readonly _almostReadyToRunExtensions: Barrier; + private readonly _readyToStartExtensionHost: Barrier; + private readonly _readyToRunExtensions: Barrier; + protected readonly _registry: ExtensionDescriptionRegistry; + private readonly _storage: ExtHostStorage; + private readonly _storagePath: IExtensionStoragePaths; + private readonly _activator: ExtensionsActivator; + private _extensionPathIndex: Promise> | null; + + private readonly _resolvers: { [authorityPrefix: string]: vscode.RemoteAuthorityResolver; }; + + private _started: boolean; + + private readonly _disposables: DisposableStore; + + constructor( + @IInstantiationService instaService: IInstantiationService, + @IHostUtils hostUtils: IHostUtils, + @IExtHostRpcService extHostContext: IExtHostRpcService, + @IExtHostWorkspace extHostWorkspace: IExtHostWorkspace, + @IExtHostConfiguration extHostConfiguration: IExtHostConfiguration, + @ILogService extHostLogService: ExtHostLogService, + @IExtHostInitDataService initData: IExtHostInitDataService, + @IExtensionStoragePaths storagePath: IExtensionStoragePaths + ) { + this._hostUtils = hostUtils; + this._extHostContext = extHostContext; + this._initData = initData; + + this._extHostWorkspace = extHostWorkspace; + this._extHostConfiguration = extHostConfiguration; + this._extHostLogService = extHostLogService; + this._disposables = new DisposableStore(); + + this._mainThreadWorkspaceProxy = this._extHostContext.getProxy(MainContext.MainThreadWorkspace); + this._mainThreadTelemetryProxy = this._extHostContext.getProxy(MainContext.MainThreadTelemetry); + this._mainThreadExtensionsProxy = this._extHostContext.getProxy(MainContext.MainThreadExtensionService); + + this._almostReadyToRunExtensions = new Barrier(); + this._readyToStartExtensionHost = new Barrier(); + this._readyToRunExtensions = new Barrier(); + this._registry = new ExtensionDescriptionRegistry(this._initData.extensions); + this._storage = new ExtHostStorage(this._extHostContext); + this._storagePath = storagePath; + + this._instaService = instaService.createChild(new ServiceCollection( + [IExtHostStorage, this._storage] + )); + + const hostExtensions = new Set(); + this._initData.hostExtensions.forEach((extensionId) => hostExtensions.add(ExtensionIdentifier.toKey(extensionId))); + + this._activator = new ExtensionsActivator(this._registry, this._initData.resolvedExtensions, this._initData.hostExtensions, { + onExtensionActivationError: (extensionId: ExtensionIdentifier, error: ExtensionActivationError): void => { + this._mainThreadExtensionsProxy.$onExtensionActivationError(extensionId, error); + }, + + actualActivateExtension: async (extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise => { + if (hostExtensions.has(ExtensionIdentifier.toKey(extensionId))) { + const activationEvent = (reason instanceof ExtensionActivatedByEvent ? reason.activationEvent : null); + await this._mainThreadExtensionsProxy.$activateExtension(extensionId, activationEvent); + return new HostExtension(); + } + const extensionDescription = this._registry.getExtensionDescription(extensionId)!; + return this._activateExtension(extensionDescription, reason); + } + }); + this._extensionPathIndex = null; + this._resolvers = Object.create(null); + this._started = false; + } + + public async initialize(): Promise { + try { + + await this._beforeAlmostReadyToRunExtensions(); + this._almostReadyToRunExtensions.open(); + + await this._extHostWorkspace.waitForInitializeCall(); + this._readyToStartExtensionHost.open(); + + if (this._initData.autoStart) { + this._startExtensionHost(); + } + } catch (err) { + errors.onUnexpectedError(err); + } + } + + protected abstract _beforeAlmostReadyToRunExtensions(): Promise; + + public async deactivateAll(): Promise { + let allPromises: Promise[] = []; + try { + const allExtensions = this._registry.getAllExtensionDescriptions(); + const allExtensionsIds = allExtensions.map(ext => ext.identifier); + const activatedExtensions = allExtensionsIds.filter(id => this.isActivated(id)); + + allPromises = activatedExtensions.map((extensionId) => { + return this._deactivate(extensionId); + }); + } catch (err) { + // TODO: write to log once we have one + } + await allPromises; + } + + public isActivated(extensionId: ExtensionIdentifier): boolean { + if (this._readyToRunExtensions.isOpen()) { + return this._activator.isActivated(extensionId); + } + return false; + } + + private _activateByEvent(activationEvent: string, startup: boolean): Promise { + const reason = new ExtensionActivatedByEvent(startup, activationEvent); + return this._activator.activateByEvent(activationEvent, reason); + } + + private _activateById(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise { + return this._activator.activateById(extensionId, reason); + } + + public activateByIdWithErrors(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise { + return this._activateById(extensionId, reason).then(() => { + const extension = this._activator.getActivatedExtension(extensionId); + if (extension.activationFailed) { + // activation failed => bubble up the error as the promise result + return Promise.reject(extension.activationFailedError); + } + return undefined; + }); + } + + public getExtensionRegistry(): Promise { + return this._readyToRunExtensions.wait().then(_ => this._registry); + } + + public getExtensionExports(extensionId: ExtensionIdentifier): IExtensionAPI | null | undefined { + if (this._readyToRunExtensions.isOpen()) { + return this._activator.getActivatedExtension(extensionId).exports; + } else { + return null; + } + } + + // create trie to enable fast 'filename -> extension id' look up + public getExtensionPathIndex(): Promise> { + if (!this._extensionPathIndex) { + const tree = TernarySearchTree.forPaths(); + const extensions = this._registry.getAllExtensionDescriptions().map(ext => { + if (!ext.main) { + return undefined; + } + return this._hostUtils.realpath(ext.extensionLocation.fsPath).then(value => tree.set(URI.file(value).fsPath, ext)); + }); + this._extensionPathIndex = Promise.all(extensions).then(() => tree); + } + return this._extensionPathIndex; + } + + private _deactivate(extensionId: ExtensionIdentifier): Promise { + let result = Promise.resolve(undefined); + + if (!this._readyToRunExtensions.isOpen()) { + return result; + } + + if (!this._activator.isActivated(extensionId)) { + return result; + } + + const extension = this._activator.getActivatedExtension(extensionId); + if (!extension) { + return result; + } + + // call deactivate if available + try { + if (typeof extension.module.deactivate === 'function') { + result = Promise.resolve(extension.module.deactivate()).then(undefined, (err) => { + // TODO: Do something with err if this is not the shutdown case + return Promise.resolve(undefined); + }); + } + } catch (err) { + // TODO: Do something with err if this is not the shutdown case + } + + // clean up subscriptions + try { + dispose(extension.subscriptions); + } catch (err) { + // TODO: Do something with err if this is not the shutdown case + } + + return result; + } + + // --- impl + + private _activateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): Promise { + this._mainThreadExtensionsProxy.$onWillActivateExtension(extensionDescription.identifier); + return this._doActivateExtension(extensionDescription, reason).then((activatedExtension) => { + const activationTimes = activatedExtension.activationTimes; + const activationEvent = (reason instanceof ExtensionActivatedByEvent ? reason.activationEvent : null); + this._mainThreadExtensionsProxy.$onDidActivateExtension(extensionDescription.identifier, activationTimes.startup, activationTimes.codeLoadingTime, activationTimes.activateCallTime, activationTimes.activateResolvedTime, activationEvent); + this._logExtensionActivationTimes(extensionDescription, reason, 'success', activationTimes); + return activatedExtension; + }, (err) => { + this._logExtensionActivationTimes(extensionDescription, reason, 'failure'); + throw err; + }); + } + + private _logExtensionActivationTimes(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason, outcome: string, activationTimes?: ExtensionActivationTimes) { + const event = getTelemetryActivationEvent(extensionDescription, reason); + type ExtensionActivationTimesClassification = { + outcome: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; + } & TelemetryActivationEventFragment & ExtensionActivationTimesFragment; + + type ExtensionActivationTimesEvent = { + outcome: string + } & ActivationTimesEvent & TelemetryActivationEvent; + + type ActivationTimesEvent = { + startup?: boolean; + codeLoadingTime?: number; + activateCallTime?: number; + activateResolvedTime?: number; + }; + + this._mainThreadTelemetryProxy.$publicLog2('extensionActivationTimes', { + ...event, + ...(activationTimes || {}), + outcome + }); + } + + private _doActivateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): Promise { + const event = getTelemetryActivationEvent(extensionDescription, reason); + type ActivatePluginClassification = {} & TelemetryActivationEventFragment; + this._mainThreadTelemetryProxy.$publicLog2('activatePlugin', event); + if (!extensionDescription.main) { + // Treat the extension as being empty => NOT AN ERROR CASE + return Promise.resolve(new EmptyExtension(ExtensionActivationTimes.NONE)); + } + + this._extHostLogService.info(`ExtensionService#_doActivateExtension ${extensionDescription.identifier.value} ${JSON.stringify(reason)}`); + + const activationTimesBuilder = new ExtensionActivationTimesBuilder(reason.startup); + return Promise.all([ + this._loadCommonJSModule(extensionDescription.main, activationTimesBuilder), + this._loadExtensionContext(extensionDescription) + ]).then(values => { + return AbstractExtHostExtensionService._callActivate(this._extHostLogService, extensionDescription.identifier, values[0], values[1], activationTimesBuilder); + }); + } + + protected abstract _loadCommonJSModule(modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise; + + private _loadExtensionContext(extensionDescription: IExtensionDescription): Promise { + + const globalState = new ExtensionMemento(extensionDescription.identifier.value, true, this._storage); + const workspaceState = new ExtensionMemento(extensionDescription.identifier.value, false, this._storage); + + this._extHostLogService.trace(`ExtensionService#loadExtensionContext ${extensionDescription.identifier.value}`); + return Promise.all([ + globalState.whenReady, + workspaceState.whenReady, + this._storagePath.whenReady + ]).then(() => { + const that = this; + return Object.freeze({ + globalState, + workspaceState, + subscriptions: [], + get extensionPath() { return extensionDescription.extensionLocation.fsPath; }, + storagePath: this._storagePath.workspaceValue(extensionDescription), + globalStoragePath: this._storagePath.globalValue(extensionDescription), + asAbsolutePath: (relativePath: string) => { return path.join(extensionDescription.extensionLocation.fsPath, relativePath); }, + logPath: that._extHostLogService.getLogDirectory(extensionDescription.identifier), + executionContext: this._initData.remote.isRemote ? ExtensionExecutionContext.Remote : ExtensionExecutionContext.Local, + }); + }); + } + + private static _callActivate(logService: ILogService, extensionId: ExtensionIdentifier, extensionModule: IExtensionModule, context: IExtensionContext, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { + // Make sure the extension's surface is not undefined + extensionModule = extensionModule || { + activate: undefined, + deactivate: undefined + }; + + return this._callActivateOptional(logService, extensionId, extensionModule, context, activationTimesBuilder).then((extensionExports) => { + return new ActivatedExtension(false, null, activationTimesBuilder.build(), extensionModule, extensionExports, context.subscriptions); + }); + } + + private static _callActivateOptional(logService: ILogService, extensionId: ExtensionIdentifier, extensionModule: IExtensionModule, context: IExtensionContext, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { + if (typeof extensionModule.activate === 'function') { + try { + activationTimesBuilder.activateCallStart(); + logService.trace(`ExtensionService#_callActivateOptional ${extensionId.value}`); + const activateResult: Promise = extensionModule.activate.apply(global, [context]); + activationTimesBuilder.activateCallStop(); + + activationTimesBuilder.activateResolveStart(); + return Promise.resolve(activateResult).then((value) => { + activationTimesBuilder.activateResolveStop(); + return value; + }); + } catch (err) { + return Promise.reject(err); + } + } else { + // No activate found => the module is the extension's exports + return Promise.resolve(extensionModule); + } + } + + // -- eager activation + + // Handle "eager" activation extensions + private _handleEagerExtensions(): Promise { + this._activateByEvent('*', true).then(undefined, (err) => { + console.error(err); + }); + + this._disposables.add(this._extHostWorkspace.onDidChangeWorkspace((e) => this._handleWorkspaceContainsEagerExtensions(e.added))); + const folders = this._extHostWorkspace.workspace ? this._extHostWorkspace.workspace.folders : []; + return this._handleWorkspaceContainsEagerExtensions(folders); + } + + private _handleWorkspaceContainsEagerExtensions(folders: ReadonlyArray): Promise { + if (folders.length === 0) { + return Promise.resolve(undefined); + } + + return Promise.all( + this._registry.getAllExtensionDescriptions().map((desc) => { + return this._handleWorkspaceContainsEagerExtension(folders, desc); + }) + ).then(() => { }); + } + + private _handleWorkspaceContainsEagerExtension(folders: ReadonlyArray, desc: IExtensionDescription): Promise { + const activationEvents = desc.activationEvents; + if (!activationEvents) { + return Promise.resolve(undefined); + } + + if (this.isActivated(desc.identifier)) { + return Promise.resolve(undefined); + } + + const fileNames: string[] = []; + const globPatterns: string[] = []; + + for (const activationEvent of activationEvents) { + if (/^workspaceContains:/.test(activationEvent)) { + const fileNameOrGlob = activationEvent.substr('workspaceContains:'.length); + if (fileNameOrGlob.indexOf('*') >= 0 || fileNameOrGlob.indexOf('?') >= 0) { + globPatterns.push(fileNameOrGlob); + } else { + fileNames.push(fileNameOrGlob); + } + } + } + + if (fileNames.length === 0 && globPatterns.length === 0) { + return Promise.resolve(undefined); + } + + const fileNamePromise = Promise.all(fileNames.map((fileName) => this._activateIfFileName(folders, desc.identifier, fileName))).then(() => { }); + const globPatternPromise = this._activateIfGlobPatterns(folders, desc.identifier, globPatterns); + + return Promise.all([fileNamePromise, globPatternPromise]).then(() => { }); + } + + private async _activateIfFileName(folders: ReadonlyArray, extensionId: ExtensionIdentifier, fileName: string): Promise { + + // find exact path + for (const { uri } of folders) { + if (await this._hostUtils.exists(path.join(URI.revive(uri).fsPath, fileName))) { + // the file was found + return ( + this._activateById(extensionId, new ExtensionActivatedByEvent(true, `workspaceContains:${fileName}`)) + .then(undefined, err => console.error(err)) + ); + } + } + + return undefined; + } + + private async _activateIfGlobPatterns(folders: ReadonlyArray, extensionId: ExtensionIdentifier, globPatterns: string[]): Promise { + this._extHostLogService.trace(`extensionHostMain#activateIfGlobPatterns: fileSearch, extension: ${extensionId.value}, entryPoint: workspaceContains`); + + if (globPatterns.length === 0) { + return Promise.resolve(undefined); + } + + const tokenSource = new CancellationTokenSource(); + const searchP = this._mainThreadWorkspaceProxy.$checkExists(folders.map(folder => folder.uri), globPatterns, tokenSource.token); + + const timer = setTimeout(async () => { + tokenSource.cancel(); + this._activateById(extensionId, new ExtensionActivatedByEvent(true, `workspaceContainsTimeout:${globPatterns.join(',')}`)) + .then(undefined, err => console.error(err)); + }, AbstractExtHostExtensionService.WORKSPACE_CONTAINS_TIMEOUT); + + let exists: boolean = false; + try { + exists = await searchP; + } catch (err) { + if (!errors.isPromiseCanceledError(err)) { + console.error(err); + } + } + + tokenSource.dispose(); + clearTimeout(timer); + + if (exists) { + // a file was found matching one of the glob patterns + return ( + this._activateById(extensionId, new ExtensionActivatedByEvent(true, `workspaceContains:${globPatterns.join(',')}`)) + .then(undefined, err => console.error(err)) + ); + } + + return Promise.resolve(undefined); + } + + private _handleExtensionTests(): Promise { + return this._doHandleExtensionTests().then(undefined, error => { + console.error(error); // ensure any error message makes it onto the console + + return Promise.reject(error); + }); + } + + private _doHandleExtensionTests(): Promise { + const { extensionDevelopmentLocationURI: extensionDevelopmentLocationURI, extensionTestsLocationURI } = this._initData.environment; + if (!(extensionDevelopmentLocationURI && extensionTestsLocationURI && extensionTestsLocationURI.scheme === Schemas.file)) { + return Promise.resolve(undefined); + } + + const extensionTestsPath = originalFSPath(extensionTestsLocationURI); + + // Require the test runner via node require from the provided path + let testRunner: ITestRunner | INewTestRunner | undefined; + let requireError: Error | undefined; + try { + testRunner = require.__$__nodeRequire(extensionTestsPath); + } catch (error) { + requireError = error; + } + + // Execute the runner if it follows the old `run` spec + if (testRunner && typeof testRunner.run === 'function') { + return new Promise((c, e) => { + const oldTestRunnerCallback = (error: Error, failures: number | undefined) => { + if (error) { + e(error.toString()); + } else { + c(undefined); + } + + // after tests have run, we shutdown the host + this._gracefulExit(error || (typeof failures === 'number' && failures > 0) ? 1 /* ERROR */ : 0 /* OK */); + }; + + const runResult = testRunner!.run(extensionTestsPath, oldTestRunnerCallback); + + // Using the new API `run(): Promise` + if (runResult && runResult.then) { + runResult + .then(() => { + c(); + this._gracefulExit(0); + }) + .catch((err: Error) => { + e(err.toString()); + this._gracefulExit(1); + }); + } + }); + } + + // Otherwise make sure to shutdown anyway even in case of an error + else { + this._gracefulExit(1 /* ERROR */); + } + + return Promise.reject(new Error(requireError ? requireError.toString() : nls.localize('extensionTestError', "Path {0} does not point to a valid extension test runner.", extensionTestsPath))); + } + + private _gracefulExit(code: number): void { + // to give the PH process a chance to flush any outstanding console + // messages to the main process, we delay the exit() by some time + setTimeout(() => { + // If extension tests are running, give the exit code to the renderer + if (this._initData.remote.isRemote && !!this._initData.environment.extensionTestsLocationURI) { + this._mainThreadExtensionsProxy.$onExtensionHostExit(code); + return; + } + + this._hostUtils.exit(code); + }, 500); + } + + private _startExtensionHost(): Promise { + if (this._started) { + throw new Error(`Extension host is already started!`); + } + this._started = true; + + return this._readyToStartExtensionHost.wait() + .then(() => this._readyToRunExtensions.open()) + .then(() => this._handleEagerExtensions()) + .then(() => this._handleExtensionTests()) + .then(() => { + this._extHostLogService.info(`eager extensions activated`); + }); + } + + // -- called by extensions + + public registerRemoteAuthorityResolver(authorityPrefix: string, resolver: vscode.RemoteAuthorityResolver): vscode.Disposable { + this._resolvers[authorityPrefix] = resolver; + return toDisposable(() => { + delete this._resolvers[authorityPrefix]; + }); + } + + // -- called by main thread + + public async $resolveAuthority(remoteAuthority: string, resolveAttempt: number): Promise { + const authorityPlusIndex = remoteAuthority.indexOf('+'); + if (authorityPlusIndex === -1) { + throw new Error(`Not an authority that can be resolved!`); + } + const authorityPrefix = remoteAuthority.substr(0, authorityPlusIndex); + + await this._almostReadyToRunExtensions.wait(); + await this._activateByEvent(`onResolveRemoteAuthority:${authorityPrefix}`, false); + + const resolver = this._resolvers[authorityPrefix]; + if (!resolver) { + throw new Error(`No remote extension installed to resolve ${authorityPrefix}.`); + } + + try { + const result = await resolver.resolve(remoteAuthority, { resolveAttempt }); + + // Split merged API result into separate authority/options + const authority: ResolvedAuthority = { + authority: remoteAuthority, + host: result.host, + port: result.port + }; + const options: ResolvedOptions = { + extensionHostEnv: result.extensionHostEnv + }; + + return { + type: 'ok', + value: { + authority, + options + } + }; + } catch (err) { + if (err instanceof RemoteAuthorityResolverError) { + return { + type: 'error', + error: { + code: err._code, + message: err._message, + detail: err._detail + } + }; + } + throw err; + } + } + + public $startExtensionHost(enabledExtensionIds: ExtensionIdentifier[]): Promise { + this._registry.keepOnly(enabledExtensionIds); + return this._startExtensionHost(); + } + + public $activateByEvent(activationEvent: string): Promise { + return ( + this._readyToRunExtensions.wait() + .then(_ => this._activateByEvent(activationEvent, false)) + ); + } + + public async $activate(extensionId: ExtensionIdentifier, activationEvent: string): Promise { + await this._readyToRunExtensions.wait(); + if (!this._registry.getExtensionDescription(extensionId)) { + // unknown extension => ignore + return false; + } + await this._activateById(extensionId, new ExtensionActivatedByEvent(false, activationEvent)); + return true; + } + + public async $deltaExtensions(toAdd: IExtensionDescription[], toRemove: ExtensionIdentifier[]): Promise { + toAdd.forEach((extension) => (extension).extensionLocation = URI.revive(extension.extensionLocation)); + + const trie = await this.getExtensionPathIndex(); + + await Promise.all(toRemove.map(async (extensionId) => { + const extensionDescription = this._registry.getExtensionDescription(extensionId); + if (!extensionDescription) { + return; + } + const realpathValue = await this._hostUtils.realpath(extensionDescription.extensionLocation.fsPath); + trie.delete(URI.file(realpathValue).fsPath); + })); + + await Promise.all(toAdd.map(async (extensionDescription) => { + const realpathValue = await this._hostUtils.realpath(extensionDescription.extensionLocation.fsPath); + trie.set(URI.file(realpathValue).fsPath, extensionDescription); + })); + + this._registry.deltaExtensions(toAdd, toRemove); + return Promise.resolve(undefined); + } + + public async $test_latency(n: number): Promise { + return n; + } + + public async $test_up(b: VSBuffer): Promise { + return b.byteLength; + } + + public async $test_down(size: number): Promise { + let buff = VSBuffer.alloc(size); + let value = Math.random() % 256; + for (let i = 0; i < size; i++) { + buff.writeUInt8(value, i); + } + return buff; + } + + public async $setRemoteEnvironment(env: { [key: string]: string | null }): Promise { + if (!this._initData.remote.isRemote) { + return; + } + + for (const key in env) { + const value = env[key]; + if (value === null) { + delete process.env[key]; + } else { + process.env[key] = value; + } + } + } +} + + +type TelemetryActivationEvent = { + id: string; + name: string; + extensionVersion: string; + publisherDisplayName: string; + activationEvents: string | null; + isBuiltin: boolean; + reason: string; +}; + +function getTelemetryActivationEvent(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): TelemetryActivationEvent { + const reasonStr = reason instanceof ExtensionActivatedByEvent ? reason.activationEvent : + reason instanceof ExtensionActivatedByAPI ? 'api' : + ''; + const event = { + id: extensionDescription.identifier.value, + name: extensionDescription.name, + extensionVersion: extensionDescription.version, + publisherDisplayName: extensionDescription.publisher, + activationEvents: extensionDescription.activationEvents ? extensionDescription.activationEvents.join(',') : null, + isBuiltin: extensionDescription.isBuiltin, + reason: reasonStr + }; + + return event; +} + + export const IExtHostExtensionService = createDecorator('IExtHostExtensionService'); -export interface IExtHostExtensionService extends ExtHostExtensionServiceShape { +export interface IExtHostExtensionService extends AbstractExtHostExtensionService { _serviceBrand: any; - initialize(): void; + initialize(): Promise; isActivated(extensionId: ExtensionIdentifier): boolean; activateByIdWithErrors(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise; deactivateAll(): Promise; diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index eb2fb4ae37b..320a88a4563 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -3,819 +3,59 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nls from 'vs/nls'; -import * as path from 'vs/base/common/path'; -import { originalFSPath } from 'vs/base/common/resources'; -import { Barrier } from 'vs/base/common/async'; -import { dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; -import { TernarySearchTree } from 'vs/base/common/map'; -import { URI } from 'vs/base/common/uri'; -import { ILogService } from 'vs/platform/log/common/log'; import { createApiFactoryAndRegisterActors } from 'vs/workbench/api/common/extHost.api.impl'; import { NodeModuleRequireInterceptor, VSCodeNodeModuleFactory, KeytarNodeModuleFactory, OpenNodeModuleFactory } from 'vs/workbench/api/node/extHostRequireInterceptor'; -import { ExtHostExtensionServiceShape, IInitData, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape, IResolveAuthorityResult } from 'vs/workbench/api/common/extHost.protocol'; -import { ExtHostConfiguration, IExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; -import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionModule, HostExtension, ExtensionActivationTimesFragment } from 'vs/workbench/api/common/extHostExtensionActivator'; -import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; -import { ExtHostStorage, IExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; -import { ExtHostWorkspace, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; -import { ExtensionActivationError } from 'vs/workbench/services/extensions/common/extensions'; -import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; +import { MainContext } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtensionActivationTimesBuilder } from 'vs/workbench/api/common/extHostExtensionActivator'; import { connectProxyResolver } from 'vs/workbench/services/extensions/node/proxyResolver'; -import { CancellationTokenSource } from 'vs/base/common/cancellation'; -import * as errors from 'vs/base/common/errors'; -import * as vscode from 'vscode'; -import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; -import { Schemas } from 'vs/base/common/network'; -import { VSBuffer } from 'vs/base/common/buffer'; -import { ExtensionMemento } from 'vs/workbench/api/common/extHostMemento'; -import { RemoteAuthorityResolverError, ExtensionExecutionContext } from 'vs/workbench/api/common/extHostTypes'; -import { ResolvedAuthority, ResolvedOptions } from 'vs/platform/remote/common/remoteAuthorityResolver'; -import { IInstantiationService, createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; -import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; +import { AbstractExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; import { ExtHostDownloadService } from 'vs/workbench/api/node/extHostDownloadService'; import { CLIServer } from 'vs/workbench/api/node/extHostCLIServer'; -import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths'; -import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; -import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; -interface ITestRunner { - /** Old test runner API, as exported from `vscode/lib/testrunner` */ - run(testsRoot: string, clb: (error: Error, failures?: number) => void): void; -} +export class ExtHostExtensionService extends AbstractExtHostExtensionService { -interface INewTestRunner { - /** New test runner API, as explained in the extension test doc */ - run(): Promise; -} + protected async _beforeAlmostReadyToRunExtensions(): Promise { + // initialize API and register actors + const extensionApiFactory = this._instaService.invokeFunction(createApiFactoryAndRegisterActors); -export const IHostUtils = createDecorator('IHostUtils'); + // Register Download command + this._instaService.createInstance(ExtHostDownloadService); -export interface IHostUtils { - _serviceBrand: undefined; - exit(code?: number): void; - exists(path: string): Promise; - realpath(path: string): Promise; -} - -type TelemetryActivationEventFragment = { - id: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' }; - name: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' }; - extensionVersion: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' }; - publisherDisplayName: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; - activationEvents: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; - isBuiltin: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true }; - reason: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; -}; - -export class ExtHostExtensionService implements IExtHostExtensionService, ExtHostExtensionServiceShape { - - readonly _serviceBrand: any; - - private static readonly WORKSPACE_CONTAINS_TIMEOUT = 7000; - - private readonly _hostUtils: IHostUtils; - private readonly _initData: IInitData; - private readonly _extHostContext: IExtHostRpcService; - private readonly _instaService: IInstantiationService; - private readonly _extHostWorkspace: ExtHostWorkspace; - private readonly _extHostConfiguration: ExtHostConfiguration; - private readonly _extHostLogService: ExtHostLogService; - - private readonly _mainThreadWorkspaceProxy: MainThreadWorkspaceShape; - private readonly _mainThreadTelemetryProxy: MainThreadTelemetryShape; - private readonly _mainThreadExtensionsProxy: MainThreadExtensionServiceShape; - - private readonly _almostReadyToRunExtensions: Barrier; - private readonly _readyToStartExtensionHost: Barrier; - private readonly _readyToRunExtensions: Barrier; - private readonly _registry: ExtensionDescriptionRegistry; - private readonly _storage: ExtHostStorage; - private readonly _storagePath: IExtensionStoragePaths; - private readonly _activator: ExtensionsActivator; - private _extensionPathIndex: Promise> | null; - - private readonly _resolvers: { [authorityPrefix: string]: vscode.RemoteAuthorityResolver; }; - - private _started: boolean; - - private readonly _disposables: DisposableStore; - - constructor( - @IInstantiationService instaService: IInstantiationService, - @IHostUtils hostUtils: IHostUtils, - @IExtHostRpcService extHostContext: IExtHostRpcService, - @IExtHostWorkspace extHostWorkspace: IExtHostWorkspace, - @IExtHostConfiguration extHostConfiguration: IExtHostConfiguration, - @ILogService extHostLogService: ExtHostLogService, - @IExtHostInitDataService initData: IExtHostInitDataService, - @IExtensionStoragePaths storagePath: IExtensionStoragePaths - ) { - this._hostUtils = hostUtils; - this._extHostContext = extHostContext; - this._initData = initData; - - this._extHostWorkspace = extHostWorkspace; - this._extHostConfiguration = extHostConfiguration; - this._extHostLogService = extHostLogService; - this._disposables = new DisposableStore(); - - this._mainThreadWorkspaceProxy = this._extHostContext.getProxy(MainContext.MainThreadWorkspace); - this._mainThreadTelemetryProxy = this._extHostContext.getProxy(MainContext.MainThreadTelemetry); - this._mainThreadExtensionsProxy = this._extHostContext.getProxy(MainContext.MainThreadExtensionService); - - this._almostReadyToRunExtensions = new Barrier(); - this._readyToStartExtensionHost = new Barrier(); - this._readyToRunExtensions = new Barrier(); - this._registry = new ExtensionDescriptionRegistry(this._initData.extensions); - this._storage = new ExtHostStorage(this._extHostContext); - this._storagePath = storagePath; - - this._instaService = instaService.createChild(new ServiceCollection( - [IExtHostStorage, this._storage] - )); - - const hostExtensions = new Set(); - this._initData.hostExtensions.forEach((extensionId) => hostExtensions.add(ExtensionIdentifier.toKey(extensionId))); - - this._activator = new ExtensionsActivator(this._registry, this._initData.resolvedExtensions, this._initData.hostExtensions, { - onExtensionActivationError: (extensionId: ExtensionIdentifier, error: ExtensionActivationError): void => { - this._mainThreadExtensionsProxy.$onExtensionActivationError(extensionId, error); - }, - - actualActivateExtension: async (extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise => { - if (hostExtensions.has(ExtensionIdentifier.toKey(extensionId))) { - const activationEvent = (reason instanceof ExtensionActivatedByEvent ? reason.activationEvent : null); - await this._mainThreadExtensionsProxy.$activateExtension(extensionId, activationEvent); - return new HostExtension(); - } - const extensionDescription = this._registry.getExtensionDescription(extensionId)!; - return this._activateExtension(extensionDescription, reason); - } - }); - this._extensionPathIndex = null; - this._resolvers = Object.create(null); - this._started = false; - } - - public initialize(): void { - this._initialize(); - if (this._initData.autoStart) { - this._startExtensionHost(); + // Register CLI Server for ipc + if (this._initData.remote.isRemote && this._initData.remote.authority) { + const cliServer = this._instaService.createInstance(CLIServer); + process.env['VSCODE_IPC_HOOK_CLI'] = cliServer.ipcHandlePath; } + + // Module loading tricks + const configProvider = await this._extHostConfiguration.getConfigProvider(); + const extensionPaths = await this.getExtensionPathIndex(); + NodeModuleRequireInterceptor.INSTANCE.register(new VSCodeNodeModuleFactory(extensionApiFactory, extensionPaths, this._registry, configProvider)); + NodeModuleRequireInterceptor.INSTANCE.register(new KeytarNodeModuleFactory(this._extHostContext.getProxy(MainContext.MainThreadKeytar), this._initData.environment)); + if (this._initData.remote.isRemote) { + NodeModuleRequireInterceptor.INSTANCE.register(new OpenNodeModuleFactory( + this._extHostContext.getProxy(MainContext.MainThreadWindow), + this._extHostContext.getProxy(MainContext.MainThreadTelemetry), + extensionPaths + )); + } + + // Do this when extension service exists, but extensions are not being activated yet. + await connectProxyResolver(this._extHostWorkspace, configProvider, this, this._extHostLogService, this._mainThreadTelemetryProxy); + } - private async _initialize(): Promise { - + protected _loadCommonJSModule(modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { + let r: T | null = null; + activationTimesBuilder.codeLoadingStart(); + this._extHostLogService.info(`ExtensionService#loadCommonJSModule ${modulePath}`); try { - // initialize API and register actors - const extensionApiFactory = this._instaService.invokeFunction(createApiFactoryAndRegisterActors); - - // Register Download command - this._instaService.createInstance(ExtHostDownloadService); - - // Register CLI Server for ipc - if (this._initData.remote.isRemote && this._initData.remote.authority) { - const cliServer = this._instaService.createInstance(CLIServer); - process.env['VSCODE_IPC_HOOK_CLI'] = cliServer.ipcHandlePath; - } - - // Module loading tricks - const configProvider = await this._extHostConfiguration.getConfigProvider(); - const extensionPaths = await this.getExtensionPathIndex(); - NodeModuleRequireInterceptor.INSTANCE.register(new VSCodeNodeModuleFactory(extensionApiFactory, extensionPaths, this._registry, configProvider)); - NodeModuleRequireInterceptor.INSTANCE.register(new KeytarNodeModuleFactory(this._extHostContext.getProxy(MainContext.MainThreadKeytar), this._initData.environment)); - if (this._initData.remote.isRemote) { - NodeModuleRequireInterceptor.INSTANCE.register(new OpenNodeModuleFactory( - this._extHostContext.getProxy(MainContext.MainThreadWindow), - this._extHostContext.getProxy(MainContext.MainThreadTelemetry), - extensionPaths - )); - } - - // Do this when extension service exists, but extensions are not being activated yet. - await connectProxyResolver(this._extHostWorkspace, configProvider, this, this._extHostLogService, this._mainThreadTelemetryProxy); - this._almostReadyToRunExtensions.open(); - - await this._extHostWorkspace.waitForInitializeCall(); - this._readyToStartExtensionHost.open(); - } catch (err) { - errors.onUnexpectedError(err); - } - } - - public async deactivateAll(): Promise { - let allPromises: Promise[] = []; - try { - const allExtensions = this._registry.getAllExtensionDescriptions(); - const allExtensionsIds = allExtensions.map(ext => ext.identifier); - const activatedExtensions = allExtensionsIds.filter(id => this.isActivated(id)); - - allPromises = activatedExtensions.map((extensionId) => { - return this._deactivate(extensionId); - }); - } catch (err) { - // TODO: write to log once we have one - } - await allPromises; - } - - public isActivated(extensionId: ExtensionIdentifier): boolean { - if (this._readyToRunExtensions.isOpen()) { - return this._activator.isActivated(extensionId); - } - return false; - } - - private _activateByEvent(activationEvent: string, startup: boolean): Promise { - const reason = new ExtensionActivatedByEvent(startup, activationEvent); - return this._activator.activateByEvent(activationEvent, reason); - } - - private _activateById(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise { - return this._activator.activateById(extensionId, reason); - } - - public activateByIdWithErrors(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise { - return this._activateById(extensionId, reason).then(() => { - const extension = this._activator.getActivatedExtension(extensionId); - if (extension.activationFailed) { - // activation failed => bubble up the error as the promise result - return Promise.reject(extension.activationFailedError); - } - return undefined; - }); - } - - public getExtensionRegistry(): Promise { - return this._readyToRunExtensions.wait().then(_ => this._registry); - } - - public getExtensionExports(extensionId: ExtensionIdentifier): IExtensionAPI | null | undefined { - if (this._readyToRunExtensions.isOpen()) { - return this._activator.getActivatedExtension(extensionId).exports; - } else { - return null; - } - } - - // create trie to enable fast 'filename -> extension id' look up - public getExtensionPathIndex(): Promise> { - if (!this._extensionPathIndex) { - const tree = TernarySearchTree.forPaths(); - const extensions = this._registry.getAllExtensionDescriptions().map(ext => { - if (!ext.main) { - return undefined; - } - return this._hostUtils.realpath(ext.extensionLocation.fsPath).then(value => tree.set(URI.file(value).fsPath, ext)); - }); - this._extensionPathIndex = Promise.all(extensions).then(() => tree); - } - return this._extensionPathIndex; - } - - private _deactivate(extensionId: ExtensionIdentifier): Promise { - let result = Promise.resolve(undefined); - - if (!this._readyToRunExtensions.isOpen()) { - return result; - } - - if (!this._activator.isActivated(extensionId)) { - return result; - } - - const extension = this._activator.getActivatedExtension(extensionId); - if (!extension) { - return result; - } - - // call deactivate if available - try { - if (typeof extension.module.deactivate === 'function') { - result = Promise.resolve(extension.module.deactivate()).then(undefined, (err) => { - // TODO: Do something with err if this is not the shutdown case - return Promise.resolve(undefined); - }); - } - } catch (err) { - // TODO: Do something with err if this is not the shutdown case - } - - // clean up subscriptions - try { - dispose(extension.subscriptions); - } catch (err) { - // TODO: Do something with err if this is not the shutdown case - } - - return result; - } - - // --- impl - - private _activateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): Promise { - this._mainThreadExtensionsProxy.$onWillActivateExtension(extensionDescription.identifier); - return this._doActivateExtension(extensionDescription, reason).then((activatedExtension) => { - const activationTimes = activatedExtension.activationTimes; - const activationEvent = (reason instanceof ExtensionActivatedByEvent ? reason.activationEvent : null); - this._mainThreadExtensionsProxy.$onDidActivateExtension(extensionDescription.identifier, activationTimes.startup, activationTimes.codeLoadingTime, activationTimes.activateCallTime, activationTimes.activateResolvedTime, activationEvent); - this._logExtensionActivationTimes(extensionDescription, reason, 'success', activationTimes); - return activatedExtension; - }, (err) => { - this._logExtensionActivationTimes(extensionDescription, reason, 'failure'); - throw err; - }); - } - - private _logExtensionActivationTimes(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason, outcome: string, activationTimes?: ExtensionActivationTimes) { - const event = getTelemetryActivationEvent(extensionDescription, reason); - type ExtensionActivationTimesClassification = { - outcome: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; - } & TelemetryActivationEventFragment & ExtensionActivationTimesFragment; - - type ExtensionActivationTimesEvent = { - outcome: string - } & ActivationTimesEvent & TelemetryActivationEvent; - - type ActivationTimesEvent = { - startup?: boolean; - codeLoadingTime?: number; - activateCallTime?: number; - activateResolvedTime?: number; - }; - - this._mainThreadTelemetryProxy.$publicLog2('extensionActivationTimes', { - ...event, - ...(activationTimes || {}), - outcome - }); - } - - private _doActivateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): Promise { - const event = getTelemetryActivationEvent(extensionDescription, reason); - type ActivatePluginClassification = {} & TelemetryActivationEventFragment; - this._mainThreadTelemetryProxy.$publicLog2('activatePlugin', event); - if (!extensionDescription.main) { - // Treat the extension as being empty => NOT AN ERROR CASE - return Promise.resolve(new EmptyExtension(ExtensionActivationTimes.NONE)); - } - - this._extHostLogService.info(`ExtensionService#_doActivateExtension ${extensionDescription.identifier.value} ${JSON.stringify(reason)}`); - - const activationTimesBuilder = new ExtensionActivationTimesBuilder(reason.startup); - return Promise.all([ - loadCommonJSModule(this._extHostLogService, extensionDescription.main, activationTimesBuilder), - this._loadExtensionContext(extensionDescription) - ]).then(values => { - return ExtHostExtensionService._callActivate(this._extHostLogService, extensionDescription.identifier, values[0], values[1], activationTimesBuilder); - }); - } - - private _loadExtensionContext(extensionDescription: IExtensionDescription): Promise { - - const globalState = new ExtensionMemento(extensionDescription.identifier.value, true, this._storage); - const workspaceState = new ExtensionMemento(extensionDescription.identifier.value, false, this._storage); - - this._extHostLogService.trace(`ExtensionService#loadExtensionContext ${extensionDescription.identifier.value}`); - return Promise.all([ - globalState.whenReady, - workspaceState.whenReady, - this._storagePath.whenReady - ]).then(() => { - const that = this; - return Object.freeze({ - globalState, - workspaceState, - subscriptions: [], - get extensionPath() { return extensionDescription.extensionLocation.fsPath; }, - storagePath: this._storagePath.workspaceValue(extensionDescription), - globalStoragePath: this._storagePath.globalValue(extensionDescription), - asAbsolutePath: (relativePath: string) => { return path.join(extensionDescription.extensionLocation.fsPath, relativePath); }, - logPath: that._extHostLogService.getLogDirectory(extensionDescription.identifier), - executionContext: this._initData.remote.isRemote ? ExtensionExecutionContext.Remote : ExtensionExecutionContext.Local, - }); - }); - } - - private static _callActivate(logService: ILogService, extensionId: ExtensionIdentifier, extensionModule: IExtensionModule, context: IExtensionContext, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { - // Make sure the extension's surface is not undefined - extensionModule = extensionModule || { - activate: undefined, - deactivate: undefined - }; - - return this._callActivateOptional(logService, extensionId, extensionModule, context, activationTimesBuilder).then((extensionExports) => { - return new ActivatedExtension(false, null, activationTimesBuilder.build(), extensionModule, extensionExports, context.subscriptions); - }); - } - - private static _callActivateOptional(logService: ILogService, extensionId: ExtensionIdentifier, extensionModule: IExtensionModule, context: IExtensionContext, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { - if (typeof extensionModule.activate === 'function') { - try { - activationTimesBuilder.activateCallStart(); - logService.trace(`ExtensionService#_callActivateOptional ${extensionId.value}`); - const activateResult: Promise = extensionModule.activate.apply(global, [context]); - activationTimesBuilder.activateCallStop(); - - activationTimesBuilder.activateResolveStart(); - return Promise.resolve(activateResult).then((value) => { - activationTimesBuilder.activateResolveStop(); - return value; - }); - } catch (err) { - return Promise.reject(err); - } - } else { - // No activate found => the module is the extension's exports - return Promise.resolve(extensionModule); - } - } - - // -- eager activation - - // Handle "eager" activation extensions - private _handleEagerExtensions(): Promise { - this._activateByEvent('*', true).then(undefined, (err) => { - console.error(err); - }); - - this._disposables.add(this._extHostWorkspace.onDidChangeWorkspace((e) => this._handleWorkspaceContainsEagerExtensions(e.added))); - const folders = this._extHostWorkspace.workspace ? this._extHostWorkspace.workspace.folders : []; - return this._handleWorkspaceContainsEagerExtensions(folders); - } - - private _handleWorkspaceContainsEagerExtensions(folders: ReadonlyArray): Promise { - if (folders.length === 0) { - return Promise.resolve(undefined); - } - - return Promise.all( - this._registry.getAllExtensionDescriptions().map((desc) => { - return this._handleWorkspaceContainsEagerExtension(folders, desc); - }) - ).then(() => { }); - } - - private _handleWorkspaceContainsEagerExtension(folders: ReadonlyArray, desc: IExtensionDescription): Promise { - const activationEvents = desc.activationEvents; - if (!activationEvents) { - return Promise.resolve(undefined); - } - - if (this.isActivated(desc.identifier)) { - return Promise.resolve(undefined); - } - - const fileNames: string[] = []; - const globPatterns: string[] = []; - - for (const activationEvent of activationEvents) { - if (/^workspaceContains:/.test(activationEvent)) { - const fileNameOrGlob = activationEvent.substr('workspaceContains:'.length); - if (fileNameOrGlob.indexOf('*') >= 0 || fileNameOrGlob.indexOf('?') >= 0) { - globPatterns.push(fileNameOrGlob); - } else { - fileNames.push(fileNameOrGlob); - } - } - } - - if (fileNames.length === 0 && globPatterns.length === 0) { - return Promise.resolve(undefined); - } - - const fileNamePromise = Promise.all(fileNames.map((fileName) => this._activateIfFileName(folders, desc.identifier, fileName))).then(() => { }); - const globPatternPromise = this._activateIfGlobPatterns(folders, desc.identifier, globPatterns); - - return Promise.all([fileNamePromise, globPatternPromise]).then(() => { }); - } - - private async _activateIfFileName(folders: ReadonlyArray, extensionId: ExtensionIdentifier, fileName: string): Promise { - - // find exact path - for (const { uri } of folders) { - if (await this._hostUtils.exists(path.join(URI.revive(uri).fsPath, fileName))) { - // the file was found - return ( - this._activateById(extensionId, new ExtensionActivatedByEvent(true, `workspaceContains:${fileName}`)) - .then(undefined, err => console.error(err)) - ); - } - } - - return undefined; - } - - private async _activateIfGlobPatterns(folders: ReadonlyArray, extensionId: ExtensionIdentifier, globPatterns: string[]): Promise { - this._extHostLogService.trace(`extensionHostMain#activateIfGlobPatterns: fileSearch, extension: ${extensionId.value}, entryPoint: workspaceContains`); - - if (globPatterns.length === 0) { - return Promise.resolve(undefined); - } - - const tokenSource = new CancellationTokenSource(); - const searchP = this._mainThreadWorkspaceProxy.$checkExists(folders.map(folder => folder.uri), globPatterns, tokenSource.token); - - const timer = setTimeout(async () => { - tokenSource.cancel(); - this._activateById(extensionId, new ExtensionActivatedByEvent(true, `workspaceContainsTimeout:${globPatterns.join(',')}`)) - .then(undefined, err => console.error(err)); - }, ExtHostExtensionService.WORKSPACE_CONTAINS_TIMEOUT); - - let exists: boolean = false; - try { - exists = await searchP; - } catch (err) { - if (!errors.isPromiseCanceledError(err)) { - console.error(err); - } - } - - tokenSource.dispose(); - clearTimeout(timer); - - if (exists) { - // a file was found matching one of the glob patterns - return ( - this._activateById(extensionId, new ExtensionActivatedByEvent(true, `workspaceContains:${globPatterns.join(',')}`)) - .then(undefined, err => console.error(err)) - ); - } - - return Promise.resolve(undefined); - } - - private _handleExtensionTests(): Promise { - return this._doHandleExtensionTests().then(undefined, error => { - console.error(error); // ensure any error message makes it onto the console - - return Promise.reject(error); - }); - } - - private _doHandleExtensionTests(): Promise { - const { extensionDevelopmentLocationURI: extensionDevelopmentLocationURI, extensionTestsLocationURI } = this._initData.environment; - if (!(extensionDevelopmentLocationURI && extensionTestsLocationURI && extensionTestsLocationURI.scheme === Schemas.file)) { - return Promise.resolve(undefined); - } - - const extensionTestsPath = originalFSPath(extensionTestsLocationURI); - - // Require the test runner via node require from the provided path - let testRunner: ITestRunner | INewTestRunner | undefined; - let requireError: Error | undefined; - try { - testRunner = require.__$__nodeRequire(extensionTestsPath); - } catch (error) { - requireError = error; - } - - // Execute the runner if it follows the old `run` spec - if (testRunner && typeof testRunner.run === 'function') { - return new Promise((c, e) => { - const oldTestRunnerCallback = (error: Error, failures: number | undefined) => { - if (error) { - e(error.toString()); - } else { - c(undefined); - } - - // after tests have run, we shutdown the host - this._gracefulExit(error || (typeof failures === 'number' && failures > 0) ? 1 /* ERROR */ : 0 /* OK */); - }; - - const runResult = testRunner!.run(extensionTestsPath, oldTestRunnerCallback); - - // Using the new API `run(): Promise` - if (runResult && runResult.then) { - runResult - .then(() => { - c(); - this._gracefulExit(0); - }) - .catch((err: Error) => { - e(err.toString()); - this._gracefulExit(1); - }); - } - }); - } - - // Otherwise make sure to shutdown anyway even in case of an error - else { - this._gracefulExit(1 /* ERROR */); - } - - return Promise.reject(new Error(requireError ? requireError.toString() : nls.localize('extensionTestError', "Path {0} does not point to a valid extension test runner.", extensionTestsPath))); - } - - private _gracefulExit(code: number): void { - // to give the PH process a chance to flush any outstanding console - // messages to the main process, we delay the exit() by some time - setTimeout(() => { - // If extension tests are running, give the exit code to the renderer - if (this._initData.remote.isRemote && !!this._initData.environment.extensionTestsLocationURI) { - this._mainThreadExtensionsProxy.$onExtensionHostExit(code); - return; - } - - this._hostUtils.exit(code); - }, 500); - } - - private _startExtensionHost(): Promise { - if (this._started) { - throw new Error(`Extension host is already started!`); - } - this._started = true; - - return this._readyToStartExtensionHost.wait() - .then(() => this._readyToRunExtensions.open()) - .then(() => this._handleEagerExtensions()) - .then(() => this._handleExtensionTests()) - .then(() => { - this._extHostLogService.info(`eager extensions activated`); - }); - } - - // -- called by extensions - - public registerRemoteAuthorityResolver(authorityPrefix: string, resolver: vscode.RemoteAuthorityResolver): vscode.Disposable { - this._resolvers[authorityPrefix] = resolver; - return toDisposable(() => { - delete this._resolvers[authorityPrefix]; - }); - } - - // -- called by main thread - - public async $resolveAuthority(remoteAuthority: string, resolveAttempt: number): Promise { - const authorityPlusIndex = remoteAuthority.indexOf('+'); - if (authorityPlusIndex === -1) { - throw new Error(`Not an authority that can be resolved!`); - } - const authorityPrefix = remoteAuthority.substr(0, authorityPlusIndex); - - await this._almostReadyToRunExtensions.wait(); - await this._activateByEvent(`onResolveRemoteAuthority:${authorityPrefix}`, false); - - const resolver = this._resolvers[authorityPrefix]; - if (!resolver) { - throw new Error(`No remote extension installed to resolve ${authorityPrefix}.`); - } - - try { - const result = await resolver.resolve(remoteAuthority, { resolveAttempt }); - - // Split merged API result into separate authority/options - const authority: ResolvedAuthority = { - authority: remoteAuthority, - host: result.host, - port: result.port - }; - const options: ResolvedOptions = { - extensionHostEnv: result.extensionHostEnv - }; - - return { - type: 'ok', - value: { - authority, - options - } - }; - } catch (err) { - if (err instanceof RemoteAuthorityResolverError) { - return { - type: 'error', - error: { - code: err._code, - message: err._message, - detail: err._detail - } - }; - } - throw err; - } - } - - public $startExtensionHost(enabledExtensionIds: ExtensionIdentifier[]): Promise { - this._registry.keepOnly(enabledExtensionIds); - return this._startExtensionHost(); - } - - public $activateByEvent(activationEvent: string): Promise { - return ( - this._readyToRunExtensions.wait() - .then(_ => this._activateByEvent(activationEvent, false)) - ); - } - - public async $activate(extensionId: ExtensionIdentifier, activationEvent: string): Promise { - await this._readyToRunExtensions.wait(); - if (!this._registry.getExtensionDescription(extensionId)) { - // unknown extension => ignore - return false; - } - await this._activateById(extensionId, new ExtensionActivatedByEvent(false, activationEvent)); - return true; - } - - public async $deltaExtensions(toAdd: IExtensionDescription[], toRemove: ExtensionIdentifier[]): Promise { - toAdd.forEach((extension) => (extension).extensionLocation = URI.revive(extension.extensionLocation)); - - const trie = await this.getExtensionPathIndex(); - - await Promise.all(toRemove.map(async (extensionId) => { - const extensionDescription = this._registry.getExtensionDescription(extensionId); - if (!extensionDescription) { - return; - } - const realpathValue = await this._hostUtils.realpath(extensionDescription.extensionLocation.fsPath); - trie.delete(URI.file(realpathValue).fsPath); - })); - - await Promise.all(toAdd.map(async (extensionDescription) => { - const realpathValue = await this._hostUtils.realpath(extensionDescription.extensionLocation.fsPath); - trie.set(URI.file(realpathValue).fsPath, extensionDescription); - })); - - this._registry.deltaExtensions(toAdd, toRemove); - return Promise.resolve(undefined); - } - - public async $test_latency(n: number): Promise { - return n; - } - - public async $test_up(b: VSBuffer): Promise { - return b.byteLength; - } - - public async $test_down(size: number): Promise { - let buff = VSBuffer.alloc(size); - let value = Math.random() % 256; - for (let i = 0; i < size; i++) { - buff.writeUInt8(value, i); - } - return buff; - } - - public async $setRemoteEnvironment(env: { [key: string]: string | null }): Promise { - if (!this._initData.remote.isRemote) { - return; - } - - for (const key in env) { - const value = env[key]; - if (value === null) { - delete process.env[key]; - } else { - process.env[key] = value; - } + r = require.__$__nodeRequire(modulePath); + } catch (e) { + return Promise.reject(e); + } finally { + activationTimesBuilder.codeLoadingStop(); } + return Promise.resolve(r); } } - -function loadCommonJSModule(logService: ILogService, modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { - let r: T | null = null; - activationTimesBuilder.codeLoadingStart(); - logService.info(`ExtensionService#loadCommonJSModule ${modulePath}`); - try { - r = require.__$__nodeRequire(modulePath); - } catch (e) { - return Promise.reject(e); - } finally { - activationTimesBuilder.codeLoadingStop(); - } - return Promise.resolve(r); -} - -type TelemetryActivationEvent = { - id: string; - name: string; - extensionVersion: string; - publisherDisplayName: string; - activationEvents: string | null; - isBuiltin: boolean; - reason: string; -}; - -function getTelemetryActivationEvent(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): TelemetryActivationEvent { - const reasonStr = reason instanceof ExtensionActivatedByEvent ? reason.activationEvent : - reason instanceof ExtensionActivatedByAPI ? 'api' : - ''; - const event = { - id: extensionDescription.identifier.value, - name: extensionDescription.name, - extensionVersion: extensionDescription.version, - publisherDisplayName: extensionDescription.publisher, - activationEvents: extensionDescription.activationEvents ? extensionDescription.activationEvents.join(',') : null, - isBuiltin: extensionDescription.isBuiltin, - reason: reasonStr - }; - - return event; -} diff --git a/src/vs/workbench/services/extensions/node/extensionHostMain.ts b/src/vs/workbench/services/extensions/common/extensionHostMain.ts similarity index 97% rename from src/vs/workbench/services/extensions/node/extensionHostMain.ts rename to src/vs/workbench/services/extensions/common/extensionHostMain.ts index 10a8ebd4e42..96f006ffe36 100644 --- a/src/vs/workbench/services/extensions/node/extensionHostMain.ts +++ b/src/vs/workbench/services/extensions/common/extensionHostMain.ts @@ -10,7 +10,6 @@ import { URI, setUriThrowOnMissingScheme } from 'vs/base/common/uri'; import { IURITransformer } from 'vs/base/common/uriIpc'; import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; import { IInitData, MainContext, MainThreadConsoleShape } from 'vs/workbench/api/common/extHost.protocol'; -import { IHostUtils } from 'vs/workbench/api/node/extHostExtensionService'; import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; import { RPCProtocol } from 'vs/workbench/services/extensions/common/rpcProtocol'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; @@ -22,7 +21,7 @@ import { InstantiationService } from 'vs/platform/instantiation/common/instantia import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IExtHostRpcService, ExtHostRpcService } from 'vs/workbench/api/common/rpcService'; import { IURITransformerService, URITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService'; -import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; +import { IExtHostExtensionService, IHostUtils } from 'vs/workbench/api/common/extHostExtensionService'; // we don't (yet) throw when extensions parse // uris that have no scheme diff --git a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts index 4a99e7dfd2d..f708e29da7c 100644 --- a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts +++ b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts @@ -14,13 +14,13 @@ import { NodeSocket, WebSocketNodeSocket } from 'vs/base/parts/ipc/node/ipc.net' import product from 'vs/platform/product/node/product'; import { IInitData, MainThreadConsoleShape } from 'vs/workbench/api/common/extHost.protocol'; import { MessageType, createMessageOfType, isMessageOfType, IExtHostSocketMessage, IExtHostReadyMessage } from 'vs/workbench/services/extensions/common/extensionHostProtocol'; -import { ExtensionHostMain, IExitFn, ILogServiceFn } from 'vs/workbench/services/extensions/node/extensionHostMain'; +import { ExtensionHostMain, IExitFn, ILogServiceFn } from 'vs/workbench/services/extensions/common/extensionHostMain'; import { VSBuffer } from 'vs/base/common/buffer'; import { ExtensionHostLogFileName } from 'vs/workbench/services/extensions/common/extensions'; import { IURITransformer, URITransformer, IRawURITransformer } from 'vs/base/common/uriIpc'; import { exists } from 'vs/base/node/pfs'; import { realpath } from 'vs/base/node/extpath'; -import { IHostUtils } from 'vs/workbench/api/node/extHostExtensionService'; +import { IHostUtils } from 'vs/workbench/api/common/extHostExtensionService'; import { SpdLogService } from 'vs/platform/log/node/spdlogService'; import 'vs/workbench/api/node/extHost.services'; From bbf1e51b9c8f765d24d3b5e73eadcf77315f385a Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 8 Aug 2019 19:16:15 +0200 Subject: [PATCH 380/861] fix unit test --- .../test/electron-browser/api/extHostWorkspace.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts index 285ac356774..ed1d5ed3875 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts @@ -294,8 +294,8 @@ suite('ExtHostWorkspace', function () { const protocol: IMainContext = { getProxy: () => { return undefined!; }, - set: undefined!, - assertRegistered: undefined! + set: () => { return undefined!; }, + assertRegistered: () => { } }; const ws = createExtHostWorkspace(protocol, { id: 'foo', name: 'Test', folders: [] }, new NullLogService()); From 76c7b2d8954a4eb346ab7f2f45b6213602a857b9 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 8 Aug 2019 10:31:44 -0700 Subject: [PATCH 381/861] rename scrollOff to editor.cursorSurroundingLines --- src/vs/editor/browser/viewParts/lines/viewLines.ts | 4 ++-- src/vs/editor/common/config/commonEditorConfig.ts | 6 +++--- src/vs/editor/common/config/editorOptions.ts | 14 +++++++------- src/vs/monaco.d.ts | 6 +++--- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/vs/editor/browser/viewParts/lines/viewLines.ts b/src/vs/editor/browser/viewParts/lines/viewLines.ts index 9b85e624b52..580311d7691 100644 --- a/src/vs/editor/browser/viewParts/lines/viewLines.ts +++ b/src/vs/editor/browser/viewParts/lines/viewLines.ts @@ -95,7 +95,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost, this._typicalHalfwidthCharacterWidth = conf.editor.fontInfo.typicalHalfwidthCharacterWidth; this._isViewportWrapping = conf.editor.wrappingInfo.isViewportWrapping; this._revealHorizontalRightPadding = conf.editor.viewInfo.revealHorizontalRightPadding; - this._scrollOff = conf.editor.viewInfo.scrollOff; + this._scrollOff = conf.editor.viewInfo.cursorSurroundingLines; this._canUseLayerHinting = conf.editor.canUseLayerHinting; this._viewLineOptions = new ViewLineOptions(conf, this._context.theme.type); @@ -152,7 +152,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost, } if (e.viewInfo) { this._revealHorizontalRightPadding = conf.editor.viewInfo.revealHorizontalRightPadding; - this._scrollOff = conf.editor.viewInfo.scrollOff; + this._scrollOff = conf.editor.viewInfo.cursorSurroundingLines; } if (e.canUseLayerHinting) { this._canUseLayerHinting = conf.editor.canUseLayerHinting; diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index 45f0a760a3c..65f579a296e 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -268,10 +268,10 @@ const editorConfiguration: IConfigurationNode = { 'default': 'on', 'description': nls.localize('lineNumbers', "Controls the display of line numbers.") }, - 'editor.scrollOff': { + 'editor.cursorSurroundingLines': { 'type': 'number', - 'default': EDITOR_DEFAULTS.viewInfo.scrollOff, - 'description': nls.localize('scrollOff', "Controls the number of context lines above and below the cursor.") + 'default': EDITOR_DEFAULTS.viewInfo.cursorSurroundingLines, + 'description': nls.localize('cursorSurroundingLines', "Controls the minimal number of visible leading and trailing lines surrounding the cursor. Known as 'scrollOff' or `scrollOffset` in some other editors.") }, 'editor.renderFinalNewline': { 'type': 'boolean', diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 38d27f4d44b..71b0cbb8843 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -269,10 +269,10 @@ export interface IEditorOptions { */ lineNumbers?: 'on' | 'off' | 'relative' | 'interval' | ((lineNumber: number) => string); /** - * Controls the number of context lines above and below the cursor. + * Controls the minimal number of visible leading and trailing lines surrounding the cursor. * Defaults to 0. */ - scrollOff?: number; + cursorSurroundingLines?: number; /** * Render last line number when the file ends with a newline. * Defaults to true. @@ -987,7 +987,7 @@ export interface InternalEditorViewOptions { readonly ariaLabel: string; readonly renderLineNumbers: RenderLineNumbersType; readonly renderCustomLineNumbers: ((lineNumber: number) => string) | null; - readonly scrollOff: number; + readonly cursorSurroundingLines: number; readonly renderFinalNewline: boolean; readonly selectOnLineNumbers: boolean; readonly glyphMargin: boolean; @@ -1296,7 +1296,7 @@ export class InternalEditorOptions { && a.ariaLabel === b.ariaLabel && a.renderLineNumbers === b.renderLineNumbers && a.renderCustomLineNumbers === b.renderCustomLineNumbers - && a.scrollOff === b.scrollOff + && a.cursorSurroundingLines === b.cursorSurroundingLines && a.renderFinalNewline === b.renderFinalNewline && a.selectOnLineNumbers === b.selectOnLineNumbers && a.glyphMargin === b.glyphMargin @@ -2056,7 +2056,7 @@ export class EditorOptionsValidator { disableMonospaceOptimizations: disableMonospaceOptimizations, rulers: rulers, ariaLabel: _string(opts.ariaLabel, defaults.ariaLabel), - scrollOff: _clampedInt(opts.scrollOff, defaults.cursorWidth, 0, Number.MAX_VALUE), + cursorSurroundingLines: _clampedInt(opts.cursorSurroundingLines, defaults.cursorWidth, 0, Number.MAX_VALUE), renderLineNumbers: renderLineNumbers, renderCustomLineNumbers: renderCustomLineNumbers, renderFinalNewline: _boolean(opts.renderFinalNewline, defaults.renderFinalNewline), @@ -2180,7 +2180,7 @@ export class InternalEditorOptionsFactory { ariaLabel: (accessibilityIsOff ? nls.localize('accessibilityOffAriaLabel', "The editor is not accessible at this time. Press Alt+F1 for options.") : opts.viewInfo.ariaLabel), renderLineNumbers: opts.viewInfo.renderLineNumbers, renderCustomLineNumbers: opts.viewInfo.renderCustomLineNumbers, - scrollOff: opts.viewInfo.scrollOff, + cursorSurroundingLines: opts.viewInfo.cursorSurroundingLines, renderFinalNewline: opts.viewInfo.renderFinalNewline, selectOnLineNumbers: opts.viewInfo.selectOnLineNumbers, glyphMargin: opts.viewInfo.glyphMargin, @@ -2645,7 +2645,7 @@ export const EDITOR_DEFAULTS: IValidatedEditorOptions = { ariaLabel: nls.localize('editorViewAccessibleLabel', "Editor content"), renderLineNumbers: RenderLineNumbersType.On, renderCustomLineNumbers: null, - scrollOff: 0, + cursorSurroundingLines: 0, renderFinalNewline: true, selectOnLineNumbers: true, glyphMargin: true, diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 64a44cefc6e..5cd4257b8a7 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2650,10 +2650,10 @@ declare namespace monaco.editor { */ lineNumbers?: 'on' | 'off' | 'relative' | 'interval' | ((lineNumber: number) => string); /** - * Controls the number of context lines above and below the cursor. + * Controls the minimal number of visible leading and trailing lines surrounding the cursor. * Defaults to 0. */ - scrollOff?: number; + cursorSurroundingLines?: number; /** * Render last line number when the file ends with a newline. * Defaults to true. @@ -3302,7 +3302,7 @@ declare namespace monaco.editor { readonly ariaLabel: string; readonly renderLineNumbers: RenderLineNumbersType; readonly renderCustomLineNumbers: ((lineNumber: number) => string) | null; - readonly scrollOff: number; + readonly cursorSurroundingLines: number; readonly renderFinalNewline: boolean; readonly selectOnLineNumbers: boolean; readonly glyphMargin: boolean; From 24b3d9479f7a9ef83dbedc331249ab58f08eda99 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 8 Aug 2019 19:34:32 +0200 Subject: [PATCH 382/861] $setRemoteEnvironment-implementation requires nodejs --- .../api/common/extHostExtensionService.ts | 15 +-------------- .../workbench/api/node/extHostExtensionService.ts | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts index ab08b92dd80..6f504bc9d80 100644 --- a/src/vs/workbench/api/common/extHostExtensionService.ts +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -732,20 +732,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio return buff; } - public async $setRemoteEnvironment(env: { [key: string]: string | null }): Promise { - if (!this._initData.remote.isRemote) { - return; - } - - for (const key in env) { - const value = env[key]; - if (value === null) { - delete process.env[key]; - } else { - process.env[key] = value; - } - } - } + public abstract async $setRemoteEnvironment(env: { [key: string]: string | null }): Promise; } diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 320a88a4563..efbf84cf641 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -58,4 +58,19 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { } return Promise.resolve(r); } + + public async $setRemoteEnvironment(env: { [key: string]: string | null }): Promise { + if (!this._initData.remote.isRemote) { + return; + } + + for (const key in env) { + const value = env[key]; + if (value === null) { + delete process.env[key]; + } else { + process.env[key] = value; + } + } + } } From 49c3fec57e41ba040ea1265af9790257f67d5cfe Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 8 Aug 2019 11:14:27 -0700 Subject: [PATCH 383/861] fixes #78693 --- src/vs/workbench/browser/layout.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index d928b4a6c6c..bd1d6b0b02f 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -1258,7 +1258,8 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi { type: 'leaf', data: { type: Parts.TITLEBAR_PART }, - size: titleBarHeight + size: titleBarHeight, + visible: this.isVisible(Parts.TITLEBAR_PART) }, { type: 'branch', From 3bcdfb5ce207711f43560698bf1f09bc057ccb37 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 8 Aug 2019 11:19:00 -0700 Subject: [PATCH 384/861] grid layout by default --- src/vs/workbench/browser/workbench.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index 7c36ea51726..abb2f710aa5 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -237,7 +237,7 @@ import { isMacintosh, isWindows, isLinux, isWeb } from 'vs/base/common/platform' 'workbench.useExperimentalGridLayout': { 'type': 'boolean', 'description': nls.localize('workbench.useExperimentalGridLayout', "Enables the grid layout for the workbench. This setting may enable additional layout options for workbench components."), - 'default': false, + 'default': true, 'scope': ConfigurationScope.APPLICATION } } From c4818ad8a231c5690aea90d28489d2a0116ace46 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 8 Aug 2019 11:43:41 -0700 Subject: [PATCH 385/861] fixes #78175 --- src/vs/workbench/browser/layout.ts | 39 +++++------------------------- 1 file changed, 6 insertions(+), 33 deletions(-) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index bd1d6b0b02f..7f82e7e7562 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -1076,33 +1076,15 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi toggleMaximizedPanel(): void { if (this.workbenchGrid instanceof Grid) { - const curSize = this.workbenchGrid.getViewSize(this.panelPartView); - const size = { ...curSize }; - + const size = this.workbenchGrid.getViewSize(this.panelPartView); if (!this.isPanelMaximized()) { - if (this.state.panel.position === Position.BOTTOM) { - size.height = this.panelPartView.maximumHeight; - this.state.panel.sizeBeforeMaximize = curSize.height; - } else { - size.width = this.panelPartView.maximumWidth; - this.state.panel.sizeBeforeMaximize = curSize.width; - } - + this.state.panel.sizeBeforeMaximize = this.state.panel.position === Position.BOTTOM ? size.height : size.width; this.storageService.store(Storage.PANEL_SIZE_BEFORE_MAXIMIZED, this.state.panel.sizeBeforeMaximize, StorageScope.GLOBAL); + this.setEditorHidden(true); } else { - if (this.state.panel.position === Position.BOTTOM) { - size.height = this.state.panel.sizeBeforeMaximize; - } else { - size.width = this.state.panel.sizeBeforeMaximize; - } - - // Unhide the editor if needed - if (this.state.editor.hidden) { - this.setEditorHidden(false); - } + this.setEditorHidden(false); + this.workbenchGrid.resizeView(this.panelPartView, { width: this.state.panel.position === Position.BOTTOM ? size.width : this.state.panel.sizeBeforeMaximize, height: this.state.panel.position === Position.BOTTOM ? this.state.panel.sizeBeforeMaximize : size.height }); } - - this.workbenchGrid.resizeView(this.panelPartView, size); } else { this.workbenchGrid.layout({ toggleMaximizedPanel: true, source: Parts.PANEL_PART }); } @@ -1114,16 +1096,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi } if (this.workbenchGrid instanceof Grid) { - try { - // The panel is maximum when the editor is minimum - if (this.state.panel.position === Position.BOTTOM) { - return this.workbenchGrid.getViewSize(this.editorPartView).height <= this.editorPartView.minimumHeight; - } else { - return this.workbenchGrid.getViewSize(this.editorPartView).width <= this.editorPartView.minimumWidth; - } - } catch (e) { - return false; - } + return this.state.editor.hidden; } else { return this.workbenchGrid.isPanelMaximized(); } From 52ecb5bf560ab517495463b6c392586977a9925b Mon Sep 17 00:00:00 2001 From: SteVen Batten <6561887+sbatten@users.noreply.github.com> Date: Thu, 8 Aug 2019 18:33:39 -0700 Subject: [PATCH 386/861] Dialog checkbox (#78533) * add simple checkbox adopt in dialogs * fix wrap * finalize naming --- .../base/browser/ui/checkbox/check-dark.svg | 3 ++ .../base/browser/ui/checkbox/check-light.svg | 3 ++ src/vs/base/browser/ui/checkbox/checkbox.css | 22 ++++++++- src/vs/base/browser/ui/checkbox/checkbox.ts | 49 +++++++++++++++++++ src/vs/base/browser/ui/dialog/dialog.css | 7 ++- src/vs/base/browser/ui/dialog/dialog.ts | 42 +++++++++++++--- .../platform/dialogs/browser/dialogService.ts | 43 ++++++++-------- src/vs/platform/dialogs/common/dialogs.ts | 4 +- src/vs/platform/theme/common/colorRegistry.ts | 4 ++ src/vs/platform/theme/common/styler.ts | 10 +++- .../preferences/browser/settingsWidgets.ts | 8 +-- 11 files changed, 158 insertions(+), 37 deletions(-) create mode 100644 src/vs/base/browser/ui/checkbox/check-dark.svg create mode 100644 src/vs/base/browser/ui/checkbox/check-light.svg diff --git a/src/vs/base/browser/ui/checkbox/check-dark.svg b/src/vs/base/browser/ui/checkbox/check-dark.svg new file mode 100644 index 00000000000..865cc83c347 --- /dev/null +++ b/src/vs/base/browser/ui/checkbox/check-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/checkbox/check-light.svg b/src/vs/base/browser/ui/checkbox/check-light.svg new file mode 100644 index 00000000000..e1a546660ed --- /dev/null +++ b/src/vs/base/browser/ui/checkbox/check-light.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/vs/base/browser/ui/checkbox/checkbox.css b/src/vs/base/browser/ui/checkbox/checkbox.css index 65f1dcd2318..26f48b88c02 100644 --- a/src/vs/base/browser/ui/checkbox/checkbox.css +++ b/src/vs/base/browser/ui/checkbox/checkbox.css @@ -39,4 +39,24 @@ .hc-black .monaco-custom-checkbox:hover { background: none; -} \ No newline at end of file +} + +.monaco-custom-checkbox.monaco-simple-checkbox { + height: 18px; + width: 18px; + border: 1px solid transparent; + border-radius: 3px; + margin-right: 9px; + margin-left: 0px; + padding: 0px; + opacity: 1; + background-size: 16px !important; +} + +.monaco-custom-checkbox.monaco-simple-checkbox.checked { + background: url('check-light.svg') center center no-repeat; +} + +.monaco-custom-checkbox.monaco-simple-checkbox.checked { + background: url('check-dark.svg') center center no-repeat; +} diff --git a/src/vs/base/browser/ui/checkbox/checkbox.ts b/src/vs/base/browser/ui/checkbox/checkbox.ts index ed0bcfa0ab1..f5fe47cdd85 100644 --- a/src/vs/base/browser/ui/checkbox/checkbox.ts +++ b/src/vs/base/browser/ui/checkbox/checkbox.ts @@ -25,6 +25,12 @@ export interface ICheckboxStyles { inputActiveOptionBackground?: Color; } +export interface ISimpleCheckboxStyles { + checkboxBackground?: Color; + checkboxBorder?: Color; + checkboxForeground?: Color; +} + const defaultOpts = { inputActiveOptionBorder: Color.fromHex('#007ACC00'), inputActiveOptionBackground: Color.fromHex('#0E639C50') @@ -174,3 +180,46 @@ export class Checkbox extends Widget { this.domNode.setAttribute('aria-disabled', String(true)); } } + +export class SimpleCheckbox extends Widget { + private checkbox: Checkbox; + private styles: ISimpleCheckboxStyles; + + readonly domNode: HTMLElement; + + constructor(private title: string, private isChecked: boolean) { + super(); + + this.checkbox = new Checkbox({ title: this.title, isChecked: this.isChecked, actionClassName: 'monaco-simple-checkbox' }); + + this.domNode = this.checkbox.domNode; + + this.styles = {}; + + this.checkbox.onChange(() => { + this.applyStyles(); + }); + } + + get checked(): boolean { + return this.checkbox.checked; + } + + set checked(newIsChecked: boolean) { + this.checkbox.checked = newIsChecked; + + this.applyStyles(); + } + + style(styles: ISimpleCheckboxStyles): void { + this.styles = styles; + + this.applyStyles(); + } + + protected applyStyles(): void { + this.domNode.style.color = this.styles.checkboxForeground ? this.styles.checkboxForeground.toString() : null; + this.domNode.style.backgroundColor = this.styles.checkboxBackground ? this.styles.checkboxBackground.toString() : null; + this.domNode.style.borderColor = this.styles.checkboxBorder ? this.styles.checkboxBorder.toString() : null; + } +} diff --git a/src/vs/base/browser/ui/dialog/dialog.css b/src/vs/base/browser/ui/dialog/dialog.css index e05ed90a949..83d8d7eca66 100644 --- a/src/vs/base/browser/ui/dialog/dialog.css +++ b/src/vs/base/browser/ui/dialog/dialog.css @@ -149,6 +149,11 @@ outline-style: solid; } +.monaco-workbench .dialog-box .dialog-message-row .dialog-message-container .dialog-checkbox-row { + padding: 15px 0px 0px; + display: flex; +} + /** Dialog: Buttons Row */ .monaco-workbench .dialog-box > .dialog-buttons-row { display: flex; @@ -175,4 +180,4 @@ margin: 4px 5px; /* allows button focus outline to be visible */ overflow: hidden; text-overflow: ellipsis; -} \ No newline at end of file +} diff --git a/src/vs/base/browser/ui/dialog/dialog.ts b/src/vs/base/browser/ui/dialog/dialog.ts index 2b5d836146d..f6b707d975d 100644 --- a/src/vs/base/browser/ui/dialog/dialog.ts +++ b/src/vs/base/browser/ui/dialog/dialog.ts @@ -16,15 +16,23 @@ import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; import { Action } from 'vs/base/common/actions'; import { mnemonicButtonLabel } from 'vs/base/common/labels'; import { isMacintosh, isLinux } from 'vs/base/common/platform'; +import { SimpleCheckbox, ISimpleCheckboxStyles } from 'vs/base/browser/ui/checkbox/checkbox'; export interface IDialogOptions { cancelId?: number; detail?: string; + checkboxLabel?: string; + checkboxChecked?: boolean; type?: 'none' | 'info' | 'error' | 'question' | 'warning' | 'pending'; keyEventProcessor?: (event: StandardKeyboardEvent) => void; } -export interface IDialogStyles extends IButtonStyles { +export interface IDialogResult { + button: number; + checkboxChecked?: boolean; +} + +export interface IDialogStyles extends IButtonStyles, ISimpleCheckboxStyles { dialogForeground?: Color; dialogBackground?: Color; dialogShadow?: Color; @@ -42,6 +50,7 @@ export class Dialog extends Disposable { private buttonsContainer: HTMLElement | undefined; private messageDetailElement: HTMLElement | undefined; private iconElement: HTMLElement | undefined; + private checkbox: SimpleCheckbox | undefined; private toolbarContainer: HTMLElement | undefined; private buttonGroup: ButtonGroup | undefined; private styles: IDialogStyles | undefined; @@ -68,6 +77,19 @@ export class Dialog extends Disposable { this.messageDetailElement = messageContainer.appendChild($('.dialog-message-detail')); this.messageDetailElement.innerText = this.options.detail ? this.options.detail : message; + if (this.options.checkboxLabel) { + const checkboxRowElement = messageContainer.appendChild($('.dialog-checkbox-row')); + + this.checkbox = this._register(new SimpleCheckbox(this.options.checkboxLabel, !!this.options.checkboxChecked)); + + checkboxRowElement.appendChild(this.checkbox.domNode); + + const checkboxMessageElement = checkboxRowElement.appendChild($('.dialog-checkbox-message')); + checkboxMessageElement.innerText = this.options.checkboxLabel; + } + + + const toolbarRowElement = this.element.appendChild($('.dialog-toolbar-row')); this.toolbarContainer = toolbarRowElement.appendChild($('.dialog-toolbar')); } @@ -78,12 +100,12 @@ export class Dialog extends Disposable { } } - async show(): Promise { + async show(): Promise { this.focusToReturn = document.activeElement as HTMLElement; - return new Promise((resolve) => { + return new Promise((resolve) => { if (!this.element || !this.buttonsContainer || !this.iconElement || !this.toolbarContainer) { - resolve(0); + resolve({ button: 0 }); return; } @@ -112,7 +134,7 @@ export class Dialog extends Disposable { this._register(button.onDidClick(e => { EventHelper.stop(e); - resolve(buttonMap[index].index); + resolve({ button: buttonMap[index].index, checkboxChecked: this.checkbox ? this.checkbox.checked : undefined }); })); }); @@ -147,7 +169,7 @@ export class Dialog extends Disposable { const evt = new StandardKeyboardEvent(e); if (evt.equals(KeyCode.Escape)) { - resolve(this.options.cancelId || 0); + resolve({ button: this.options.cancelId || 0, checkboxChecked: this.checkbox ? this.checkbox.checked : undefined }); } })); @@ -187,7 +209,7 @@ export class Dialog extends Disposable { const actionBar = new ActionBar(this.toolbarContainer, {}); const action = new Action('dialog.close', nls.localize('dialogClose', "Close Dialog"), 'dialog-close-action', true, () => { - resolve(this.options.cancelId || 0); + resolve({ button: this.options.cancelId || 0, checkboxChecked: this.checkbox ? this.checkbox.checked : undefined }); return Promise.resolve(); }); @@ -221,6 +243,10 @@ export class Dialog extends Disposable { if (this.buttonGroup) { this.buttonGroup.buttons.forEach(button => button.style(style)); } + + if (this.checkbox) { + this.checkbox.style(style); + } } } } @@ -261,4 +287,4 @@ export class Dialog extends Disposable { return buttonMap; } -} \ No newline at end of file +} diff --git a/src/vs/platform/dialogs/browser/dialogService.ts b/src/vs/platform/dialogs/browser/dialogService.ts index 5a906768029..347e242dd6d 100644 --- a/src/vs/platform/dialogs/browser/dialogService.ts +++ b/src/vs/platform/dialogs/browser/dialogService.ts @@ -40,32 +40,35 @@ export class DialogService implements IDialogService { buttons.push(nls.localize('cancelButton', "Cancel")); } - const severity = this.getSeverity(confirmation.type || 'none'); - const result = await this.show(severity, confirmation.message, buttons, { cancelId: 1, detail: confirmation.detail }); + const dialogDisposables = new DisposableStore(); + const dialog = new Dialog( + this.layoutService.container, + confirmation.message, + buttons, + { + detail: confirmation.detail, + cancelId: 1, + type: confirmation.type, + keyEventProcessor: (event: StandardKeyboardEvent) => { + EventHelper.stop(event, true); + }, + checkboxChecked: confirmation.checkbox ? confirmation.checkbox.checked : undefined, + checkboxLabel: confirmation.checkbox ? confirmation.checkbox.label : undefined + }); - return { confirmed: result === 0 }; - } + dialogDisposables.add(dialog); + dialogDisposables.add(attachDialogStyler(dialog, this.themeService)); - private getSeverity(type: DialogType): Severity { - switch (type) { - case 'error': - return Severity.Error; - case 'warning': - return Severity.Warning; - case 'question': - case 'info': - return Severity.Info; - case 'none': - default: - return Severity.Ignore; - } + const result = await dialog.show(); + dialogDisposables.dispose(); + + return { confirmed: result.button === 0, checkboxChecked: result.checkboxChecked }; } private getDialogType(severity: Severity): DialogType { return (severity === Severity.Info) ? 'question' : (severity === Severity.Error) ? 'error' : (severity === Severity.Warning) ? 'warning' : 'none'; } - async show(severity: Severity, message: string, buttons: string[], options?: IDialogOptions): Promise { this.logService.trace('DialogService#show', message); @@ -86,9 +89,9 @@ export class DialogService implements IDialogService { dialogDisposables.add(dialog); dialogDisposables.add(attachDialogStyler(dialog, this.themeService)); - const choice = await dialog.show(); + const result = await dialog.show(); dialogDisposables.dispose(); - return choice; + return result.button; } } diff --git a/src/vs/platform/dialogs/common/dialogs.ts b/src/vs/platform/dialogs/common/dialogs.ts index ea57ce91233..6999633d9f0 100644 --- a/src/vs/platform/dialogs/common/dialogs.ts +++ b/src/vs/platform/dialogs/common/dialogs.ts @@ -127,6 +127,8 @@ export const IDialogService = createDecorator('dialogService'); export interface IDialogOptions { cancelId?: number; detail?: string; + checkboxLabel?: string; + checkboxChecked?: boolean; } /** @@ -234,4 +236,4 @@ export function getConfirmMessage(start: string, resourcesToConfirm: URI[]): str message.push(''); return message.join('\n'); -} \ No newline at end of file +} diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index 6f356bfe66b..47b428fbb84 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -222,6 +222,10 @@ export const selectListBackground = registerColor('dropdown.listBackground', { d export const selectForeground = registerColor('dropdown.foreground', { dark: '#F0F0F0', light: null, hc: Color.white }, nls.localize('dropdownForeground', "Dropdown foreground.")); export const selectBorder = registerColor('dropdown.border', { dark: selectBackground, light: '#CECECE', hc: contrastBorder }, nls.localize('dropdownBorder', "Dropdown border.")); +export const simpleCheckboxBackground = registerColor('checkbox.background', { dark: selectBackground, light: selectBackground, hc: selectBackground }, nls.localize('checkbox.background', "Background color of checkbox widget.")); +export const simpleCheckboxForeground = registerColor('checkbox.foreground', { dark: selectForeground, light: selectForeground, hc: selectForeground }, nls.localize('checkbox.foreground', "Foreground color of checkbox widget.")); +export const simpleCheckboxBorder = registerColor('checkbox.border', { dark: selectBorder, light: selectBorder, hc: selectBorder }, nls.localize('checkbox.border', "Border color of checkbox widget.")); + export const listFocusBackground = registerColor('list.focusBackground', { dark: '#062F4A', light: '#D6EBFF', hc: null }, nls.localize('listFocusBackground', "List/Tree background color for the focused item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); export const listFocusForeground = registerColor('list.focusForeground', { dark: null, light: null, hc: null }, nls.localize('listFocusForeground', "List/Tree foreground color for the focused item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); export const listActiveSelectionBackground = registerColor('list.activeSelectionBackground', { dark: '#094771', light: '#0074E8', hc: null }, nls.localize('listActiveSelectionBackground', "List/Tree background color for the selected item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); diff --git a/src/vs/platform/theme/common/styler.ts b/src/vs/platform/theme/common/styler.ts index c1732ca1735..40de3567375 100644 --- a/src/vs/platform/theme/common/styler.ts +++ b/src/vs/platform/theme/common/styler.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { ITheme, IThemeService } from 'vs/platform/theme/common/themeService'; -import { focusBorder, inputBackground, inputForeground, ColorIdentifier, selectForeground, selectBackground, selectListBackground, selectBorder, inputBorder, foreground, editorBackground, contrastBorder, inputActiveOptionBorder, inputActiveOptionBackground, listFocusBackground, listFocusForeground, listActiveSelectionBackground, listActiveSelectionForeground, listInactiveSelectionForeground, listInactiveSelectionBackground, listInactiveFocusBackground, listHoverBackground, listHoverForeground, listDropBackground, pickerGroupBorder, pickerGroupForeground, widgetShadow, inputValidationInfoBorder, inputValidationInfoBackground, inputValidationWarningBorder, inputValidationWarningBackground, inputValidationErrorBorder, inputValidationErrorBackground, activeContrastBorder, buttonForeground, buttonBackground, buttonHoverBackground, ColorFunction, badgeBackground, badgeForeground, progressBarBackground, breadcrumbsForeground, breadcrumbsFocusForeground, breadcrumbsActiveSelectionForeground, breadcrumbsBackground, editorWidgetBorder, inputValidationInfoForeground, inputValidationWarningForeground, inputValidationErrorForeground, menuForeground, menuBackground, menuSelectionForeground, menuSelectionBackground, menuSelectionBorder, menuBorder, menuSeparatorBackground, darken, listFilterWidgetOutline, listFilterWidgetNoMatchesOutline, listFilterWidgetBackground, editorWidgetBackground, treeIndentGuidesStroke, editorWidgetForeground } from 'vs/platform/theme/common/colorRegistry'; +import { focusBorder, inputBackground, inputForeground, ColorIdentifier, selectForeground, selectBackground, selectListBackground, selectBorder, inputBorder, foreground, editorBackground, contrastBorder, inputActiveOptionBorder, inputActiveOptionBackground, listFocusBackground, listFocusForeground, listActiveSelectionBackground, listActiveSelectionForeground, listInactiveSelectionForeground, listInactiveSelectionBackground, listInactiveFocusBackground, listHoverBackground, listHoverForeground, listDropBackground, pickerGroupBorder, pickerGroupForeground, widgetShadow, inputValidationInfoBorder, inputValidationInfoBackground, inputValidationWarningBorder, inputValidationWarningBackground, inputValidationErrorBorder, inputValidationErrorBackground, activeContrastBorder, buttonForeground, buttonBackground, buttonHoverBackground, ColorFunction, badgeBackground, badgeForeground, progressBarBackground, breadcrumbsForeground, breadcrumbsFocusForeground, breadcrumbsActiveSelectionForeground, breadcrumbsBackground, editorWidgetBorder, inputValidationInfoForeground, inputValidationWarningForeground, inputValidationErrorForeground, menuForeground, menuBackground, menuSelectionForeground, menuSelectionBackground, menuSelectionBorder, menuBorder, menuSeparatorBackground, darken, listFilterWidgetOutline, listFilterWidgetNoMatchesOutline, listFilterWidgetBackground, editorWidgetBackground, treeIndentGuidesStroke, editorWidgetForeground, simpleCheckboxBackground, simpleCheckboxBorder, simpleCheckboxForeground } from 'vs/platform/theme/common/colorRegistry'; import { IDisposable } from 'vs/base/common/lifecycle'; import { Color } from 'vs/base/common/color'; import { mixin } from 'vs/base/common/objects'; @@ -341,6 +341,9 @@ export interface IDialogStyleOverrides extends IButtonStyleOverrides { dialogBackground?: ColorIdentifier; dialogShadow?: ColorIdentifier; dialogBorder?: ColorIdentifier; + checkboxBorder?: ColorIdentifier; + checkboxBackground?: ColorIdentifier; + checkboxForeground?: ColorIdentifier; } export const defaultDialogStyles = { @@ -351,7 +354,10 @@ export const defaultDialogStyles = { buttonForeground: buttonForeground, buttonBackground: buttonBackground, buttonHoverBackground: buttonHoverBackground, - buttonBorder: contrastBorder + buttonBorder: contrastBorder, + checkboxBorder: simpleCheckboxBorder, + checkboxBackground: simpleCheckboxBackground, + checkboxForeground: simpleCheckboxForeground }; diff --git a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts index cb7d13e51e5..6a2fbad2b88 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts @@ -16,7 +16,7 @@ import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import 'vs/css!./media/settingsWidgets'; import { localize } from 'vs/nls'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; -import { foreground, inputBackground, inputBorder, inputForeground, listActiveSelectionBackground, listActiveSelectionForeground, listHoverBackground, listHoverForeground, listInactiveSelectionBackground, listInactiveSelectionForeground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground, textPreformatForeground, editorWidgetBorder, textLinkActiveForeground } from 'vs/platform/theme/common/colorRegistry'; +import { foreground, inputBackground, inputBorder, inputForeground, listActiveSelectionBackground, listActiveSelectionForeground, listHoverBackground, listHoverForeground, listInactiveSelectionBackground, listInactiveSelectionForeground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground, textPreformatForeground, editorWidgetBorder, textLinkActiveForeground, simpleCheckboxBackground, simpleCheckboxForeground, simpleCheckboxBorder } from 'vs/platform/theme/common/colorRegistry'; import { attachButtonStyler, attachInputBoxStyler } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { disposableTimeout } from 'vs/base/common/async'; @@ -37,9 +37,9 @@ export const settingsSelectBorder = registerColor('settings.dropdownBorder', { d export const settingsSelectListBorder = registerColor('settings.dropdownListBorder', { dark: editorWidgetBorder, light: editorWidgetBorder, hc: editorWidgetBorder }, localize('settingsDropdownListBorder', "(For settings editor preview) Settings editor dropdown list border. This surrounds the options and separates the options from the description.")); // Bool control colors -export const settingsCheckboxBackground = registerColor('settings.checkboxBackground', { dark: selectBackground, light: selectBackground, hc: selectBackground }, localize('settingsCheckboxBackground', "(For settings editor preview) Settings editor checkbox background.")); -export const settingsCheckboxForeground = registerColor('settings.checkboxForeground', { dark: selectForeground, light: selectForeground, hc: selectForeground }, localize('settingsCheckboxForeground', "(For settings editor preview) Settings editor checkbox foreground.")); -export const settingsCheckboxBorder = registerColor('settings.checkboxBorder', { dark: selectBorder, light: selectBorder, hc: selectBorder }, localize('settingsCheckboxBorder', "(For settings editor preview) Settings editor checkbox border.")); +export const settingsCheckboxBackground = registerColor('settings.checkboxBackground', { dark: simpleCheckboxBackground, light: simpleCheckboxBackground, hc: simpleCheckboxBackground }, localize('settingsCheckboxBackground', "(For settings editor preview) Settings editor checkbox background.")); +export const settingsCheckboxForeground = registerColor('settings.checkboxForeground', { dark: simpleCheckboxForeground, light: simpleCheckboxForeground, hc: simpleCheckboxForeground }, localize('settingsCheckboxForeground', "(For settings editor preview) Settings editor checkbox foreground.")); +export const settingsCheckboxBorder = registerColor('settings.checkboxBorder', { dark: simpleCheckboxBorder, light: simpleCheckboxBorder, hc: simpleCheckboxBorder }, localize('settingsCheckboxBorder', "(For settings editor preview) Settings editor checkbox border.")); // Text control colors export const settingsTextInputBackground = registerColor('settings.textInputBackground', { dark: inputBackground, light: inputBackground, hc: inputBackground }, localize('textInputBoxBackground', "(For settings editor preview) Settings editor text input box background.")); From 406b1f385a54caca5b829b2b9c8f2617f0fff48f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 9 Aug 2019 07:49:19 +0200 Subject: [PATCH 387/861] more editor group context keys (fix #22755) --- src/vs/workbench/browser/contextkeys.ts | 24 ++++++++++++++----- .../browser/parts/editor/editorPart.ts | 12 ++++++++-- src/vs/workbench/common/editor.ts | 2 ++ .../editor/common/editorGroupsService.ts | 5 ++++ .../test/browser/editorGroupsService.test.ts | 9 +++++++ .../workbench/test/workbenchTestServices.ts | 1 + 6 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/browser/contextkeys.ts b/src/vs/workbench/browser/contextkeys.ts index b1de1c5bdc6..10bb2639e9e 100644 --- a/src/vs/workbench/browser/contextkeys.ts +++ b/src/vs/workbench/browser/contextkeys.ts @@ -8,7 +8,7 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { IContextKeyService, IContextKey, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { InputFocusedContext } from 'vs/platform/contextkey/common/contextkeys'; import { IWindowsConfiguration } from 'vs/platform/windows/common/windows'; -import { ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, TEXT_DIFF_EDITOR_ID, SplitEditorsVertically, InEditorZenModeContext, IsCenteredLayoutContext } from 'vs/workbench/common/editor'; +import { ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, TEXT_DIFF_EDITOR_ID, SplitEditorsVertically, InEditorZenModeContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext } from 'vs/workbench/common/editor'; import { trackFocus, addDisposableListener, EventType } from 'vs/base/browser/dom'; import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -52,17 +52,20 @@ export class WorkbenchContextKeysHandler extends Disposable { private inputFocusedContext: IContextKey; private activeEditorContext: IContextKey; + + private activeEditorGroupEmpty: IContextKey; + private activeEditorGroupIndex: IContextKey; + private activeEditorGroupLast: IContextKey; + private multipleEditorGroupsContext: IContextKey; + private editorsVisibleContext: IContextKey; private textCompareEditorVisibleContext: IContextKey; private textCompareEditorActiveContext: IContextKey; - private activeEditorGroupEmpty: IContextKey; - private multipleEditorGroupsContext: IContextKey; private splitEditorsVerticallyContext: IContextKey; private workbenchStateContext: IContextKey; private workspaceFolderCountContext: IContextKey; - private inZenModeContext: IContextKey; private isFullscreenContext: IContextKey; private isCenteredLayoutContext: IContextKey; @@ -90,8 +93,10 @@ export class WorkbenchContextKeysHandler extends Disposable { this._register(this.editorService.onDidActiveEditorChange(() => this.updateEditorContextKeys())); this._register(this.editorService.onDidVisibleEditorsChange(() => this.updateEditorContextKeys())); + this._register(this.editorGroupService.onDidAddGroup(() => this.updateEditorContextKeys())); this._register(this.editorGroupService.onDidRemoveGroup(() => this.updateEditorContextKeys())); + this._register(this.editorGroupService.onDidGroupIndexChange(() => this.updateEditorContextKeys())); this._register(addDisposableListener(window, EventType.FOCUS_IN, () => this.updateInputContextKeys(), true)); @@ -141,6 +146,8 @@ export class WorkbenchContextKeysHandler extends Disposable { this.textCompareEditorVisibleContext = TextCompareEditorVisibleContext.bindTo(this.contextKeyService); this.textCompareEditorActiveContext = TextCompareEditorActiveContext.bindTo(this.contextKeyService); this.activeEditorGroupEmpty = ActiveEditorGroupEmptyContext.bindTo(this.contextKeyService); + this.activeEditorGroupIndex = ActiveEditorGroupIndexContext.bindTo(this.contextKeyService); + this.activeEditorGroupLast = ActiveEditorGroupLastContext.bindTo(this.contextKeyService); this.multipleEditorGroupsContext = MultipleEditorGroupsContext.bindTo(this.contextKeyService); // Inputs @@ -176,6 +183,7 @@ export class WorkbenchContextKeysHandler extends Disposable { } private updateEditorContextKeys(): void { + const activeGroup = this.editorGroupService.activeGroup; const activeControl = this.editorService.activeControl; const visibleEditors = this.editorService.visibleControls; @@ -194,12 +202,16 @@ export class WorkbenchContextKeysHandler extends Disposable { this.activeEditorGroupEmpty.reset(); } - if (this.editorGroupService.count > 1) { + const groupCount = this.editorGroupService.count; + if (groupCount > 1) { this.multipleEditorGroupsContext.set(true); } else { this.multipleEditorGroupsContext.reset(); } + this.activeEditorGroupIndex.set(activeGroup.index); + this.activeEditorGroupLast.set(activeGroup.index === groupCount - 1); + if (activeControl) { this.activeEditorContext.set(activeControl.getId()); } else { @@ -250,4 +262,4 @@ export class WorkbenchContextKeysHandler extends Disposable { private updateSideBarContextKeys(): void { this.sideBarVisibleContext.set(this.layoutService.isVisible(Parts.SIDEBAR_PART)); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index f4b7ce43846..81f9ab6a168 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -94,6 +94,9 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro private readonly _onDidActiveGroupChange: Emitter = this._register(new Emitter()); readonly onDidActiveGroupChange: Event = this._onDidActiveGroupChange.event; + private readonly _onDidGroupIndexChange: Emitter = this._register(new Emitter()); + readonly onDidGroupIndexChange: Event = this._onDidGroupIndexChange.event; + private readonly _onDidActivateGroup: Emitter = this._register(new Emitter()); readonly onDidActivateGroup: Event = this._onDidActivateGroup.event; @@ -512,8 +515,13 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro // Track editor change groupDisposables.add(groupView.onDidGroupChange(e => { - if (e.kind === GroupChangeKind.EDITOR_ACTIVE) { - this.updateContainer(); + switch (e.kind) { + case GroupChangeKind.EDITOR_ACTIVE: + this.updateContainer(); + break; + case GroupChangeKind.GROUP_INDEX: + this._onDidGroupIndexChange.fire(groupView); + break; } })); diff --git a/src/vs/workbench/common/editor.ts b/src/vs/workbench/common/editor.ts index 9827b74e519..97f5aa1e79d 100644 --- a/src/vs/workbench/common/editor.ts +++ b/src/vs/workbench/common/editor.ts @@ -30,6 +30,8 @@ export const NoEditorsVisibleContext: ContextKeyExpr = EditorsVisibleContext.toN export const TextCompareEditorVisibleContext = new RawContextKey('textCompareEditorVisible', false); export const TextCompareEditorActiveContext = new RawContextKey('textCompareEditorActive', false); export const ActiveEditorGroupEmptyContext = new RawContextKey('activeEditorGroupEmpty', false); +export const ActiveEditorGroupIndexContext = new RawContextKey('activeEditorGroupIndex', -1); +export const ActiveEditorGroupLastContext = new RawContextKey('activeEditorGroupLast', false); export const MultipleEditorGroupsContext = new RawContextKey('multipleEditorGroups', false); export const SingleEditorGroupsContext = MultipleEditorGroupsContext.toNegated(); export const InEditorZenModeContext = new RawContextKey('inZenMode', false); diff --git a/src/vs/workbench/services/editor/common/editorGroupsService.ts b/src/vs/workbench/services/editor/common/editorGroupsService.ts index 78e852dd29c..6c9a974e6ea 100644 --- a/src/vs/workbench/services/editor/common/editorGroupsService.ts +++ b/src/vs/workbench/services/editor/common/editorGroupsService.ts @@ -176,6 +176,11 @@ export interface IEditorGroupsService { */ readonly onDidLayout: Event; + /** + * An event for when the index of a group changes. + */ + readonly onDidGroupIndexChange: Event; + /** * The size of the editor groups area. */ diff --git a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts index 35584c57600..042ca015221 100644 --- a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts @@ -261,6 +261,11 @@ suite('EditorGroupsService', () => { const rightGroup = part.addGroup(rootGroup, GroupDirection.RIGHT); const downGroup = part.addGroup(rightGroup, GroupDirection.DOWN); + let groupIndexChangedCounter = 0; + const groupIndexChangedListener = part.onDidGroupIndexChange(() => { + groupIndexChangedCounter++; + }); + let indexChangeCounter = 0; const labelChangeListener = downGroup.onDidGroupChange(e => { if (e.kind === GroupChangeKind.GROUP_INDEX) { @@ -281,6 +286,7 @@ suite('EditorGroupsService', () => { assert.equal(rootGroup.label, 'Group 1'); assert.equal(downGroup.label, 'Group 2'); assert.equal(indexChangeCounter, 1); + assert.equal(groupIndexChangedCounter, 1); part.moveGroup(downGroup, rootGroup, GroupDirection.UP); assert.equal(downGroup.index, 0); @@ -288,6 +294,7 @@ suite('EditorGroupsService', () => { assert.equal(downGroup.label, 'Group 1'); assert.equal(rootGroup.label, 'Group 2'); assert.equal(indexChangeCounter, 2); + assert.equal(groupIndexChangedCounter, 3); const newFirstGroup = part.addGroup(downGroup, GroupDirection.UP); assert.equal(newFirstGroup.index, 0); @@ -297,8 +304,10 @@ suite('EditorGroupsService', () => { assert.equal(downGroup.label, 'Group 2'); assert.equal(rootGroup.label, 'Group 3'); assert.equal(indexChangeCounter, 3); + assert.equal(groupIndexChangedCounter, 6); labelChangeListener.dispose(); + groupIndexChangedListener.dispose(); part.dispose(); }); diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 3895ed64e2a..3bebf0fa5a9 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -665,6 +665,7 @@ export class TestEditorGroupsService implements IEditorGroupsService { onDidAddGroup: Event = Event.None; onDidRemoveGroup: Event = Event.None; onDidMoveGroup: Event = Event.None; + onDidGroupIndexChange: Event = Event.None; onDidLayout: Event = Event.None; orientation: any; From a417a060ab396ad8fe4b778a363d62fa08476966 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 9 Aug 2019 09:27:45 +0200 Subject: [PATCH 388/861] fixes #78167 --- src/vs/base/browser/ui/grid/gridview.ts | 1 + src/vs/base/browser/ui/splitview/splitview.css | 3 ++- src/vs/base/browser/ui/splitview/splitview.ts | 7 ++++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts index 497678cee41..ae8c4ed810a 100644 --- a/src/vs/base/browser/ui/grid/gridview.ts +++ b/src/vs/base/browser/ui/grid/gridview.ts @@ -348,6 +348,7 @@ class BranchNode implements ISplitView, IDisposable { } this.splitview.setViewVisible(index, visible); + this._onDidChange.fire(undefined); } getChildCachedVisibleSize(index: number): number | undefined { diff --git a/src/vs/base/browser/ui/splitview/splitview.css b/src/vs/base/browser/ui/splitview/splitview.css index 6fb8f1c61d0..c0f3634d499 100644 --- a/src/vs/base/browser/ui/splitview/splitview.css +++ b/src/vs/base/browser/ui/splitview/splitview.css @@ -39,6 +39,7 @@ white-space: initial; flex: none; position: relative; + overflow: hidden; } .monaco-split-view2 > .split-view-container > .split-view-view:not(.visible) { @@ -72,4 +73,4 @@ .monaco-split-view2.separator-border.vertical > .split-view-container > .split-view-view:not(:first-child)::before { height: 1px; width: 100%; -} \ No newline at end of file +} diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index 37d44dbaad9..5f6cbe73e3e 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -125,7 +125,10 @@ abstract class ViewItem { dom.addClass(container, 'visible'); } - abstract layout(): void; + layout(): void { + this.container.scrollTop = 0; + this.container.scrollLeft = 0; + } layoutView(orientation: Orientation): void { this.view.layout(this.size, orientation); @@ -140,6 +143,7 @@ abstract class ViewItem { class VerticalViewItem extends ViewItem { layout(): void { + super.layout(); this.container.style.height = `${this.size}px`; this.layoutView(Orientation.VERTICAL); } @@ -148,6 +152,7 @@ class VerticalViewItem extends ViewItem { class HorizontalViewItem extends ViewItem { layout(): void { + super.layout(); this.container.style.width = `${this.size}px`; this.layoutView(Orientation.HORIZONTAL); } From c89d568be63b5b5e97ebd18839b185291eb8e659 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 9 Aug 2019 09:47:41 +0200 Subject: [PATCH 389/861] :lipstick: --- .../workbench/api/common/extHost.api.impl.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 1e096e0a6c2..857c54638d7 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -104,16 +104,23 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I rpcProtocol.set(ExtHostContext.ExtHostExtensionService, extensionService); rpcProtocol.set(ExtHostContext.ExtHostStorage, extHostStorage); - // create and register addressable instances + // automatically create and register addressable instances const extHostDecorations = rpcProtocol.set(ExtHostContext.ExtHostDecorations, accessor.get(IExtHostDecorations)); + const extHostDocumentsAndEditors = rpcProtocol.set(ExtHostContext.ExtHostDocumentsAndEditors, accessor.get(IExtHostDocumentsAndEditors)); + const extHostCommands = rpcProtocol.set(ExtHostContext.ExtHostCommands, accessor.get(IExtHostCommands)); + const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, accessor.get(IExtHostTerminalService)); + const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, accessor.get(IExtHostDebugService)); + const extHostSearch = rpcProtocol.set(ExtHostContext.ExtHostSearch, accessor.get(IExtHostSearch)); + const extHostTask = rpcProtocol.set(ExtHostContext.ExtHostTask, accessor.get(IExtHostTask)); + const extHostOutputService = rpcProtocol.set(ExtHostContext.ExtHostOutputService, accessor.get(IExtHostOutputService)); + + // manually create and register addressable instances const extHostWebviews = rpcProtocol.set(ExtHostContext.ExtHostWebviews, new ExtHostWebviews(rpcProtocol, initData.environment)); const extHostUrls = rpcProtocol.set(ExtHostContext.ExtHostUrls, new ExtHostUrls(rpcProtocol)); - const extHostDocumentsAndEditors = rpcProtocol.set(ExtHostContext.ExtHostDocumentsAndEditors, accessor.get(IExtHostDocumentsAndEditors)); const extHostDocuments = rpcProtocol.set(ExtHostContext.ExtHostDocuments, new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors)); const extHostDocumentContentProviders = rpcProtocol.set(ExtHostContext.ExtHostDocumentContentProviders, new ExtHostDocumentContentProvider(rpcProtocol, extHostDocumentsAndEditors, extHostLogService)); const extHostDocumentSaveParticipant = rpcProtocol.set(ExtHostContext.ExtHostDocumentSaveParticipant, new ExtHostDocumentSaveParticipant(extHostLogService, extHostDocuments, rpcProtocol.getProxy(MainContext.MainThreadTextEditors))); const extHostEditors = rpcProtocol.set(ExtHostContext.ExtHostEditors, new ExtHostEditors(rpcProtocol, extHostDocumentsAndEditors)); - const extHostCommands = rpcProtocol.set(ExtHostContext.ExtHostCommands, accessor.get(IExtHostCommands)); const extHostTreeViews = rpcProtocol.set(ExtHostContext.ExtHostTreeViews, new ExtHostTreeViews(rpcProtocol.getProxy(MainContext.MainThreadTreeViews), extHostCommands, extHostLogService)); const extHostEditorInsets = rpcProtocol.set(ExtHostContext.ExtHostEditorInsets, new ExtHostEditorInsets(rpcProtocol.getProxy(MainContext.MainThreadEditorInsets), extHostEditors, initData.environment)); const extHostDiagnostics = rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, new ExtHostDiagnostics(rpcProtocol)); @@ -121,15 +128,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I const extHostFileSystem = rpcProtocol.set(ExtHostContext.ExtHostFileSystem, new ExtHostFileSystem(rpcProtocol, extHostLanguageFeatures)); const extHostFileSystemEvent = rpcProtocol.set(ExtHostContext.ExtHostFileSystemEventService, new ExtHostFileSystemEventService(rpcProtocol, extHostDocumentsAndEditors)); const extHostQuickOpen = rpcProtocol.set(ExtHostContext.ExtHostQuickOpen, new ExtHostQuickOpen(rpcProtocol, extHostWorkspace, extHostCommands)); - const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, accessor.get(IExtHostTerminalService)); - const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, accessor.get(IExtHostDebugService)); const extHostSCM = rpcProtocol.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(rpcProtocol, extHostCommands, extHostLogService)); const extHostComment = rpcProtocol.set(ExtHostContext.ExtHostComments, new ExtHostComments(rpcProtocol, extHostCommands, extHostDocuments)); - const extHostSearch = rpcProtocol.set(ExtHostContext.ExtHostSearch, accessor.get(IExtHostSearch)); - const extHostTask = rpcProtocol.set(ExtHostContext.ExtHostTask, accessor.get(IExtHostTask)); const extHostWindow = rpcProtocol.set(ExtHostContext.ExtHostWindow, new ExtHostWindow(rpcProtocol)); const extHostProgress = rpcProtocol.set(ExtHostContext.ExtHostProgress, new ExtHostProgress(rpcProtocol.getProxy(MainContext.MainThreadProgress))); - const extHostOutputService = rpcProtocol.set(ExtHostContext.ExtHostOutputService, accessor.get(IExtHostOutputService)); const extHostLabelService = rpcProtocol.set(ExtHostContext.ExtHosLabelService, new ExtHostLabelService(rpcProtocol)); // Check that no named customers are missing From 7a6f22b3afaa5fe586d157a79d12897100ac9335 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 9 Aug 2019 09:51:22 +0200 Subject: [PATCH 390/861] rename rpcService to extHostRpcService --- .../workbench/api/common/extHost.api.impl.ts | 2 +- .../workbench/api/common/extHostCommands.ts | 2 +- .../api/common/extHostConfiguration.ts | 2 +- .../api/common/extHostDecorations.ts | 2 +- .../api/common/extHostDocumentsAndEditors.ts | 2 +- .../api/common/extHostExtensionService.ts | 2 +- src/vs/workbench/api/common/extHostOutput.ts | 2 +- .../{rpcService.ts => extHostRpcService.ts} | 19 +++++++++---------- src/vs/workbench/api/common/extHostStorage.ts | 2 +- .../workbench/api/common/extHostWorkspace.ts | 2 +- .../workbench/api/node/extHostDebugService.ts | 2 +- .../api/node/extHostDownloadService.ts | 2 +- .../api/node/extHostOutputService.ts | 2 +- src/vs/workbench/api/node/extHostSearch.ts | 2 +- src/vs/workbench/api/node/extHostTask.ts | 2 +- .../api/node/extHostTerminalService.ts | 2 +- .../extensions/common/extensionHostMain.ts | 2 +- .../api/extHostWorkspace.test.ts | 2 +- .../electron-browser/api/testRPCProtocol.ts | 2 +- 19 files changed, 27 insertions(+), 28 deletions(-) rename src/vs/workbench/api/common/{rpcService.ts => extHostRpcService.ts} (50%) diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 857c54638d7..4272e94a833 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -67,7 +67,7 @@ import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugServic import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch'; import { ILogService } from 'vs/platform/log/common/log'; import { IURITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService'; -import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; export interface IExtensionApiFactory { diff --git a/src/vs/workbench/api/common/extHostCommands.ts b/src/vs/workbench/api/common/extHostCommands.ts index b0219c67096..1e229fc3dad 100644 --- a/src/vs/workbench/api/common/extHostCommands.ts +++ b/src/vs/workbench/api/common/extHostCommands.ts @@ -20,7 +20,7 @@ import { URI } from 'vs/base/common/uri'; import { Event, Emitter } from 'vs/base/common/event'; import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; interface CommandHandler { callback: Function; diff --git a/src/vs/workbench/api/common/extHostConfiguration.ts b/src/vs/workbench/api/common/extHostConfiguration.ts index bebd81571fc..99402c46057 100644 --- a/src/vs/workbench/api/common/extHostConfiguration.ts +++ b/src/vs/workbench/api/common/extHostConfiguration.ts @@ -19,7 +19,7 @@ import { isObject } from 'vs/base/common/types'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { Barrier } from 'vs/base/common/async'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; function lookUp(tree: any, key: string) { if (key) { diff --git a/src/vs/workbench/api/common/extHostDecorations.ts b/src/vs/workbench/api/common/extHostDecorations.ts index 37b57b9de13..b62fc15ee32 100644 --- a/src/vs/workbench/api/common/extHostDecorations.ts +++ b/src/vs/workbench/api/common/extHostDecorations.ts @@ -11,7 +11,7 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { asArray } from 'vs/base/common/arrays'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; interface ProviderData { provider: vscode.DecorationProvider; diff --git a/src/vs/workbench/api/common/extHostDocumentsAndEditors.ts b/src/vs/workbench/api/common/extHostDocumentsAndEditors.ts index 6a5762373ec..e80289ecb5f 100644 --- a/src/vs/workbench/api/common/extHostDocumentsAndEditors.ts +++ b/src/vs/workbench/api/common/extHostDocumentsAndEditors.ts @@ -13,7 +13,7 @@ import { ExtHostTextEditor } from 'vs/workbench/api/common/extHostTextEditor'; import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters'; import { Disposable } from 'vs/workbench/api/common/extHostTypes'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsShape { diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts index 6f504bc9d80..d3e9be7b6ab 100644 --- a/src/vs/workbench/api/common/extHostExtensionService.ts +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -31,7 +31,7 @@ import { ResolvedAuthority, ResolvedOptions } from 'vs/platform/remote/common/re import { IInstantiationService, createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths'; -import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; interface ITestRunner { diff --git a/src/vs/workbench/api/common/extHostOutput.ts b/src/vs/workbench/api/common/extHostOutput.ts index 78aca487bf8..69fa1b36861 100644 --- a/src/vs/workbench/api/common/extHostOutput.ts +++ b/src/vs/workbench/api/common/extHostOutput.ts @@ -10,7 +10,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { VSBuffer } from 'vs/base/common/buffer'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; export abstract class AbstractExtHostOutputChannel extends Disposable implements vscode.OutputChannel { diff --git a/src/vs/workbench/api/common/rpcService.ts b/src/vs/workbench/api/common/extHostRpcService.ts similarity index 50% rename from src/vs/workbench/api/common/rpcService.ts rename to src/vs/workbench/api/common/extHostRpcService.ts index ab2a788d52c..5524e6f2ebd 100644 --- a/src/vs/workbench/api/common/rpcService.ts +++ b/src/vs/workbench/api/common/extHostRpcService.ts @@ -3,27 +3,26 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IMainContext } from 'vs/workbench/api/common/extHost.protocol'; -import { ProxyIdentifier } from 'vs/workbench/services/extensions/common/proxyIdentifier'; +import { ProxyIdentifier, IRPCProtocol } from 'vs/workbench/services/extensions/common/proxyIdentifier'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; export const IExtHostRpcService = createDecorator('IExtHostRpcService'); -export interface IExtHostRpcService extends IMainContext { +export interface IExtHostRpcService extends IRPCProtocol { _serviceBrand: any; } export class ExtHostRpcService implements IExtHostRpcService { readonly _serviceBrand: any; - getProxy: (identifier: ProxyIdentifier) => T; - set: (identifier: ProxyIdentifier, instance: R) => R; - assertRegistered: (identifiers: ProxyIdentifier[]) => void; + readonly getProxy: (identifier: ProxyIdentifier) => T; + readonly set: (identifier: ProxyIdentifier, instance: R) => R; + readonly assertRegistered: (identifiers: ProxyIdentifier[]) => void; - constructor(mainContext: IMainContext) { - this.getProxy = mainContext.getProxy.bind(mainContext); - this.set = mainContext.set.bind(mainContext); - this.assertRegistered = mainContext.assertRegistered.bind(mainContext); + constructor(rpcProtocol: IRPCProtocol) { + this.getProxy = rpcProtocol.getProxy.bind(rpcProtocol); + this.set = rpcProtocol.set.bind(rpcProtocol); + this.assertRegistered = rpcProtocol.assertRegistered.bind(rpcProtocol); } diff --git a/src/vs/workbench/api/common/extHostStorage.ts b/src/vs/workbench/api/common/extHostStorage.ts index f8669c45311..efa42fa2142 100644 --- a/src/vs/workbench/api/common/extHostStorage.ts +++ b/src/vs/workbench/api/common/extHostStorage.ts @@ -5,7 +5,7 @@ import { MainContext, MainThreadStorageShape, ExtHostStorageShape } from './extHost.protocol'; import { Emitter } from 'vs/base/common/event'; -import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; export interface IStorageChangeEvent { diff --git a/src/vs/workbench/api/common/extHostWorkspace.ts b/src/vs/workbench/api/common/extHostWorkspace.ts index e0b0b2006d6..60430507428 100644 --- a/src/vs/workbench/api/common/extHostWorkspace.ts +++ b/src/vs/workbench/api/common/extHostWorkspace.ts @@ -27,7 +27,7 @@ import { Schemas } from 'vs/base/common/network'; import { withUndefinedAsNull } from 'vs/base/common/types'; import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; export interface IExtHostWorkspaceProvider { getWorkspaceFolder2(uri: vscode.Uri, resolveParent?: boolean): Promise; diff --git a/src/vs/workbench/api/node/extHostDebugService.ts b/src/vs/workbench/api/node/extHostDebugService.ts index cf179f59a6f..f18bd5bfe91 100644 --- a/src/vs/workbench/api/node/extHostDebugService.ts +++ b/src/vs/workbench/api/node/extHostDebugService.ts @@ -36,7 +36,7 @@ import { IExtensionDescription } from 'vs/platform/extensions/common/extensions' import { SignService } from 'vs/platform/sign/node/signService'; import { ISignService } from 'vs/platform/sign/common/sign'; import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; -import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService'; export class ExtHostDebugService implements IExtHostDebugService, ExtHostDebugServiceShape { diff --git a/src/vs/workbench/api/node/extHostDownloadService.ts b/src/vs/workbench/api/node/extHostDownloadService.ts index 4bf43510397..9d81fe712ed 100644 --- a/src/vs/workbench/api/node/extHostDownloadService.ts +++ b/src/vs/workbench/api/node/extHostDownloadService.ts @@ -10,7 +10,7 @@ import { IExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; import { Disposable } from 'vs/base/common/lifecycle'; import { MainContext } from 'vs/workbench/api/common/extHost.protocol'; import { URI } from 'vs/base/common/uri'; -import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; export class ExtHostDownloadService extends Disposable { diff --git a/src/vs/workbench/api/node/extHostOutputService.ts b/src/vs/workbench/api/node/extHostOutputService.ts index 5ad2047201a..3a69496d989 100644 --- a/src/vs/workbench/api/node/extHostOutputService.ts +++ b/src/vs/workbench/api/node/extHostOutputService.ts @@ -12,7 +12,7 @@ import { toLocalISOString } from 'vs/base/common/date'; import { dirExists, mkdirp } from 'vs/base/node/pfs'; import { AbstractExtHostOutputChannel, ExtHostPushOutputChannel, ExtHostOutputService, LazyOutputChannel } from 'vs/workbench/api/common/extHostOutput'; import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; -import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; export class ExtHostOutputChannelBackedByFile extends AbstractExtHostOutputChannel { diff --git a/src/vs/workbench/api/node/extHostSearch.ts b/src/vs/workbench/api/node/extHostSearch.ts index ea1ee401e18..b0e8753c0cd 100644 --- a/src/vs/workbench/api/node/extHostSearch.ts +++ b/src/vs/workbench/api/node/extHostSearch.ts @@ -16,7 +16,7 @@ import { OutputChannel } from 'vs/workbench/services/search/node/ripgrepSearchUt import { TextSearchManager } from 'vs/workbench/services/search/node/textSearchManager'; import * as vscode from 'vscode'; import { ExtHostSearchShape, MainContext, MainThreadSearchShape } from '../common/extHost.protocol'; -import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; import { IURITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService'; import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index c826cccf633..647a2be3f08 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -31,7 +31,7 @@ import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { CancellationToken } from 'vs/base/common/cancellation'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; -import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; import { Schemas } from 'vs/base/common/network'; diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index e32decd5177..02de2e82ed6 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -23,7 +23,7 @@ import { ExtHostDocumentsAndEditors, IExtHostDocumentsAndEditors } from 'vs/work import { getSystemShell, detectAvailableShells } from 'vs/workbench/contrib/terminal/node/terminal'; import { getMainProcessParentEnv } from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; -import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; export class BaseExtHostTerminal { public _id: number | undefined; diff --git a/src/vs/workbench/services/extensions/common/extensionHostMain.ts b/src/vs/workbench/services/extensions/common/extensionHostMain.ts index 96f006ffe36..d1c8e25185b 100644 --- a/src/vs/workbench/services/extensions/common/extensionHostMain.ts +++ b/src/vs/workbench/services/extensions/common/extensionHostMain.ts @@ -19,7 +19,7 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IExtHostRpcService, ExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostRpcService, ExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; import { IURITransformerService, URITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService'; import { IExtHostExtensionService, IHostUtils } from 'vs/workbench/api/common/extHostExtensionService'; diff --git a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts index ed1d5ed3875..0a605c63bd0 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts @@ -16,7 +16,7 @@ import { RelativePattern } from 'vs/workbench/api/common/extHostTypes'; import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import { mock } from 'vs/workbench/test/electron-browser/api/mock'; import { TestRPCProtocol } from './testRPCProtocol'; -import { ExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { ExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; function createExtHostWorkspace(mainContext: IMainContext, data: IWorkspaceData, logService: ILogService): ExtHostWorkspace { diff --git a/src/vs/workbench/test/electron-browser/api/testRPCProtocol.ts b/src/vs/workbench/test/electron-browser/api/testRPCProtocol.ts index a51c4feb788..4eef6eb559c 100644 --- a/src/vs/workbench/test/electron-browser/api/testRPCProtocol.ts +++ b/src/vs/workbench/test/electron-browser/api/testRPCProtocol.ts @@ -7,7 +7,7 @@ import { ProxyIdentifier } from 'vs/workbench/services/extensions/common/proxyId import { CharCode } from 'vs/base/common/charCode'; import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol'; import { isThenable } from 'vs/base/common/async'; -import { IExtHostRpcService } from 'vs/workbench/api/common/rpcService'; +import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; export function SingleProxyRPCProtocol(thing: any): IExtHostContext & IExtHostRpcService { return { From cd6ed7bc7831637e936b22b22406e0d8bee4857b Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 9 Aug 2019 09:53:57 +0200 Subject: [PATCH 391/861] fixed minimist reference & js typing --- src/main.js | 4 ++-- src/tsconfig.base.json | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main.js b/src/main.js index 6902f1d6530..4be5f2ed955 100644 --- a/src/main.js +++ b/src/main.js @@ -133,7 +133,7 @@ function onReady() { } /** - * @typedef {import('minimist').ParsedArgs} ParsedArgs + * @typedef {{ [arg: string]: any; '--'?: string[]; _: string[]; }} ParsedArgs * * @param {ParsedArgs} cliArgs */ @@ -186,7 +186,7 @@ function getUserDataPath(cliArgs) { * @returns {ParsedArgs} */ function parseCLIArgs() { - const minimist = require('minimist'); + const minimist = require('vscode-minimist'); return minimist(process.argv, { string: [ diff --git a/src/tsconfig.base.json b/src/tsconfig.base.json index cfd4b390a62..79d754c01f5 100644 --- a/src/tsconfig.base.json +++ b/src/tsconfig.base.json @@ -20,11 +20,10 @@ }, "types": [ "keytar", - "minimist", "mocha", "semver", "sinon", "winreg" ] } -} \ No newline at end of file +} From 481d955239e7d3026dd61b1648fd1d2e0c98e76d Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 9 Aug 2019 10:01:21 +0200 Subject: [PATCH 392/861] no require.__$__nodeRequire in /common/-layer --- src/vs/workbench/api/common/extHostExtensionService.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts index d3e9be7b6ab..58098d94099 100644 --- a/src/vs/workbench/api/common/extHostExtensionService.ts +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -524,7 +524,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio }); } - private _doHandleExtensionTests(): Promise { + private async _doHandleExtensionTests(): Promise { const { extensionDevelopmentLocationURI: extensionDevelopmentLocationURI, extensionTestsLocationURI } = this._initData.environment; if (!(extensionDevelopmentLocationURI && extensionTestsLocationURI && extensionTestsLocationURI.scheme === Schemas.file)) { return Promise.resolve(undefined); @@ -536,7 +536,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio let testRunner: ITestRunner | INewTestRunner | undefined; let requireError: Error | undefined; try { - testRunner = require.__$__nodeRequire(extensionTestsPath); + testRunner = await this._loadCommonJSModule(extensionTestsPath, new ExtensionActivationTimesBuilder(false)); } catch (error) { requireError = error; } From 96e0edcd3347facba71e06378b42c69d8011127e Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 9 Aug 2019 10:46:04 +0200 Subject: [PATCH 393/861] iconLabel: supportOcticons by defaul should be false #77747 --- src/vs/base/browser/ui/iconLabel/iconLabel.ts | 6 +++--- src/vs/base/parts/quickopen/browser/quickOpenModel.ts | 2 +- src/vs/editor/contrib/suggest/suggestWidget.ts | 2 +- src/vs/workbench/browser/parts/quickinput/quickInputList.ts | 2 +- src/vs/workbench/browser/parts/views/customView.ts | 2 +- .../workbench/contrib/files/browser/views/explorerViewer.ts | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vs/base/browser/ui/iconLabel/iconLabel.ts b/src/vs/base/browser/ui/iconLabel/iconLabel.ts index a61b1bba525..ec4a3c2f6de 100644 --- a/src/vs/base/browser/ui/iconLabel/iconLabel.ts +++ b/src/vs/base/browser/ui/iconLabel/iconLabel.ts @@ -12,7 +12,7 @@ import { Disposable } from 'vs/base/common/lifecycle'; export interface IIconLabelCreationOptions { supportHighlights?: boolean; supportDescriptionHighlights?: boolean; - donotSupportOcticons?: boolean; + supportOcticons?: boolean; } export interface IIconLabelValueOptions { @@ -100,13 +100,13 @@ export class IconLabel extends Disposable { this.labelDescriptionContainer = this._register(new FastLabelNode(dom.append(this.domNode.element, dom.$('.monaco-icon-label-description-container')))); if (options && options.supportHighlights) { - this.labelNode = new HighlightedLabel(dom.append(this.labelDescriptionContainer.element, dom.$('a.label-name')), !options.donotSupportOcticons); + this.labelNode = new HighlightedLabel(dom.append(this.labelDescriptionContainer.element, dom.$('a.label-name')), !!options.supportOcticons); } else { this.labelNode = this._register(new FastLabelNode(dom.append(this.labelDescriptionContainer.element, dom.$('a.label-name')))); } if (options && options.supportDescriptionHighlights) { - this.descriptionNodeFactory = () => new HighlightedLabel(dom.append(this.labelDescriptionContainer.element, dom.$('span.label-description')), !options.donotSupportOcticons); + this.descriptionNodeFactory = () => new HighlightedLabel(dom.append(this.labelDescriptionContainer.element, dom.$('span.label-description')), !!options.supportOcticons); } else { this.descriptionNodeFactory = () => this._register(new FastLabelNode(dom.append(this.labelDescriptionContainer.element, dom.$('span.label-description')))); } diff --git a/src/vs/base/parts/quickopen/browser/quickOpenModel.ts b/src/vs/base/parts/quickopen/browser/quickOpenModel.ts index 6b549c62b44..bb9dec75605 100644 --- a/src/vs/base/parts/quickopen/browser/quickOpenModel.ts +++ b/src/vs/base/parts/quickopen/browser/quickOpenModel.ts @@ -352,7 +352,7 @@ class Renderer implements IRenderer { row1.appendChild(icon); // Label - const label = new IconLabel(row1, { supportHighlights: true, supportDescriptionHighlights: true }); + const label = new IconLabel(row1, { supportHighlights: true, supportDescriptionHighlights: true, supportOcticons: true }); // Keybinding const keybindingContainer = document.createElement('span'); diff --git a/src/vs/editor/contrib/suggest/suggestWidget.ts b/src/vs/editor/contrib/suggest/suggestWidget.ts index e0ac791724b..57b6ed5638a 100644 --- a/src/vs/editor/contrib/suggest/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/suggestWidget.ts @@ -115,7 +115,7 @@ class Renderer implements IListRenderer const text = append(container, $('.contents')); const main = append(text, $('.main')); - data.iconLabel = new IconLabel(main, { supportHighlights: true }); + data.iconLabel = new IconLabel(main, { supportHighlights: true, supportOcticons: true }); data.disposables.add(data.iconLabel); data.typeLabel = append(main, $('span.type-label')); diff --git a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts index 97bc546f7e8..b685f8ccabc 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts @@ -114,7 +114,7 @@ class ListElementRenderer implements IListRenderer Date: Fri, 9 Aug 2019 11:17:24 +0200 Subject: [PATCH 394/861] :lipstick: --- src/vs/workbench/browser/parts/editor/editorPart.ts | 3 +++ .../services/editor/test/browser/editorGroupsService.test.ts | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index 81f9ab6a168..df41417a615 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -821,6 +821,9 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro // Update container this.updateContainer(); + + // Notify group index change we created the entire grid + this.notifyGroupIndexChange(); } private doCreateGridControlWithPreviousState(): boolean { diff --git a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts index 042ca015221..c09e9aaf1e7 100644 --- a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts @@ -196,8 +196,11 @@ suite('EditorGroupsService', () => { const gridOrder = part.getGroups(GroupsOrder.GRID_APPEARANCE); assert.equal(gridOrder.length, 3); assert.equal(gridOrder[0], rootGroup); + assert.equal(gridOrder[0].index, 0); assert.equal(gridOrder[1], rightGroup); + assert.equal(gridOrder[1].index, 1); assert.equal(gridOrder[2], downGroup); + assert.equal(gridOrder[2].index, 2); part.moveGroup(downGroup, rightGroup, GroupDirection.DOWN); assert.equal(groupMovedCounter, 1); From 3c93450dd495b07111ffc371ce7f12d9b94a84cb Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 9 Aug 2019 11:23:17 +0200 Subject: [PATCH 395/861] list: add additionalScrollHeight option --- src/vs/base/browser/ui/list/listView.ts | 6 +++++- src/vs/base/browser/ui/tree/abstractTree.ts | 1 + src/vs/base/browser/ui/tree/asyncDataTree.ts | 3 ++- src/vs/platform/list/browser/listService.ts | 4 +++- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/vs/base/browser/ui/list/listView.ts b/src/vs/base/browser/ui/list/listView.ts index c35ddf1e1dd..4f5394f773d 100644 --- a/src/vs/base/browser/ui/list/listView.ts +++ b/src/vs/base/browser/ui/list/listView.ts @@ -57,6 +57,7 @@ export interface IListViewOptions { readonly mouseSupport?: boolean; readonly horizontalScrolling?: boolean; readonly ariaProvider?: IAriaProvider; + readonly additionalScrollHeight?: number; } const DefaultOptions = { @@ -175,6 +176,7 @@ export class ListView implements ISpliceable, IDisposable { private setRowLineHeight: boolean; private supportDynamicHeights: boolean; private horizontalScrolling: boolean; + private additionalScrollHeight: number; private ariaProvider: IAriaProvider; private scrollWidth: number | undefined; private canUseTranslate3d: boolean | undefined = undefined; @@ -228,6 +230,8 @@ export class ListView implements ISpliceable, IDisposable { this.horizontalScrolling = getOrDefault(options, o => o.horizontalScrolling, DefaultOptions.horizontalScrolling); DOM.toggleClass(this.domNode, 'horizontal-scrolling', this.horizontalScrolling); + this.additionalScrollHeight = typeof options.additionalScrollHeight === 'undefined' ? 0 : options.additionalScrollHeight; + this.ariaProvider = options.ariaProvider || { getSetSize: (e, i, length) => length, getPosInSet: (_, index) => index + 1 }; this.rowsContainer = document.createElement('div'); @@ -688,7 +692,7 @@ export class ListView implements ISpliceable, IDisposable { } get scrollHeight(): number { - return this._scrollHeight + (this.horizontalScrolling ? 10 : 0); + return this._scrollHeight + (this.horizontalScrolling ? 10 : 0) + this.additionalScrollHeight; } // Events diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 05f6841fd72..ee5fda5a4ab 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -897,6 +897,7 @@ export interface IAbstractTreeOptions extends IAbstractTr readonly autoExpandSingleChildren?: boolean; readonly keyboardNavigationEventFilter?: IKeyboardNavigationEventFilter; readonly expandOnlyOnTwistieClick?: boolean | ((e: T) => boolean); + readonly additionalScrollHeight?: number; } function dfs(node: ITreeNode, fn: (node: ITreeNode) => void): void { diff --git a/src/vs/base/browser/ui/tree/asyncDataTree.ts b/src/vs/base/browser/ui/tree/asyncDataTree.ts index 385cd3556de..b26b80d2c49 100644 --- a/src/vs/base/browser/ui/tree/asyncDataTree.ts +++ b/src/vs/base/browser/ui/tree/asyncDataTree.ts @@ -238,7 +238,8 @@ function asObjectTreeOptions(options?: IAsyncDataTreeOpt e => (options.expandOnlyOnTwistieClick as ((e: T) => boolean))(e.element as T) ) ), - ariaProvider: undefined + ariaProvider: undefined, + additionalScrollHeight: options.additionalScrollHeight }; } diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index 0ef822bae84..6c5ac488c5f 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -890,6 +890,7 @@ function workbenchTreeDataPreamble Date: Fri, 9 Aug 2019 11:23:37 +0200 Subject: [PATCH 396/861] explorer: adopt additionalScrollHeight fixes #1043 --- src/vs/workbench/contrib/files/browser/views/explorerView.ts | 3 ++- src/vs/workbench/contrib/files/browser/views/explorerViewer.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerView.ts b/src/vs/workbench/contrib/files/browser/views/explorerView.ts index f5a52355075..defa67d92f8 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerView.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerView.ts @@ -301,7 +301,8 @@ export class ExplorerView extends ViewletPanel { filter: this.filter, sorter: this.instantiationService.createInstance(FileSorter), dnd: this.instantiationService.createInstance(FileDragAndDrop), - autoExpandSingleChildren: true + autoExpandSingleChildren: true, + additionalScrollHeight: 2 * ExplorerDelegate.ITEM_HEIGHT }); this._register(this.tree); diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index bffa827671f..11e50458c94 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -49,7 +49,7 @@ import { FuzzyScore, createMatches } from 'vs/base/common/filters'; export class ExplorerDelegate implements IListVirtualDelegate { - private static readonly ITEM_HEIGHT = 22; + static readonly ITEM_HEIGHT = 22; getHeight(element: ExplorerItem): number { return ExplorerDelegate.ITEM_HEIGHT; From 4e23501dfa0713c8b2ba5aabe360722509f16a2b Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Fri, 9 Aug 2019 12:11:02 +0200 Subject: [PATCH 397/861] Allow empty string in variables promptString Fixes ##68617 --- .../browser/configurationResolverService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts b/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts index f406a3e0d63..4709a15555b 100644 --- a/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts +++ b/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts @@ -250,7 +250,7 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR inputOptions.value = info.default; } return this.quickInputService.input(inputOptions).then(resolvedInput => { - return resolvedInput ? resolvedInput : undefined; + return resolvedInput; }); } From 41df640e0602b20c852d11d5c26eb2f45e648706 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 9 Aug 2019 13:24:40 +0200 Subject: [PATCH 398/861] format error message properly (#78740) --- src/vs/workbench/api/common/extHostWorkspace.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/api/common/extHostWorkspace.ts b/src/vs/workbench/api/common/extHostWorkspace.ts index 3c176107270..a36bcf43346 100644 --- a/src/vs/workbench/api/common/extHostWorkspace.ts +++ b/src/vs/workbench/api/common/extHostWorkspace.ts @@ -288,7 +288,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac this._unconfirmedWorkspace = undefined; // show error to user - this._messageService.$showMessage(Severity.Error, localize('updateerror', "Extension '{0}' failed to update workspace folders: {1}", extName, error), { extension }, []); + this._messageService.$showMessage(Severity.Error, localize('updateerror', "Extension '{0}' failed to update workspace folders: {1}", extName, error.toString()), { extension }, []); }); } From 74a08650d6fc4fb2f09061bdeb000e88669c2109 Mon Sep 17 00:00:00 2001 From: Darrien Singleton Date: Fri, 9 Aug 2019 08:08:42 -0400 Subject: [PATCH 399/861] Fixed incorrect git uri ref for untracked files --- extensions/git/src/commands.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 20843b21ada..74de81e31fa 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -353,11 +353,11 @@ export class CommandCenter { switch (resource.type) { case Status.INDEX_MODIFIED: case Status.INDEX_RENAMED: - case Status.UNTRACKED: case Status.INDEX_ADDED: return this.getURI(resource.original, 'HEAD'); case Status.MODIFIED: + case Status.UNTRACKED: return this.getURI(resource.resourceUri, '~'); case Status.DELETED_BY_THEM: From b092c9a88bb23e22c2528a1e8ac23b99ebe122e4 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 9 Aug 2019 14:18:26 +0200 Subject: [PATCH 400/861] fix tests --- src/vs/base/browser/ui/splitview/splitview.ts | 1 + src/vs/base/test/browser/ui/grid/grid.test.ts | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index 5f6cbe73e3e..e6eaeae6bdc 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -462,6 +462,7 @@ export class SplitView extends Disposable { this.distributeEmptySpace(index); this.layoutViews(); + this.saveProportions(); } getViewCachedVisibleSize(index: number): number | undefined { diff --git a/src/vs/base/test/browser/ui/grid/grid.test.ts b/src/vs/base/test/browser/ui/grid/grid.test.ts index 3c2b1b4ec44..25468a06bb9 100644 --- a/src/vs/base/test/browser/ui/grid/grid.test.ts +++ b/src/vs/base/test/browser/ui/grid/grid.test.ts @@ -834,6 +834,24 @@ suite('SerializableGrid', function () { assert.deepEqual(view4.size, [200, 200]); assert.deepEqual(view5.size, [600, 0]); + grid.setViewVisible(view5, true); + + assert.deepEqual(view1.size, [600, 300]); + assert.deepEqual(view2.size, [600, 200]); + assert.deepEqual(view3.size, [200, 400]); + assert.deepEqual(view4.size, [200, 200]); + assert.deepEqual(view5.size, [600, 100]); + + grid.setViewVisible(view5, false); + + assert.deepEqual(view1.size, [600, 400]); + assert.deepEqual(view2.size, [600, 200]); + assert.deepEqual(view3.size, [200, 400]); + assert.deepEqual(view4.size, [200, 200]); + assert.deepEqual(view5.size, [600, 0]); + + grid.setViewVisible(view5, false); + const json = grid.serialize(); assert.deepEqual(json, { orientation: 0, From 642d3a08f5466a0e9b67151fda6d7220a6340a68 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 9 Aug 2019 14:52:42 +0200 Subject: [PATCH 401/861] editors - add action to toggle editor group maximize (fix #72968) --- .../parts/editor/editor.contribution.ts | 3 +- .../workbench/browser/parts/editor/editor.ts | 4 +- .../browser/parts/editor/editorActions.ts | 16 +++++++ .../browser/parts/editor/editorDropTarget.ts | 2 +- .../browser/parts/editor/editorGroupView.ts | 32 ++++++++------ .../browser/parts/editor/editorPart.ts | 43 ++++++++++++++----- .../editor/common/editorGroupsService.ts | 8 +++- .../test/browser/editorGroupsService.test.ts | 28 ++++++------ .../workbench/test/workbenchTestServices.ts | 4 +- 9 files changed, 98 insertions(+), 42 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editor.contribution.ts b/src/vs/workbench/browser/parts/editor/editor.contribution.ts index 354ef330025..31daf2483f5 100644 --- a/src/vs/workbench/browser/parts/editor/editor.contribution.ts +++ b/src/vs/workbench/browser/parts/editor/editor.contribution.ts @@ -36,7 +36,7 @@ import { SplitEditorUpAction, SplitEditorDownAction, MoveEditorToLeftGroupAction, MoveEditorToRightGroupAction, MoveEditorToAboveGroupAction, MoveEditorToBelowGroupAction, CloseAllEditorGroupsAction, JoinAllGroupsAction, FocusLeftGroup, FocusAboveGroup, FocusRightGroup, FocusBelowGroup, EditorLayoutSingleAction, EditorLayoutTwoColumnsAction, EditorLayoutThreeColumnsAction, EditorLayoutTwoByTwoGridAction, EditorLayoutTwoRowsAction, EditorLayoutThreeRowsAction, EditorLayoutTwoColumnsBottomAction, EditorLayoutTwoRowsRightAction, NewEditorGroupLeftAction, NewEditorGroupRightAction, - NewEditorGroupAboveAction, NewEditorGroupBelowAction, SplitEditorOrthogonalAction, CloseEditorInAllGroupsAction, NavigateToLastEditLocationAction + NewEditorGroupAboveAction, NewEditorGroupBelowAction, SplitEditorOrthogonalAction, CloseEditorInAllGroupsAction, NavigateToLastEditLocationAction, ToggleGroupSizesAction } from 'vs/workbench/browser/parts/editor/editorActions'; import * as editorCommands from 'vs/workbench/browser/parts/editor/editorCommands'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; @@ -334,6 +334,7 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(JoinTwoGroupsAction, J registry.registerWorkbenchAction(new SyncActionDescriptor(JoinAllGroupsAction, JoinAllGroupsAction.ID, JoinAllGroupsAction.LABEL), 'View: Join All Editor Groups', category); registry.registerWorkbenchAction(new SyncActionDescriptor(NavigateBetweenGroupsAction, NavigateBetweenGroupsAction.ID, NavigateBetweenGroupsAction.LABEL), 'View: Navigate Between Editor Groups', category); registry.registerWorkbenchAction(new SyncActionDescriptor(ResetGroupSizesAction, ResetGroupSizesAction.ID, ResetGroupSizesAction.LABEL), 'View: Reset Editor Group Sizes', category); +registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleGroupSizesAction, ToggleGroupSizesAction.ID, ToggleGroupSizesAction.LABEL), 'View: Toggle Editor Group Sizes', category); registry.registerWorkbenchAction(new SyncActionDescriptor(MaximizeGroupAction, MaximizeGroupAction.ID, MaximizeGroupAction.LABEL), 'View: Maximize Editor Group and Hide Side Bar', category); registry.registerWorkbenchAction(new SyncActionDescriptor(MinimizeOtherGroupsAction, MinimizeOtherGroupsAction.ID, MinimizeOtherGroupsAction.LABEL), 'View: Maximize Editor Group', category); registry.registerWorkbenchAction(new SyncActionDescriptor(MoveEditorLeftInGroupAction, MoveEditorLeftInGroupAction.ID, MoveEditorLeftInGroupAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.PageUp, mac: { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.LeftArrow) } }), 'View: Move Editor Left', category); diff --git a/src/vs/workbench/browser/parts/editor/editor.ts b/src/vs/workbench/browser/parts/editor/editor.ts index f36234ec441..5a56c61b3f0 100644 --- a/src/vs/workbench/browser/parts/editor/editor.ts +++ b/src/vs/workbench/browser/parts/editor/editor.ts @@ -109,6 +109,9 @@ export interface IEditorGroupView extends IDisposable, ISerializableView, IEdito readonly whenRestored: Promise; readonly disposed: boolean; + readonly isEmpty: boolean; + readonly isMinimized: boolean; + readonly onDidFocus: Event; readonly onWillDispose: Event; readonly onWillOpenEditor: Event; @@ -116,7 +119,6 @@ export interface IEditorGroupView extends IDisposable, ISerializableView, IEdito readonly onWillCloseEditor: Event; readonly onDidCloseEditor: Event; - isEmpty(): boolean; setActive(isActive: boolean): void; notifyIndexChanged(newIndex: number): void; diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index ba90f283b0a..0464d3131be 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -880,6 +880,22 @@ export class ResetGroupSizesAction extends Action { } } +export class ToggleGroupSizesAction extends Action { + + static readonly ID = 'workbench.action.toggleEditorWidths'; + static readonly LABEL = nls.localize('toggleEditorWidths', "Toggle Editor Group Sizes"); + + constructor(id: string, label: string, @IEditorGroupsService private readonly editorGroupService: IEditorGroupsService) { + super(id, label); + } + + run(): Promise { + this.editorGroupService.arrangeGroups(GroupsArrangement.TOGGLE); + + return Promise.resolve(false); + } +} + export class MaximizeGroupAction extends Action { static readonly ID = 'workbench.action.maximizeEditor'; diff --git a/src/vs/workbench/browser/parts/editor/editorDropTarget.ts b/src/vs/workbench/browser/parts/editor/editorDropTarget.ts index 266f09275db..97cabc264b6 100644 --- a/src/vs/workbench/browser/parts/editor/editorDropTarget.ts +++ b/src/vs/workbench/browser/parts/editor/editorDropTarget.ts @@ -409,7 +409,7 @@ class DropOverlay extends Themable { } private getOverlayOffsetHeight(): number { - if (!this.groupView.isEmpty() && this.accessor.partOptions.showTabs) { + if (!this.groupView.isEmpty && this.accessor.partOptions.showTabs) { return EDITOR_TITLE_HEIGHT; // show overlay below title if group shows tabs } diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 6f575845305..bbf73ff14da 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -250,7 +250,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { // Open new file via doubleclick on empty container this._register(addDisposableListener(this.element, EventType.DBLCLICK, e => { - if (this.isEmpty()) { + if (this.isEmpty) { EventHelper.stop(e); this.openEditor(this.untitledEditorService.createOrGet(), EditorOptions.create({ pinned: true })); @@ -259,7 +259,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { // Close empty editor group via middle mouse click this._register(addDisposableListener(this.element, EventType.MOUSE_UP, e => { - if (this.isEmpty() && e.button === 1 /* Middle Button */) { + if (this.isEmpty && e.button === 1 /* Middle Button */) { EventHelper.stop(e); this.accessor.removeGroup(this); @@ -308,7 +308,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { } private onShowContainerContextMenu(menu: IMenu, e?: MouseEvent): void { - if (!this.isEmpty()) { + if (!this.isEmpty) { return; // only for empty editor groups } @@ -339,7 +339,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { // Container const containerFocusTracker = this._register(trackFocus(this.element)); this._register(containerFocusTracker.onDidFocus(() => { - if (this.isEmpty()) { + if (this.isEmpty) { this._onDidFocus.fire(); // only when empty to prevent accident focus } })); @@ -381,7 +381,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { private updateContainer(): void { // Empty Container: add some empty container attributes - if (this.isEmpty()) { + if (this.isEmpty) { addClass(this.element, 'empty'); this.element.tabIndex = 0; this.element.setAttribute('aria-label', localize('emptyEditorGroup', "{0} (empty)", this.label)); @@ -672,6 +672,18 @@ export class EditorGroupView extends Themable implements IEditorGroupView { return this._whenRestored; } + get isEmpty(): boolean { + return this._group.count === 0; + } + + get isMinimized(): boolean { + if (!this.dimension) { + return false; + } + + return this.dimension.width === this.minimumWidth || this.dimension.height === this.minimumHeight; + } + notifyIndexChanged(newIndex: number): void { if (this._index !== newIndex) { this._index = newIndex; @@ -696,10 +708,6 @@ export class EditorGroupView extends Themable implements IEditorGroupView { this._onDidGroupChange.fire({ kind: GroupChangeKind.GROUP_ACTIVE }); } - isEmpty(): boolean { - return this._group.count === 0; - } - //#endregion //#region IEditorGroup @@ -1224,7 +1232,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { //#region closeEditors() async closeEditors(args: EditorInput[] | ICloseEditorsFilter, options?: ICloseEditorOptions): Promise { - if (this.isEmpty()) { + if (this.isEmpty) { return; } @@ -1296,7 +1304,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { //#region closeAllEditors() async closeAllEditors(): Promise { - if (this.isEmpty()) { + if (this.isEmpty) { // If the group is empty and the request is to close all editors, we still close // the editor group is the related setting to close empty groups is enabled for @@ -1408,7 +1416,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { //#region Themable protected updateStyles(): void { - const isEmpty = this.isEmpty(); + const isEmpty = this.isEmpty; // Container if (isEmpty) { diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index df41417a615..4dc5c4a28ad 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -346,15 +346,36 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro return; // we have not been created yet } - // Even all group sizes - if (arrangement === GroupsArrangement.EVEN) { - this.gridWidget.distributeViewSizes(); + switch (arrangement) { + case GroupsArrangement.EVEN: + this.gridWidget.distributeViewSizes(); + break; + case GroupsArrangement.MINIMIZE_OTHERS: + this.gridWidget.maximizeViewSize(this.activeGroup); + break; + case GroupsArrangement.TOGGLE: + if (this.isGroupMaximized(this.activeGroup)) { + this.arrangeGroups(GroupsArrangement.EVEN); + } else { + this.arrangeGroups(GroupsArrangement.MINIMIZE_OTHERS); + } + + break; + } + } + + private isGroupMaximized(targetGroup: IEditorGroupView): boolean { + for (const group of this.groups) { + if (group === targetGroup) { + continue; // ignore target group + } + + if (!group.isMinimized) { + return false; // target cannot be maximized if one group is not minimized + } } - // Maximize the current active group - else { - this.gridWidget.maximizeViewSize(this.activeGroup); - } + return true; } setGroupOrientation(orientation: GroupOrientation): void { @@ -604,7 +625,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro } // Remove empty group - if (groupView.isEmpty()) { + if (groupView.isEmpty) { return this.doRemoveEmptyGroup(groupView); } @@ -722,7 +743,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro }); // Remove source if the view is now empty and not already removed - if (sourceView.isEmpty() && !sourceView.disposed /* could have been disposed already via workbench.editor.closeEmptyGroups setting */) { + if (sourceView.isEmpty && !sourceView.disposed /* could have been disposed already via workbench.editor.closeEmptyGroups setting */) { this.removeGroup(sourceView); } @@ -925,7 +946,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro } private isEmpty(): boolean { - return this.groupViews.size === 1 && this._activeGroup.isEmpty(); + return this.groupViews.size === 1 && this._activeGroup.isEmpty; } layout(width: number, height: number): void { @@ -957,7 +978,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro mostRecentActiveGroups: this.mostRecentActiveGroups }; - if (this.isEmpty()) { + if (this.isEmpty) { delete this.workspaceMemento[EditorPart.EDITOR_PART_UI_STATE_STORAGE_KEY]; } else { this.workspaceMemento[EditorPart.EDITOR_PART_UI_STATE_STORAGE_KEY] = uiState; diff --git a/src/vs/workbench/services/editor/common/editorGroupsService.ts b/src/vs/workbench/services/editor/common/editorGroupsService.ts index 6c9a974e6ea..a53e5ce507e 100644 --- a/src/vs/workbench/services/editor/common/editorGroupsService.ts +++ b/src/vs/workbench/services/editor/common/editorGroupsService.ts @@ -59,7 +59,13 @@ export const enum GroupsArrangement { /** * Size all groups evenly. */ - EVEN + EVEN, + + /** + * Will behave like MINIMIZE_OTHERS if the active + * group is not already maximized and EVEN otherwise + */ + TOGGLE } export interface GroupLayoutArgument { diff --git a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts index c09e9aaf1e7..d461e545ddc 100644 --- a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts @@ -388,7 +388,7 @@ suite('EditorGroupsService', () => { test('editor basics', async function () { const part = createPart(); const group = part.activeGroup; - assert.equal(group.isEmpty(), true); + assert.equal(group.isEmpty, true); await part.whenRestored; @@ -437,7 +437,7 @@ suite('EditorGroupsService', () => { assert.equal(group.isActive(inputInactive), false); assert.equal(group.isOpened(input), true); assert.equal(group.isOpened(inputInactive), true); - assert.equal(group.isEmpty(), false); + assert.equal(group.isEmpty, false); assert.equal(group.count, 2); assert.equal(editorWillOpenCounter, 2); assert.equal(editorDidOpenCounter, 2); @@ -486,7 +486,7 @@ suite('EditorGroupsService', () => { test('openEditors / closeEditors', async () => { const part = createPart(); const group = part.activeGroup; - assert.equal(group.isEmpty(), true); + assert.equal(group.isEmpty, true); const input = new TestEditorInput(URI.file('foo/bar')); const inputInactive = new TestEditorInput(URI.file('foo/bar/inactive')); @@ -497,14 +497,14 @@ suite('EditorGroupsService', () => { assert.equal(group.getEditor(1), inputInactive); await group.closeEditors([input, inputInactive]); - assert.equal(group.isEmpty(), true); + assert.equal(group.isEmpty, true); part.dispose(); }); test('closeEditors (except one)', async () => { const part = createPart(); const group = part.activeGroup; - assert.equal(group.isEmpty(), true); + assert.equal(group.isEmpty, true); const input1 = new TestEditorInput(URI.file('foo/bar1')); const input2 = new TestEditorInput(URI.file('foo/bar2')); @@ -525,7 +525,7 @@ suite('EditorGroupsService', () => { test('closeEditors (saved only)', async () => { const part = createPart(); const group = part.activeGroup; - assert.equal(group.isEmpty(), true); + assert.equal(group.isEmpty, true); const input1 = new TestEditorInput(URI.file('foo/bar1')); const input2 = new TestEditorInput(URI.file('foo/bar2')); @@ -545,7 +545,7 @@ suite('EditorGroupsService', () => { test('closeEditors (direction: right)', async () => { const part = createPart(); const group = part.activeGroup; - assert.equal(group.isEmpty(), true); + assert.equal(group.isEmpty, true); const input1 = new TestEditorInput(URI.file('foo/bar1')); const input2 = new TestEditorInput(URI.file('foo/bar2')); @@ -567,7 +567,7 @@ suite('EditorGroupsService', () => { test('closeEditors (direction: left)', async () => { const part = createPart(); const group = part.activeGroup; - assert.equal(group.isEmpty(), true); + assert.equal(group.isEmpty, true); const input1 = new TestEditorInput(URI.file('foo/bar1')); const input2 = new TestEditorInput(URI.file('foo/bar2')); @@ -589,7 +589,7 @@ suite('EditorGroupsService', () => { test('closeAllEditors', async () => { const part = createPart(); const group = part.activeGroup; - assert.equal(group.isEmpty(), true); + assert.equal(group.isEmpty, true); const input = new TestEditorInput(URI.file('foo/bar')); const inputInactive = new TestEditorInput(URI.file('foo/bar/inactive')); @@ -600,14 +600,14 @@ suite('EditorGroupsService', () => { assert.equal(group.getEditor(1), inputInactive); await group.closeAllEditors(); - assert.equal(group.isEmpty(), true); + assert.equal(group.isEmpty, true); part.dispose(); }); test('moveEditor (same group)', async () => { const part = createPart(); const group = part.activeGroup; - assert.equal(group.isEmpty(), true); + assert.equal(group.isEmpty, true); const input = new TestEditorInput(URI.file('foo/bar')); const inputInactive = new TestEditorInput(URI.file('foo/bar/inactive')); @@ -635,7 +635,7 @@ suite('EditorGroupsService', () => { test('moveEditor (across groups)', async () => { const part = createPart(); const group = part.activeGroup; - assert.equal(group.isEmpty(), true); + assert.equal(group.isEmpty, true); const rightGroup = part.addGroup(group, GroupDirection.RIGHT); @@ -657,7 +657,7 @@ suite('EditorGroupsService', () => { test('copyEditor (across groups)', async () => { const part = createPart(); const group = part.activeGroup; - assert.equal(group.isEmpty(), true); + assert.equal(group.isEmpty, true); const rightGroup = part.addGroup(group, GroupDirection.RIGHT); @@ -680,7 +680,7 @@ suite('EditorGroupsService', () => { test('replaceEditors', async () => { const part = createPart(); const group = part.activeGroup; - assert.equal(group.isEmpty(), true); + assert.equal(group.isEmpty, true); const input = new TestEditorInput(URI.file('foo/bar')); const inputInactive = new TestEditorInput(URI.file('foo/bar/inactive')); diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 3bebf0fa5a9..0ca22ba62b8 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -770,6 +770,9 @@ export class TestEditorGroup implements IEditorGroupView { minimumHeight: number; maximumHeight: number; + isEmpty = true; + isMinimized = false; + onWillDispose: Event = Event.None; onDidGroupChange: Event = Event.None; onWillCloseEditor: Event = Event.None; @@ -839,7 +842,6 @@ export class TestEditorGroup implements IEditorGroupView { throw new Error('not implemented'); } - isEmpty(): boolean { return true; } setActive(_isActive: boolean): void { } notifyIndexChanged(_index: number): void { } dispose(): void { } From 5afc55a7c3ab825046fedc803092c7adbde00a1c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 9 Aug 2019 14:55:06 +0200 Subject: [PATCH 402/861] keep recently used item selected as long as it's in the top suggestions group, #78571 --- .../editor/contrib/suggest/suggestMemory.ts | 43 +++++++++++-------- .../suggest/test/suggestMemory.test.ts | 23 ++++++++++ 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/src/vs/editor/contrib/suggest/suggestMemory.ts b/src/vs/editor/contrib/suggest/suggestMemory.ts index f8997401fde..d08685206be 100644 --- a/src/vs/editor/contrib/suggest/suggestMemory.ts +++ b/src/vs/editor/contrib/suggest/suggestMemory.ts @@ -22,10 +22,10 @@ export abstract class Memory { if (items.length === 0) { return 0; } - let topScore = items[0].score; + let topScore = items[0].score[0]; for (let i = 1; i < items.length; i++) { const { score, completion: suggestion } = items[i]; - if (score !== topScore) { + if (score[0] !== topScore) { // stop when leaving the group of top matches break; } @@ -81,33 +81,42 @@ export class LRUMemory extends Memory { } select(model: ITextModel, pos: IPosition, items: CompletionItem[]): number { - // in order of completions, select the first - // that has been used in the past - let { word } = model.getWordUntilPosition(pos); - if (word.length !== 0) { - return super.select(model, pos, items); + + if (items.length === 0) { + return 0; } - let lineSuffix = model.getLineContent(pos.lineNumber).substr(pos.column - 10, pos.column - 1); + const lineSuffix = model.getLineContent(pos.lineNumber).substr(pos.column - 10, pos.column - 1); if (/\s$/.test(lineSuffix)) { return super.select(model, pos, items); } - let res = -1; + let topScore = items[0].score[0]; + let indexPreselect = -1; + let indexRecency = -1; let seq = -1; for (let i = 0; i < items.length; i++) { - const { completion: suggestion } = items[i]; - const key = `${model.getLanguageIdentifier().language}/${suggestion.label}`; - const item = this._cache.get(key); - if (item && item.touch > seq && item.type === suggestion.kind && item.insertText === suggestion.insertText) { + if (items[i].score[0] !== topScore) { + // consider only top items + break; + } + const key = `${model.getLanguageIdentifier().language}/${items[i].completion.label}`; + const item = this._cache.peek(key); + if (item && item.touch > seq && item.type === items[i].completion.kind && item.insertText === items[i].completion.insertText) { seq = item.touch; - res = i; + indexRecency = i; + } + if (items[i].completion.preselect && indexPreselect === -1) { + // stop when seeing an auto-select-item + return indexPreselect = i; } } - if (res === -1) { - return super.select(model, pos, items); + if (indexRecency !== -1) { + return indexRecency; + } else if (indexPreselect !== -1) { + return indexPreselect; } else { - return res; + return 0; } } diff --git a/src/vs/editor/contrib/suggest/test/suggestMemory.test.ts b/src/vs/editor/contrib/suggest/test/suggestMemory.test.ts index 3dda6f9f6fb..fd2ee8ec49c 100644 --- a/src/vs/editor/contrib/suggest/test/suggestMemory.test.ts +++ b/src/vs/editor/contrib/suggest/test/suggestMemory.test.ts @@ -101,6 +101,29 @@ suite('SuggestMemories', function () { ]), 0); }); + test('`"editor.suggestSelection": "recentlyUsed"` should be a little more sticky #78571', function () { + + let item1 = createSuggestItem('gamma', 0); + let item2 = createSuggestItem('game', 0); + items = [item1, item2]; + + let mem = new LRUMemory(); + buffer.setValue(' foo.'); + mem.memorize(buffer, { lineNumber: 1, column: 1 }, item2); + + assert.equal(mem.select(buffer, { lineNumber: 1, column: 2 }, items), 0); // leading whitespace -> ignore recent items + + mem.memorize(buffer, { lineNumber: 1, column: 9 }, item2); + assert.equal(mem.select(buffer, { lineNumber: 1, column: 9 }, items), 1); // foo. + + buffer.setValue(' foo.g'); + assert.equal(mem.select(buffer, { lineNumber: 1, column: 10 }, items), 1); // foo.g, 'gamma' and 'game' have the same score + + item1.score = [10, 0, 0]; + assert.equal(mem.select(buffer, { lineNumber: 1, column: 10 }, items), 0); // foo.g, 'gamma' has higher score + + }); + test('intellisense is not showing top options first #43429', function () { // ensure we don't memorize for whitespace prefixes From da6bc5fa118070a443d90a9a1fed98d9b713c067 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 9 Aug 2019 15:13:03 +0200 Subject: [PATCH 403/861] rephrase related to #78724 --- src/vs/workbench/contrib/scm/browser/scm.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/scm/browser/scm.contribution.ts b/src/vs/workbench/contrib/scm/browser/scm.contribution.ts index 8385ae8124d..84504b8b1f5 100644 --- a/src/vs/workbench/contrib/scm/browser/scm.contribution.ts +++ b/src/vs/workbench/contrib/scm/browser/scm.contribution.ts @@ -70,7 +70,7 @@ Registry.as(ConfigurationExtensions.Configuration).regis properties: { 'scm.alwaysShowProviders': { type: 'boolean', - description: localize('alwaysShowProviders', "Controls whether to always show the Source Control Provider section."), + description: localize('alwaysShowProviders', "Controls whether to show the Source Control Provider section even when there's only one Provider registered."), default: false }, 'scm.providers.visible': { From 601475370feab5387d4eaf9bb03819ad4e96b20c Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 9 Aug 2019 15:28:16 +0200 Subject: [PATCH 404/861] explorer: additionalScrollHeight only one element --- src/vs/workbench/contrib/files/browser/views/explorerView.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerView.ts b/src/vs/workbench/contrib/files/browser/views/explorerView.ts index defa67d92f8..c5bd34e7ac6 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerView.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerView.ts @@ -302,7 +302,7 @@ export class ExplorerView extends ViewletPanel { sorter: this.instantiationService.createInstance(FileSorter), dnd: this.instantiationService.createInstance(FileDragAndDrop), autoExpandSingleChildren: true, - additionalScrollHeight: 2 * ExplorerDelegate.ITEM_HEIGHT + additionalScrollHeight: ExplorerDelegate.ITEM_HEIGHT }); this._register(this.tree); From 3ceb1b998c5ab897ea4bb2ddd23285efac0f07c4 Mon Sep 17 00:00:00 2001 From: Marcus Noble Date: Fri, 9 Aug 2019 14:35:36 +0100 Subject: [PATCH 405/861] Add setting to make touchbar controls optional (#70174) * Add setting to make touchbar controls optional * fix bad merge * fix unneccessary change * :lipstick: * fix --- src/vs/workbench/electron-browser/window.ts | 7 +++++++ .../services/keybinding/browser/keybindingService.ts | 1 - .../electron-browser/keybinding.contribution.ts | 11 ++++++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index e10a49baee6..8391373c4fb 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -213,6 +213,8 @@ export class ElectronWindow extends Disposable { this._register(this.configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration('window.zoomLevel')) { this.updateWindowZoomLevel(); + } else if (e.affectsConfiguration('keyboard.touchbar.ignored')) { + this.updateTouchbarMenu(); } })); @@ -372,10 +374,15 @@ export class ElectronWindow extends Disposable { // Convert into command action multi array const items: ICommandAction[][] = []; let group: ICommandAction[] = []; + const ignoredItems = this.configurationService.getValue('keyboard.touchbar.ignored') || []; for (const action of actions) { // Command if (action instanceof MenuItemAction) { + if (ignoredItems.indexOf(action.item.id) >= 0) { + continue; // ignored + } + group.push(action.item); } diff --git a/src/vs/workbench/services/keybinding/browser/keybindingService.ts b/src/vs/workbench/services/keybinding/browser/keybindingService.ts index dec59cfca2c..c9394b52fc8 100644 --- a/src/vs/workbench/services/keybinding/browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/browser/keybindingService.ts @@ -725,7 +725,6 @@ const keyboardConfiguration: IConfigurationNode = { 'markdownDescription': nls.localize('dispatch', "Controls the dispatching logic for key presses to use either `code` (recommended) or `keyCode`."), 'included': OS === OperatingSystem.Macintosh || OS === OperatingSystem.Linux } - // no touch bar support } }; diff --git a/src/vs/workbench/services/keybinding/electron-browser/keybinding.contribution.ts b/src/vs/workbench/services/keybinding/electron-browser/keybinding.contribution.ts index eec3ac01744..ae95d7b85f4 100644 --- a/src/vs/workbench/services/keybinding/electron-browser/keybinding.contribution.ts +++ b/src/vs/workbench/services/keybinding/electron-browser/keybinding.contribution.ts @@ -22,8 +22,17 @@ const keyboardConfiguration: IConfigurationNode = { 'default': true, 'description': nls.localize('touchbar.enabled', "Enables the macOS touchbar buttons on the keyboard if available."), 'included': OS === OperatingSystem.Macintosh && parseFloat(release()) >= 16 // Minimum: macOS Sierra (10.12.x = darwin 16.x) + }, + 'keyboard.touchbar.ignored': { + 'type': 'array', + 'items': { + 'type': 'string' + }, + 'default': [], + 'description': nls.localize('touchbar.ignored', 'A set of identifiers for entries in the touchbar that should not show up (for example `workbench.action.navigateBack`.'), + 'included': OS === OperatingSystem.Macintosh && parseFloat(release()) >= 16 // Minimum: macOS Sierra (10.12.x = darwin 16.x) } } }; -configurationRegistry.registerConfiguration(keyboardConfiguration); \ No newline at end of file +configurationRegistry.registerConfiguration(keyboardConfiguration); From 5d8c287767fbbacf642ed3023f9043d3f567025a Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Fri, 9 Aug 2019 15:41:12 +0200 Subject: [PATCH 406/861] Add refresh queueing for tree views Fixes #71698 --- src/vs/workbench/api/common/extHostTreeViews.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/api/common/extHostTreeViews.ts b/src/vs/workbench/api/common/extHostTreeViews.ts index 6b5d8d02c58..f8d6dbb5906 100644 --- a/src/vs/workbench/api/common/extHostTreeViews.ts +++ b/src/vs/workbench/api/common/extHostTreeViews.ts @@ -177,6 +177,7 @@ class ExtHostTreeView extends Disposable { private _onDidChangeData: Emitter> = this._register(new Emitter>()); private refreshPromise: Promise = Promise.resolve(); + private refreshQueue: Promise = Promise.resolve(); constructor(private viewId: string, options: vscode.TreeViewOptions, private proxy: MainThreadTreeViewsShape, private commands: CommandsConverter, private logService: ILogService, private extension: IExtensionDescription) { super(); @@ -206,9 +207,11 @@ class ExtHostTreeView extends Disposable { return result; }, 200)(({ message, elements }) => { if (elements.length) { - const _promiseCallback = promiseCallback; - refreshingPromise = null; - this.refresh(elements).then(() => _promiseCallback()); + this.refreshQueue = this.refreshQueue.then(() => { + const _promiseCallback = promiseCallback; + refreshingPromise = null; + return this.refresh(elements).then(() => _promiseCallback()); + }); } if (message) { this.proxy.$setMessage(this.viewId, this._message); From 0c8a07500ae75420693bfcf4301161c3e05c8beb Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 9 Aug 2019 15:44:46 +0200 Subject: [PATCH 407/861] touchbar - allow to disable/enable without restart --- .../common/relauncher.contribution.ts | 8 ---- src/vs/workbench/electron-browser/window.ts | 47 ++++++++++--------- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/src/vs/workbench/contrib/relauncher/common/relauncher.contribution.ts b/src/vs/workbench/contrib/relauncher/common/relauncher.contribution.ts index 080e6d741e7..d3c0d4f064f 100644 --- a/src/vs/workbench/contrib/relauncher/common/relauncher.contribution.ts +++ b/src/vs/workbench/contrib/relauncher/common/relauncher.contribution.ts @@ -23,7 +23,6 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/ interface IConfiguration extends IWindowsConfiguration { update: { mode: string; }; telemetry: { enableCrashReporter: boolean }; - keyboard: { touchbar: { enabled: boolean } }; workbench: { list: { horizontalScrolling: boolean }, useExperimentalGridLayout: boolean }; debug: { console: { wordWrap: boolean } }; } @@ -36,7 +35,6 @@ export class SettingsChangeRelauncher extends Disposable implements IWorkbenchCo private clickThroughInactive: boolean; private updateMode: string; private enableCrashReporter: boolean; - private touchbarEnabled: boolean; private treeHorizontalScrolling: boolean; private useGridLayout: boolean; private debugConsoleWordWrap: boolean; @@ -112,12 +110,6 @@ export class SettingsChangeRelauncher extends Disposable implements IWorkbenchCo this.enableCrashReporter = config.telemetry.enableCrashReporter; changed = true; } - - // macOS: Touchbar config - if (isMacintosh && config.keyboard && config.keyboard.touchbar && typeof config.keyboard.touchbar.enabled === 'boolean' && config.keyboard.touchbar.enabled !== this.touchbarEnabled) { - this.touchbarEnabled = config.keyboard.touchbar.enabled; - changed = true; - } } // Notify only when changed and we are the focused window (avoids notification spam across windows) diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index 8391373c4fb..bfc7916011e 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -213,7 +213,7 @@ export class ElectronWindow extends Disposable { this._register(this.configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration('window.zoomLevel')) { this.updateWindowZoomLevel(); - } else if (e.affectsConfiguration('keyboard.touchbar.ignored')) { + } else if (e.affectsConfiguration('keyboard.touchbar.enabled') || e.affectsConfiguration('keyboard.touchbar.ignored')) { this.updateTouchbarMenu(); } })); @@ -342,11 +342,8 @@ export class ElectronWindow extends Disposable { } private updateTouchbarMenu(): void { - if ( - !isMacintosh || // macOS only - !this.configurationService.getValue('keyboard.touchbar.enabled') // disabled via setting - ) { - return; + if (!isMacintosh) { + return; // macOS only } // Dispose old @@ -368,36 +365,40 @@ export class ElectronWindow extends Disposable { const actions: Array = []; + const disabled = this.configurationService.getValue('keyboard.touchbar.enabled') === false; + const ignoredItems = this.configurationService.getValue('keyboard.touchbar.ignored') || []; + // Fill actions into groups respecting order this.touchBarDisposables.add(createAndFillInActionBarActions(this.touchBarMenu, undefined, actions)); // Convert into command action multi array const items: ICommandAction[][] = []; let group: ICommandAction[] = []; - const ignoredItems = this.configurationService.getValue('keyboard.touchbar.ignored') || []; - for (const action of actions) { + if (!disabled) { + for (const action of actions) { - // Command - if (action instanceof MenuItemAction) { - if (ignoredItems.indexOf(action.item.id) >= 0) { - continue; // ignored + // Command + if (action instanceof MenuItemAction) { + if (ignoredItems.indexOf(action.item.id) >= 0) { + continue; // ignored + } + + group.push(action.item); } - group.push(action.item); - } + // Separator + else if (action instanceof Separator) { + if (group.length) { + items.push(group); + } - // Separator - else if (action instanceof Separator) { - if (group.length) { - items.push(group); + group = []; } - - group = []; } - } - if (group.length) { - items.push(group); + if (group.length) { + items.push(group); + } } // Only update if the actions have changed From 091f1c855eae6d49dcb8577faf7df0ed89a9948d Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 9 Aug 2019 15:53:50 +0200 Subject: [PATCH 408/861] fixes #78724 --- .../contrib/scm/browser/scmViewlet.ts | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/contrib/scm/browser/scmViewlet.ts b/src/vs/workbench/contrib/scm/browser/scmViewlet.ts index 5c596e9ef7d..30ef53951d0 100644 --- a/src/vs/workbench/contrib/scm/browser/scmViewlet.ts +++ b/src/vs/workbench/contrib/scm/browser/scmViewlet.ts @@ -49,6 +49,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IViewsRegistry, IViewDescriptor, Extensions } from 'vs/workbench/common/views'; import { Registry } from 'vs/platform/registry/common/platform'; +import { nextTick } from 'vs/base/common/process'; export interface ISpliceEvent { index: number; @@ -324,7 +325,7 @@ export class MainPanel extends ViewletPanel { } private onListSelectionChange(e: IListEvent): void { - if (e.elements.length > 0) { + if (e.browserEvent && e.elements.length > 0) { const scrollTop = this.list.scrollTop; this.viewModel.setVisibleRepositories(e.elements); this.list.scrollTop = scrollTop; @@ -332,7 +333,7 @@ export class MainPanel extends ViewletPanel { } private onListFocusChange(e: IListEvent): void { - if (e.elements.length > 0) { + if (e.browserEvent && e.elements.length > 0) { e.elements[0].focus(); } } @@ -1102,6 +1103,9 @@ export class SCMViewlet extends ViewContainerViewlet implements IViewModel { } } + private readonly _onDidChangeRepositories = new Emitter(); + private readonly onDidFinishStartup = Event.once(Event.debounce(this._onDidChangeRepositories.event, () => null, 1000)); + constructor( @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, @ITelemetryService telemetryService: ITelemetryService, @@ -1130,6 +1134,9 @@ export class SCMViewlet extends ViewContainerViewlet implements IViewModel { this.onDidChangeRepositories(); } })); + + this._register(this.onDidFinishStartup(this.onAfterStartup, this)); + this._register(this.viewsModel.onDidRemove(this.onDidHideView, this)); } create(parent: HTMLElement): void { @@ -1190,20 +1197,28 @@ export class SCMViewlet extends ViewContainerViewlet implements IViewModel { if (alwaysShowProviders && repositoryCount > 0) { this.viewsModel.setVisible(MainPanel.ID, true); - } else if (!alwaysShowProviders && repositoryCount === 1) { - this.viewsModel.setVisible(MainPanel.ID, false); - } else if (this.repositoryCount < 2 && repositoryCount >= 2) { - this.viewsModel.setVisible(MainPanel.ID, true); - } else if (this.repositoryCount >= 2 && repositoryCount === 1) { - this.viewsModel.setVisible(MainPanel.ID, false); - } - - if (repositoryCount === 1) { - this.viewsModel.setVisible(this.viewDescriptors[0].id, true); } toggleClass(this.el, 'empty', repositoryCount === 0); this.repositoryCount = repositoryCount; + + this._onDidChangeRepositories.fire(); + } + + private onAfterStartup(): void { + if (this.repositoryCount > 0 && this.viewDescriptors.every(d => !this.viewsModel.isVisible(d.id))) { + this.viewsModel.setVisible(this.viewDescriptors[0].id, true); + } + } + + private onDidHideView(): void { + nextTick(() => { + if (this.repositoryCount > 0 && this.viewDescriptors.every(d => !this.viewsModel.isVisible(d.id))) { + const alwaysShowProviders = this.configurationService.getValue('scm.alwaysShowProviders') || false; + this.viewsModel.setVisible(MainPanel.ID, alwaysShowProviders || this.repositoryCount > 1); + this.viewsModel.setVisible(this.viewDescriptors[0].id, true); + } + }); } focus(): void { From af8b26c93993cdf858eeee162e31bbc586240cb4 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 9 Aug 2019 15:56:07 +0200 Subject: [PATCH 409/861] fix #48357 --- .../workbench/electron-browser/actions/windowActions.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/vs/workbench/electron-browser/actions/windowActions.ts b/src/vs/workbench/electron-browser/actions/windowActions.ts index 7bb652eb2f5..bc094a193fd 100644 --- a/src/vs/workbench/electron-browser/actions/windowActions.ts +++ b/src/vs/workbench/electron-browser/actions/windowActions.ts @@ -55,8 +55,12 @@ export class NewWindowAction extends Action { } export abstract class BaseZoomAction extends Action { + private static readonly SETTING_KEY = 'window.zoomLevel'; + private static readonly MAX_ZOOM_LEVEL = 9; + private static readonly MIN_ZOOM_LEVEL = -8; + constructor( id: string, label: string, @@ -68,6 +72,10 @@ export abstract class BaseZoomAction extends Action { protected async setConfiguredZoomLevel(level: number): Promise { level = Math.round(level); // when reaching smallest zoom, prevent fractional zoom levels + if (level > BaseZoomAction.MAX_ZOOM_LEVEL || level < BaseZoomAction.MIN_ZOOM_LEVEL) { + return; // https://github.com/microsoft/vscode/issues/48357 + } + const applyZoom = () => { webFrame.setZoomLevel(level); browser.setZoomFactor(webFrame.getZoomFactor()); From f1aa0929db61ae84f8677210d44b0dbc09d6a280 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 9 Aug 2019 16:10:50 +0200 Subject: [PATCH 410/861] adopt ext host service world, add dummy implementations for some services --- .../api/common/extHostExtensionService.ts | 3 +- .../api/worker/extHostExtensionService.ts | 55 + .../api/worker/extHostStoragePaths.ts | 23 + .../extensions/worker/extHost.api.impl.ts | 964 ------------------ .../extensions/worker/extHost.services.ts | 51 + .../worker/extHostExtensionService.ts | 826 --------------- .../extensions/worker/extensionHostMain.ts | 154 --- .../extensions/worker/extensionHostWorker.ts | 10 +- 8 files changed, 137 insertions(+), 1949 deletions(-) create mode 100644 src/vs/workbench/api/worker/extHostExtensionService.ts create mode 100644 src/vs/workbench/api/worker/extHostStoragePaths.ts delete mode 100644 src/vs/workbench/services/extensions/worker/extHost.api.impl.ts create mode 100644 src/vs/workbench/services/extensions/worker/extHost.services.ts delete mode 100644 src/vs/workbench/services/extensions/worker/extHostExtensionService.ts delete mode 100644 src/vs/workbench/services/extensions/worker/extensionHostMain.ts diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts index 58098d94099..cd25ceb4bba 100644 --- a/src/vs/workbench/api/common/extHostExtensionService.ts +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -385,7 +385,8 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio try { activationTimesBuilder.activateCallStart(); logService.trace(`ExtensionService#_callActivateOptional ${extensionId.value}`); - const activateResult: Promise = extensionModule.activate.apply(global, [context]); + const scope = typeof global === 'object' ? global : self; //todo@joh not so nice + const activateResult: Promise = extensionModule.activate.apply(scope, [context]); activationTimesBuilder.activateCallStop(); activationTimesBuilder.activateResolveStart(); diff --git a/src/vs/workbench/api/worker/extHostExtensionService.ts b/src/vs/workbench/api/worker/extHostExtensionService.ts new file mode 100644 index 00000000000..30d15e39399 --- /dev/null +++ b/src/vs/workbench/api/worker/extHostExtensionService.ts @@ -0,0 +1,55 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { createApiFactoryAndRegisterActors } from 'vs/workbench/api/common/extHost.api.impl'; +import { ExtensionActivationTimesBuilder } from 'vs/workbench/api/common/extHostExtensionActivator'; +import { AbstractExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; +import { endsWith } from 'vs/base/common/strings'; +import { nullExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; + +export class ExtHostExtensionService extends AbstractExtHostExtensionService { + + protected async _beforeAlmostReadyToRunExtensions(): Promise { + // initialize API and register actors + const factory = this._instaService.invokeFunction(createApiFactoryAndRegisterActors); + + // globally define the vscode module and share that for all extensions + // todo@joh have an instance per extension, not a shared one.... + const sharedApiInstance = factory(nullExtensionDescription, this._registry, await this._extHostConfiguration.getConfigProvider()); + define('vscode', sharedApiInstance); + } + + protected _loadCommonJSModule(modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { + // fake commonjs world + const module = { exports: {} }; + //@ts-ignore + self['module'] = module; + //@ts-ignore + self['exports'] = module.exports; + // that's improper but might help extensions that aren't author correctly + // @ts-ignore + self['window'] = self; + + try { + activationTimesBuilder.codeLoadingStart(); + // import the single (!) script, make sure it's a JS-file + const suffix = '.js'; + if (endsWith(modulePath, suffix)) { + importScripts(modulePath); + } else { + importScripts(modulePath + suffix); + } + } finally { + activationTimesBuilder.codeLoadingStop(); + } + + // return what it exported + return Promise.resolve(module.exports as T); + } + + public async $setRemoteEnvironment(env: { [key: string]: string | null }): Promise { + throw new Error('Not supported'); + } +} diff --git a/src/vs/workbench/api/worker/extHostStoragePaths.ts b/src/vs/workbench/api/worker/extHostStoragePaths.ts new file mode 100644 index 00000000000..3d07dff7de0 --- /dev/null +++ b/src/vs/workbench/api/worker/extHostStoragePaths.ts @@ -0,0 +1,23 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths'; +import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; + +export class ExtensionStoragePaths implements IExtensionStoragePaths { + + readonly _serviceBrand: undefined; + + readonly whenReady: Promise = Promise.resolve(); + + //todo@joh -> this isn't proper but also hard to get right... + workspaceValue(_extension: IExtensionDescription): string | undefined { + return ''; + } + + globalValue(_extension: IExtensionDescription): string { + return ''; + } +} diff --git a/src/vs/workbench/services/extensions/worker/extHost.api.impl.ts b/src/vs/workbench/services/extensions/worker/extHost.api.impl.ts deleted file mode 100644 index e0c1f3ad4d1..00000000000 --- a/src/vs/workbench/services/extensions/worker/extHost.api.impl.ts +++ /dev/null @@ -1,964 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * 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 { CancellationTokenSource } from 'vs/base/common/cancellation'; -import * as errors from 'vs/base/common/errors'; -import { Emitter, Event } from 'vs/base/common/event'; -import * as path from 'vs/base/common/path'; -import Severity from 'vs/base/common/severity'; -import { URI } from 'vs/base/common/uri'; -import { TextEditorCursorStyle } from 'vs/editor/common/config/editorOptions'; -import { OverviewRulerLane } from 'vs/editor/common/model'; -import * as languageConfiguration from 'vs/editor/common/modes/languageConfiguration'; -import { score } from 'vs/editor/common/modes/languageSelector'; -import * as files from 'vs/platform/files/common/files'; -import { ExtHostContext, IInitData, IMainContext, MainContext } from 'vs/workbench/api/common/extHost.protocol'; -import { ExtHostApiCommands } from 'vs/workbench/api/common/extHostApiCommands'; -import { ExtHostClipboard } from 'vs/workbench/api/common/extHostClipboard'; -import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; -import { ExtHostComments } from 'vs/workbench/api/common/extHostComments'; -import { ExtHostConfiguration, ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration'; -// import { ExtHostDebugService } from 'vs/workbench/api/node/extHostDebugService'; -import { ExtHostDecorations } from 'vs/workbench/api/common/extHostDecorations'; -import { ExtHostDiagnostics } from 'vs/workbench/api/common/extHostDiagnostics'; -import { ExtHostDialogs } from 'vs/workbench/api/common/extHostDialogs'; -import { ExtHostDocumentContentProvider } from 'vs/workbench/api/common/extHostDocumentContentProviders'; -import { ExtHostDocumentSaveParticipant } from 'vs/workbench/api/common/extHostDocumentSaveParticipant'; -import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments'; -import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; -import { ExtensionActivatedByAPI } from 'vs/workbench/api/common/extHostExtensionActivator'; -import { ExtHostExtensionService } from './extHostExtensionService'; -import { ExtHostFileSystem } from 'vs/workbench/api/common/extHostFileSystem'; -import { ExtHostFileSystemEventService } from 'vs/workbench/api/common/extHostFileSystemEventService'; -import { ExtHostLanguageFeatures } from 'vs/workbench/api/common/extHostLanguageFeatures'; -import { ExtHostLanguages } from 'vs/workbench/api/common/extHostLanguages'; -import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; -import { ExtHostMessageService } from 'vs/workbench/api/common/extHostMessageService'; -import { ExtHostOutputService, PushOutputChannelFactory } from 'vs/workbench/api/common/extHostOutput'; -// import { LogOutputChannelFactory } from 'vs/workbench/api/node/extHostOutputService'; -import { ExtHostProgress } from 'vs/workbench/api/common/extHostProgress'; -import { ExtHostQuickOpen } from 'vs/workbench/api/common/extHostQuickOpen'; -import { ExtHostSCM } from 'vs/workbench/api/common/extHostSCM'; -// import { ExtHostSearch, registerEHSearchProviders } from 'vs/workbench/api/node/extHostSearch'; -import { ExtHostStatusBar } from 'vs/workbench/api/common/extHostStatusBar'; -import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; -// import { ExtHostTask } from 'vs/workbench/api/node/extHostTask'; -// import { ExtHostTerminalService } from 'vs/workbench/api/node/extHostTerminalService'; -import { ExtHostEditors } from 'vs/workbench/api/common/extHostTextEditors'; -import { ExtHostTreeViews } from 'vs/workbench/api/common/extHostTreeViews'; -// import { ExtHostDownloadService } from 'vs/workbench/api/node/extHostDownloadService'; -import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters'; -import * as extHostTypes from 'vs/workbench/api/common/extHostTypes'; -import { ExtHostUrls } from 'vs/workbench/api/common/extHostUrls'; -import { ExtHostWebviews } from 'vs/workbench/api/common/extHostWebview'; -import { ExtHostWindow } from 'vs/workbench/api/common/extHostWindow'; -import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; -import { throwProposedApiError, checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions'; -import { ProxyIdentifier } from 'vs/workbench/services/extensions/common/proxyIdentifier'; -import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; -import * as vscode from 'vscode'; -import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; -import { originalFSPath } from 'vs/base/common/resources'; -// import { CLIServer } from 'vs/workbench/api/node/extHostCLIServer'; -import { values } from 'vs/base/common/collections'; -// import { Schemas } from 'vs/base/common/network'; -import { IURITransformer } from 'vs/base/common/uriIpc'; -import { ExtHostEditorInsets } from 'vs/workbench/api/common/extHostCodeInsets'; -import { ExtHostLabelService } from 'vs/workbench/api/common/extHostLabelService'; -// import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; -// import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; -// import { getSingletonServiceDescriptors } from 'vs/platform/instantiation/common/extensions'; -import { getRemoteName } from 'vs/platform/remote/common/remoteHosts'; - -export interface IExtensionApiFactory { - (extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode; -} - -function proposedApiFunction(extension: IExtensionDescription, fn: T): T { - if (extension.enableProposedApi) { - return fn; - } else { - return throwProposedApiError.bind(null, extension) as any as T; - } -} - -/** - * This method instantiates and returns the extension API surface - */ -export function createApiFactory( - initData: IInitData, - rpcProtocol: IMainContext, - extHostWorkspace: ExtHostWorkspace, - extHostConfiguration: ExtHostConfiguration, - extensionService: ExtHostExtensionService, - extHostLogService: ExtHostLogService, - extHostStorage: ExtHostStorage, - uriTransformer: IURITransformer | null -): IExtensionApiFactory { - - // bootstrap services - // const services = new ServiceCollection(...getSingletonServiceDescriptors()); - // const instaService = new InstantiationService(services); - - // Addressable instances - rpcProtocol.set(ExtHostContext.ExtHostLogService, extHostLogService); - const extHostDecorations = rpcProtocol.set(ExtHostContext.ExtHostDecorations, new ExtHostDecorations(rpcProtocol)); - const extHostWebviews = rpcProtocol.set(ExtHostContext.ExtHostWebviews, new ExtHostWebviews(rpcProtocol, initData.environment)); - const extHostUrls = rpcProtocol.set(ExtHostContext.ExtHostUrls, new ExtHostUrls(rpcProtocol)); - const extHostDocumentsAndEditors = rpcProtocol.set(ExtHostContext.ExtHostDocumentsAndEditors, new ExtHostDocumentsAndEditors(rpcProtocol)); - const extHostDocuments = rpcProtocol.set(ExtHostContext.ExtHostDocuments, new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors)); - const extHostDocumentContentProviders = rpcProtocol.set(ExtHostContext.ExtHostDocumentContentProviders, new ExtHostDocumentContentProvider(rpcProtocol, extHostDocumentsAndEditors, extHostLogService)); - const extHostDocumentSaveParticipant = rpcProtocol.set(ExtHostContext.ExtHostDocumentSaveParticipant, new ExtHostDocumentSaveParticipant(extHostLogService, extHostDocuments, rpcProtocol.getProxy(MainContext.MainThreadTextEditors))); - const extHostEditors = rpcProtocol.set(ExtHostContext.ExtHostEditors, new ExtHostEditors(rpcProtocol, extHostDocumentsAndEditors)); - const extHostCommands = rpcProtocol.set(ExtHostContext.ExtHostCommands, new ExtHostCommands(rpcProtocol, extHostLogService)); - const extHostTreeViews = rpcProtocol.set(ExtHostContext.ExtHostTreeViews, new ExtHostTreeViews(rpcProtocol.getProxy(MainContext.MainThreadTreeViews), extHostCommands, extHostLogService)); - // rpcProtocol.set(ExtHostContext.ExtHostDownloadService, new ExtHostDownloadService(rpcProtocol.getProxy(MainContext.MainThreadDownloadService), extHostCommands)); - rpcProtocol.set(ExtHostContext.ExtHostWorkspace, extHostWorkspace); - rpcProtocol.set(ExtHostContext.ExtHostConfiguration, extHostConfiguration); - const extHostEditorInsets = rpcProtocol.set(ExtHostContext.ExtHostEditorInsets, new ExtHostEditorInsets(rpcProtocol.getProxy(MainContext.MainThreadEditorInsets), extHostEditors, initData.environment)); - const extHostDiagnostics = rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, new ExtHostDiagnostics(rpcProtocol)); - const extHostLanguageFeatures = rpcProtocol.set(ExtHostContext.ExtHostLanguageFeatures, new ExtHostLanguageFeatures(rpcProtocol, uriTransformer, extHostDocuments, extHostCommands, extHostDiagnostics, extHostLogService)); - const extHostFileSystem = rpcProtocol.set(ExtHostContext.ExtHostFileSystem, new ExtHostFileSystem(rpcProtocol, extHostLanguageFeatures)); - const extHostFileSystemEvent = rpcProtocol.set(ExtHostContext.ExtHostFileSystemEventService, new ExtHostFileSystemEventService(rpcProtocol, extHostDocumentsAndEditors)); - const extHostQuickOpen = rpcProtocol.set(ExtHostContext.ExtHostQuickOpen, new ExtHostQuickOpen(rpcProtocol, extHostWorkspace, extHostCommands)); - // const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(rpcProtocol, extHostConfiguration, extHostWorkspace, extHostDocumentsAndEditors, extHostLogService)); - // const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, instaService.createInstance(ExtHostDebugService, rpcProtocol, extHostWorkspace, extensionService, extHostDocumentsAndEditors, extHostConfiguration, extHostTerminalService, extHostCommands)); - const extHostSCM = rpcProtocol.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(rpcProtocol, extHostCommands, extHostLogService)); - const extHostComment = rpcProtocol.set(ExtHostContext.ExtHostComments, new ExtHostComments(rpcProtocol, extHostCommands, extHostDocuments)); - // const extHostSearch = rpcProtocol.set(ExtHostContext.ExtHostSearch, new ExtHostSearch(rpcProtocol, uriTransformer, extHostLogService)); - // const extHostTask = rpcProtocol.set(ExtHostContext.ExtHostTask, new ExtHostTask(rpcProtocol, extHostWorkspace, extHostDocumentsAndEditors, extHostConfiguration, extHostTerminalService)); - const extHostWindow = rpcProtocol.set(ExtHostContext.ExtHostWindow, new ExtHostWindow(rpcProtocol)); - rpcProtocol.set(ExtHostContext.ExtHostExtensionService, extensionService); - const extHostProgress = rpcProtocol.set(ExtHostContext.ExtHostProgress, new ExtHostProgress(rpcProtocol.getProxy(MainContext.MainThreadProgress))); - const extHostOutputService = rpcProtocol.set(ExtHostContext.ExtHostOutputService, new ExtHostOutputService(PushOutputChannelFactory, initData.logsLocation, rpcProtocol)); - rpcProtocol.set(ExtHostContext.ExtHostStorage, extHostStorage); - const extHostLabelService = rpcProtocol.set(ExtHostContext.ExtHosLabelService, new ExtHostLabelService(rpcProtocol)); - - // if (initData.remote.isRemote && initData.remote.authority) { - // extHostTask.registerTaskSystem(Schemas.vscodeRemote, { - // scheme: Schemas.vscodeRemote, - // authority: initData.remote.authority, - // platform: process.platform - // }); - - // registerEHSearchProviders(extHostSearch, extHostLogService); - - // const cliServer = new CLIServer(extHostCommands); - // process.env['VSCODE_IPC_HOOK_CLI'] = cliServer.ipcHandlePath; - // } - - // todo@joh - const proxy: any = new Proxy({}, {}); - rpcProtocol.set(ExtHostContext.ExtHostTerminalService, proxy); - rpcProtocol.set(ExtHostContext.ExtHostDebugService, proxy); - rpcProtocol.set(ExtHostContext.ExtHostSearch, proxy); - rpcProtocol.set(ExtHostContext.ExtHostTask, proxy); - rpcProtocol.set(ExtHostContext.ExtHostDownloadService, proxy); - - // Check that no named customers are missing - const expected: ProxyIdentifier[] = values(ExtHostContext); - rpcProtocol.assertRegistered(expected); - - // Other instances - const extHostClipboard = new ExtHostClipboard(rpcProtocol); - const extHostMessageService = new ExtHostMessageService(rpcProtocol); - const extHostDialogs = new ExtHostDialogs(rpcProtocol); - const extHostStatusBar = new ExtHostStatusBar(rpcProtocol); - const extHostLanguages = new ExtHostLanguages(rpcProtocol, extHostDocuments); - - // Register an output channel for exthost log - const outputChannelName = initData.remote.isRemote ? nls.localize('remote extension host Log', "Remote Extension Host") : nls.localize('extension host Log', "Extension Host"); - extHostOutputService.createOutputChannelFromLogFile(outputChannelName, extHostLogService.logFile); - - // Register API-ish commands - ExtHostApiCommands.register(extHostCommands); - - return function (extension: IExtensionDescription, extensionRegistry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode { - - // Check document selectors for being overly generic. Technically this isn't a problem but - // in practice many extensions say they support `fooLang` but need fs-access to do so. Those - // extension should specify then the `file`-scheme, e.g. `{ scheme: 'fooLang', language: 'fooLang' }` - // We only inform once, it is not a warning because we just want to raise awareness and because - // we cannot say if the extension is doing it right or wrong... - const checkSelector = (function () { - let done = (!extension.isUnderDevelopment); - function informOnce(selector: vscode.DocumentSelector) { - if (!done) { - console.info(`Extension '${extension.identifier.value}' uses a document selector without scheme. Learn more about this: https://go.microsoft.com/fwlink/?linkid=872305`); - done = true; - } - } - return function perform(selector: vscode.DocumentSelector): vscode.DocumentSelector { - if (Array.isArray(selector)) { - selector.forEach(perform); - } else if (typeof selector === 'string') { - informOnce(selector); - } else { - if (typeof selector.scheme === 'undefined') { - informOnce(selector); - } - if (!extension.enableProposedApi && typeof selector.exclusive === 'boolean') { - throwProposedApiError(extension); - } - } - return selector; - }; - })(); - - - // namespace: commands - const commands: typeof vscode.commands = { - registerCommand(id: string, command: (...args: any[]) => T | Thenable, thisArgs?: any): vscode.Disposable { - return extHostCommands.registerCommand(true, id, command, thisArgs); - }, - registerTextEditorCommand(id: string, callback: (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit, ...args: any[]) => void, thisArg?: any): vscode.Disposable { - return extHostCommands.registerCommand(true, id, (...args: any[]): any => { - const activeTextEditor = extHostEditors.getActiveTextEditor(); - if (!activeTextEditor) { - console.warn('Cannot execute ' + id + ' because there is no active text editor.'); - return undefined; - } - - return activeTextEditor.edit((edit: vscode.TextEditorEdit) => { - args.unshift(activeTextEditor, edit); - callback.apply(thisArg, args); - - }).then((result) => { - if (!result) { - console.warn('Edits from command ' + id + ' were not applied.'); - } - }, (err) => { - console.warn('An error occurred while running command ' + id, err); - }); - }); - }, - registerDiffInformationCommand: proposedApiFunction(extension, (id: string, callback: (diff: vscode.LineChange[], ...args: any[]) => any, thisArg?: any): vscode.Disposable => { - return extHostCommands.registerCommand(true, id, async (...args: any[]): Promise => { - const activeTextEditor = extHostEditors.getActiveTextEditor(); - if (!activeTextEditor) { - console.warn('Cannot execute ' + id + ' because there is no active text editor.'); - return undefined; - } - - const diff = await extHostEditors.getDiffInformation(activeTextEditor.id); - callback.apply(thisArg, [diff, ...args]); - }); - }), - executeCommand(id: string, ...args: any[]): Thenable { - return extHostCommands.executeCommand(id, ...args); - }, - getCommands(filterInternal: boolean = false): Thenable { - return extHostCommands.getCommands(filterInternal); - }, - onDidExecuteCommand: proposedApiFunction(extension, (listener, thisArgs?, disposables?) => { - checkProposedApiEnabled(extension); - return extHostCommands.onDidExecuteCommand(listener, thisArgs, disposables); - }), - }; - - // namespace: env - const env: typeof vscode.env = { - get machineId() { return initData.telemetryInfo.machineId; }, - get sessionId() { return initData.telemetryInfo.sessionId; }, - get language() { return initData.environment.appLanguage; }, - get appName() { return initData.environment.appName; }, - get appRoot() { return initData.environment.appRoot!.fsPath; }, - get uriScheme() { return initData.environment.appUriScheme; }, - get logLevel() { - checkProposedApiEnabled(extension); - return typeConverters.LogLevel.to(extHostLogService.getLevel()); - }, - get onDidChangeLogLevel() { - checkProposedApiEnabled(extension); - return Event.map(extHostLogService.onDidChangeLogLevel, l => typeConverters.LogLevel.to(l)); - }, - get clipboard(): vscode.Clipboard { - return extHostClipboard; - }, - get shell(): string { - throw new Error('not implemented'); - // return extHostTerminalService.getDefaultShell(configProvider); - }, - openExternal(uri: URI) { - return extHostWindow.openUri(uri, { allowTunneling: !!initData.remote.isRemote }); - }, - get remoteName() { - return getRemoteName(initData.remote.authority); - } - }; - if (!initData.environment.extensionTestsLocationURI) { - // allow to patch env-function when running tests - Object.freeze(env); - } - - const extensionKind = initData.remote.isRemote - ? extHostTypes.ExtensionKind.Workspace - : extHostTypes.ExtensionKind.UI; - - // namespace: extensions - const extensions: typeof vscode.extensions = { - getExtension(extensionId: string): Extension | undefined { - const desc = extensionRegistry.getExtensionDescription(extensionId); - if (desc) { - return new Extension(extensionService, desc, extensionKind); - } - return undefined; - }, - get all(): Extension[] { - return extensionRegistry.getAllExtensionDescriptions().map((desc) => new Extension(extensionService, desc, extensionKind)); - }, - get onDidChange() { - return extensionRegistry.onDidChange; - } - }; - - // namespace: languages - const languages: typeof vscode.languages = { - createDiagnosticCollection(name?: string): vscode.DiagnosticCollection { - return extHostDiagnostics.createDiagnosticCollection(name); - }, - get onDidChangeDiagnostics() { - return extHostDiagnostics.onDidChangeDiagnostics; - }, - getDiagnostics: (resource?: vscode.Uri) => { - return extHostDiagnostics.getDiagnostics(resource); - }, - getLanguages(): Thenable { - return extHostLanguages.getLanguages(); - }, - setTextDocumentLanguage(document: vscode.TextDocument, languageId: string): Thenable { - return extHostLanguages.changeLanguage(document.uri, languageId); - }, - match(selector: vscode.DocumentSelector, document: vscode.TextDocument): number { - return score(typeConverters.LanguageSelector.from(selector), document.uri, document.languageId, true); - }, - registerCodeActionsProvider(selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider, metadata?: vscode.CodeActionProviderMetadata): vscode.Disposable { - return extHostLanguageFeatures.registerCodeActionProvider(extension, checkSelector(selector), provider, metadata); - }, - registerCodeLensProvider(selector: vscode.DocumentSelector, provider: vscode.CodeLensProvider): vscode.Disposable { - return extHostLanguageFeatures.registerCodeLensProvider(extension, checkSelector(selector), provider); - }, - registerDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.DefinitionProvider): vscode.Disposable { - return extHostLanguageFeatures.registerDefinitionProvider(extension, checkSelector(selector), provider); - }, - registerDeclarationProvider(selector: vscode.DocumentSelector, provider: vscode.DeclarationProvider): vscode.Disposable { - return extHostLanguageFeatures.registerDeclarationProvider(extension, checkSelector(selector), provider); - }, - registerImplementationProvider(selector: vscode.DocumentSelector, provider: vscode.ImplementationProvider): vscode.Disposable { - return extHostLanguageFeatures.registerImplementationProvider(extension, checkSelector(selector), provider); - }, - registerTypeDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.TypeDefinitionProvider): vscode.Disposable { - return extHostLanguageFeatures.registerTypeDefinitionProvider(extension, checkSelector(selector), provider); - }, - registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable { - return extHostLanguageFeatures.registerHoverProvider(extension, checkSelector(selector), provider, extension.identifier); - }, - registerDocumentHighlightProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentHighlightProvider): vscode.Disposable { - return extHostLanguageFeatures.registerDocumentHighlightProvider(extension, checkSelector(selector), provider); - }, - registerReferenceProvider(selector: vscode.DocumentSelector, provider: vscode.ReferenceProvider): vscode.Disposable { - return extHostLanguageFeatures.registerReferenceProvider(extension, checkSelector(selector), provider); - }, - registerRenameProvider(selector: vscode.DocumentSelector, provider: vscode.RenameProvider): vscode.Disposable { - return extHostLanguageFeatures.registerRenameProvider(extension, checkSelector(selector), provider); - }, - registerDocumentSymbolProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentSymbolProvider, metadata?: vscode.DocumentSymbolProviderMetadata): vscode.Disposable { - return extHostLanguageFeatures.registerDocumentSymbolProvider(extension, checkSelector(selector), provider, metadata); - }, - registerWorkspaceSymbolProvider(provider: vscode.WorkspaceSymbolProvider): vscode.Disposable { - return extHostLanguageFeatures.registerWorkspaceSymbolProvider(extension, provider); - }, - registerDocumentFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentFormattingEditProvider): vscode.Disposable { - return extHostLanguageFeatures.registerDocumentFormattingEditProvider(extension, checkSelector(selector), provider); - }, - registerDocumentRangeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentRangeFormattingEditProvider): vscode.Disposable { - return extHostLanguageFeatures.registerDocumentRangeFormattingEditProvider(extension, checkSelector(selector), provider); - }, - registerOnTypeFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.OnTypeFormattingEditProvider, firstTriggerCharacter: string, ...moreTriggerCharacters: string[]): vscode.Disposable { - return extHostLanguageFeatures.registerOnTypeFormattingEditProvider(extension, checkSelector(selector), provider, [firstTriggerCharacter].concat(moreTriggerCharacters)); - }, - registerSignatureHelpProvider(selector: vscode.DocumentSelector, provider: vscode.SignatureHelpProvider, firstItem?: string | vscode.SignatureHelpProviderMetadata, ...remaining: string[]): vscode.Disposable { - if (typeof firstItem === 'object') { - return extHostLanguageFeatures.registerSignatureHelpProvider(extension, checkSelector(selector), provider, firstItem); - } - return extHostLanguageFeatures.registerSignatureHelpProvider(extension, checkSelector(selector), provider, typeof firstItem === 'undefined' ? [] : [firstItem, ...remaining]); - }, - registerCompletionItemProvider(selector: vscode.DocumentSelector, provider: vscode.CompletionItemProvider, ...triggerCharacters: string[]): vscode.Disposable { - return extHostLanguageFeatures.registerCompletionItemProvider(extension, checkSelector(selector), provider, triggerCharacters); - }, - registerDocumentLinkProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentLinkProvider): vscode.Disposable { - return extHostLanguageFeatures.registerDocumentLinkProvider(extension, checkSelector(selector), provider); - }, - registerColorProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentColorProvider): vscode.Disposable { - return extHostLanguageFeatures.registerColorProvider(extension, checkSelector(selector), provider); - }, - registerFoldingRangeProvider(selector: vscode.DocumentSelector, provider: vscode.FoldingRangeProvider): vscode.Disposable { - return extHostLanguageFeatures.registerFoldingRangeProvider(extension, checkSelector(selector), provider); - }, - registerSelectionRangeProvider(selector: vscode.DocumentSelector, provider: vscode.SelectionRangeProvider): vscode.Disposable { - return extHostLanguageFeatures.registerSelectionRangeProvider(extension, selector, provider); - }, - registerCallHierarchyProvider(selector: vscode.DocumentSelector, provider: vscode.CallHierarchyItemProvider): vscode.Disposable { - checkProposedApiEnabled(extension); - return extHostLanguageFeatures.registerCallHierarchyProvider(extension, selector, provider); - }, - setLanguageConfiguration: (language: string, configuration: vscode.LanguageConfiguration): vscode.Disposable => { - return extHostLanguageFeatures.setLanguageConfiguration(language, configuration); - } - }; - - // namespace: window - const window: typeof vscode.window = { - get activeTextEditor() { - return extHostEditors.getActiveTextEditor(); - }, - get visibleTextEditors() { - return extHostEditors.getVisibleTextEditors(); - }, - get activeTerminal(): vscode.Terminal { - throw new Error('not implemented'); - // return extHostTerminalService.activeTerminal; - }, - get terminals(): vscode.Terminal[] { - throw new Error('not implemented'); - // return extHostTerminalService.terminals; - }, - showTextDocument(documentOrUri: vscode.TextDocument | vscode.Uri, columnOrOptions?: vscode.ViewColumn | vscode.TextDocumentShowOptions, preserveFocus?: boolean): Thenable { - let documentPromise: Promise; - if (URI.isUri(documentOrUri)) { - documentPromise = Promise.resolve(workspace.openTextDocument(documentOrUri)); - } else { - documentPromise = Promise.resolve(documentOrUri); - } - return documentPromise.then(document => { - return extHostEditors.showTextDocument(document, columnOrOptions, preserveFocus); - }); - }, - createTextEditorDecorationType(options: vscode.DecorationRenderOptions): vscode.TextEditorDecorationType { - return extHostEditors.createTextEditorDecorationType(options); - }, - onDidChangeActiveTextEditor(listener, thisArg?, disposables?) { - return extHostEditors.onDidChangeActiveTextEditor(listener, thisArg, disposables); - }, - onDidChangeVisibleTextEditors(listener, thisArg, disposables) { - return extHostEditors.onDidChangeVisibleTextEditors(listener, thisArg, disposables); - }, - onDidChangeTextEditorSelection(listener: (e: vscode.TextEditorSelectionChangeEvent) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) { - return extHostEditors.onDidChangeTextEditorSelection(listener, thisArgs, disposables); - }, - onDidChangeTextEditorOptions(listener: (e: vscode.TextEditorOptionsChangeEvent) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) { - return extHostEditors.onDidChangeTextEditorOptions(listener, thisArgs, disposables); - }, - onDidChangeTextEditorVisibleRanges(listener: (e: vscode.TextEditorVisibleRangesChangeEvent) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) { - return extHostEditors.onDidChangeTextEditorVisibleRanges(listener, thisArgs, disposables); - }, - onDidChangeTextEditorViewColumn(listener, thisArg?, disposables?) { - return extHostEditors.onDidChangeTextEditorViewColumn(listener, thisArg, disposables); - }, - onDidCloseTerminal(listener, thisArg?, disposables?) { - throw new Error('not implemented'); - // return extHostTerminalService.onDidCloseTerminal(listener, thisArg, disposables); - }, - onDidOpenTerminal(listener, thisArg?, disposables?) { - throw new Error('not implemented'); - // return extHostTerminalService.onDidOpenTerminal(listener, thisArg, disposables); - }, - onDidChangeActiveTerminal(listener, thisArg?, disposables?) { - throw new Error('not implemented'); - // return extHostTerminalService.onDidChangeActiveTerminal(listener, thisArg, disposables); - }, - onDidChangeTerminalDimensions(listener, thisArg?, disposables?) { - throw new Error('not implemented'); - // return extHostTerminalService.onDidChangeTerminalDimensions(listener, thisArg, disposables); - }, - get state() { - return extHostWindow.state; - }, - onDidChangeWindowState(listener, thisArg?, disposables?) { - return extHostWindow.onDidChangeWindowState(listener, thisArg, disposables); - }, - showInformationMessage(message: string, first: vscode.MessageOptions | string | vscode.MessageItem, ...rest: Array) { - return extHostMessageService.showMessage(extension, Severity.Info, message, first, rest); - }, - showWarningMessage(message: string, first: vscode.MessageOptions | string | vscode.MessageItem, ...rest: Array) { - return extHostMessageService.showMessage(extension, Severity.Warning, message, first, rest); - }, - showErrorMessage(message: string, first: vscode.MessageOptions | string | vscode.MessageItem, ...rest: Array) { - return extHostMessageService.showMessage(extension, Severity.Error, message, first, rest); - }, - showQuickPick(items: any, options: vscode.QuickPickOptions, token?: vscode.CancellationToken): any { - return extHostQuickOpen.showQuickPick(items, !!extension.enableProposedApi, options, token); - }, - showWorkspaceFolderPick(options: vscode.WorkspaceFolderPickOptions) { - return extHostQuickOpen.showWorkspaceFolderPick(options); - }, - showInputBox(options?: vscode.InputBoxOptions, token?: vscode.CancellationToken) { - return extHostQuickOpen.showInput(options, token); - }, - showOpenDialog(options) { - return extHostDialogs.showOpenDialog(options); - }, - showSaveDialog(options) { - return extHostDialogs.showSaveDialog(options); - }, - createStatusBarItem(alignmentOrOptions?: vscode.StatusBarAlignment | vscode.window.StatusBarItemOptions, priority?: number): vscode.StatusBarItem { - let id: string; - let name: string; - let alignment: number | undefined; - - if (alignmentOrOptions && typeof alignmentOrOptions !== 'number') { - id = alignmentOrOptions.id; - name = alignmentOrOptions.name; - alignment = alignmentOrOptions.alignment; - priority = alignmentOrOptions.priority; - } else { - id = extension.identifier.value; - name = nls.localize('extensionLabel', "{0} (Extension)", extension.displayName || extension.name); - alignment = alignmentOrOptions; - priority = priority; - } - - return extHostStatusBar.createStatusBarEntry(id, name, alignment, priority); - }, - setStatusBarMessage(text: string, timeoutOrThenable?: number | Thenable): vscode.Disposable { - return extHostStatusBar.setStatusBarMessage(text, timeoutOrThenable); - }, - withScmProgress(task: (progress: vscode.Progress) => Thenable) { - console.warn(`[Deprecation Warning] function 'withScmProgress' is deprecated and should no longer be used. Use 'withProgress' instead.`); - return extHostProgress.withProgress(extension, { location: extHostTypes.ProgressLocation.SourceControl }, (progress, token) => task({ report(n: number) { /*noop*/ } })); - }, - withProgress(options: vscode.ProgressOptions, task: (progress: vscode.Progress<{ message?: string; worked?: number }>, token: vscode.CancellationToken) => Thenable) { - return extHostProgress.withProgress(extension, options, task); - }, - createOutputChannel(name: string): vscode.OutputChannel { - return extHostOutputService.createOutputChannel(name); - }, - createWebviewPanel(viewType: string, title: string, showOptions: vscode.ViewColumn | { viewColumn: vscode.ViewColumn, preserveFocus?: boolean }, options: vscode.WebviewPanelOptions & vscode.WebviewOptions): vscode.WebviewPanel { - return extHostWebviews.createWebviewPanel(extension, viewType, title, showOptions, options); - }, - createWebviewTextEditorInset(editor: vscode.TextEditor, line: number, height: number, options: vscode.WebviewOptions): vscode.WebviewEditorInset { - checkProposedApiEnabled(extension); - return extHostEditorInsets.createWebviewEditorInset(editor, line, height, options, extension); - }, - createTerminal(nameOrOptions?: vscode.TerminalOptions | vscode.ExtensionTerminalOptions | string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal { - throw new Error('not implemented'); - // if (typeof nameOrOptions === 'object') { - // if ('pty' in nameOrOptions) { - // return extHostTerminalService.createExtensionTerminal(nameOrOptions); - // } - // return extHostTerminalService.createTerminalFromOptions(nameOrOptions); - // } - // return extHostTerminalService.createTerminal(nameOrOptions, shellPath, shellArgs); - }, - createTerminalRenderer(name: string): vscode.TerminalRenderer { - throw new Error('not implemented'); - // return extHostTerminalService.createTerminalRenderer(name); - }, - registerTreeDataProvider(viewId: string, treeDataProvider: vscode.TreeDataProvider): vscode.Disposable { - return extHostTreeViews.registerTreeDataProvider(viewId, treeDataProvider, extension); - }, - createTreeView(viewId: string, options: { treeDataProvider: vscode.TreeDataProvider }): vscode.TreeView { - return extHostTreeViews.createTreeView(viewId, options, extension); - }, - registerWebviewPanelSerializer: (viewType: string, serializer: vscode.WebviewPanelSerializer) => { - return extHostWebviews.registerWebviewPanelSerializer(viewType, serializer); - }, - registerDecorationProvider: proposedApiFunction(extension, (provider: vscode.DecorationProvider) => { - return extHostDecorations.registerDecorationProvider(provider, extension.identifier); - }), - registerUriHandler(handler: vscode.UriHandler) { - return extHostUrls.registerUriHandler(extension.identifier, handler); - }, - createQuickPick(): vscode.QuickPick { - return extHostQuickOpen.createQuickPick(extension.identifier, !!extension.enableProposedApi); - }, - createInputBox(): vscode.InputBox { - return extHostQuickOpen.createInputBox(extension.identifier); - } - }; - - // namespace: workspace - const workspace: typeof vscode.workspace = { - get rootPath() { - return extHostWorkspace.getPath(); - }, - set rootPath(value) { - throw errors.readonly(); - }, - getWorkspaceFolder(resource) { - return extHostWorkspace.getWorkspaceFolder(resource); - }, - get workspaceFolders() { - return extHostWorkspace.getWorkspaceFolders(); - }, - get name() { - return extHostWorkspace.name; - }, - set name(value) { - throw errors.readonly(); - }, - get workspaceFile() { - return extHostWorkspace.workspaceFile; - }, - set workspaceFile(value) { - throw errors.readonly(); - }, - updateWorkspaceFolders: (index, deleteCount, ...workspaceFoldersToAdd) => { - return extHostWorkspace.updateWorkspaceFolders(extension, index, deleteCount || 0, ...workspaceFoldersToAdd); - }, - onDidChangeWorkspaceFolders: function (listener, thisArgs?, disposables?) { - return extHostWorkspace.onDidChangeWorkspace(listener, thisArgs, disposables); - }, - asRelativePath: (pathOrUri, includeWorkspace?) => { - return extHostWorkspace.getRelativePath(pathOrUri, includeWorkspace); - }, - findFiles: (include, exclude, maxResults?, token?) => { - // Note, undefined/null have different meanings on "exclude" - return extHostWorkspace.findFiles(typeConverters.GlobPattern.from(include), typeConverters.GlobPattern.from(exclude), maxResults, extension.identifier, token); - }, - findTextInFiles: (query: vscode.TextSearchQuery, optionsOrCallback: vscode.FindTextInFilesOptions | ((result: vscode.TextSearchResult) => void), callbackOrToken?: vscode.CancellationToken | ((result: vscode.TextSearchResult) => void), token?: vscode.CancellationToken) => { - let options: vscode.FindTextInFilesOptions; - let callback: (result: vscode.TextSearchResult) => void; - - if (typeof optionsOrCallback === 'object') { - options = optionsOrCallback; - callback = callbackOrToken as (result: vscode.TextSearchResult) => void; - } else { - options = {}; - callback = optionsOrCallback; - token = callbackOrToken as vscode.CancellationToken; - } - - return extHostWorkspace.findTextInFiles(query, options || {}, callback, extension.identifier, token); - }, - saveAll: (includeUntitled?) => { - return extHostWorkspace.saveAll(includeUntitled); - }, - applyEdit(edit: vscode.WorkspaceEdit): Thenable { - return extHostEditors.applyWorkspaceEdit(edit); - }, - createFileSystemWatcher: (pattern, ignoreCreate, ignoreChange, ignoreDelete): vscode.FileSystemWatcher => { - return extHostFileSystemEvent.createFileSystemWatcher(typeConverters.GlobPattern.from(pattern), ignoreCreate, ignoreChange, ignoreDelete); - }, - get textDocuments() { - return extHostDocuments.getAllDocumentData().map(data => data.document); - }, - set textDocuments(value) { - throw errors.readonly(); - }, - openTextDocument(uriOrFileNameOrOptions?: vscode.Uri | string | { language?: string; content?: string; }) { - let uriPromise: Thenable; - - const options = uriOrFileNameOrOptions as { language?: string; content?: string; }; - if (typeof uriOrFileNameOrOptions === 'string') { - uriPromise = Promise.resolve(URI.file(uriOrFileNameOrOptions)); - } else if (uriOrFileNameOrOptions instanceof URI) { - uriPromise = Promise.resolve(uriOrFileNameOrOptions); - } else if (!options || typeof options === 'object') { - uriPromise = extHostDocuments.createDocumentData(options); - } else { - throw new Error('illegal argument - uriOrFileNameOrOptions'); - } - - return uriPromise.then(uri => { - return extHostDocuments.ensureDocumentData(uri).then(() => { - return extHostDocuments.getDocument(uri); - }); - }); - }, - onDidOpenTextDocument: (listener, thisArgs?, disposables?) => { - return extHostDocuments.onDidAddDocument(listener, thisArgs, disposables); - }, - onDidCloseTextDocument: (listener, thisArgs?, disposables?) => { - return extHostDocuments.onDidRemoveDocument(listener, thisArgs, disposables); - }, - onDidChangeTextDocument: (listener, thisArgs?, disposables?) => { - return extHostDocuments.onDidChangeDocument(listener, thisArgs, disposables); - }, - onDidSaveTextDocument: (listener, thisArgs?, disposables?) => { - return extHostDocuments.onDidSaveDocument(listener, thisArgs, disposables); - }, - onWillSaveTextDocument: (listener, thisArgs?, disposables?) => { - return extHostDocumentSaveParticipant.getOnWillSaveTextDocumentEvent(extension)(listener, thisArgs, disposables); - }, - onDidChangeConfiguration: (listener: (_: any) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) => { - return configProvider.onDidChangeConfiguration(listener, thisArgs, disposables); - }, - getConfiguration(section?: string, resource?: vscode.Uri): vscode.WorkspaceConfiguration { - resource = arguments.length === 1 ? undefined : resource; - return configProvider.getConfiguration(section, resource, extension.identifier); - }, - registerTextDocumentContentProvider(scheme: string, provider: vscode.TextDocumentContentProvider) { - return extHostDocumentContentProviders.registerTextDocumentContentProvider(scheme, provider); - }, - registerTaskProvider: (type: string, provider: vscode.TaskProvider) => { - throw new Error('not implemented'); - // return extHostTask.registerTaskProvider(extension, type, provider); - }, - registerFileSystemProvider(scheme, provider, options) { - return extHostFileSystem.registerFileSystemProvider(scheme, provider, options); - }, - get fs() { - return extHostFileSystem.fileSystem; - }, - registerFileSearchProvider: proposedApiFunction(extension, (scheme: string, provider: vscode.FileSearchProvider) => { - throw new Error('not implemented'); - // return extHostSearch.registerFileSearchProvider(scheme, provider); - }), - registerTextSearchProvider: proposedApiFunction(extension, (scheme: string, provider: vscode.TextSearchProvider) => { - throw new Error('not implemented'); - // return extHostSearch.registerTextSearchProvider(scheme, provider); - }), - registerRemoteAuthorityResolver: proposedApiFunction(extension, (authorityPrefix: string, resolver: vscode.RemoteAuthorityResolver) => { - return extensionService.registerRemoteAuthorityResolver(authorityPrefix, resolver); - }), - registerResourceLabelFormatter: proposedApiFunction(extension, (formatter: vscode.ResourceLabelFormatter) => { - return extHostLabelService.$registerResourceLabelFormatter(formatter); - }), - onDidRenameFile: proposedApiFunction(extension, (listener: (e: vscode.FileRenameEvent) => any, thisArg?: any, disposables?: vscode.Disposable[]) => { - return extHostFileSystemEvent.onDidRenameFile(listener, thisArg, disposables); - }), - onWillRenameFile: proposedApiFunction(extension, (listener: (e: vscode.FileWillRenameEvent) => any, thisArg?: any, disposables?: vscode.Disposable[]) => { - return extHostFileSystemEvent.getOnWillRenameFileEvent(extension)(listener, thisArg, disposables); - }) - }; - - // namespace: scm - const scm: typeof vscode.scm = { - get inputBox() { - return extHostSCM.getLastInputBox(extension)!; // Strict null override - Deprecated api - }, - createSourceControl(id: string, label: string, rootUri?: vscode.Uri) { - return extHostSCM.createSourceControl(extension, id, label, rootUri); - } - }; - - const comment: typeof vscode.comments = { - createCommentController(id: string, label: string) { - return extHostComment.createCommentController(extension, id, label); - } - }; - - const comments = comment; - - // namespace: debug - // const debug: typeof vscode.debug = { - // get activeDebugSession() { - // return extHostDebugService.activeDebugSession; - // }, - // get activeDebugConsole() { - // return extHostDebugService.activeDebugConsole; - // }, - // get breakpoints() { - // return extHostDebugService.breakpoints; - // }, - // onDidStartDebugSession(listener, thisArg?, disposables?) { - // return extHostDebugService.onDidStartDebugSession(listener, thisArg, disposables); - // }, - // onDidTerminateDebugSession(listener, thisArg?, disposables?) { - // return extHostDebugService.onDidTerminateDebugSession(listener, thisArg, disposables); - // }, - // onDidChangeActiveDebugSession(listener, thisArg?, disposables?) { - // return extHostDebugService.onDidChangeActiveDebugSession(listener, thisArg, disposables); - // }, - // onDidReceiveDebugSessionCustomEvent(listener, thisArg?, disposables?) { - // return extHostDebugService.onDidReceiveDebugSessionCustomEvent(listener, thisArg, disposables); - // }, - // onDidChangeBreakpoints(listener, thisArgs?, disposables?) { - // return extHostDebugService.onDidChangeBreakpoints(listener, thisArgs, disposables); - // }, - // registerDebugConfigurationProvider(debugType: string, provider: vscode.DebugConfigurationProvider) { - // return extHostDebugService.registerDebugConfigurationProvider(debugType, provider); - // }, - // registerDebugAdapterDescriptorFactory(debugType: string, factory: vscode.DebugAdapterDescriptorFactory) { - // return extHostDebugService.registerDebugAdapterDescriptorFactory(extension, debugType, factory); - // }, - // registerDebugAdapterTrackerFactory(debugType: string, factory: vscode.DebugAdapterTrackerFactory) { - // return extHostDebugService.registerDebugAdapterTrackerFactory(debugType, factory); - // }, - // startDebugging(folder: vscode.WorkspaceFolder | undefined, nameOrConfig: string | vscode.DebugConfiguration, parentSession?: vscode.DebugSession) { - // return extHostDebugService.startDebugging(folder, nameOrConfig, parentSession); - // }, - // addBreakpoints(breakpoints: vscode.Breakpoint[]) { - // return extHostDebugService.addBreakpoints(breakpoints); - // }, - // removeBreakpoints(breakpoints: vscode.Breakpoint[]) { - // return extHostDebugService.removeBreakpoints(breakpoints); - // } - // }; - - // const tasks: typeof vscode.tasks = { - // registerTaskProvider: (type: string, provider: vscode.TaskProvider) => { - // return extHostTask.registerTaskProvider(extension, type, provider); - // }, - // fetchTasks: (filter?: vscode.TaskFilter): Thenable => { - // return extHostTask.fetchTasks(filter); - // }, - // executeTask: (task: vscode.Task): Thenable => { - // return extHostTask.executeTask(extension, task); - // }, - // get taskExecutions(): vscode.TaskExecution[] { - // return extHostTask.taskExecutions; - // }, - // onDidStartTask: (listeners, thisArgs?, disposables?) => { - // return extHostTask.onDidStartTask(listeners, thisArgs, disposables); - // }, - // onDidEndTask: (listeners, thisArgs?, disposables?) => { - // return extHostTask.onDidEndTask(listeners, thisArgs, disposables); - // }, - // onDidStartTaskProcess: (listeners, thisArgs?, disposables?) => { - // return extHostTask.onDidStartTaskProcess(listeners, thisArgs, disposables); - // }, - // onDidEndTaskProcess: (listeners, thisArgs?, disposables?) => { - // return extHostTask.onDidEndTaskProcess(listeners, thisArgs, disposables); - // } - // }; - - return { - version: initData.version, - // namespaces - commands, - get debug(): typeof vscode.debug { throw new Error('not implemented'); }, - env, - extensions, - languages, - scm, - comment, - comments, - get tasks(): typeof vscode.tasks { throw new Error('not implemented'); }, - window, - workspace, - // types - Breakpoint: extHostTypes.Breakpoint, - CancellationTokenSource: CancellationTokenSource, - CodeAction: extHostTypes.CodeAction, - CodeActionKind: extHostTypes.CodeActionKind, - CodeActionTrigger: extHostTypes.CodeActionTrigger, - CodeLens: extHostTypes.CodeLens, - CodeInset: extHostTypes.CodeInset, - Color: extHostTypes.Color, - ColorInformation: extHostTypes.ColorInformation, - ColorPresentation: extHostTypes.ColorPresentation, - CommentThreadCollapsibleState: extHostTypes.CommentThreadCollapsibleState, - CommentMode: extHostTypes.CommentMode, - CompletionItem: extHostTypes.CompletionItem, - CompletionItemKind: extHostTypes.CompletionItemKind, - CompletionList: extHostTypes.CompletionList, - CompletionTriggerKind: extHostTypes.CompletionTriggerKind, - ConfigurationTarget: extHostTypes.ConfigurationTarget, - DebugAdapterExecutable: extHostTypes.DebugAdapterExecutable, - DebugAdapterServer: extHostTypes.DebugAdapterServer, - DecorationRangeBehavior: extHostTypes.DecorationRangeBehavior, - Diagnostic: extHostTypes.Diagnostic, - DiagnosticRelatedInformation: extHostTypes.DiagnosticRelatedInformation, - DiagnosticSeverity: extHostTypes.DiagnosticSeverity, - DiagnosticTag: extHostTypes.DiagnosticTag, - Disposable: extHostTypes.Disposable, - DocumentHighlight: extHostTypes.DocumentHighlight, - DocumentHighlightKind: extHostTypes.DocumentHighlightKind, - DocumentLink: extHostTypes.DocumentLink, - DocumentSymbol: extHostTypes.DocumentSymbol, - EndOfLine: extHostTypes.EndOfLine, - EventEmitter: Emitter, - ExtensionExecutionContext: extHostTypes.ExtensionExecutionContext, - ExtensionKind: extHostTypes.ExtensionKind, - CustomExecution: extHostTypes.CustomExecution, - CustomExecution2: extHostTypes.CustomExecution2, - FileChangeType: extHostTypes.FileChangeType, - FileSystemError: extHostTypes.FileSystemError, - FileType: files.FileType, - FoldingRange: extHostTypes.FoldingRange, - FoldingRangeKind: extHostTypes.FoldingRangeKind, - FunctionBreakpoint: extHostTypes.FunctionBreakpoint, - Hover: extHostTypes.Hover, - IndentAction: languageConfiguration.IndentAction, - Location: extHostTypes.Location, - LogLevel: extHostTypes.LogLevel, - MarkdownString: extHostTypes.MarkdownString, - OverviewRulerLane: OverviewRulerLane, - ParameterInformation: extHostTypes.ParameterInformation, - Position: extHostTypes.Position, - ProcessExecution: extHostTypes.ProcessExecution, - ProgressLocation: extHostTypes.ProgressLocation, - QuickInputButtons: extHostTypes.QuickInputButtons, - Range: extHostTypes.Range, - RelativePattern: extHostTypes.RelativePattern, - ResolvedAuthority: extHostTypes.ResolvedAuthority, - RemoteAuthorityResolverError: extHostTypes.RemoteAuthorityResolverError, - Selection: extHostTypes.Selection, - SelectionRange: extHostTypes.SelectionRange, - ShellExecution: extHostTypes.ShellExecution, - ShellQuoting: extHostTypes.ShellQuoting, - SignatureHelpTriggerKind: extHostTypes.SignatureHelpTriggerKind, - SignatureHelp: extHostTypes.SignatureHelp, - SignatureInformation: extHostTypes.SignatureInformation, - SnippetString: extHostTypes.SnippetString, - SourceBreakpoint: extHostTypes.SourceBreakpoint, - SourceControlInputBoxValidationType: extHostTypes.SourceControlInputBoxValidationType, - StatusBarAlignment: extHostTypes.StatusBarAlignment, - SymbolInformation: extHostTypes.SymbolInformation, - SymbolKind: extHostTypes.SymbolKind, - Task: extHostTypes.Task, - Task2: extHostTypes.Task, - TaskGroup: extHostTypes.TaskGroup, - TaskPanelKind: extHostTypes.TaskPanelKind, - TaskRevealKind: extHostTypes.TaskRevealKind, - TaskScope: extHostTypes.TaskScope, - TextDocumentSaveReason: extHostTypes.TextDocumentSaveReason, - TextEdit: extHostTypes.TextEdit, - TextEditorCursorStyle: TextEditorCursorStyle, - TextEditorLineNumbersStyle: extHostTypes.TextEditorLineNumbersStyle, - TextEditorRevealType: extHostTypes.TextEditorRevealType, - TextEditorSelectionChangeKind: extHostTypes.TextEditorSelectionChangeKind, - ThemeColor: extHostTypes.ThemeColor, - ThemeIcon: extHostTypes.ThemeIcon, - TreeItem: extHostTypes.TreeItem, - TreeItem2: extHostTypes.TreeItem, - TreeItemCollapsibleState: extHostTypes.TreeItemCollapsibleState, - Uri: URI, - ViewColumn: extHostTypes.ViewColumn, - WorkspaceEdit: extHostTypes.WorkspaceEdit, - // proposed - CallHierarchyDirection: extHostTypes.CallHierarchyDirection, - CallHierarchyItem: extHostTypes.CallHierarchyItem - }; - }; -} - -class Extension implements vscode.Extension { - - private _extensionService: ExtHostExtensionService; - private _identifier: ExtensionIdentifier; - - readonly id: string; - readonly extensionPath: string; - readonly packageJSON: IExtensionDescription; - readonly extensionKind: vscode.ExtensionKind; - - constructor(extensionService: ExtHostExtensionService, description: IExtensionDescription, kind: extHostTypes.ExtensionKind) { - this._extensionService = extensionService; - this._identifier = description.identifier; - this.id = description.identifier.value; - this.extensionPath = path.normalize(originalFSPath(description.extensionLocation)); - this.packageJSON = description; - this.extensionKind = kind; - } - - get isActive(): boolean { - return this._extensionService.isActivated(this._identifier); - } - - get exports(): T { - if (this.packageJSON.api === 'none') { - return undefined!; // Strict nulloverride - Public api - } - return this._extensionService.getExtensionExports(this._identifier); - } - - activate(): Thenable { - return this._extensionService.activateByIdWithErrors(this._identifier, new ExtensionActivatedByAPI(false)).then(() => this.exports); - } -} diff --git a/src/vs/workbench/services/extensions/worker/extHost.services.ts b/src/vs/workbench/services/extensions/worker/extHost.services.ts new file mode 100644 index 00000000000..69ad6dbfe4b --- /dev/null +++ b/src/vs/workbench/services/extensions/worker/extHost.services.ts @@ -0,0 +1,51 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IExtHostOutputService, ExtHostOutputService } from 'vs/workbench/api/common/extHostOutput'; +import { IExtHostWorkspace, ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; +import { IExtHostDecorations, ExtHostDecorations } from 'vs/workbench/api/common/extHostDecorations'; +import { IExtHostConfiguration, ExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; +import { IExtHostCommands, ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; +import { IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; +import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; +import { IExtHostTask } from 'vs/workbench/api/common/extHostTask'; +import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService'; +import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch'; +import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths'; +import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; +import { IExtHostStorage, ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; +import { ExtHostExtensionService } from 'vs/workbench/api/worker/extHostExtensionService'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import { ExtensionStoragePaths } from 'vs/workbench/api/worker/extHostStoragePaths'; + + +// register singleton services +registerSingleton(IExtHostOutputService, ExtHostOutputService); +registerSingleton(IExtHostWorkspace, ExtHostWorkspace); +registerSingleton(IExtHostDecorations, ExtHostDecorations); +registerSingleton(IExtHostConfiguration, ExtHostConfiguration); +registerSingleton(IExtHostCommands, ExtHostCommands); +registerSingleton(IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors); +registerSingleton(IExtHostStorage, ExtHostStorage); +registerSingleton(IExtensionStoragePaths, ExtensionStoragePaths); +registerSingleton(IExtHostExtensionService, ExtHostExtensionService); + +// register services that only throw errors +function NotImplementedProxy(name: ServiceIdentifier): { new(): T } { + return class { + constructor() { + return new Proxy({}, { + get(_target: any, prop: any) { + throw new Error(`Not Implemented: ${name}->${String(prop)}`); + } + }); + } + }; +} +registerSingleton(IExtHostTerminalService, class extends NotImplementedProxy(IExtHostTerminalService) { }); +registerSingleton(IExtHostTask, class extends NotImplementedProxy(IExtHostTask) { }); +registerSingleton(IExtHostDebugService, class extends NotImplementedProxy(IExtHostDebugService) { }); +registerSingleton(IExtHostSearch, class extends NotImplementedProxy(IExtHostSearch) { }); diff --git a/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts b/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts deleted file mode 100644 index 6e4cc7adb42..00000000000 --- a/src/vs/workbench/services/extensions/worker/extHostExtensionService.ts +++ /dev/null @@ -1,826 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * 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 * as path from 'vs/base/common/path'; -import { originalFSPath } from 'vs/base/common/resources'; -import { Barrier } from 'vs/base/common/async'; -import { dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; -import { TernarySearchTree } from 'vs/base/common/map'; -import { URI } from 'vs/base/common/uri'; -import { ILogService } from 'vs/platform/log/common/log'; -import { createApiFactory, IExtensionApiFactory } from './extHost.api.impl'; -// import { NodeModuleRequireInterceptor, VSCodeNodeModuleFactory, KeytarNodeModuleFactory, OpenNodeModuleFactory } from 'vs/workbench/api/node/extHostRequireInterceptor'; -import { ExtHostExtensionServiceShape, IEnvironment, IInitData, IMainContext, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape, IResolveAuthorityResult } from 'vs/workbench/api/common/extHost.protocol'; -import { ExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; -import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionModule, HostExtension, ExtensionActivationTimesFragment } from 'vs/workbench/api/common/extHostExtensionActivator'; -import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; -import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; -import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; -import { ExtensionActivationError, nullExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; -import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; -// import { connectProxyResolver } from 'vs/workbench/services/extensions/node/proxyResolver'; -import { CancellationTokenSource } from 'vs/base/common/cancellation'; -import * as errors from 'vs/base/common/errors'; -import * as vscode from 'vscode'; -import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; -import { Schemas } from 'vs/base/common/network'; -// import { withNullAsUndefined } from 'vs/base/common/types'; -import { VSBuffer } from 'vs/base/common/buffer'; -import { ExtensionMemento } from 'vs/workbench/api/common/extHostMemento'; -// import { ExtensionStoragePaths } from 'vs/workbench/api/node/extHostStoragePaths'; -import { RemoteAuthorityResolverError, ExtensionExecutionContext } from 'vs/workbench/api/common/extHostTypes'; -import { IURITransformer } from 'vs/base/common/uriIpc'; -import { ResolvedAuthority, ResolvedOptions } from 'vs/platform/remote/common/remoteAuthorityResolver'; -import { endsWith } from 'vs/base/common/strings'; - -interface ITestRunner { - /** Old test runner API, as exported from `vscode/lib/testrunner` */ - run(testsRoot: string, clb: (error: Error, failures?: number) => void): void; -} - -interface INewTestRunner { - /** New test runner API, as explained in the extension test doc */ - run(): Promise; -} - -export interface IHostUtils { - exit(code?: number): void; - exists(path: string): Promise; - realpath(path: string): Promise; -} - -type TelemetryActivationEventFragment = { - id: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' }; - name: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' }; - extensionVersion: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' }; - publisherDisplayName: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; - activationEvents: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; - isBuiltin: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true }; - reason: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; -}; - -export class ExtHostExtensionService implements ExtHostExtensionServiceShape { - - private static readonly WORKSPACE_CONTAINS_TIMEOUT = 7000; - - private readonly _hostUtils: IHostUtils; - private readonly _initData: IInitData; - private readonly _extHostContext: IMainContext; - private readonly _extHostWorkspace: ExtHostWorkspace; - private readonly _extHostConfiguration: ExtHostConfiguration; - // private readonly _environment: IEnvironment; - private readonly _extHostLogService: ExtHostLogService; - - private readonly _mainThreadWorkspaceProxy: MainThreadWorkspaceShape; - private readonly _mainThreadTelemetryProxy: MainThreadTelemetryShape; - private readonly _mainThreadExtensionsProxy: MainThreadExtensionServiceShape; - - private readonly _almostReadyToRunExtensions: Barrier; - private readonly _readyToStartExtensionHost: Barrier; - private readonly _readyToRunExtensions: Barrier; - private readonly _registry: ExtensionDescriptionRegistry; - private readonly _storage: ExtHostStorage; - // private readonly _storagePath: ExtensionStoragePaths; - private readonly _activator: ExtensionsActivator; - private _extensionPathIndex: Promise> | null; - private readonly _extensionApiFactory: IExtensionApiFactory; - - private readonly _resolvers: { [authorityPrefix: string]: vscode.RemoteAuthorityResolver; }; - - private _started: boolean; - - private readonly _disposables: DisposableStore; - - constructor( - hostUtils: IHostUtils, - initData: IInitData, - extHostContext: IMainContext, - extHostWorkspace: ExtHostWorkspace, - extHostConfiguration: ExtHostConfiguration, - environment: IEnvironment, - extHostLogService: ExtHostLogService, - uriTransformer: IURITransformer | null - ) { - this._hostUtils = hostUtils; - this._initData = initData; - this._extHostContext = extHostContext; - this._extHostWorkspace = extHostWorkspace; - this._extHostConfiguration = extHostConfiguration; - // this._environment = environment; - this._extHostLogService = extHostLogService; - this._disposables = new DisposableStore(); - - this._mainThreadWorkspaceProxy = this._extHostContext.getProxy(MainContext.MainThreadWorkspace); - this._mainThreadTelemetryProxy = this._extHostContext.getProxy(MainContext.MainThreadTelemetry); - this._mainThreadExtensionsProxy = this._extHostContext.getProxy(MainContext.MainThreadExtensionService); - - this._almostReadyToRunExtensions = new Barrier(); - this._readyToStartExtensionHost = new Barrier(); - this._readyToRunExtensions = new Barrier(); - this._registry = new ExtensionDescriptionRegistry(initData.extensions); - this._storage = new ExtHostStorage(this._extHostContext); - // this._storagePath = new ExtensionStoragePaths(withNullAsUndefined(initData.workspace), initData.environment); - - const hostExtensions = new Set(); - initData.hostExtensions.forEach((extensionId) => hostExtensions.add(ExtensionIdentifier.toKey(extensionId))); - - this._activator = new ExtensionsActivator(this._registry, initData.resolvedExtensions, initData.hostExtensions, { - onExtensionActivationError: (extensionId: ExtensionIdentifier, error: ExtensionActivationError): void => { - this._mainThreadExtensionsProxy.$onExtensionActivationError(extensionId, error); - }, - - actualActivateExtension: async (extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise => { - if (hostExtensions.has(ExtensionIdentifier.toKey(extensionId))) { - const activationEvent = (reason instanceof ExtensionActivatedByEvent ? reason.activationEvent : null); - await this._mainThreadExtensionsProxy.$activateExtension(extensionId, activationEvent); - return new HostExtension(); - } - const extensionDescription = this._registry.getExtensionDescription(extensionId)!; - return this._activateExtension(extensionDescription, reason); - } - }); - this._extensionPathIndex = null; - - // initialize API first (i.e. do not release barrier until the API is initialized) - this._extensionApiFactory = createApiFactory( - this._initData, - this._extHostContext, - this._extHostWorkspace, - this._extHostConfiguration, - this, - this._extHostLogService, - this._storage, - uriTransformer - ); - - this._resolvers = Object.create(null); - - this._started = false; - - this._initialize(); - - if (this._initData.autoStart) { - this._startExtensionHost(); - } - } - - private async _initialize(): Promise { - - // WORKER: globally define the vscode module and share that for all extensions - define('vscode', this._extensionApiFactory(nullExtensionDescription, this._registry, await this._extHostConfiguration.getConfigProvider())); - - try { - // const configProvider = await this._extHostConfiguration.getConfigProvider(); - // const extensionPaths = await this.getExtensionPathIndex(); - // NodeModuleRequireInterceptor.INSTANCE.register(new VSCodeNodeModuleFactory(this._extensionApiFactory, extensionPaths, this._registry, configProvider)); - // NodeModuleRequireInterceptor.INSTANCE.register(new KeytarNodeModuleFactory(this._extHostContext.getProxy(MainContext.MainThreadKeytar), this._environment)); - // if (this._initData.remoteAuthority) { - // NodeModuleRequireInterceptor.INSTANCE.register(new OpenNodeModuleFactory( - // this._extHostContext.getProxy(MainContext.MainThreadWindow), - // this._extHostContext.getProxy(MainContext.MainThreadTelemetry), - // extensionPaths - // )); - // } - - // // Do this when extension service exists, but extensions are not being activated yet. - // await connectProxyResolver(this._extHostWorkspace, configProvider, this, this._extHostLogService, this._mainThreadTelemetryProxy); - this._almostReadyToRunExtensions.open(); - - await this._extHostWorkspace.waitForInitializeCall(); - this._readyToStartExtensionHost.open(); - } catch (err) { - errors.onUnexpectedError(err); - } - } - - public async deactivateAll(): Promise { - let allPromises: Promise[] = []; - try { - const allExtensions = this._registry.getAllExtensionDescriptions(); - const allExtensionsIds = allExtensions.map(ext => ext.identifier); - const activatedExtensions = allExtensionsIds.filter(id => this.isActivated(id)); - - allPromises = activatedExtensions.map((extensionId) => { - return this._deactivate(extensionId); - }); - } catch (err) { - // TODO: write to log once we have one - } - await allPromises; - } - - public isActivated(extensionId: ExtensionIdentifier): boolean { - if (this._readyToRunExtensions.isOpen()) { - return this._activator.isActivated(extensionId); - } - return false; - } - - private _activateByEvent(activationEvent: string, startup: boolean): Promise { - const reason = new ExtensionActivatedByEvent(startup, activationEvent); - return this._activator.activateByEvent(activationEvent, reason); - } - - private _activateById(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise { - return this._activator.activateById(extensionId, reason); - } - - public activateByIdWithErrors(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise { - return this._activateById(extensionId, reason).then(() => { - const extension = this._activator.getActivatedExtension(extensionId); - if (extension.activationFailed) { - // activation failed => bubble up the error as the promise result - return Promise.reject(extension.activationFailedError); - } - return undefined; - }); - } - - public getExtensionRegistry(): Promise { - return this._readyToRunExtensions.wait().then(_ => this._registry); - } - - public getExtensionExports(extensionId: ExtensionIdentifier): IExtensionAPI | null | undefined { - if (this._readyToRunExtensions.isOpen()) { - return this._activator.getActivatedExtension(extensionId).exports; - } else { - return null; - } - } - - // create trie to enable fast 'filename -> extension id' look up - public getExtensionPathIndex(): Promise> { - if (!this._extensionPathIndex) { - const tree = TernarySearchTree.forPaths(); - const extensions = this._registry.getAllExtensionDescriptions().map(ext => { - if (!ext.main) { - return undefined; - } - return this._hostUtils.realpath(ext.extensionLocation.fsPath).then(value => tree.set(URI.file(value).fsPath, ext)); - }); - this._extensionPathIndex = Promise.all(extensions).then(() => tree); - } - return this._extensionPathIndex; - } - - private _deactivate(extensionId: ExtensionIdentifier): Promise { - let result = Promise.resolve(undefined); - - if (!this._readyToRunExtensions.isOpen()) { - return result; - } - - if (!this._activator.isActivated(extensionId)) { - return result; - } - - const extension = this._activator.getActivatedExtension(extensionId); - if (!extension) { - return result; - } - - // call deactivate if available - try { - if (typeof extension.module.deactivate === 'function') { - result = Promise.resolve(extension.module.deactivate()).then(undefined, (err) => { - // TODO: Do something with err if this is not the shutdown case - return Promise.resolve(undefined); - }); - } - } catch (err) { - // TODO: Do something with err if this is not the shutdown case - } - - // clean up subscriptions - try { - dispose(extension.subscriptions); - } catch (err) { - // TODO: Do something with err if this is not the shutdown case - } - - return result; - } - - // --- impl - - private _activateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): Promise { - this._mainThreadExtensionsProxy.$onWillActivateExtension(extensionDescription.identifier); - return this._doActivateExtension(extensionDescription, reason).then((activatedExtension) => { - const activationTimes = activatedExtension.activationTimes; - const activationEvent = (reason instanceof ExtensionActivatedByEvent ? reason.activationEvent : null); - this._mainThreadExtensionsProxy.$onDidActivateExtension(extensionDescription.identifier, activationTimes.startup, activationTimes.codeLoadingTime, activationTimes.activateCallTime, activationTimes.activateResolvedTime, activationEvent); - this._logExtensionActivationTimes(extensionDescription, reason, 'success', activationTimes); - return activatedExtension; - }, (err) => { - this._logExtensionActivationTimes(extensionDescription, reason, 'failure'); - throw err; - }); - } - - private _logExtensionActivationTimes(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason, outcome: string, activationTimes?: ExtensionActivationTimes) { - const event = getTelemetryActivationEvent(extensionDescription, reason); - type ExtensionActivationTimesClassification = { - outcome: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; - } & TelemetryActivationEventFragment & ExtensionActivationTimesFragment; - - type ExtensionActivationTimesEvent = { - outcome: string - } & ActivationTimesEvent & TelemetryActivationEvent; - - type ActivationTimesEvent = { - startup?: boolean; - codeLoadingTime?: number; - activateCallTime?: number; - activateResolvedTime?: number; - }; - - this._mainThreadTelemetryProxy.$publicLog2('extensionActivationTimes', { - ...event, - ...(activationTimes || {}), - outcome - }); - } - - private _doActivateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): Promise { - const event = getTelemetryActivationEvent(extensionDescription, reason); - type ActivatePluginClassification = {} & TelemetryActivationEventFragment; - this._mainThreadTelemetryProxy.$publicLog2('activatePlugin', event); - if (!extensionDescription.main) { - // Treat the extension as being empty => NOT AN ERROR CASE - return Promise.resolve(new EmptyExtension(ExtensionActivationTimes.NONE)); - } - - this._extHostLogService.info(`ExtensionService#_doActivateExtension ${extensionDescription.identifier.value} ${JSON.stringify(reason)}`); - - const activationTimesBuilder = new ExtensionActivationTimesBuilder(reason.startup); - return Promise.all([ - loadCommonJSModule(this._extHostLogService, extensionDescription.main, activationTimesBuilder), - this._loadExtensionContext(extensionDescription) - ]).then(values => { - return ExtHostExtensionService._callActivate(this._extHostLogService, extensionDescription.identifier, values[0], values[1], activationTimesBuilder); - }); - } - - private _loadExtensionContext(extensionDescription: IExtensionDescription): Promise { - - const globalState = new ExtensionMemento(extensionDescription.identifier.value, true, this._storage); - const workspaceState = new ExtensionMemento(extensionDescription.identifier.value, false, this._storage); - - this._extHostLogService.trace(`ExtensionService#loadExtensionContext ${extensionDescription.identifier.value}`); - return Promise.all([ - globalState.whenReady, - workspaceState.whenReady, - // this._storagePath.whenReady - ]).then(() => { - const that = this; - return Object.freeze({ - globalState, - workspaceState, - subscriptions: [], - get extensionPath() { return extensionDescription.extensionLocation.fsPath; }, - // storagePath: this._storagePath.workspaceValue(extensionDescription), - // globalStoragePath: this._storagePath.globalValue(extensionDescription), - get storagePath(): string { throw new Error('not impl'); },// this._storagePath.workspaceValue(extensionDescription), - get globalStoragePath(): string { throw new Error('not impl'); },// this._storagePath.globalValue(extensionDescription), - asAbsolutePath: (relativePath: string) => { return path.join(extensionDescription.extensionLocation.fsPath, relativePath); }, - logPath: that._extHostLogService.getLogDirectory(extensionDescription.identifier), - executionContext: this._initData.remote.isRemote ? ExtensionExecutionContext.Remote : ExtensionExecutionContext.Local, - }); - }); - } - - private static _callActivate(logService: ILogService, extensionId: ExtensionIdentifier, extensionModule: IExtensionModule, context: IExtensionContext, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { - // Make sure the extension's surface is not undefined - extensionModule = extensionModule || { - activate: undefined, - deactivate: undefined - }; - - return this._callActivateOptional(logService, extensionId, extensionModule, context, activationTimesBuilder).then((extensionExports) => { - return new ActivatedExtension(false, null, activationTimesBuilder.build(), extensionModule, extensionExports, context.subscriptions); - }); - } - - private static _callActivateOptional(logService: ILogService, extensionId: ExtensionIdentifier, extensionModule: IExtensionModule, context: IExtensionContext, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { - if (typeof extensionModule.activate === 'function') { - try { - activationTimesBuilder.activateCallStart(); - logService.trace(`ExtensionService#_callActivateOptional ${extensionId.value}`); - // const activateResult: Promise = extensionModule.activate.apply(global, [context]); - const activateResult: Promise = extensionModule.activate.apply(undefined, [context]); - activationTimesBuilder.activateCallStop(); - - activationTimesBuilder.activateResolveStart(); - return Promise.resolve(activateResult).then((value) => { - activationTimesBuilder.activateResolveStop(); - return value; - }); - } catch (err) { - return Promise.reject(err); - } - } else { - // No activate found => the module is the extension's exports - return Promise.resolve(extensionModule); - } - } - - // -- eager activation - - // Handle "eager" activation extensions - private _handleEagerExtensions(): Promise { - this._activateByEvent('*', true).then(undefined, (err) => { - console.error(err); - }); - - this._disposables.add(this._extHostWorkspace.onDidChangeWorkspace((e) => this._handleWorkspaceContainsEagerExtensions(e.added))); - const folders = this._extHostWorkspace.workspace ? this._extHostWorkspace.workspace.folders : []; - return this._handleWorkspaceContainsEagerExtensions(folders); - } - - private _handleWorkspaceContainsEagerExtensions(folders: ReadonlyArray): Promise { - if (folders.length === 0) { - return Promise.resolve(undefined); - } - - return Promise.all( - this._registry.getAllExtensionDescriptions().map((desc) => { - return this._handleWorkspaceContainsEagerExtension(folders, desc); - }) - ).then(() => { }); - } - - private _handleWorkspaceContainsEagerExtension(folders: ReadonlyArray, desc: IExtensionDescription): Promise { - const activationEvents = desc.activationEvents; - if (!activationEvents) { - return Promise.resolve(undefined); - } - - if (this.isActivated(desc.identifier)) { - return Promise.resolve(undefined); - } - - const fileNames: string[] = []; - const globPatterns: string[] = []; - - for (const activationEvent of activationEvents) { - if (/^workspaceContains:/.test(activationEvent)) { - const fileNameOrGlob = activationEvent.substr('workspaceContains:'.length); - if (fileNameOrGlob.indexOf('*') >= 0 || fileNameOrGlob.indexOf('?') >= 0) { - globPatterns.push(fileNameOrGlob); - } else { - fileNames.push(fileNameOrGlob); - } - } - } - - if (fileNames.length === 0 && globPatterns.length === 0) { - return Promise.resolve(undefined); - } - - const fileNamePromise = Promise.all(fileNames.map((fileName) => this._activateIfFileName(folders, desc.identifier, fileName))).then(() => { }); - const globPatternPromise = this._activateIfGlobPatterns(folders, desc.identifier, globPatterns); - - return Promise.all([fileNamePromise, globPatternPromise]).then(() => { }); - } - - private async _activateIfFileName(folders: ReadonlyArray, extensionId: ExtensionIdentifier, fileName: string): Promise { - - // find exact path - for (const { uri } of folders) { - if (await this._hostUtils.exists(path.join(URI.revive(uri).fsPath, fileName))) { - // the file was found - return ( - this._activateById(extensionId, new ExtensionActivatedByEvent(true, `workspaceContains:${fileName}`)) - .then(undefined, err => console.error(err)) - ); - } - } - - return undefined; - } - - private async _activateIfGlobPatterns(folders: ReadonlyArray, extensionId: ExtensionIdentifier, globPatterns: string[]): Promise { - this._extHostLogService.trace(`extensionHostMain#activateIfGlobPatterns: fileSearch, extension: ${extensionId.value}, entryPoint: workspaceContains`); - - if (globPatterns.length === 0) { - return Promise.resolve(undefined); - } - - const tokenSource = new CancellationTokenSource(); - const searchP = this._mainThreadWorkspaceProxy.$checkExists(folders.map(folder => folder.uri), globPatterns, tokenSource.token); - - const timer = setTimeout(async () => { - tokenSource.cancel(); - this._activateById(extensionId, new ExtensionActivatedByEvent(true, `workspaceContainsTimeout:${globPatterns.join(',')}`)) - .then(undefined, err => console.error(err)); - }, ExtHostExtensionService.WORKSPACE_CONTAINS_TIMEOUT); - - let exists: boolean = false; - try { - exists = await searchP; - } catch (err) { - if (!errors.isPromiseCanceledError(err)) { - console.error(err); - } - } - - tokenSource.dispose(); - clearTimeout(timer); - - if (exists) { - // a file was found matching one of the glob patterns - return ( - this._activateById(extensionId, new ExtensionActivatedByEvent(true, `workspaceContains:${globPatterns.join(',')}`)) - .then(undefined, err => console.error(err)) - ); - } - - return Promise.resolve(undefined); - } - - private _handleExtensionTests(): Promise { - return this._doHandleExtensionTests().then(undefined, error => { - console.error(error); // ensure any error message makes it onto the console - - return Promise.reject(error); - }); - } - - private _doHandleExtensionTests(): Promise { - const { extensionDevelopmentLocationURI: extensionDevelopmentLocationURI, extensionTestsLocationURI } = this._initData.environment; - if (!(extensionDevelopmentLocationURI && extensionTestsLocationURI && extensionTestsLocationURI.scheme === Schemas.file)) { - return Promise.resolve(undefined); - } - - const extensionTestsPath = originalFSPath(extensionTestsLocationURI); - - // Require the test runner via node require from the provided path - let testRunner: ITestRunner | INewTestRunner | undefined; - let requireError: Error | undefined; - try { - testRunner = require.__$__nodeRequire(extensionTestsPath); - } catch (error) { - requireError = error; - } - - // Execute the runner if it follows the old `run` spec - if (testRunner && typeof testRunner.run === 'function') { - return new Promise((c, e) => { - const oldTestRunnerCallback = (error: Error, failures: number | undefined) => { - if (error) { - e(error.toString()); - } else { - c(undefined); - } - - // after tests have run, we shutdown the host - this._gracefulExit(error || (typeof failures === 'number' && failures > 0) ? 1 /* ERROR */ : 0 /* OK */); - }; - - const runResult = testRunner!.run(extensionTestsPath, oldTestRunnerCallback); - - // Using the new API `run(): Promise` - if (runResult && runResult.then) { - runResult - .then(() => { - c(); - this._gracefulExit(0); - }) - .catch((err: Error) => { - e(err.toString()); - this._gracefulExit(1); - }); - } - }); - } - - // Otherwise make sure to shutdown anyway even in case of an error - else { - this._gracefulExit(1 /* ERROR */); - } - - return Promise.reject(new Error(requireError ? requireError.toString() : nls.localize('extensionTestError', "Path {0} does not point to a valid extension test runner.", extensionTestsPath))); - } - - private _gracefulExit(code: number): void { - // to give the PH process a chance to flush any outstanding console - // messages to the main process, we delay the exit() by some time - setTimeout(() => { - // If extension tests are running, give the exit code to the renderer - if (this._initData.remote.isRemote && !!this._initData.environment.extensionTestsLocationURI) { - this._mainThreadExtensionsProxy.$onExtensionHostExit(code); - return; - } - - this._hostUtils.exit(code); - }, 500); - } - - private _startExtensionHost(): Promise { - if (this._started) { - throw new Error(`Extension host is already started!`); - } - this._started = true; - - return this._readyToStartExtensionHost.wait() - .then(() => this._readyToRunExtensions.open()) - .then(() => this._handleEagerExtensions()) - .then(() => this._handleExtensionTests()) - .then(() => { - this._extHostLogService.info(`eager extensions activated`); - }); - } - - // -- called by extensions - - public registerRemoteAuthorityResolver(authorityPrefix: string, resolver: vscode.RemoteAuthorityResolver): vscode.Disposable { - this._resolvers[authorityPrefix] = resolver; - return toDisposable(() => { - delete this._resolvers[authorityPrefix]; - }); - } - - // -- called by main thread - - public async $resolveAuthority(remoteAuthority: string, resolveAttempt: number): Promise { - const authorityPlusIndex = remoteAuthority.indexOf('+'); - if (authorityPlusIndex === -1) { - throw new Error(`Not an authority that can be resolved!`); - } - const authorityPrefix = remoteAuthority.substr(0, authorityPlusIndex); - - await this._almostReadyToRunExtensions.wait(); - await this._activateByEvent(`onResolveRemoteAuthority:${authorityPrefix}`, false); - - const resolver = this._resolvers[authorityPrefix]; - if (!resolver) { - throw new Error(`No remote extension installed to resolve ${authorityPrefix}.`); - } - - try { - const result = await resolver.resolve(remoteAuthority, { resolveAttempt }); - - // Split merged API result into separate authority/options - const authority: ResolvedAuthority = { - authority: remoteAuthority, - host: result.host, - port: result.port - }; - const options: ResolvedOptions = { - extensionHostEnv: result.extensionHostEnv - }; - - return { - type: 'ok', - value: { - authority, - options - } - }; - } catch (err) { - if (err instanceof RemoteAuthorityResolverError) { - return { - type: 'error', - error: { - code: err._code, - message: err._message, - detail: err._detail - } - }; - } - throw err; - } - } - - public $startExtensionHost(enabledExtensionIds: ExtensionIdentifier[]): Promise { - this._registry.keepOnly(enabledExtensionIds); - return this._startExtensionHost(); - } - - public $activateByEvent(activationEvent: string): Promise { - return ( - this._readyToRunExtensions.wait() - .then(_ => this._activateByEvent(activationEvent, false)) - ); - } - - public async $activate(extensionId: ExtensionIdentifier, activationEvent: string): Promise { - await this._readyToRunExtensions.wait(); - if (!this._registry.getExtensionDescription(extensionId)) { - // unknown extension => ignore - return false; - } - await this._activateById(extensionId, new ExtensionActivatedByEvent(false, activationEvent)); - return true; - } - - public async $deltaExtensions(toAdd: IExtensionDescription[], toRemove: ExtensionIdentifier[]): Promise { - toAdd.forEach((extension) => (extension).extensionLocation = URI.revive(extension.extensionLocation)); - - const trie = await this.getExtensionPathIndex(); - - await Promise.all(toRemove.map(async (extensionId) => { - const extensionDescription = this._registry.getExtensionDescription(extensionId); - if (!extensionDescription) { - return; - } - const realpathValue = await this._hostUtils.realpath(extensionDescription.extensionLocation.fsPath); - trie.delete(URI.file(realpathValue).fsPath); - })); - - await Promise.all(toAdd.map(async (extensionDescription) => { - const realpathValue = await this._hostUtils.realpath(extensionDescription.extensionLocation.fsPath); - trie.set(URI.file(realpathValue).fsPath, extensionDescription); - })); - - this._registry.deltaExtensions(toAdd, toRemove); - return Promise.resolve(undefined); - } - - public async $test_latency(n: number): Promise { - return n; - } - - public async $test_up(b: VSBuffer): Promise { - return b.byteLength; - } - - public async $test_down(size: number): Promise { - let buff = VSBuffer.alloc(size); - let value = Math.random() % 256; - for (let i = 0; i < size; i++) { - buff.writeUInt8(value, i); - } - return buff; - } - - public async $setRemoteEnvironment(env: { [key: string]: string | null }): Promise { - if (!this._initData.remote.isRemote) { - return; - } - - for (const key in env) { - const value = env[key]; - if (value === null) { - delete process.env[key]; - } else { - process.env[key] = value; - } - } - } -} - -async function loadCommonJSModule(logService: ILogService, modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { - - // fake commonjs world - const module = { exports: {} }; - //@ts-ignore - self['module'] = module; - //@ts-ignore - self['exports'] = module.exports; - - // that's improper but might help extensions that aren't author correctly - // @ts-ignore - self['window'] = self; - - // import the single (!) script, make sure it's a JS-file - const suffix = '.js'; - if (endsWith(modulePath, suffix)) { - importScripts(modulePath); - } else { - importScripts(modulePath + suffix); - } - - // return what it exported - return module.exports as T; -} - -type TelemetryActivationEvent = { - id: string; - name: string; - extensionVersion: string; - publisherDisplayName: string; - activationEvents: string | null; - isBuiltin: boolean; - reason: string; -}; - -function getTelemetryActivationEvent(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): TelemetryActivationEvent { - const reasonStr = reason instanceof ExtensionActivatedByEvent ? reason.activationEvent : - reason instanceof ExtensionActivatedByAPI ? 'api' : - ''; - const event = { - id: extensionDescription.identifier.value, - name: extensionDescription.name, - extensionVersion: extensionDescription.version, - publisherDisplayName: extensionDescription.publisher, - activationEvents: extensionDescription.activationEvents ? extensionDescription.activationEvents.join(',') : null, - isBuiltin: extensionDescription.isBuiltin, - reason: reasonStr - }; - - return event; -} diff --git a/src/vs/workbench/services/extensions/worker/extensionHostMain.ts b/src/vs/workbench/services/extensions/worker/extensionHostMain.ts deleted file mode 100644 index 54094e12547..00000000000 --- a/src/vs/workbench/services/extensions/worker/extensionHostMain.ts +++ /dev/null @@ -1,154 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { timeout } from 'vs/base/common/async'; -import * as errors from 'vs/base/common/errors'; -import { DisposableStore } from 'vs/base/common/lifecycle'; -import { URI, setUriThrowOnMissingScheme } from 'vs/base/common/uri'; -import { IURITransformer } from 'vs/base/common/uriIpc'; -import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; -import { IInitData, MainContext, MainThreadConsoleShape } from 'vs/workbench/api/common/extHost.protocol'; -import { ExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; -import { ExtHostExtensionService, IHostUtils } from './extHostExtensionService'; -import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; -import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; -import { RPCProtocol } from 'vs/workbench/services/extensions/common/rpcProtocol'; -import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; -import { withNullAsUndefined } from 'vs/base/common/types'; -import { ILogService } from 'vs/platform/log/common/log'; - -// we don't (yet) throw when extensions parse -// uris that have no scheme -setUriThrowOnMissingScheme(false); - -export interface IExitFn { - (code?: number): any; -} - -export interface IConsolePatchFn { - (mainThreadConsole: MainThreadConsoleShape): any; -} - -export interface ILogServiceFn { - (initData: IInitData): ILogService; -} - -export class ExtensionHostMain { - - private _isTerminating: boolean; - private readonly _hostUtils: IHostUtils; - private readonly _extensionService: ExtHostExtensionService; - private readonly _disposables = new DisposableStore(); - - constructor( - protocol: IMessagePassingProtocol, - initData: IInitData, - hostUtils: IHostUtils, - consolePatchFn: IConsolePatchFn, - logServiceFn: ILogServiceFn, - uriTransformer: IURITransformer | null - ) { - this._isTerminating = false; - this._hostUtils = hostUtils; - const rpcProtocol = new RPCProtocol(protocol, null, uriTransformer); - - // ensure URIs are transformed and revived - initData = ExtensionHostMain._transform(initData, rpcProtocol); - - // allow to patch console - consolePatchFn(rpcProtocol.getProxy(MainContext.MainThreadConsole)); - - // services - const extHostLogService = new ExtHostLogService(logServiceFn(initData), initData.logsLocation.fsPath); - this._disposables.add(extHostLogService); - - const extHostWorkspace = new ExtHostWorkspace(rpcProtocol, extHostLogService, withNullAsUndefined(initData.workspace)); - - extHostLogService.info('extension host started'); - extHostLogService.trace('initData', initData); - - const extHostConfiguraiton = new ExtHostConfiguration(rpcProtocol.getProxy(MainContext.MainThreadConfiguration), extHostWorkspace); - this._extensionService = new ExtHostExtensionService( - hostUtils, - initData, - rpcProtocol, - extHostWorkspace, - extHostConfiguraiton, - initData.environment, - extHostLogService, - uriTransformer - ); - - // error forwarding and stack trace scanning - Error.stackTraceLimit = 100; // increase number of stack frames (from 10, https://github.com/v8/v8/wiki/Stack-Trace-API) - const extensionErrors = new WeakMap(); - this._extensionService.getExtensionPathIndex().then(map => { - (Error).prepareStackTrace = (error: Error, stackTrace: errors.V8CallSite[]) => { - let stackTraceMessage = ''; - let extension: IExtensionDescription | undefined; - let fileName: string; - for (const call of stackTrace) { - stackTraceMessage += `\n\tat ${call.toString()}`; - fileName = call.getFileName(); - if (!extension && fileName) { - extension = map.findSubstr(fileName); - } - - } - extensionErrors.set(error, extension); - return `${error.name || 'Error'}: ${error.message || ''}${stackTraceMessage}`; - }; - }); - - const mainThreadExtensions = rpcProtocol.getProxy(MainContext.MainThreadExtensionService); - const mainThreadErrors = rpcProtocol.getProxy(MainContext.MainThreadErrors); - errors.setUnexpectedErrorHandler(err => { - const data = errors.transformErrorForSerialization(err); - const extension = extensionErrors.get(err); - if (extension) { - mainThreadExtensions.$onExtensionRuntimeError(extension.identifier, data); - } else { - mainThreadErrors.$onUnexpectedError(data); - } - }); - } - - terminate(): void { - if (this._isTerminating) { - // we are already shutting down... - return; - } - this._isTerminating = true; - - this._disposables.dispose(); - - errors.setUnexpectedErrorHandler((err) => { - // TODO: write to log once we have one - }); - - const extensionsDeactivated = this._extensionService.deactivateAll(); - - // Give extensions 1 second to wrap up any async dispose, then exit in at most 4 seconds - setTimeout(() => { - Promise.race([timeout(4000), extensionsDeactivated]).finally(() => this._hostUtils.exit()); - }, 1000); - } - - private static _transform(initData: IInitData, rpcProtocol: RPCProtocol): IInitData { - initData.extensions.forEach((ext) => (ext).extensionLocation = URI.revive(rpcProtocol.transformIncomingURIs(ext.extensionLocation))); - initData.environment.appRoot = URI.revive(rpcProtocol.transformIncomingURIs(initData.environment.appRoot)); - initData.environment.appSettingsHome = URI.revive(rpcProtocol.transformIncomingURIs(initData.environment.appSettingsHome)); - const extDevLocs = initData.environment.extensionDevelopmentLocationURI; - if (extDevLocs) { - initData.environment.extensionDevelopmentLocationURI = extDevLocs.map(url => URI.revive(rpcProtocol.transformIncomingURIs(url))); - } - initData.environment.extensionTestsLocationURI = URI.revive(rpcProtocol.transformIncomingURIs(initData.environment.extensionTestsLocationURI)); - initData.environment.globalStorageHome = URI.revive(rpcProtocol.transformIncomingURIs(initData.environment.globalStorageHome)); - initData.environment.userHome = URI.revive(rpcProtocol.transformIncomingURIs(initData.environment.userHome)); - initData.logsLocation = URI.revive(rpcProtocol.transformIncomingURIs(initData.logsLocation)); - initData.workspace = rpcProtocol.transformIncomingURIs(initData.workspace); - return initData; - } -} diff --git a/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts b/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts index 61a30631c8b..7d42bf2044d 100644 --- a/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts +++ b/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts @@ -9,9 +9,10 @@ import { VSBuffer } from 'vs/base/common/buffer'; import { Emitter } from 'vs/base/common/event'; import { isMessageOfType, MessageType, createMessageOfType } from 'vs/workbench/services/extensions/common/extensionHostProtocol'; import { IInitData } from 'vs/workbench/api/common/extHost.protocol'; -import { IHostUtils } from 'vs/workbench/services/extensions/worker/extHostExtensionService'; -import { ExtensionHostMain } from 'vs/workbench/services/extensions/worker/extensionHostMain'; +import { ExtensionHostMain } from 'vs/workbench/services/extensions/common/extensionHostMain'; import { ConsoleLogService } from 'vs/platform/log/common/log'; +import { IHostUtils } from 'vs/workbench/api/common/extHostExtensionService'; +import 'vs/workbench/services/extensions/worker/extHost.services'; // worker-self declare namespace self { @@ -24,10 +25,11 @@ self.close = () => console.trace('An extension called terminate and this was pre let onTerminate = nativeClose; const hostUtil = new class implements IHostUtils { - exit(code?: number | undefined): void { + _serviceBrand: any; + exit(_code?: number | undefined): void { nativeClose(); } - async exists(path: string): Promise { + async exists(_path: string): Promise { return true; } async realpath(path: string): Promise { From 5880f8ab0c9adeb4a16eceee988e0ca50f62046d Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 9 Aug 2019 16:20:30 +0200 Subject: [PATCH 411/861] keep empty services in one place --- .../api/worker/extHostStoragePaths.ts | 23 ------------------- .../extensions/worker/extHost.services.ts | 13 +++++++---- 2 files changed, 9 insertions(+), 27 deletions(-) delete mode 100644 src/vs/workbench/api/worker/extHostStoragePaths.ts diff --git a/src/vs/workbench/api/worker/extHostStoragePaths.ts b/src/vs/workbench/api/worker/extHostStoragePaths.ts deleted file mode 100644 index 3d07dff7de0..00000000000 --- a/src/vs/workbench/api/worker/extHostStoragePaths.ts +++ /dev/null @@ -1,23 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths'; -import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; - -export class ExtensionStoragePaths implements IExtensionStoragePaths { - - readonly _serviceBrand: undefined; - - readonly whenReady: Promise = Promise.resolve(); - - //todo@joh -> this isn't proper but also hard to get right... - workspaceValue(_extension: IExtensionDescription): string | undefined { - return ''; - } - - globalValue(_extension: IExtensionDescription): string { - return ''; - } -} diff --git a/src/vs/workbench/services/extensions/worker/extHost.services.ts b/src/vs/workbench/services/extensions/worker/extHost.services.ts index 69ad6dbfe4b..127250f83be 100644 --- a/src/vs/workbench/services/extensions/worker/extHost.services.ts +++ b/src/vs/workbench/services/extensions/worker/extHost.services.ts @@ -19,8 +19,6 @@ import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensi import { IExtHostStorage, ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; import { ExtHostExtensionService } from 'vs/workbench/api/worker/extHostExtensionService'; import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; -import { ExtensionStoragePaths } from 'vs/workbench/api/worker/extHostStoragePaths'; - // register singleton services registerSingleton(IExtHostOutputService, ExtHostOutputService); @@ -30,7 +28,6 @@ registerSingleton(IExtHostConfiguration, ExtHostConfiguration); registerSingleton(IExtHostCommands, ExtHostCommands); registerSingleton(IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors); registerSingleton(IExtHostStorage, ExtHostStorage); -registerSingleton(IExtensionStoragePaths, ExtensionStoragePaths); registerSingleton(IExtHostExtensionService, ExtHostExtensionService); // register services that only throw errors @@ -38,7 +35,10 @@ function NotImplementedProxy(name: ServiceIdentifier): { new(): T } { return class { constructor() { return new Proxy({}, { - get(_target: any, prop: any) { + get(target: any, prop: string | number) { + if (target[prop]) { + return target[prop]; + } throw new Error(`Not Implemented: ${name}->${String(prop)}`); } }); @@ -49,3 +49,8 @@ registerSingleton(IExtHostTerminalService, class extends NotImplementedProxy(IEx registerSingleton(IExtHostTask, class extends NotImplementedProxy(IExtHostTask) { }); registerSingleton(IExtHostDebugService, class extends NotImplementedProxy(IExtHostDebugService) { }); registerSingleton(IExtHostSearch, class extends NotImplementedProxy(IExtHostSearch) { }); +registerSingleton(IExtensionStoragePaths, class extends NotImplementedProxy(IExtensionStoragePaths) { + whenReady = Promise.resolve(); + globalValue = () => ''; + workspaceValue = () => ''; +}); From f2a365226c105287c816503b1b42f630ca8728d6 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 9 Aug 2019 16:28:16 +0200 Subject: [PATCH 412/861] :lipstick: --- .../workbench/browser/actions/listCommands.ts | 62 ++++++++++--------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/src/vs/workbench/browser/actions/listCommands.ts b/src/vs/workbench/browser/actions/listCommands.ts index 4234594231e..7de343ab1d3 100644 --- a/src/vs/workbench/browser/actions/listCommands.ts +++ b/src/vs/workbench/browser/actions/listCommands.ts @@ -320,6 +320,38 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ } }); + +KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: 'list.focusParent', + weight: KeybindingWeight.WorkbenchContrib, + when: WorkbenchListFocusContextKey, + handler: (accessor) => { + const focused = accessor.get(IListService).lastFocusedList; + + if (!focused || focused instanceof List || focused instanceof PagedList) { + return; + } + + if (focused instanceof ObjectTree || focused instanceof DataTree || focused instanceof AsyncDataTree) { + const tree = focused; + const focusedElements = tree.getFocus(); + if (focusedElements.length === 0) { + return; + } + const focus = focusedElements[0]; + const parent = tree.getParentElement(focus); + if (parent) { + const fakeKeyboardEvent = new KeyboardEvent('keydown'); + tree.setFocus([parent], fakeKeyboardEvent); + tree.reveal(parent); + } + } else { + const tree = focused; + tree.focusParent({ origin: 'keyboard' }); + } + } +}); + KeybindingsRegistry.registerCommandAndKeybindingRule({ id: 'list.expand', weight: KeybindingWeight.WorkbenchContrib, @@ -808,33 +840,3 @@ CommandsRegistry.registerCommand({ } } }); - -KeybindingsRegistry.registerCommandAndKeybindingRule({ - id: 'list.focusParent', - weight: KeybindingWeight.WorkbenchContrib, - when: WorkbenchListFocusContextKey, - primary: KeyCode.Shift | KeyCode.LeftArrow, - handler: (accessor) => { - const focused = accessor.get(IListService).lastFocusedList; - // Tree only - if (focused && !(focused instanceof List || focused instanceof PagedList)) { - if (focused instanceof ObjectTree || focused instanceof DataTree || focused instanceof AsyncDataTree) { - const tree = focused; - const focusedElements = tree.getFocus(); - if (focusedElements.length === 0) { - return; - } - const focus = focusedElements[0]; - const parent = tree.getParentElement(focus); - if (parent) { - const fakeKeyboardEvent = new KeyboardEvent('keydown'); - tree.setFocus([parent], fakeKeyboardEvent); - tree.reveal(parent); - } - } else { - const tree = focused; - tree.focusParent({ origin: 'keyboard' }); - } - } - } -}); \ No newline at end of file From 5438c9bedec4cd164c408d9bb0324b57b0c9426d Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 9 Aug 2019 08:11:25 -0700 Subject: [PATCH 413/861] Have terminals fire onExit when killed by user Fixes #78804 --- .../workbench/contrib/terminal/browser/terminalInstance.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 9d6decb1a34..1f27f4d08e5 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -814,6 +814,9 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } this._processManager.dispose(immediate); + // Process manager dispose/shutdown doesn't fire process exit, trigger with undefined if it + // hasn't happened yet + this._onProcessExit(undefined); if (!this._isDisposed) { this._isDisposed = true; @@ -1012,13 +1015,13 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { * through user action. */ private _onProcessExit(exitCode?: number): void { - this._logService.debug(`Terminal process exit (id: ${this.id}) with code ${exitCode}`); - // Prevent dispose functions being triggered multiple times if (this._isExiting) { return; } + this._logService.debug(`Terminal process exit (id: ${this.id}) with code ${exitCode}`); + this._isExiting = true; let exitCodeMessage: string | undefined; From bbd27437f7c62317ac20b702bd5b72b0fc04597e Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 9 Aug 2019 17:33:26 +0200 Subject: [PATCH 414/861] explorer.incrementalNaming fixes #76752 --- .../contrib/files/browser/fileActions.ts | 117 +++++++--- .../files/browser/files.contribution.ts | 9 + .../files/browser/views/explorerViewer.ts | 4 +- .../workbench/contrib/files/common/files.ts | 1 + .../test/electron-browser/fileActions.test.ts | 204 ++++++++++++++++-- 5 files changed, 287 insertions(+), 48 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/fileActions.ts b/src/vs/workbench/contrib/files/browser/fileActions.ts index cb9ac033e43..8a2c0fe652f 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.ts @@ -15,7 +15,7 @@ import { toErrorMessage } from 'vs/base/common/errorMessage'; import * as strings from 'vs/base/common/strings'; import { Action } from 'vs/base/common/actions'; import { dispose, IDisposable } from 'vs/base/common/lifecycle'; -import { VIEWLET_ID, IExplorerService } from 'vs/workbench/contrib/files/common/files'; +import { VIEWLET_ID, IExplorerService, IFilesConfiguration } from 'vs/workbench/contrib/files/common/files'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IFileService, AutoSaveConfiguration } from 'vs/platform/files/common/files'; import { toResource, SideBySideEditor } from 'vs/workbench/common/editor'; @@ -328,7 +328,7 @@ function containsBothDirectoryAndFile(distinctElements: ExplorerItem[]): boolean } -export function findValidPasteFileTarget(targetFolder: ExplorerItem, fileToPaste: { resource: URI, isDirectory?: boolean, allowOverwrite: boolean }): URI { +export function findValidPasteFileTarget(targetFolder: ExplorerItem, fileToPaste: { resource: URI, isDirectory?: boolean, allowOverwrite: boolean }, incrementalNaming: 'simple' | 'smart'): URI { let name = resources.basenameOrAuthority(fileToPaste.resource); let candidate = resources.joinPath(targetFolder.resource, name); @@ -337,37 +337,104 @@ export function findValidPasteFileTarget(targetFolder: ExplorerItem, fileToPaste break; } - name = incrementFileName(name, !!fileToPaste.isDirectory); + name = incrementFileName(name, !!fileToPaste.isDirectory, incrementalNaming); candidate = resources.joinPath(targetFolder.resource, name); } return candidate; } -export function incrementFileName(name: string, isFolder: boolean): string { - let namePrefix = name; - let extSuffix = ''; - if (!isFolder) { - extSuffix = extname(name); - namePrefix = basename(name, extSuffix); +export function incrementFileName(name: string, isFolder: boolean, incrementalNaming: 'simple' | 'smart'): string { + if (incrementalNaming === 'simple') { + let namePrefix = name; + let extSuffix = ''; + if (!isFolder) { + extSuffix = extname(name); + namePrefix = basename(name, extSuffix); + } + + // name copy 5(.txt) => name copy 6(.txt) + // name copy(.txt) => name copy 2(.txt) + const suffixRegex = /^(.+ copy)( \d+)?$/; + if (suffixRegex.test(namePrefix)) { + return namePrefix.replace(suffixRegex, (match, g1?, g2?) => { + let number = (g2 ? parseInt(g2) : 1); + return number === 0 + ? `${g1}` + : (number < Constants.MAX_SAFE_SMALL_INTEGER + ? `${g1} ${number + 1}` + : `${g1}${g2} copy`); + }) + extSuffix; + } + + // name(.txt) => name copy(.txt) + return `${namePrefix} copy${extSuffix}`; } - // name copy 5(.txt) => name copy 6(.txt) - // name copy(.txt) => name copy 2(.txt) - const suffixRegex = /^(.+ copy)( \d+)?$/; - if (suffixRegex.test(namePrefix)) { - return namePrefix.replace(suffixRegex, (match, g1?, g2?) => { - let number = (g2 ? parseInt(g2) : 1); - return number === 0 - ? `${g1}` - : (number < Constants.MAX_SAFE_SMALL_INTEGER - ? `${g1} ${number + 1}` - : `${g1}${g2} copy`); - }) + extSuffix; + const separators = '[\\.\\-_]'; + const maxNumber = Constants.MAX_SAFE_SMALL_INTEGER; + + // file.1.txt=>file.2.txt + let suffixFileRegex = RegExp('(.*' + separators + ')(\\d+)(\\..*)$'); + if (!isFolder && name.match(suffixFileRegex)) { + return name.replace(suffixFileRegex, (match, g1?, g2?, g3?) => { + let number = parseInt(g2); + return number < maxNumber + ? g1 + strings.pad(number + 1, g2.length) + g3 + : strings.format('{0}{1}.1{2}', g1, g2, g3); + }); } - // name(.txt) => name copy(.txt) - return `${namePrefix} copy${extSuffix}`; + // 1.file.txt=>2.file.txt + let prefixFileRegex = RegExp('(\\d+)(' + separators + '.*)(\\..*)$'); + if (!isFolder && name.match(prefixFileRegex)) { + return name.replace(prefixFileRegex, (match, g1?, g2?, g3?) => { + let number = parseInt(g1); + return number < maxNumber + ? strings.pad(number + 1, g1.length) + g2 + g3 + : strings.format('{0}{1}.1{2}', g1, g2, g3); + }); + } + + // 1.txt=>2.txt + let prefixFileNoNameRegex = RegExp('(\\d+)(\\..*)$'); + if (!isFolder && name.match(prefixFileNoNameRegex)) { + return name.replace(prefixFileNoNameRegex, (match, g1?, g2?) => { + let number = parseInt(g1); + return number < maxNumber + ? strings.pad(number + 1, g1.length) + g2 + : strings.format('{0}.1{1}', g1, g2); + }); + } + + // file.txt=>file.1.txt + const lastIndexOfDot = name.lastIndexOf('.'); + if (!isFolder && lastIndexOfDot >= 0) { + return strings.format('{0}.1{1}', name.substr(0, lastIndexOfDot), name.substr(lastIndexOfDot)); + } + + // folder.1=>folder.2 + if (isFolder && name.match(/(\d+)$/)) { + return name.replace(/(\d+)$/, (match: string, ...groups: any[]) => { + let number = parseInt(groups[0]); + return number < maxNumber + ? strings.pad(number + 1, groups[0].length) + : strings.format('{0}.1', groups[0]); + }); + } + + // 1.folder=>2.folder + if (isFolder && name.match(/^(\d+)/)) { + return name.replace(/^(\d+)(.*)$/, (match: string, ...groups: any[]) => { + let number = parseInt(groups[0]); + return number < maxNumber + ? strings.pad(number + 1, groups[0].length) + groups[1] + : strings.format('{0}{1}.1', groups[0], groups[1]); + }); + } + + // file/folder=>file.1/folder.1 + return strings.format('{0}.1', name); } // Global Compare with @@ -1006,6 +1073,7 @@ export const pasteFileHandler = async (accessor: ServicesAccessor) => { const textFileService = accessor.get(ITextFileService); const notificationService = accessor.get(INotificationService); const editorService = accessor.get(IEditorService); + const configurationService = accessor.get(IConfigurationService); if (listService.lastFocusedList) { const explorerContext = getContext(listService.lastFocusedList); @@ -1030,7 +1098,8 @@ export const pasteFileHandler = async (accessor: ServicesAccessor) => { target = element.isDirectory ? element : element.parent!; } - const targetFile = findValidPasteFileTarget(target, { resource: fileToPaste, isDirectory: fileToPasteStat.isDirectory, allowOverwrite: pasteShouldMove }); + const incrementalNaming = configurationService.getValue().explorer.incrementalNaming; + const targetFile = findValidPasteFileTarget(target, { resource: fileToPaste, isDirectory: fileToPasteStat.isDirectory, allowOverwrite: pasteShouldMove }, incrementalNaming); // Move/Copy File if (pasteShouldMove) { diff --git a/src/vs/workbench/contrib/files/browser/files.contribution.ts b/src/vs/workbench/contrib/files/browser/files.contribution.ts index b219a608bd2..19fcd5b0acb 100644 --- a/src/vs/workbench/contrib/files/browser/files.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/files.contribution.ts @@ -426,6 +426,15 @@ configurationRegistry.registerConfiguration({ description: nls.localize('explorer.decorations.badges', "Controls whether file decorations should use badges."), default: true }, + 'explorer.incrementalNaming': { + enum: ['simple', 'smart'], + enumDescriptions: [ + nls.localize('simple', "Appends the word \"copy\" at the end of the duplicated name potentially followed by a number"), + nls.localize('smart', "Adds a number at the end of the duplicated name. If some number is already part of the name, tries to increase that number") + ], + description: nls.localize('explorer.incrementalNaming', "Controls what naming strategy to use when a giving a new name to a duplicated explorer item on paste."), + default: 'simple' + } } }); diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 11e50458c94..75aae73d144 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -808,8 +808,8 @@ export class FileDragAndDrop implements ITreeDragAndDrop { private doHandleExplorerDrop(source: ExplorerItem, target: ExplorerItem, isCopy: boolean): Promise { // Reuse duplicate action if user copies if (isCopy) { - - return this.fileService.copy(source.resource, findValidPasteFileTarget(target, { resource: source.resource, isDirectory: source.isDirectory, allowOverwrite: false })).then(stat => { + const incrementalNaming = this.configurationService.getValue().explorer.incrementalNaming; + return this.fileService.copy(source.resource, findValidPasteFileTarget(target, { resource: source.resource, isDirectory: source.isDirectory, allowOverwrite: false }, incrementalNaming)).then(stat => { if (!stat.isDirectory) { return this.editorService.openEditor({ resource: stat.resource, options: { pinned: true } }).then(() => undefined); } diff --git a/src/vs/workbench/contrib/files/common/files.ts b/src/vs/workbench/contrib/files/common/files.ts index e60fda6cf31..342088011f5 100644 --- a/src/vs/workbench/contrib/files/common/files.ts +++ b/src/vs/workbench/contrib/files/common/files.ts @@ -114,6 +114,7 @@ export interface IFilesConfiguration extends IFilesConfiguration, IWorkbenchEdit colors: boolean; badges: boolean; }; + incrementalNaming: 'simple' | 'smart'; }; editor: IEditorOptions; } diff --git a/src/vs/workbench/contrib/files/test/electron-browser/fileActions.test.ts b/src/vs/workbench/contrib/files/test/electron-browser/fileActions.test.ts index d52b99bb2d9..355e381038b 100644 --- a/src/vs/workbench/contrib/files/test/electron-browser/fileActions.test.ts +++ b/src/vs/workbench/contrib/files/test/electron-browser/fileActions.test.ts @@ -6,132 +6,292 @@ import * as assert from 'assert'; import { incrementFileName } from 'vs/workbench/contrib/files/browser/fileActions'; -suite('Files - Increment file name', () => { +suite('Files - Increment file name simple', () => { test('Increment file name without any version', function () { const name = 'test.js'; - const result = incrementFileName(name, false); + const result = incrementFileName(name, false, 'simple'); assert.strictEqual(result, 'test copy.js'); }); test('Increment file name with suffix version', function () { const name = 'test copy.js'; - const result = incrementFileName(name, false); + const result = incrementFileName(name, false, 'simple'); assert.strictEqual(result, 'test copy 2.js'); }); test('Increment file name with suffix version with leading zeros', function () { const name = 'test copy 005.js'; - const result = incrementFileName(name, false); + const result = incrementFileName(name, false, 'simple'); assert.strictEqual(result, 'test copy 6.js'); }); test('Increment file name with suffix version, too big number', function () { const name = 'test copy 9007199254740992.js'; - const result = incrementFileName(name, false); + const result = incrementFileName(name, false, 'simple'); assert.strictEqual(result, 'test copy 9007199254740992 copy.js'); }); test('Increment file name with just version in name', function () { const name = 'copy.js'; - const result = incrementFileName(name, false); + const result = incrementFileName(name, false, 'simple'); assert.strictEqual(result, 'copy copy.js'); }); test('Increment file name with just version in name, v2', function () { const name = 'copy 2.js'; - const result = incrementFileName(name, false); + const result = incrementFileName(name, false, 'simple'); assert.strictEqual(result, 'copy 2 copy.js'); }); test('Increment file name without any extension or version', function () { const name = 'test'; - const result = incrementFileName(name, false); + const result = incrementFileName(name, false, 'simple'); assert.strictEqual(result, 'test copy'); }); test('Increment file name without any extension or version, trailing dot', function () { const name = 'test.'; - const result = incrementFileName(name, false); + const result = incrementFileName(name, false, 'simple'); assert.strictEqual(result, 'test copy.'); }); test('Increment file name without any extension or version, leading dot', function () { const name = '.test'; - const result = incrementFileName(name, false); + const result = incrementFileName(name, false, 'simple'); assert.strictEqual(result, '.test copy'); }); test('Increment file name without any extension or version, leading dot v2', function () { const name = '..test'; - const result = incrementFileName(name, false); + const result = incrementFileName(name, false, 'simple'); assert.strictEqual(result, '. copy.test'); }); test('Increment file name without any extension but with suffix version', function () { const name = 'test copy 5'; - const result = incrementFileName(name, false); + const result = incrementFileName(name, false, 'simple'); assert.strictEqual(result, 'test copy 6'); }); test('Increment folder name without any version', function () { const name = 'test'; - const result = incrementFileName(name, true); + const result = incrementFileName(name, true, 'simple'); assert.strictEqual(result, 'test copy'); }); test('Increment folder name with suffix version', function () { const name = 'test copy'; - const result = incrementFileName(name, true); + const result = incrementFileName(name, true, 'simple'); assert.strictEqual(result, 'test copy 2'); }); test('Increment folder name with suffix version, leading zeros', function () { const name = 'test copy 005'; - const result = incrementFileName(name, true); + const result = incrementFileName(name, true, 'simple'); assert.strictEqual(result, 'test copy 6'); }); test('Increment folder name with suffix version, too big number', function () { const name = 'test copy 9007199254740992'; - const result = incrementFileName(name, true); + const result = incrementFileName(name, true, 'simple'); assert.strictEqual(result, 'test copy 9007199254740992 copy'); }); test('Increment folder name with just version in name', function () { const name = 'copy'; - const result = incrementFileName(name, true); + const result = incrementFileName(name, true, 'simple'); assert.strictEqual(result, 'copy copy'); }); test('Increment folder name with just version in name, v2', function () { const name = 'copy 2'; - const result = incrementFileName(name, true); + const result = incrementFileName(name, true, 'simple'); assert.strictEqual(result, 'copy 2 copy'); }); test('Increment folder name "with extension" but without any version', function () { const name = 'test.js'; - const result = incrementFileName(name, true); + const result = incrementFileName(name, true, 'simple'); assert.strictEqual(result, 'test.js copy'); }); test('Increment folder name "with extension" and with suffix version', function () { const name = 'test.js copy 5'; - const result = incrementFileName(name, true); + const result = incrementFileName(name, true, 'simple'); assert.strictEqual(result, 'test.js copy 6'); }); test('Increment file/folder name with suffix version, special case 1', function () { const name = 'test copy 0'; - const result = incrementFileName(name, true); + const result = incrementFileName(name, true, 'simple'); assert.strictEqual(result, 'test copy'); }); test('Increment file/folder name with suffix version, special case 2', function () { const name = 'test copy 1'; - const result = incrementFileName(name, true); + const result = incrementFileName(name, true, 'simple'); assert.strictEqual(result, 'test copy 2'); }); }); + +suite('Files - Increment file name smart', () => { + + test('Increment file name without any version', function () { + const name = 'test.js'; + const result = incrementFileName(name, false, 'smart'); + assert.strictEqual(result, 'test.1.js'); + }); + + test('Increment folder name without any version', function () { + const name = 'test'; + const result = incrementFileName(name, true); + assert.strictEqual(result, 'test.1'); + }); + + test('Increment file name with suffix version', function () { + const name = 'test.1.js'; + const result = incrementFileName(name, false, 'smart'); + assert.strictEqual(result, 'test.2.js'); + }); + + test('Increment file name with suffix version with trailing zeros', function () { + const name = 'test.001.js'; + const result = incrementFileName(name, false, 'smart'); + assert.strictEqual(result, 'test.002.js'); + }); + + test('Increment file name with suffix version with trailing zeros, changing length', function () { + const name = 'test.009.js'; + const result = incrementFileName(name, false, 'smart'); + assert.strictEqual(result, 'test.010.js'); + }); + + test('Increment file name with suffix version with `-` as separator', function () { + const name = 'test-1.js'; + const result = incrementFileName(name, false, 'smart'); + assert.strictEqual(result, 'test-2.js'); + }); + + test('Increment file name with suffix version with `-` as separator, trailing zeros', function () { + const name = 'test-001.js'; + const result = incrementFileName(name, false, 'smart'); + assert.strictEqual(result, 'test-002.js'); + }); + + test('Increment file name with suffix version with `-` as separator, trailing zeros, changnig length', function () { + const name = 'test-099.js'; + const result = incrementFileName(name, false, 'smart'); + assert.strictEqual(result, 'test-100.js'); + }); + + test('Increment file name with suffix version with `_` as separator', function () { + const name = 'test_1.js'; + const result = incrementFileName(name, false, 'smart'); + assert.strictEqual(result, 'test_2.js'); + }); + + test('Increment folder name with suffix version', function () { + const name = 'test.1'; + const result = incrementFileName(name, true, 'smart'); + assert.strictEqual(result, 'test.2'); + }); + + test('Increment folder name with suffix version, trailing zeros', function () { + const name = 'test.001'; + const result = incrementFileName(name, true, 'smart'); + assert.strictEqual(result, 'test.002'); + }); + + test('Increment folder name with suffix version with `-` as separator', function () { + const name = 'test-1'; + const result = incrementFileName(name, true, 'smart'); + assert.strictEqual(result, 'test-2'); + }); + + test('Increment folder name with suffix version with `_` as separator', function () { + const name = 'test_1'; + const result = incrementFileName(name, true, 'smart'); + assert.strictEqual(result, 'test_2'); + }); + + test('Increment file name with suffix version, too big number', function () { + const name = 'test.9007199254740992.js'; + const result = incrementFileName(name, false, 'smart'); + assert.strictEqual(result, 'test.9007199254740992.1.js'); + }); + + test('Increment folder name with suffix version, too big number', function () { + const name = 'test.9007199254740992'; + const result = incrementFileName(name, true, 'smart'); + assert.strictEqual(result, 'test.9007199254740992.1'); + }); + + test('Increment file name with prefix version', function () { + const name = '1.test.js'; + const result = incrementFileName(name, false, 'smart'); + assert.strictEqual(result, '2.test.js'); + }); + + test('Increment file name with just version in name', function () { + const name = '1.js'; + const result = incrementFileName(name, false, 'smart'); + assert.strictEqual(result, '2.js'); + }); + + test('Increment file name with just version in name, too big number', function () { + const name = '9007199254740992.js'; + const result = incrementFileName(name, false, 'smart'); + assert.strictEqual(result, '9007199254740992.1.js'); + }); + + test('Increment file name with prefix version, trailing zeros', function () { + const name = '001.test.js'; + const result = incrementFileName(name, false, 'smart'); + assert.strictEqual(result, '002.test.js'); + }); + + test('Increment file name with prefix version with `-` as separator', function () { + const name = '1-test.js'; + const result = incrementFileName(name, false, 'smart'); + assert.strictEqual(result, '2-test.js'); + }); + + test('Increment file name with prefix version with `-` as separator', function () { + const name = '1_test.js'; + const result = incrementFileName(name, false, 'smart'); + assert.strictEqual(result, '2_test.js'); + }); + + test('Increment file name with prefix version, too big number', function () { + const name = '9007199254740992.test.js'; + const result = incrementFileName(name, false, 'smart'); + assert.strictEqual(result, '9007199254740992.test.1.js'); + }); + + test('Increment folder name with prefix version', function () { + const name = '1.test'; + const result = incrementFileName(name, true, 'smart'); + assert.strictEqual(result, '2.test'); + }); + + test('Increment folder name with prefix version, too big number', function () { + const name = '9007199254740992.test'; + const result = incrementFileName(name, true, 'smart'); + assert.strictEqual(result, '9007199254740992.test.1'); + }); + + test('Increment folder name with prefix version, trailing zeros', function () { + const name = '001.test'; + const result = incrementFileName(name, true, 'smart'); + assert.strictEqual(result, '002.test'); + }); + + test('Increment folder name with prefix version with `-` as separator', function () { + const name = '1-test'; + const result = incrementFileName(name, true, 'smart'); + assert.strictEqual(result, '2-test'); + }); + +}); From 041e24b1c7329093bdfe5597d8a3d3cff0e76b4b Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 9 Aug 2019 17:59:30 +0200 Subject: [PATCH 415/861] fix compile error --- .../contrib/files/test/electron-browser/fileActions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/files/test/electron-browser/fileActions.test.ts b/src/vs/workbench/contrib/files/test/electron-browser/fileActions.test.ts index 355e381038b..bf0642cde5c 100644 --- a/src/vs/workbench/contrib/files/test/electron-browser/fileActions.test.ts +++ b/src/vs/workbench/contrib/files/test/electron-browser/fileActions.test.ts @@ -146,7 +146,7 @@ suite('Files - Increment file name smart', () => { test('Increment folder name without any version', function () { const name = 'test'; - const result = incrementFileName(name, true); + const result = incrementFileName(name, true, 'smart'); assert.strictEqual(result, 'test.1'); }); From 796b5dbd433ef9000db60bfb42087b3b1cafe4ec Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 9 Aug 2019 18:08:15 +0200 Subject: [PATCH 416/861] :lipstick: --- src/vs/platform/environment/common/environment.ts | 5 +++-- src/vs/platform/environment/node/environmentService.ts | 3 ++- src/vs/platform/windows/common/windows.ts | 2 +- .../services/environment/browser/environmentService.ts | 4 +++- .../services/environment/node/environmentService.ts | 4 +++- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index 3a53fd21524..b13a82f4447 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { URI } from 'vs/base/common/uri'; export interface ParsedArgs { @@ -98,7 +98,8 @@ export interface IExtensionHostDebugParams extends IDebugParams { export const BACKUPS = 'Backups'; export interface IEnvironmentService { - _serviceBrand: any; + + _serviceBrand: ServiceIdentifier; args: ParsedArgs; diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index 9373b22383b..c5c4e66272c 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -16,6 +16,7 @@ import { toLocalISOString } from 'vs/base/common/date'; import { isWindows, isLinux } from 'vs/base/common/platform'; import { getPathFromAmdModule } from 'vs/base/common/amd'; import { URI } from 'vs/base/common/uri'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; // Read this before there's any chance it is overwritten // Related to https://github.com/Microsoft/vscode/issues/30624 @@ -76,7 +77,7 @@ function getCLIPath(execPath: string, appRoot: string, isBuilt: boolean): string export class EnvironmentService implements IEnvironmentService { - _serviceBrand: any; + _serviceBrand!: ServiceIdentifier; get args(): ParsedArgs { return this._args; } diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index 9be9dbfc291..a1f50a5a715 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -426,6 +426,7 @@ export interface IWindowConfiguration extends ParsedArgs { folderUri?: ISingleFolderWorkspaceIdentifier; remoteAuthority?: string; + connectionToken?: string; zoomLevel?: number; fullscreen?: boolean; @@ -444,7 +445,6 @@ export interface IWindowConfiguration extends ParsedArgs { filesToDiff?: IPath[]; filesToWait?: IPathsToWaitFor; termProgram?: string; - connectionToken?: string; } export interface IRunActionInWindowRequest { diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts index d6c619eae10..b6c34540a10 100644 --- a/src/vs/workbench/services/environment/browser/environmentService.ts +++ b/src/vs/workbench/services/environment/browser/environmentService.ts @@ -32,11 +32,13 @@ export class BrowserWindowConfiguration implements IWindowConfiguration { nodeCachedDataDir?: string; backupPath?: string; + backupWorkspaceResource?: URI; workspace?: IWorkspaceIdentifier; folderUri?: ISingleFolderWorkspaceIdentifier; - remoteAuthority: string; + remoteAuthority?: string; + connectionToken?: string; zoomLevel?: number; fullscreen?: boolean; diff --git a/src/vs/workbench/services/environment/node/environmentService.ts b/src/vs/workbench/services/environment/node/environmentService.ts index 8b8b9354b63..2ebf10365a2 100644 --- a/src/vs/workbench/services/environment/node/environmentService.ts +++ b/src/vs/workbench/services/environment/node/environmentService.ts @@ -10,16 +10,18 @@ import { memoize } from 'vs/base/common/decorators'; import { URI } from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; import { toBackupWorkspaceResource } from 'vs/workbench/services/backup/common/backup'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; export class WorkbenchEnvironmentService extends EnvironmentService implements IWorkbenchEnvironmentService { - _serviceBrand: any; + _serviceBrand!: ServiceIdentifier; constructor( private _configuration: IWindowConfiguration, execPath: string ) { super(_configuration, execPath); + this._configuration.backupWorkspaceResource = this._configuration.backupPath ? toBackupWorkspaceResource(this._configuration.backupPath, this) : undefined; } From ded1ac53799e89796a09b7a2e9cc78bad5fea2ad Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 9 Aug 2019 18:34:17 +0200 Subject: [PATCH 417/861] window - remove obsolete code for showing window in did-finish-load We since have changed the code so much that we always show the window after it is being created. --- src/vs/code/electron-main/window.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 517417b9867..c6d2f29b1ba 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -360,17 +360,6 @@ export class CodeWindow extends Disposable implements ICodeWindow { this.pendingLoadConfig = undefined; } - - // To prevent flashing, we set the window visible after the page has finished to load but before Code is loaded - if (this._win && !this._win.isVisible()) { - if (this.windowState.mode === WindowMode.Maximized) { - this._win.maximize(); - } - - if (!this._win.isVisible()) { // maximize also makes visible - this._win.show(); - } - } }); // Window Focus From 37e0b8e229305c09b0cd3753cc28e314b60d93f3 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 9 Aug 2019 09:15:43 -0700 Subject: [PATCH 418/861] Add terminal.integrated.automationShell Fixes #78497 --- .../api/browser/mainThreadTerminalService.ts | 2 +- .../workbench/api/common/extHost.api.impl.ts | 2 +- .../workbench/api/common/extHost.protocol.ts | 2 +- .../api/common/extHostTerminalService.ts | 2 +- .../workbench/api/node/extHostDebugService.ts | 2 +- .../api/node/extHostTerminalService.ts | 19 ++++++------- .../tasks/browser/terminalTaskSystem.ts | 2 +- .../terminal/browser/terminal.contribution.ts | 15 +++++++++++ .../contrib/terminal/browser/terminal.ts | 2 +- .../browser/terminalInstanceService.ts | 9 ++++--- .../browser/terminalProcessManager.ts | 2 +- .../contrib/terminal/common/terminal.ts | 8 +++++- .../terminal/common/terminalEnvironment.ts | 27 ++++++++++++++++--- .../terminalInstanceService.ts | 4 ++- 14 files changed, 72 insertions(+), 26 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index 871087e2be6..6c6acac7a80 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -335,7 +335,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape private _onRequestDefaultShellAndArgs(request: IDefaultShellAndArgsRequest): void { if (this._isPrimaryExtHost()) { - this._proxy.$requestDefaultShellAndArgs().then(e => request(e.shell, e.args)); + this._proxy.$requestDefaultShellAndArgs(request.useAutomationShell).then(e => request.callback(e.shell, e.args)); } } diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 4272e94a833..e8fec875029 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -255,7 +255,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I return extHostClipboard; }, get shell() { - return extHostTerminalService.getDefaultShell(configProvider); + return extHostTerminalService.getDefaultShell(false, configProvider); }, openExternal(uri: URI) { return extHostWindow.openUri(uri, { allowTunneling: !!initData.remote.isRemote }); diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index ea7865ddb0d..dc50dfafa7c 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1166,7 +1166,7 @@ export interface ExtHostTerminalServiceShape { $acceptProcessRequestLatency(id: number): number; $acceptWorkspacePermissionsChanged(isAllowed: boolean): void; $requestAvailableShells(): Promise; - $requestDefaultShellAndArgs(): Promise; + $requestDefaultShellAndArgs(useAutomationShell: boolean): Promise; } export interface ExtHostSCMShape { diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index 7c6907caa26..fcd283b560c 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -26,7 +26,7 @@ export interface IExtHostTerminalService extends ExtHostTerminalServiceShape { createTerminalFromOptions(options: vscode.TerminalOptions): vscode.Terminal; createExtensionTerminal(options: vscode.ExtensionTerminalOptions): vscode.Terminal; attachPtyToTerminal(id: number, pty: vscode.Pseudoterminal): void; - getDefaultShell(configProvider: ExtHostConfigProvider): string; + getDefaultShell(useAutomationShell: boolean, configProvider: ExtHostConfigProvider): string; } export const IExtHostTerminalService = createDecorator('IExtHostTerminalService'); diff --git a/src/vs/workbench/api/node/extHostDebugService.ts b/src/vs/workbench/api/node/extHostDebugService.ts index f18bd5bfe91..87adb02d748 100644 --- a/src/vs/workbench/api/node/extHostDebugService.ts +++ b/src/vs/workbench/api/node/extHostDebugService.ts @@ -349,7 +349,7 @@ export class ExtHostDebugService implements IExtHostDebugService, ExtHostDebugSe }).then(async needNewTerminal => { const configProvider = await this._configurationService.getConfigProvider(); - const shell = this._terminalService.getDefaultShell(configProvider); + const shell = this._terminalService.getDefaultShell(true, configProvider); if (needNewTerminal || !this._integratedTerminalInstance) { const options: vscode.TerminalOptions = { diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 02de2e82ed6..99a7cc8309c 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -274,7 +274,7 @@ export class ExtHostTerminalService implements IExtHostTerminalService, ExtHostT this._setupExtHostProcessListeners(id, p); } - public getDefaultShell(configProvider: ExtHostConfigProvider): string { + public getDefaultShell(useAutomationShell: boolean, configProvider: ExtHostConfigProvider): string { const fetchSetting = (key: string) => { const setting = configProvider .getConfiguration(key.substr(0, key.lastIndexOf('.'))) @@ -289,11 +289,12 @@ export class ExtHostTerminalService implements IExtHostTerminalService, ExtHostT process.env.windir, this._lastActiveWorkspace, this._variableResolver, - this._logService + this._logService, + useAutomationShell ); } - private _getDefaultShellArgs(configProvider: ExtHostConfigProvider): string[] | string { + private _getDefaultShellArgs(useAutomationShell: boolean, configProvider: ExtHostConfigProvider): string[] | string { const fetchSetting = (key: string) => { const setting = configProvider .getConfiguration(key.substr(0, key.lastIndexOf('.'))) @@ -301,7 +302,7 @@ export class ExtHostTerminalService implements IExtHostTerminalService, ExtHostT return this._apiInspectConfigToPlain(setting); }; - return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed, this._lastActiveWorkspace, this._variableResolver, this._logService); + return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed, useAutomationShell, this._lastActiveWorkspace, this._variableResolver, this._logService); } public async $acceptActiveTerminalChanged(id: number | null): Promise { @@ -461,8 +462,8 @@ export class ExtHostTerminalService implements IExtHostTerminalService, ExtHostT const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux'); const configProvider = await this._extHostConfiguration.getConfigProvider(); if (!shellLaunchConfig.executable) { - shellLaunchConfig.executable = this.getDefaultShell(configProvider); - shellLaunchConfig.args = this._getDefaultShellArgs(configProvider); + shellLaunchConfig.executable = this.getDefaultShell(false, configProvider); + shellLaunchConfig.args = this._getDefaultShellArgs(false, configProvider); } else { if (this._variableResolver) { shellLaunchConfig.executable = this._variableResolver.resolve(this._lastActiveWorkspace, shellLaunchConfig.executable); @@ -603,11 +604,11 @@ export class ExtHostTerminalService implements IExtHostTerminalService, ExtHostT return detectAvailableShells(); } - public async $requestDefaultShellAndArgs(): Promise { + public async $requestDefaultShellAndArgs(useAutomationShell: boolean): Promise { const configProvider = await this._extHostConfiguration.getConfigProvider(); return Promise.resolve({ - shell: this.getDefaultShell(configProvider), - args: this._getDefaultShellArgs(configProvider) + shell: this.getDefaultShell(useAutomationShell, configProvider), + args: this._getDefaultShellArgs(useAutomationShell, configProvider) }); } diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index 2559188da9e..9d52970cf2c 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -766,7 +766,7 @@ export class TerminalTaskSystem implements ITaskSystem { let terminalName = this.createTerminalName(task, workspaceFolder); let originalCommand = task.command.name; if (isShellCommand) { - const defaultConfig = await this.terminalInstanceService.getDefaultShellAndArgs(platform); + const defaultConfig = await this.terminalInstanceService.getDefaultShellAndArgs(true, platform); shellLaunchConfig = { name: terminalName, executable: defaultConfig.shell, args: defaultConfig.args, waitOnExit }; let shellSpecified: boolean = false; let shellOptions: ShellConfiguration | undefined = task.command.options && task.command.options.shell; diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts index f1481ee18f6..dbd0aa41286 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts @@ -71,6 +71,21 @@ configurationRegistry.registerConfiguration({ title: nls.localize('terminalIntegratedConfigurationTitle', "Integrated Terminal"), type: 'object', properties: { + 'terminal.integrated.automationShell.linux': { + markdownDescription: nls.localize('terminal.integrated.automationShell.linux', "A path that when set will override {0} and ignore {1} and {2} values for automation-related terminal usage like tasks and debug.", '`terminal.integrated.shell.linux`', '`shellArgs`', '`env`'), + type: ['string', 'null'], + default: null + }, + 'terminal.integrated.automationShell.osx': { + markdownDescription: nls.localize('terminal.integrated.automationShell.osx', "A path that when set will override {0} and ignore {1} and {2} values for automation-related terminal usage like tasks and debug.", '`terminal.integrated.shell.osx`', '`shellArgs`', '`env`'), + type: ['string', 'null'], + default: null + }, + 'terminal.integrated.automationShell.windows': { + markdownDescription: nls.localize('terminal.integrated.automationShell.windows', "A path that when set will override {0} and ignore {1} and {2} values for automation-related terminal usage like tasks and debug.", '`terminal.integrated.shell.windows`', '`shellArgs`', '`env`'), + type: ['string', 'null'], + default: null + }, 'terminal.integrated.shellArgs.linux': { markdownDescription: nls.localize('terminal.integrated.shellArgs.linux', "The command line arguments to use when on the Linux terminal. [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration)."), type: 'array', diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 418b2900f17..42e98f25547 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -30,7 +30,7 @@ export interface ITerminalInstanceService { createWindowsShellHelper(shellProcessId: number, instance: ITerminalInstance, xterm: XTermTerminal): IWindowsShellHelper; createTerminalProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean): ITerminalChildProcess; - getDefaultShellAndArgs(platformOverride?: Platform): Promise<{ shell: string, args: string[] | string | undefined }>; + getDefaultShellAndArgs(useAutomationShell: boolean, platformOverride?: Platform): Promise<{ shell: string, args: string[] | string | undefined }>; getMainProcessParentEnv(): Promise; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts index 08980a94000..3ed29f8f3bc 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts @@ -52,11 +52,14 @@ export class TerminalInstanceService implements ITerminalInstanceService { throw new Error('Not implemented'); } - public getDefaultShellAndArgs(): Promise<{ shell: string, args: string[] | string | undefined }> { - return new Promise(r => this._onRequestDefaultShellAndArgs.fire((shell, args) => r({ shell, args }))); + public getDefaultShellAndArgs(useAutomationShell: boolean, ): Promise<{ shell: string, args: string[] | string | undefined }> { + return new Promise(r => this._onRequestDefaultShellAndArgs.fire({ + useAutomationShell, + callback: (shell, args) => r({ shell, args }) + })); } public async getMainProcessParentEnv(): Promise { return {}; } -} \ No newline at end of file +} diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index 826122750b8..b3ff7db5e88 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -195,7 +195,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux'); const lastActiveWorkspace = activeWorkspaceRootUri ? this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) : null; if (!shellLaunchConfig.executable) { - const defaultConfig = await this._terminalInstanceService.getDefaultShellAndArgs(); + const defaultConfig = await this._terminalInstanceService.getDefaultShellAndArgs(false); shellLaunchConfig.executable = defaultConfig.shell; shellLaunchConfig.args = defaultConfig.args; } else { diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index eb991bcabfa..9c988c3a6e6 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -76,6 +76,11 @@ export interface ITerminalConfiguration { osx: string | null; windows: string | null; }; + automationShell: { + linux: string | null; + osx: string | null; + windows: string | null; + }; shellArgs: { linux: string[]; osx: string[]; @@ -754,7 +759,8 @@ export interface IAvailableShellsRequest { } export interface IDefaultShellAndArgsRequest { - (shell: string, args: string[] | string | undefined): void; + useAutomationShell: boolean; + callback: (shell: string, args: string[] | string | undefined) => void; } export enum LinuxDistro { diff --git a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index 4a75398475f..255e7f232ab 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -197,11 +197,10 @@ export function getDefaultShell( lastActiveWorkspace: IWorkspaceFolder | undefined, configurationResolverService: IConfigurationResolverService | undefined, logService: ILogService, + useAutomationShell: boolean, platformOverride: platform.Platform = platform.platform ): string { - const platformKey = platformOverride === platform.Platform.Windows ? 'windows' : platformOverride === platform.Platform.Mac ? 'osx' : 'linux'; - const shellConfigValue = fetchSetting(`terminal.integrated.shell.${platformKey}`); - let executable = (isWorkspaceShellAllowed ? shellConfigValue.value : shellConfigValue.user) || (shellConfigValue.default || defaultShell); + let executable = getAutomationShell(fetchSetting, isWorkspaceShellAllowed, useAutomationShell, platformOverride) || defaultShell; // Change Sysnative to System32 if the OS is Windows but NOT WoW64. It's // safe to assume that this was used by accident as Sysnative does not @@ -222,7 +221,7 @@ export function getDefaultShell( try { executable = configurationResolverService.resolve(lastActiveWorkspace, executable); } catch (e) { - logService.error(`Could not resolve terminal.integrated.shell.${platformKey}`, e); + logService.error(`Could not resolve shell`, e); executable = executable; } } @@ -233,11 +232,18 @@ export function getDefaultShell( export function getDefaultShellArgs( fetchSetting: (key: string) => { user: string | string[] | undefined, value: string | string[] | undefined, default: string | string[] | undefined }, isWorkspaceShellAllowed: boolean, + useAutomationShell: boolean, lastActiveWorkspace: IWorkspaceFolder | undefined, configurationResolverService: IConfigurationResolverService | undefined, logService: ILogService, platformOverride: platform.Platform = platform.platform, ): string | string[] { + if (useAutomationShell) { + if (!!getAutomationShell(fetchSetting, isWorkspaceShellAllowed, useAutomationShell, platformOverride)) { + return []; + } + } + const platformKey = platformOverride === platform.Platform.Windows ? 'windows' : platformOverride === platform.Platform.Mac ? 'osx' : 'linux'; const shellArgsConfigValue = fetchSetting(`terminal.integrated.shellArgs.${platformKey}`); let args = ((isWorkspaceShellAllowed ? shellArgsConfigValue.value : shellArgsConfigValue.user) || shellArgsConfigValue.default); @@ -259,6 +265,19 @@ export function getDefaultShellArgs( return args; } +function getAutomationShell( + fetchSetting: (key: string) => { user: string | string[] | undefined, value: string | string[] | undefined, default: string | string[] | undefined }, + isWorkspaceShellAllowed: boolean, + useAutomationShell: boolean, + platformOverride: platform.Platform = platform.platform, +): string | null { + const platformKey = platformOverride === platform.Platform.Windows ? 'windows' : platformOverride === platform.Platform.Mac ? 'osx' : 'linux'; + const shellTypeKey = useAutomationShell ? 'automationShell' : 'shell'; + const shellConfigValue = fetchSetting(`terminal.integrated.${shellTypeKey}.${platformKey}`); + const executable = (isWorkspaceShellAllowed ? shellConfigValue.value : shellConfigValue.user) || (shellConfigValue.default); + return executable; +} + export function createTerminalEnvironment( shellLaunchConfig: IShellLaunchConfig, lastActiveWorkspace: IWorkspaceFolder | null, diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts index 2b7fa1c4fa3..a7c3813e987 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts @@ -73,7 +73,7 @@ export class TerminalInstanceService implements ITerminalInstanceService { return this._storageService.getBoolean(IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, StorageScope.WORKSPACE, false); } - public getDefaultShellAndArgs(platformOverride: Platform = platform): Promise<{ shell: string, args: string | string[] }> { + public getDefaultShellAndArgs(useAutomationShell: boolean, platformOverride: Platform = platform): Promise<{ shell: string, args: string | string[] }> { const isWorkspaceShellAllowed = this._isWorkspaceShellAllowed(); const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(); let lastActiveWorkspace = activeWorkspaceRootUri ? this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) : undefined; @@ -87,11 +87,13 @@ export class TerminalInstanceService implements ITerminalInstanceService { lastActiveWorkspace, this._configurationResolverService, this._logService, + useAutomationShell, platformOverride ); const args = getDefaultShellArgs( (key) => this._configurationService.inspect(key), isWorkspaceShellAllowed, + useAutomationShell, lastActiveWorkspace, this._configurationResolverService, this._logService, From b2b37e4d89f193f3cecf71f4ba19dfb8a0152cd8 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 9 Aug 2019 09:40:34 -0700 Subject: [PATCH 419/861] Add some tests for getDefaultShell --- .../terminal/common/terminalEnvironment.ts | 35 ++++++++------ .../test/node/terminalEnvironment.test.ts | 46 ++++++++++++++++++- 2 files changed, 66 insertions(+), 15 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index 255e7f232ab..9d6215af30c 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -200,33 +200,41 @@ export function getDefaultShell( useAutomationShell: boolean, platformOverride: platform.Platform = platform.platform ): string { - let executable = getAutomationShell(fetchSetting, isWorkspaceShellAllowed, useAutomationShell, platformOverride) || defaultShell; + let maybeExecutable: string | null = null; + if (useAutomationShell) { + // If automationShell is specified, this should override the normal setting + maybeExecutable = getShellSetting(fetchSetting, isWorkspaceShellAllowed, 'automationShell', platformOverride); + } + if (!maybeExecutable) { + maybeExecutable = getShellSetting(fetchSetting, isWorkspaceShellAllowed, 'shell', platformOverride); + } + maybeExecutable = maybeExecutable || defaultShell; // Change Sysnative to System32 if the OS is Windows but NOT WoW64. It's // safe to assume that this was used by accident as Sysnative does not // exist and will break the terminal in non-WoW64 environments. if ((platformOverride === platform.Platform.Windows) && !isWoW64 && windir) { - const sysnativePath = path.join(windir, 'Sysnative').toLowerCase(); - if (executable && executable.toLowerCase().indexOf(sysnativePath) === 0) { - executable = path.join(windir, 'System32', executable.substr(sysnativePath.length)); + const sysnativePath = path.join(windir, 'Sysnative').replace(/\//g, '\\').toLowerCase(); + if (maybeExecutable && maybeExecutable.toLowerCase().indexOf(sysnativePath) === 0) { + maybeExecutable = path.join(windir, 'System32', maybeExecutable.substr(sysnativePath.length + 1)); } } // Convert / to \ on Windows for convenience - if (executable && platformOverride === platform.Platform.Windows) { - executable = executable.replace(/\//g, '\\'); + if (maybeExecutable && platformOverride === platform.Platform.Windows) { + maybeExecutable = maybeExecutable.replace(/\//g, '\\'); } if (configurationResolverService) { try { - executable = configurationResolverService.resolve(lastActiveWorkspace, executable); + maybeExecutable = configurationResolverService.resolve(lastActiveWorkspace, maybeExecutable); } catch (e) { logService.error(`Could not resolve shell`, e); - executable = executable; + maybeExecutable = maybeExecutable; } } - return executable; + return maybeExecutable; } export function getDefaultShellArgs( @@ -239,7 +247,7 @@ export function getDefaultShellArgs( platformOverride: platform.Platform = platform.platform, ): string | string[] { if (useAutomationShell) { - if (!!getAutomationShell(fetchSetting, isWorkspaceShellAllowed, useAutomationShell, platformOverride)) { + if (!!getShellSetting(fetchSetting, isWorkspaceShellAllowed, 'automationShell', platformOverride)) { return []; } } @@ -265,15 +273,14 @@ export function getDefaultShellArgs( return args; } -function getAutomationShell( +function getShellSetting( fetchSetting: (key: string) => { user: string | string[] | undefined, value: string | string[] | undefined, default: string | string[] | undefined }, isWorkspaceShellAllowed: boolean, - useAutomationShell: boolean, + type: 'automationShell' | 'shell', platformOverride: platform.Platform = platform.platform, ): string | null { const platformKey = platformOverride === platform.Platform.Windows ? 'windows' : platformOverride === platform.Platform.Mac ? 'osx' : 'linux'; - const shellTypeKey = useAutomationShell ? 'automationShell' : 'shell'; - const shellConfigValue = fetchSetting(`terminal.integrated.${shellTypeKey}.${platformKey}`); + const shellConfigValue = fetchSetting(`terminal.integrated.${type}.${platformKey}`); const executable = (isWorkspaceShellAllowed ? shellConfigValue.value : shellConfigValue.user) || (shellConfigValue.default); return executable; } diff --git a/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts b/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts index 2368badf9b8..7fce80a22a2 100644 --- a/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts +++ b/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts @@ -9,7 +9,7 @@ import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/termi import { URI as Uri } from 'vs/base/common/uri'; import { IStringDictionary } from 'vs/base/common/collections'; -suite('Workbench - TerminalEnvironment', () => { +suite.only('Workbench - TerminalEnvironment', () => { test('addTerminalEnvironmentKeys', () => { const env: { [key: string]: any } = { FOO: 'bar' }; const locale = 'en-au'; @@ -128,4 +128,48 @@ suite('Workbench - TerminalEnvironment', () => { assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [], ignoreConfigurationCwd: true }, '/userHome/', undefined, undefined, Uri.file('/bar'), '/foo'), '/bar'); }); }); + + suite('getDefaultShell', () => { + test('should change Sysnative to System32 in non-WoW64 systems', () => { + const shell = terminalEnvironment.getDefaultShell(key => { + return ({ + 'terminal.integrated.shell.windows': { user: 'C:\\Windows\\Sysnative\\cmd.exe', value: undefined, default: undefined } + } as any)[key]; + }, false, 'DEFAULT', false, 'C:\\Windows', undefined, undefined, {} as any, false, platform.Platform.Windows); + assert.equal(shell, 'C:\\Windows\\System32\\cmd.exe'); + }); + + test('should not change Sysnative to System32 in WoW64 systems', () => { + const shell = terminalEnvironment.getDefaultShell(key => { + return ({ + 'terminal.integrated.shell.windows': { user: 'C:\\Windows\\Sysnative\\cmd.exe', value: undefined, default: undefined } + } as any)[key]; + }, false, 'DEFAULT', true, 'C:\\Windows', undefined, undefined, {} as any, false, platform.Platform.Windows); + assert.equal(shell, 'C:\\Windows\\Sysnative\\cmd.exe'); + }); + + test('should use automationShell when specified', () => { + const shell1 = terminalEnvironment.getDefaultShell(key => { + return ({ + 'terminal.integrated.shell.windows': { user: 'shell', value: undefined, default: undefined }, + 'terminal.integrated.automationShell.windows': { user: undefined, value: undefined, default: undefined } + } as any)[key]; + }, false, 'DEFAULT', false, 'C:\\Windows', undefined, undefined, {} as any, false, platform.Platform.Windows); + assert.equal(shell1, 'shell', 'automationShell was false'); + const shell2 = terminalEnvironment.getDefaultShell(key => { + return ({ + 'terminal.integrated.shell.windows': { user: 'shell', value: undefined, default: undefined }, + 'terminal.integrated.automationShell.windows': { user: undefined, value: undefined, default: undefined } + } as any)[key]; + }, false, 'DEFAULT', false, 'C:\\Windows', undefined, undefined, {} as any, true, platform.Platform.Windows); + assert.equal(shell2, 'shell', 'automationShell was true'); + const shell3 = terminalEnvironment.getDefaultShell(key => { + return ({ + 'terminal.integrated.shell.windows': { user: 'shell', value: undefined, default: undefined }, + 'terminal.integrated.automationShell.windows': { user: 'automationShell', value: undefined, default: undefined } + } as any)[key]; + }, false, 'DEFAULT', false, 'C:\\Windows', undefined, undefined, {} as any, true, platform.Platform.Windows); + assert.equal(shell3, 'automationShell', 'automationShell was true and specified in settings'); + }); + }); }); From 3d64c7ef94756a04fef8285b70d9abf4ed8b7e08 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 9 Aug 2019 10:03:08 -0700 Subject: [PATCH 420/861] Allow web tests to pass electron path exists check --- test/smoke/src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/smoke/src/main.ts b/test/smoke/src/main.ts index 4972be890f1..34364d39ded 100644 --- a/test/smoke/src/main.ts +++ b/test/smoke/src/main.ts @@ -133,7 +133,7 @@ if (testCodePath) { process.env.VSCODE_CLI = '1'; } -if (!fs.existsSync(electronPath || '')) { +if (!opts.web && !fs.existsSync(electronPath || '')) { fail(`Can't find Code at ${electronPath}.`); } From 76a93d02f33f995bb8383bc86d5d790fce35894c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 9 Aug 2019 10:24:20 -0700 Subject: [PATCH 421/861] xterm@3.15.0-beta94 Diff: https://github.com/xtermjs/xterm.js/compare/58e1b0d...30161c3 Changes: - Fix non-mouse events cursor Fixes #78762 --- package.json | 2 +- remote/package.json | 2 +- remote/yarn.lock | 8 ++++---- yarn.lock | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 98d73a82799..a429413d054 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "vscode-ripgrep": "^1.5.6", "vscode-sqlite3": "4.0.8", "vscode-textmate": "^4.2.2", - "xterm": "3.15.0-beta93", + "xterm": "3.15.0-beta94", "xterm-addon-search": "0.2.0-beta3", "xterm-addon-web-links": "0.1.0-beta10", "yauzl": "^2.9.2", diff --git a/remote/package.json b/remote/package.json index 82324d430aa..a057fcb87cd 100644 --- a/remote/package.json +++ b/remote/package.json @@ -20,7 +20,7 @@ "vscode-proxy-agent": "0.4.0", "vscode-ripgrep": "^1.5.5", "vscode-textmate": "^4.2.2", - "xterm": "3.15.0-beta93", + "xterm": "3.15.0-beta94", "xterm-addon-search": "0.2.0-beta3", "xterm-addon-web-links": "0.1.0-beta10", "yauzl": "^2.9.2", diff --git a/remote/yarn.lock b/remote/yarn.lock index 0467f0810c3..4c1a99d899c 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -1159,10 +1159,10 @@ xterm-addon-web-links@0.1.0-beta10: resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23" integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg== -xterm@3.15.0-beta93: - version "3.15.0-beta93" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta93.tgz#ba1d5e4588f07be9bb36c70082a0e034f9bad565" - integrity sha512-MgzlwBOOwa/xYmWnLiTmqVOk3v/YRxzlPej940zpcp/chXW+ErsSPW6sehy68wedO9TWbR3oBUe8agfLH0uOuA== +xterm@3.15.0-beta94: + version "3.15.0-beta94" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta94.tgz#a2c48db73252021adc9d33d75f1f91c859b81b5f" + integrity sha512-JScndNQV90vicwBDsZiF2BAxMdruzXvVaN8TY6jFqMPC+YjXTXFDBFUij8iCONnGcTZBfNjbrVng+zLheAKphg== yauzl@^2.9.2: version "2.10.0" diff --git a/yarn.lock b/yarn.lock index 35c0842584e..1f75b23ba87 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9888,10 +9888,10 @@ xterm-addon-web-links@0.1.0-beta10: resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23" integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg== -xterm@3.15.0-beta93: - version "3.15.0-beta93" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta93.tgz#ba1d5e4588f07be9bb36c70082a0e034f9bad565" - integrity sha512-MgzlwBOOwa/xYmWnLiTmqVOk3v/YRxzlPej940zpcp/chXW+ErsSPW6sehy68wedO9TWbR3oBUe8agfLH0uOuA== +xterm@3.15.0-beta94: + version "3.15.0-beta94" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta94.tgz#a2c48db73252021adc9d33d75f1f91c859b81b5f" + integrity sha512-JScndNQV90vicwBDsZiF2BAxMdruzXvVaN8TY6jFqMPC+YjXTXFDBFUij8iCONnGcTZBfNjbrVng+zLheAKphg== y18n@^3.2.1: version "3.2.1" From 734c85e96db19ccf7e6c9b5a28bcc276a900351a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 9 Aug 2019 10:28:18 -0700 Subject: [PATCH 422/861] Update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a429413d054..404e64edf2b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "fffc03749d2060757cd83580d67a15ded244c2af", + "distro": "7790b9530e2afa8fed5a59c4686e25e9f511c216", "author": { "name": "Microsoft Corporation" }, From 803e140a230c85f0329154d1f2fdbb971082d1df Mon Sep 17 00:00:00 2001 From: RMacfarlane Date: Wed, 7 Aug 2019 09:29:51 -0700 Subject: [PATCH 423/861] Use application insights module instead of script tag, fixes https://github.com/microsoft/vscode/issues/78475 --- package.json | 1 + remote/package.json | 1 + remote/web/package.json | 1 + remote/web/yarn.lock | 68 +++++++++++++++++ remote/yarn.lock | 68 +++++++++++++++++ src/typings/applicationinsights-web.d.ts | 59 +++++++++++++++ src/vs/code/browser/workbench/workbench.html | 3 - src/vs/code/browser/workbench/workbench.js | 3 +- .../telemetry/browser/telemetryService.ts | 73 +++---------------- tslint.json | 3 +- yarn.lock | 68 +++++++++++++++++ 11 files changed, 280 insertions(+), 68 deletions(-) create mode 100644 src/typings/applicationinsights-web.d.ts diff --git a/package.json b/package.json index 404e64edf2b..2b4d2a8ee87 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "update-distro": "node build/npm/update-distro.js" }, "dependencies": { + "@microsoft/applicationinsights-web": "^2.1.1", "applicationinsights": "1.0.8", "graceful-fs": "4.1.11", "http-proxy-agent": "^2.1.0", diff --git a/remote/package.json b/remote/package.json index a057fcb87cd..662e9fb7c2d 100644 --- a/remote/package.json +++ b/remote/package.json @@ -2,6 +2,7 @@ "name": "vscode-reh", "version": "0.0.0", "dependencies": { + "@microsoft/applicationinsights-web": "^2.1.1", "applicationinsights": "1.0.8", "getmac": "1.4.1", "graceful-fs": "4.1.11", diff --git a/remote/web/package.json b/remote/web/package.json index c7a487b6c2d..f54afe1a3e6 100644 --- a/remote/web/package.json +++ b/remote/web/package.json @@ -2,6 +2,7 @@ "name": "vscode-web", "version": "0.0.0", "dependencies": { + "@microsoft/applicationinsights-web": "^2.1.1", "onigasm-umd": "^2.2.2", "vscode-textmate": "^4.1.1", "xterm": "3.15.0-beta67", diff --git a/remote/web/yarn.lock b/remote/web/yarn.lock index b624eb37290..23ad784a554 100644 --- a/remote/web/yarn.lock +++ b/remote/web/yarn.lock @@ -2,6 +2,69 @@ # yarn lockfile v1 +"@microsoft/applicationinsights-analytics-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-2.1.1.tgz#6d09c1915f808026e2d45165d04802f09affed59" + integrity sha512-VKIutoFKY99CyKwxLUuj6Vnq14/QwXo9/QSQDpYnHEjo+uKn7QmLsHqWw0K9uYNfNAXt4BZimX/zDg6jZtzeXg== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-channel-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.1.1.tgz#e205eddd93e49d17d9e0711a612b4bfc9810888f" + integrity sha512-fYr9IAqtaEr9AmaPaL3SLQVT3t3GQzl+n74gpNKyAVakDIm0nYQ/bimjdcAhJMDf1VGNSPg/xICneyuZg7Wxlg== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-common@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.1.1.tgz#27e6074584a7a3a8ca3f11f7ff2b7ff0f395bf2d" + integrity sha512-2hkS1Ia1FmAjCuYZ5JlG20/WgObqdsKtmK5YALAFGHIB4KSQ/Za1qazS+7GsG+E0F9UJivNWL1geUIcNqg5Qjg== + dependencies: + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-core-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.1.1.tgz#30fb6a519cc1c6119c419c4811ce72c260217d9e" + integrity sha512-4t4wf6SKqIcWEQDPg/uOhm+BxtHhu/AFreyEoYZmMfcxzAu33h1FtTQRtxBNbYH1+thiNZCh80yUpnT7d9Hrlw== + dependencies: + tslib "^1.9.3" + +"@microsoft/applicationinsights-dependencies-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-2.1.1.tgz#8154c3efcb24617d015d0bce7c2cc47797a8d3c4" + integrity sha512-yhb4EToBp+aI+qLo0h5NDNtoo3sDFV60uyIOK843YjzXqVotcXX/lRShlghTkJtYH09QhrdzDjViUHnD4sMFSQ== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-properties-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-2.1.1.tgz#ca34232766eb16167b5d87693e2ae5d94f2a1559" + integrity sha512-8l+/ppw6xKTam2RL4EHZ52Lcf217olw81j6kyBNKtIcGwSnLNHrFwEeF3vBWIteG2JKzlg1GhGjrkB3oxXsV2g== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-web@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web/-/applicationinsights-web-2.1.1.tgz#1a44eddda7c244b88d9eb052dab6c855682e4f05" + integrity sha512-crvhCkNsNxkFuPWmttyWNSAA96D5FxBtKS6UA9MV9f9XHevTfchf/E3AuU9JZcsXufWMQLwLrUQ9ZiA1QJ0EWA== + dependencies: + "@microsoft/applicationinsights-analytics-js" "2.1.1" + "@microsoft/applicationinsights-channel-js" "2.1.1" + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + "@microsoft/applicationinsights-dependencies-js" "2.1.1" + "@microsoft/applicationinsights-properties-js" "2.1.1" + nan@^2.14.0: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" @@ -24,6 +87,11 @@ semver-umd@^5.5.3: resolved "https://registry.yarnpkg.com/semver-umd/-/semver-umd-5.5.3.tgz#b64d7a2d4f5a717b369d56e31940a38e47e34d1e" integrity sha512-HOnQrn2iKnVe/xlqCTzMXQdvSz3rPbD0DmQXYuQ+oK1dpptGFfPghonQrx5JHl2O7EJwDqtQnjhE7ME23q6ngw== +tslib@^1.9.3: + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + vscode-textmate@^4.1.1: version "4.2.2" resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-4.2.2.tgz#0b4dabc69a6fba79a065cb6b615f66eac07c8f4c" diff --git a/remote/yarn.lock b/remote/yarn.lock index 4c1a99d899c..50e4ef9fb42 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -2,6 +2,69 @@ # yarn lockfile v1 +"@microsoft/applicationinsights-analytics-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-2.1.1.tgz#6d09c1915f808026e2d45165d04802f09affed59" + integrity sha512-VKIutoFKY99CyKwxLUuj6Vnq14/QwXo9/QSQDpYnHEjo+uKn7QmLsHqWw0K9uYNfNAXt4BZimX/zDg6jZtzeXg== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-channel-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.1.1.tgz#e205eddd93e49d17d9e0711a612b4bfc9810888f" + integrity sha512-fYr9IAqtaEr9AmaPaL3SLQVT3t3GQzl+n74gpNKyAVakDIm0nYQ/bimjdcAhJMDf1VGNSPg/xICneyuZg7Wxlg== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-common@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.1.1.tgz#27e6074584a7a3a8ca3f11f7ff2b7ff0f395bf2d" + integrity sha512-2hkS1Ia1FmAjCuYZ5JlG20/WgObqdsKtmK5YALAFGHIB4KSQ/Za1qazS+7GsG+E0F9UJivNWL1geUIcNqg5Qjg== + dependencies: + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-core-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.1.1.tgz#30fb6a519cc1c6119c419c4811ce72c260217d9e" + integrity sha512-4t4wf6SKqIcWEQDPg/uOhm+BxtHhu/AFreyEoYZmMfcxzAu33h1FtTQRtxBNbYH1+thiNZCh80yUpnT7d9Hrlw== + dependencies: + tslib "^1.9.3" + +"@microsoft/applicationinsights-dependencies-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-2.1.1.tgz#8154c3efcb24617d015d0bce7c2cc47797a8d3c4" + integrity sha512-yhb4EToBp+aI+qLo0h5NDNtoo3sDFV60uyIOK843YjzXqVotcXX/lRShlghTkJtYH09QhrdzDjViUHnD4sMFSQ== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-properties-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-2.1.1.tgz#ca34232766eb16167b5d87693e2ae5d94f2a1559" + integrity sha512-8l+/ppw6xKTam2RL4EHZ52Lcf217olw81j6kyBNKtIcGwSnLNHrFwEeF3vBWIteG2JKzlg1GhGjrkB3oxXsV2g== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-web@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web/-/applicationinsights-web-2.1.1.tgz#1a44eddda7c244b88d9eb052dab6c855682e4f05" + integrity sha512-crvhCkNsNxkFuPWmttyWNSAA96D5FxBtKS6UA9MV9f9XHevTfchf/E3AuU9JZcsXufWMQLwLrUQ9ZiA1QJ0EWA== + dependencies: + "@microsoft/applicationinsights-analytics-js" "2.1.1" + "@microsoft/applicationinsights-channel-js" "2.1.1" + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + "@microsoft/applicationinsights-dependencies-js" "2.1.1" + "@microsoft/applicationinsights-properties-js" "2.1.1" + agent-base@4, agent-base@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.0.tgz#9838b5c3392b962bad031e6a4c5e1024abec45ce" @@ -1024,6 +1087,11 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" +tslib@^1.9.3: + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + typechecker@^4.3.0: version "4.7.0" resolved "https://registry.yarnpkg.com/typechecker/-/typechecker-4.7.0.tgz#5249f427358f45b7250c4924fd4d01ed9ba435e9" diff --git a/src/typings/applicationinsights-web.d.ts b/src/typings/applicationinsights-web.d.ts new file mode 100644 index 00000000000..e6401fc14be --- /dev/null +++ b/src/typings/applicationinsights-web.d.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. + *--------------------------------------------------------------------------------------------*/ + +declare module 'applicationinsights-web' { + export interface IConfig { + instrumentationKey?: string; + endpointUrl?: string; + emitLineDelimitedJson?: boolean; + accountId?: string; + sessionRenewalMs?: number; + sessionExpirationMs?: number; + maxBatchSizeInBytes?: number; + maxBatchInterval?: number; + enableDebug?: boolean; + disableExceptionTracking?: boolean; + disableTelemetry?: boolean; + verboseLogging?: boolean; + diagnosticLogInterval?: number; + samplingPercentage?: number; + autoTrackPageVisitTime?: boolean; + disableAjaxTracking?: boolean; + overridePageViewDuration?: boolean; + maxAjaxCallsPerView?: number; + disableDataLossAnalysis?: boolean; + disableCorrelationHeaders?: boolean; + correlationHeaderExcludedDomains?: string[]; + disableFlushOnBeforeUnload?: boolean; + enableSessionStorageBuffer?: boolean; + isCookieUseDisabled?: boolean; + cookieDomain?: string; + isRetryDisabled?: boolean; + url?: string; + isStorageUseDisabled?: boolean; + isBeaconApiDisabled?: boolean; + sdkExtension?: string; + isBrowserLinkTrackingEnabled?: boolean; + appId?: string; + enableCorsCorrelation?: boolean; + } + + export interface ISnippet { + config: IConfig; + } + + export interface IEventTelemetry { + name: string; + properties?: { [key: string]: string }; + measurements?: { [key: string]: number }; + } + + export class ApplicationInsights { + constructor(config: ISnippet); + loadAppInsights(): void; + trackEvent(data: IEventTelemetry): void; + flush(): void; + } +} diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index 5b06636edbb..9b8e42d3a3b 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -24,9 +24,6 @@ - - - diff --git a/src/vs/code/browser/workbench/workbench.js b/src/vs/code/browser/workbench/workbench.js index 65fae7c82df..56226314d9e 100644 --- a/src/vs/code/browser/workbench/workbench.js +++ b/src/vs/code/browser/workbench/workbench.js @@ -16,6 +16,7 @@ 'xterm-addon-search': `${window.location.origin}/node_modules/xterm-addon-search/lib/xterm-addon-search.js`, 'xterm-addon-web-links': `${window.location.origin}/node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js`, 'semver-umd': `${window.location.origin}/node_modules/semver-umd/lib/semver-umd.js`, + 'applicationinsights-web': `${window.location.origin}/node_modules/@microsoft/applicationinsights-web/dist/applicationinsights-web.js`, } }); @@ -24,4 +25,4 @@ api.create(document.body, options); }); -})(); \ No newline at end of file +})(); diff --git a/src/vs/workbench/services/telemetry/browser/telemetryService.ts b/src/vs/workbench/services/telemetry/browser/telemetryService.ts index 652aaf3a2de..446040c23d2 100644 --- a/src/vs/workbench/services/telemetry/browser/telemetryService.ts +++ b/src/vs/workbench/services/telemetry/browser/telemetryService.ts @@ -15,67 +15,10 @@ import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/pla import { IStorageService } from 'vs/platform/storage/common/storage'; import { resolveWorkbenchCommonProperties } from 'vs/platform/telemetry/browser/workbenchCommonProperties'; import { IProductService } from 'vs/platform/product/common/product'; - -interface IConfig { - instrumentationKey?: string; - endpointUrl?: string; - emitLineDelimitedJson?: boolean; - accountId?: string; - sessionRenewalMs?: number; - sessionExpirationMs?: number; - maxBatchSizeInBytes?: number; - maxBatchInterval?: number; - enableDebug?: boolean; - disableExceptionTracking?: boolean; - disableTelemetry?: boolean; - verboseLogging?: boolean; - diagnosticLogInterval?: number; - samplingPercentage?: number; - autoTrackPageVisitTime?: boolean; - disableAjaxTracking?: boolean; - overridePageViewDuration?: boolean; - maxAjaxCallsPerView?: number; - disableDataLossAnalysis?: boolean; - disableCorrelationHeaders?: boolean; - correlationHeaderExcludedDomains?: string[]; - disableFlushOnBeforeUnload?: boolean; - enableSessionStorageBuffer?: boolean; - isCookieUseDisabled?: boolean; - cookieDomain?: string; - isRetryDisabled?: boolean; - url?: string; - isStorageUseDisabled?: boolean; - isBeaconApiDisabled?: boolean; - sdkExtension?: string; - isBrowserLinkTrackingEnabled?: boolean; - appId?: string; - enableCorsCorrelation?: boolean; -} - -declare class Microsoft { - public static ApplicationInsights: { - Initialization: { - new(init: { config: IConfig }): AppInsights; - } - }; -} - -declare interface IAppInsightsClient { - config: IConfig; - - /** Log a user action or other occurrence. */ - trackEvent: (name: string, properties?: { [key: string]: string }, measurements?: { [key: string]: number }) => void; - - /** Immediately send all queued telemetry. Synchronous. */ - flush(): void; -} - -interface AppInsights { - loadAppInsights: () => IAppInsightsClient; -} +import { ApplicationInsights } from 'applicationinsights-web'; export class WebTelemetryAppender implements ITelemetryAppender { - private _aiClient?: IAppInsightsClient; + private _aiClient?: ApplicationInsights; constructor(aiKey: string, private _logService: ILogService) { const initConfig = { @@ -89,8 +32,8 @@ export class WebTelemetryAppender implements ITelemetryAppender { } }; - const appInsights = new Microsoft.ApplicationInsights.Initialization(initConfig); - this._aiClient = appInsights.loadAppInsights(); + this._aiClient = new ApplicationInsights(initConfig); + this._aiClient.loadAppInsights(); } log(eventName: string, data: any): void { @@ -101,7 +44,11 @@ export class WebTelemetryAppender implements ITelemetryAppender { data = validateTelemetryData(data); this._logService.trace(`telemetry/${eventName}`, data); - this._aiClient.trackEvent('monacoworkbench/' + eventName, data.properties, data.measurements); + this._aiClient.trackEvent({ + name: 'monacoworkbench/' + eventName, + properties: data.properties, + measurements: data.measurements + }); } flush(): Promise { @@ -167,4 +114,4 @@ export class TelemetryService extends Disposable implements ITelemetryService { } } -registerSingleton(ITelemetryService, TelemetryService); \ No newline at end of file +registerSingleton(ITelemetryService, TelemetryService); diff --git a/tslint.json b/tslint.json index 155bd9a4115..1ba5a708243 100644 --- a/tslint.json +++ b/tslint.json @@ -446,7 +446,8 @@ "**/vs/workbench/{common,browser}/**", "**/vs/workbench/services/**/{common,browser}/**", "vscode-textmate", - "onigasm-umd" + "onigasm-umd", + "applicationinsights-web" ] }, { diff --git a/yarn.lock b/yarn.lock index 1f75b23ba87..717f895a416 100644 --- a/yarn.lock +++ b/yarn.lock @@ -95,6 +95,69 @@ lodash "^4.17.11" to-fast-properties "^2.0.0" +"@microsoft/applicationinsights-analytics-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-2.1.1.tgz#6d09c1915f808026e2d45165d04802f09affed59" + integrity sha512-VKIutoFKY99CyKwxLUuj6Vnq14/QwXo9/QSQDpYnHEjo+uKn7QmLsHqWw0K9uYNfNAXt4BZimX/zDg6jZtzeXg== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-channel-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.1.1.tgz#e205eddd93e49d17d9e0711a612b4bfc9810888f" + integrity sha512-fYr9IAqtaEr9AmaPaL3SLQVT3t3GQzl+n74gpNKyAVakDIm0nYQ/bimjdcAhJMDf1VGNSPg/xICneyuZg7Wxlg== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-common@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.1.1.tgz#27e6074584a7a3a8ca3f11f7ff2b7ff0f395bf2d" + integrity sha512-2hkS1Ia1FmAjCuYZ5JlG20/WgObqdsKtmK5YALAFGHIB4KSQ/Za1qazS+7GsG+E0F9UJivNWL1geUIcNqg5Qjg== + dependencies: + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-core-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.1.1.tgz#30fb6a519cc1c6119c419c4811ce72c260217d9e" + integrity sha512-4t4wf6SKqIcWEQDPg/uOhm+BxtHhu/AFreyEoYZmMfcxzAu33h1FtTQRtxBNbYH1+thiNZCh80yUpnT7d9Hrlw== + dependencies: + tslib "^1.9.3" + +"@microsoft/applicationinsights-dependencies-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-2.1.1.tgz#8154c3efcb24617d015d0bce7c2cc47797a8d3c4" + integrity sha512-yhb4EToBp+aI+qLo0h5NDNtoo3sDFV60uyIOK843YjzXqVotcXX/lRShlghTkJtYH09QhrdzDjViUHnD4sMFSQ== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-properties-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-2.1.1.tgz#ca34232766eb16167b5d87693e2ae5d94f2a1559" + integrity sha512-8l+/ppw6xKTam2RL4EHZ52Lcf217olw81j6kyBNKtIcGwSnLNHrFwEeF3vBWIteG2JKzlg1GhGjrkB3oxXsV2g== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-web@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web/-/applicationinsights-web-2.1.1.tgz#1a44eddda7c244b88d9eb052dab6c855682e4f05" + integrity sha512-crvhCkNsNxkFuPWmttyWNSAA96D5FxBtKS6UA9MV9f9XHevTfchf/E3AuU9JZcsXufWMQLwLrUQ9ZiA1QJ0EWA== + dependencies: + "@microsoft/applicationinsights-analytics-js" "2.1.1" + "@microsoft/applicationinsights-channel-js" "2.1.1" + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + "@microsoft/applicationinsights-dependencies-js" "2.1.1" + "@microsoft/applicationinsights-properties-js" "2.1.1" + "@types/commander@^2.11.0": version "2.12.2" resolved "https://registry.yarnpkg.com/@types/commander/-/commander-2.12.2.tgz#183041a23842d4281478fa5d23c5ca78e6fd08ae" @@ -8961,6 +9024,11 @@ tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== +tslib@^1.9.3: + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + tslint@^5.16.0: version "5.16.0" resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.16.0.tgz#ae61f9c5a98d295b9a4f4553b1b1e831c1984d67" From 0d740b99131b292d4195d76c0006e7c11921798a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 9 Aug 2019 10:41:07 -0700 Subject: [PATCH 424/861] Enable passing tests --- test/smoke/src/main.ts | 12 +++++++++++- test/smoke/src/vscode/puppeteer-driver.ts | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/test/smoke/src/main.ts b/test/smoke/src/main.ts index 34364d39ded..761684e4104 100644 --- a/test/smoke/src/main.ts +++ b/test/smoke/src/main.ts @@ -279,9 +279,19 @@ describe('Running Code', () => { } if (opts.web) { + // setupDataLossTests(); setupDataExplorerTests(); - setupDataPreferencesTests(); + // setupDataPreferencesTests(); + setupDataSearchTests(); + setupDataCSSTests(); + // setupDataEditorTests(); + // setupDataDebugTests(); + // setupDataGitTests(); + // setupDataStatusbarTests(); + // setupDataExtensionTests(); setupTerminalTests(); + // setupDataMultirootTests(); + // setupDataLocalizationTests(); return; } diff --git a/test/smoke/src/vscode/puppeteer-driver.ts b/test/smoke/src/vscode/puppeteer-driver.ts index fbe7b26db47..97fe587c902 100644 --- a/test/smoke/src/vscode/puppeteer-driver.ts +++ b/test/smoke/src/vscode/puppeteer-driver.ts @@ -11,6 +11,7 @@ const height = 800; const vscodeToPuppeteerKey = { cmd: 'Meta', ctrl: 'Control', + shift: 'Shift', enter: 'Enter', escape: 'Escape', right: 'ArrowRight', From ce8cd89e000ce9ee311bbf3d274487d5cf87c680 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Fri, 9 Aug 2019 10:55:03 -0700 Subject: [PATCH 425/861] disable grid for webview --- src/vs/workbench/browser/workbench.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index abb2f710aa5..7c36ea51726 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -237,7 +237,7 @@ import { isMacintosh, isWindows, isLinux, isWeb } from 'vs/base/common/platform' 'workbench.useExperimentalGridLayout': { 'type': 'boolean', 'description': nls.localize('workbench.useExperimentalGridLayout', "Enables the grid layout for the workbench. This setting may enable additional layout options for workbench components."), - 'default': true, + 'default': false, 'scope': ConfigurationScope.APPLICATION } } From d224d533c872b78ecbc8ca26dbd796993df31887 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 9 Aug 2019 11:06:01 -0700 Subject: [PATCH 426/861] Add all passing web tests --- test/smoke/src/main.ts | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/test/smoke/src/main.ts b/test/smoke/src/main.ts index 761684e4104..9bf6d4a7786 100644 --- a/test/smoke/src/main.ts +++ b/test/smoke/src/main.ts @@ -278,35 +278,18 @@ describe('Running Code', () => { }); } - if (opts.web) { - // setupDataLossTests(); - setupDataExplorerTests(); - // setupDataPreferencesTests(); - setupDataSearchTests(); - setupDataCSSTests(); - // setupDataEditorTests(); - // setupDataDebugTests(); - // setupDataGitTests(); - // setupDataStatusbarTests(); - // setupDataExtensionTests(); - setupTerminalTests(); - // setupDataMultirootTests(); - // setupDataLocalizationTests(); - return; - } - - setupDataLossTests(); + if (!opts.web) { setupDataLossTests(); } setupDataExplorerTests(); - setupDataPreferencesTests(); + if (!opts.web) { setupDataPreferencesTests(); } setupDataSearchTests(); setupDataCSSTests(); setupDataEditorTests(); - setupDataDebugTests(); + if (!opts.web) { setupDataDebugTests(); } setupDataGitTests(); setupDataStatusbarTests(); setupDataExtensionTests(); setupTerminalTests(); - setupDataMultirootTests(); + if (!opts.web) { setupDataMultirootTests(); } setupDataLocalizationTests(); }); From d2ed5fb5e5c1784926e2a93571e18e7f9bcc6b1f Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 9 Aug 2019 11:11:54 -0700 Subject: [PATCH 427/861] Make tslint.json jsonc language Fixes #78821 --- extensions/json/package.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/extensions/json/package.json b/extensions/json/package.json index 1606f6a3d64..e23e86b14a6 100644 --- a/extensions/json/package.json +++ b/extensions/json/package.json @@ -50,7 +50,8 @@ ".babelrc", ".jsonc", ".eslintrc", - ".eslintrc.json" + ".eslintrc.json", + "tslint.json" ], "configuration": "./language-configuration.json" } @@ -74,4 +75,4 @@ } ] } -} \ No newline at end of file +} From eff2a4a4540f521e9e1d6bac9db39793e5b9f21a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 9 Aug 2019 11:14:36 -0700 Subject: [PATCH 428/861] Fix tslint complaining about xterm import --- src/vs/platform/driver/browser/baseDriver.ts | 2 -- tslint.json | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/vs/platform/driver/browser/baseDriver.ts b/src/vs/platform/driver/browser/baseDriver.ts index 7b7d3057db6..fe6fc6e1e46 100644 --- a/src/vs/platform/driver/browser/baseDriver.ts +++ b/src/vs/platform/driver/browser/baseDriver.ts @@ -4,8 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import { getTopLeftOffset } from 'vs/base/browser/dom'; -// TODO: Allow this -// tslint:disable-next-line: import-patterns import { Terminal } from 'xterm'; import { coalesce } from 'vs/base/common/arrays'; import { IElement, IWindowDriver } from 'vs/platform/driver/common/driver'; diff --git a/tslint.json b/tslint.json index 155bd9a4115..b67d9aeeb5c 100644 --- a/tslint.json +++ b/tslint.json @@ -175,7 +175,8 @@ "vs/css!./**/*", "**/vs/base/{common,browser}/**", "**/vs/base/parts/*/{common,browser}/**", - "**/vs/platform/*/{common,browser}/**" + "**/vs/platform/*/{common,browser}/**", + "xterm" // xterm is strictly a browser-only component ] }, { From b7bc1563193b05e1d5f1e5173b5e968f24ebbc3c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 9 Aug 2019 11:15:45 -0700 Subject: [PATCH 429/861] Remove resolved TODOs --- test/smoke/src/application.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/smoke/src/application.ts b/test/smoke/src/application.ts index 52fe19dd834..1daaf4527c3 100644 --- a/test/smoke/src/application.ts +++ b/test/smoke/src/application.ts @@ -66,7 +66,6 @@ export class Application { async start(expectWalkthroughPart = true): Promise { await this._start(); - // TODO: web doesn't show explorer? await this.code.waitForElement('.explorer-folders-view'); if (expectWalkthroughPart) { @@ -139,7 +138,6 @@ export class Application { } await this.code.waitForWindowIds(ids => ids.length > 0); - // TODO: Remove on web? await this.code.waitForElement('.monaco-workbench'); if (this.remote) { From 7721d6e373822fb9a9e9aa3d9e142a211acaff1e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 9 Aug 2019 11:21:40 -0700 Subject: [PATCH 430/861] Support launching web smoketests in headless mode --- test/smoke/src/application.ts | 3 ++- test/smoke/src/main.ts | 6 ++++-- test/smoke/src/vscode/code.ts | 7 ++++--- test/smoke/src/vscode/puppeteer-driver.ts | 4 ++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/test/smoke/src/application.ts b/test/smoke/src/application.ts index 1daaf4527c3..874a17421b2 100644 --- a/test/smoke/src/application.ts +++ b/test/smoke/src/application.ts @@ -125,7 +125,8 @@ export class Application { log: this.options.log, extraArgs, remote: this.options.remote, - web: this.options.web + web: this.options.web, + headless: this.options.headless }); this._workbench = new Workbench(this._code, this.userDataPath); diff --git a/test/smoke/src/main.ts b/test/smoke/src/main.ts index 9bf6d4a7786..bb75ee6066b 100644 --- a/test/smoke/src/main.ts +++ b/test/smoke/src/main.ts @@ -52,7 +52,8 @@ const opts = minimist(args, { boolean: [ 'verbose', 'remote', - 'web' + 'web', + 'headless' ], default: { verbose: false @@ -214,7 +215,8 @@ function createOptions(): ApplicationOptions { log, screenshotsPath, remote: opts.remote, - web: opts.web + web: opts.web, + headless: opts.headless }; } diff --git a/test/smoke/src/vscode/code.ts b/test/smoke/src/vscode/code.ts index da5326e929c..f381ed002e9 100644 --- a/test/smoke/src/vscode/code.ts +++ b/test/smoke/src/vscode/code.ts @@ -101,6 +101,8 @@ export interface SpawnOptions { remote?: boolean; /** Run in the web */ web?: boolean; + /** Run in headless mode (only applies when web is true) */ + headless?: boolean; } async function createDriverHandle(): Promise { @@ -172,7 +174,7 @@ export async function spawn(options: SpawnOptions): Promise { if (options.web) { launch(args); - connectDriver = connectPuppeteerDriver; + connectDriver = connectPuppeteerDriver.bind(connectPuppeteerDriver, !!options.headless); } else { const spawnOptions: cp.SpawnOptions = { env }; child = cp.spawn(electronPath, args, spawnOptions); @@ -180,7 +182,6 @@ export async function spawn(options: SpawnOptions): Promise { child.once('exit', () => instances.delete(child!)); connectDriver = connectElectronDriver; } - return connect(connectDriver, child, outPath, handle, options.logger); } @@ -379,4 +380,4 @@ export function findElements(element: IElement, fn: (element: IElement) => boole } return result; -} \ No newline at end of file +} diff --git a/test/smoke/src/vscode/puppeteer-driver.ts b/test/smoke/src/vscode/puppeteer-driver.ts index 97fe587c902..0397c313436 100644 --- a/test/smoke/src/vscode/puppeteer-driver.ts +++ b/test/smoke/src/vscode/puppeteer-driver.ts @@ -183,12 +183,12 @@ export function launch(_args): void { // TODO: Move puppeteer launch here } -export function connect(outPath: string, handle: string): Promise<{ client: IDisposable, driver: IDriver }> { +export function connect(headless: boolean, outPath: string, handle: string): Promise<{ client: IDisposable, driver: IDriver }> { return new Promise(async (c) => { const browser = await puppeteer.launch({ // Run in Edge dev on macOS // executablePath: '/Applications/Microsoft\ Edge\ Dev.app/Contents/MacOS/Microsoft\ Edge\ Dev', - headless: false, + headless, slowMo: 80, args: [`--window-size=${width},${height}`] }); From 52333e3769d63c152f7fba4108dec316b2c11db4 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 9 Aug 2019 11:30:29 -0700 Subject: [PATCH 431/861] Remove strong typing of xterm access in smoke tests This makes the monaco check happy, while we could add xterm to the list of typings in the monaco tsconfig it's probably too risky. --- src/tsconfig.monaco.json | 2 +- src/vs/platform/driver/browser/baseDriver.ts | 5 ++--- tslint.json | 3 +-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/tsconfig.monaco.json b/src/tsconfig.monaco.json index 32983503724..aa0af48b342 100644 --- a/src/tsconfig.monaco.json +++ b/src/tsconfig.monaco.json @@ -14,7 +14,7 @@ }, "include": [ "typings/require.d.ts", - "./typings/require-monaco.d.ts", + "typings/require-monaco.d.ts", "typings/thenable.d.ts", "typings/es6-promise.d.ts", "typings/lib.es2018.promise.d.ts", diff --git a/src/vs/platform/driver/browser/baseDriver.ts b/src/vs/platform/driver/browser/baseDriver.ts index fe6fc6e1e46..df59dd6e879 100644 --- a/src/vs/platform/driver/browser/baseDriver.ts +++ b/src/vs/platform/driver/browser/baseDriver.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import { getTopLeftOffset } from 'vs/base/browser/dom'; -import { Terminal } from 'xterm'; import { coalesce } from 'vs/base/common/arrays'; import { IElement, IWindowDriver } from 'vs/platform/driver/common/driver'; @@ -129,7 +128,7 @@ export abstract class BaseWindowDriver implements IWindowDriver { throw new Error(`Terminal not found: ${selector}`); } - const xterm: Terminal = (element as any).xterm; + const xterm = (element as any).xterm; if (!xterm) { throw new Error(`Xterm not found: ${selector}`); @@ -151,7 +150,7 @@ export abstract class BaseWindowDriver implements IWindowDriver { throw new Error(`Element not found: ${selector}`); } - const xterm: Terminal = (element as any).xterm; + const xterm = (element as any).xterm; if (!xterm) { throw new Error(`Xterm not found: ${selector}`); diff --git a/tslint.json b/tslint.json index b67d9aeeb5c..155bd9a4115 100644 --- a/tslint.json +++ b/tslint.json @@ -175,8 +175,7 @@ "vs/css!./**/*", "**/vs/base/{common,browser}/**", "**/vs/base/parts/*/{common,browser}/**", - "**/vs/platform/*/{common,browser}/**", - "xterm" // xterm is strictly a browser-only component + "**/vs/platform/*/{common,browser}/**" ] }, { From abb40b14ff689d109b6f7166c96726839d5b0b38 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Fri, 9 Aug 2019 11:44:52 -0700 Subject: [PATCH 432/861] Revert "Use application insights module instead of script tag, fixes https://github.com/microsoft/vscode/issues/78475" This reverts commit 803e140a230c85f0329154d1f2fdbb971082d1df. --- package.json | 1 - remote/package.json | 1 - remote/web/package.json | 1 - remote/web/yarn.lock | 68 ----------------- remote/yarn.lock | 68 ----------------- src/typings/applicationinsights-web.d.ts | 59 --------------- src/vs/code/browser/workbench/workbench.html | 3 + src/vs/code/browser/workbench/workbench.js | 3 +- .../telemetry/browser/telemetryService.ts | 73 ++++++++++++++++--- tslint.json | 3 +- yarn.lock | 68 ----------------- 11 files changed, 68 insertions(+), 280 deletions(-) delete mode 100644 src/typings/applicationinsights-web.d.ts diff --git a/package.json b/package.json index 2b4d2a8ee87..404e64edf2b 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "update-distro": "node build/npm/update-distro.js" }, "dependencies": { - "@microsoft/applicationinsights-web": "^2.1.1", "applicationinsights": "1.0.8", "graceful-fs": "4.1.11", "http-proxy-agent": "^2.1.0", diff --git a/remote/package.json b/remote/package.json index 662e9fb7c2d..a057fcb87cd 100644 --- a/remote/package.json +++ b/remote/package.json @@ -2,7 +2,6 @@ "name": "vscode-reh", "version": "0.0.0", "dependencies": { - "@microsoft/applicationinsights-web": "^2.1.1", "applicationinsights": "1.0.8", "getmac": "1.4.1", "graceful-fs": "4.1.11", diff --git a/remote/web/package.json b/remote/web/package.json index f54afe1a3e6..c7a487b6c2d 100644 --- a/remote/web/package.json +++ b/remote/web/package.json @@ -2,7 +2,6 @@ "name": "vscode-web", "version": "0.0.0", "dependencies": { - "@microsoft/applicationinsights-web": "^2.1.1", "onigasm-umd": "^2.2.2", "vscode-textmate": "^4.1.1", "xterm": "3.15.0-beta67", diff --git a/remote/web/yarn.lock b/remote/web/yarn.lock index 23ad784a554..b624eb37290 100644 --- a/remote/web/yarn.lock +++ b/remote/web/yarn.lock @@ -2,69 +2,6 @@ # yarn lockfile v1 -"@microsoft/applicationinsights-analytics-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-2.1.1.tgz#6d09c1915f808026e2d45165d04802f09affed59" - integrity sha512-VKIutoFKY99CyKwxLUuj6Vnq14/QwXo9/QSQDpYnHEjo+uKn7QmLsHqWw0K9uYNfNAXt4BZimX/zDg6jZtzeXg== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-channel-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.1.1.tgz#e205eddd93e49d17d9e0711a612b4bfc9810888f" - integrity sha512-fYr9IAqtaEr9AmaPaL3SLQVT3t3GQzl+n74gpNKyAVakDIm0nYQ/bimjdcAhJMDf1VGNSPg/xICneyuZg7Wxlg== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-common@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.1.1.tgz#27e6074584a7a3a8ca3f11f7ff2b7ff0f395bf2d" - integrity sha512-2hkS1Ia1FmAjCuYZ5JlG20/WgObqdsKtmK5YALAFGHIB4KSQ/Za1qazS+7GsG+E0F9UJivNWL1geUIcNqg5Qjg== - dependencies: - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-core-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.1.1.tgz#30fb6a519cc1c6119c419c4811ce72c260217d9e" - integrity sha512-4t4wf6SKqIcWEQDPg/uOhm+BxtHhu/AFreyEoYZmMfcxzAu33h1FtTQRtxBNbYH1+thiNZCh80yUpnT7d9Hrlw== - dependencies: - tslib "^1.9.3" - -"@microsoft/applicationinsights-dependencies-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-2.1.1.tgz#8154c3efcb24617d015d0bce7c2cc47797a8d3c4" - integrity sha512-yhb4EToBp+aI+qLo0h5NDNtoo3sDFV60uyIOK843YjzXqVotcXX/lRShlghTkJtYH09QhrdzDjViUHnD4sMFSQ== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-properties-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-2.1.1.tgz#ca34232766eb16167b5d87693e2ae5d94f2a1559" - integrity sha512-8l+/ppw6xKTam2RL4EHZ52Lcf217olw81j6kyBNKtIcGwSnLNHrFwEeF3vBWIteG2JKzlg1GhGjrkB3oxXsV2g== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-web@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web/-/applicationinsights-web-2.1.1.tgz#1a44eddda7c244b88d9eb052dab6c855682e4f05" - integrity sha512-crvhCkNsNxkFuPWmttyWNSAA96D5FxBtKS6UA9MV9f9XHevTfchf/E3AuU9JZcsXufWMQLwLrUQ9ZiA1QJ0EWA== - dependencies: - "@microsoft/applicationinsights-analytics-js" "2.1.1" - "@microsoft/applicationinsights-channel-js" "2.1.1" - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - "@microsoft/applicationinsights-dependencies-js" "2.1.1" - "@microsoft/applicationinsights-properties-js" "2.1.1" - nan@^2.14.0: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" @@ -87,11 +24,6 @@ semver-umd@^5.5.3: resolved "https://registry.yarnpkg.com/semver-umd/-/semver-umd-5.5.3.tgz#b64d7a2d4f5a717b369d56e31940a38e47e34d1e" integrity sha512-HOnQrn2iKnVe/xlqCTzMXQdvSz3rPbD0DmQXYuQ+oK1dpptGFfPghonQrx5JHl2O7EJwDqtQnjhE7ME23q6ngw== -tslib@^1.9.3: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== - vscode-textmate@^4.1.1: version "4.2.2" resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-4.2.2.tgz#0b4dabc69a6fba79a065cb6b615f66eac07c8f4c" diff --git a/remote/yarn.lock b/remote/yarn.lock index 50e4ef9fb42..4c1a99d899c 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -2,69 +2,6 @@ # yarn lockfile v1 -"@microsoft/applicationinsights-analytics-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-2.1.1.tgz#6d09c1915f808026e2d45165d04802f09affed59" - integrity sha512-VKIutoFKY99CyKwxLUuj6Vnq14/QwXo9/QSQDpYnHEjo+uKn7QmLsHqWw0K9uYNfNAXt4BZimX/zDg6jZtzeXg== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-channel-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.1.1.tgz#e205eddd93e49d17d9e0711a612b4bfc9810888f" - integrity sha512-fYr9IAqtaEr9AmaPaL3SLQVT3t3GQzl+n74gpNKyAVakDIm0nYQ/bimjdcAhJMDf1VGNSPg/xICneyuZg7Wxlg== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-common@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.1.1.tgz#27e6074584a7a3a8ca3f11f7ff2b7ff0f395bf2d" - integrity sha512-2hkS1Ia1FmAjCuYZ5JlG20/WgObqdsKtmK5YALAFGHIB4KSQ/Za1qazS+7GsG+E0F9UJivNWL1geUIcNqg5Qjg== - dependencies: - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-core-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.1.1.tgz#30fb6a519cc1c6119c419c4811ce72c260217d9e" - integrity sha512-4t4wf6SKqIcWEQDPg/uOhm+BxtHhu/AFreyEoYZmMfcxzAu33h1FtTQRtxBNbYH1+thiNZCh80yUpnT7d9Hrlw== - dependencies: - tslib "^1.9.3" - -"@microsoft/applicationinsights-dependencies-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-2.1.1.tgz#8154c3efcb24617d015d0bce7c2cc47797a8d3c4" - integrity sha512-yhb4EToBp+aI+qLo0h5NDNtoo3sDFV60uyIOK843YjzXqVotcXX/lRShlghTkJtYH09QhrdzDjViUHnD4sMFSQ== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-properties-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-2.1.1.tgz#ca34232766eb16167b5d87693e2ae5d94f2a1559" - integrity sha512-8l+/ppw6xKTam2RL4EHZ52Lcf217olw81j6kyBNKtIcGwSnLNHrFwEeF3vBWIteG2JKzlg1GhGjrkB3oxXsV2g== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-web@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web/-/applicationinsights-web-2.1.1.tgz#1a44eddda7c244b88d9eb052dab6c855682e4f05" - integrity sha512-crvhCkNsNxkFuPWmttyWNSAA96D5FxBtKS6UA9MV9f9XHevTfchf/E3AuU9JZcsXufWMQLwLrUQ9ZiA1QJ0EWA== - dependencies: - "@microsoft/applicationinsights-analytics-js" "2.1.1" - "@microsoft/applicationinsights-channel-js" "2.1.1" - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - "@microsoft/applicationinsights-dependencies-js" "2.1.1" - "@microsoft/applicationinsights-properties-js" "2.1.1" - agent-base@4, agent-base@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.0.tgz#9838b5c3392b962bad031e6a4c5e1024abec45ce" @@ -1087,11 +1024,6 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" -tslib@^1.9.3: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== - typechecker@^4.3.0: version "4.7.0" resolved "https://registry.yarnpkg.com/typechecker/-/typechecker-4.7.0.tgz#5249f427358f45b7250c4924fd4d01ed9ba435e9" diff --git a/src/typings/applicationinsights-web.d.ts b/src/typings/applicationinsights-web.d.ts deleted file mode 100644 index e6401fc14be..00000000000 --- a/src/typings/applicationinsights-web.d.ts +++ /dev/null @@ -1,59 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -declare module 'applicationinsights-web' { - export interface IConfig { - instrumentationKey?: string; - endpointUrl?: string; - emitLineDelimitedJson?: boolean; - accountId?: string; - sessionRenewalMs?: number; - sessionExpirationMs?: number; - maxBatchSizeInBytes?: number; - maxBatchInterval?: number; - enableDebug?: boolean; - disableExceptionTracking?: boolean; - disableTelemetry?: boolean; - verboseLogging?: boolean; - diagnosticLogInterval?: number; - samplingPercentage?: number; - autoTrackPageVisitTime?: boolean; - disableAjaxTracking?: boolean; - overridePageViewDuration?: boolean; - maxAjaxCallsPerView?: number; - disableDataLossAnalysis?: boolean; - disableCorrelationHeaders?: boolean; - correlationHeaderExcludedDomains?: string[]; - disableFlushOnBeforeUnload?: boolean; - enableSessionStorageBuffer?: boolean; - isCookieUseDisabled?: boolean; - cookieDomain?: string; - isRetryDisabled?: boolean; - url?: string; - isStorageUseDisabled?: boolean; - isBeaconApiDisabled?: boolean; - sdkExtension?: string; - isBrowserLinkTrackingEnabled?: boolean; - appId?: string; - enableCorsCorrelation?: boolean; - } - - export interface ISnippet { - config: IConfig; - } - - export interface IEventTelemetry { - name: string; - properties?: { [key: string]: string }; - measurements?: { [key: string]: number }; - } - - export class ApplicationInsights { - constructor(config: ISnippet); - loadAppInsights(): void; - trackEvent(data: IEventTelemetry): void; - flush(): void; - } -} diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index 9b8e42d3a3b..5b06636edbb 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -24,6 +24,9 @@ + + + diff --git a/src/vs/code/browser/workbench/workbench.js b/src/vs/code/browser/workbench/workbench.js index 56226314d9e..65fae7c82df 100644 --- a/src/vs/code/browser/workbench/workbench.js +++ b/src/vs/code/browser/workbench/workbench.js @@ -16,7 +16,6 @@ 'xterm-addon-search': `${window.location.origin}/node_modules/xterm-addon-search/lib/xterm-addon-search.js`, 'xterm-addon-web-links': `${window.location.origin}/node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js`, 'semver-umd': `${window.location.origin}/node_modules/semver-umd/lib/semver-umd.js`, - 'applicationinsights-web': `${window.location.origin}/node_modules/@microsoft/applicationinsights-web/dist/applicationinsights-web.js`, } }); @@ -25,4 +24,4 @@ api.create(document.body, options); }); -})(); +})(); \ No newline at end of file diff --git a/src/vs/workbench/services/telemetry/browser/telemetryService.ts b/src/vs/workbench/services/telemetry/browser/telemetryService.ts index 446040c23d2..652aaf3a2de 100644 --- a/src/vs/workbench/services/telemetry/browser/telemetryService.ts +++ b/src/vs/workbench/services/telemetry/browser/telemetryService.ts @@ -15,10 +15,67 @@ import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/pla import { IStorageService } from 'vs/platform/storage/common/storage'; import { resolveWorkbenchCommonProperties } from 'vs/platform/telemetry/browser/workbenchCommonProperties'; import { IProductService } from 'vs/platform/product/common/product'; -import { ApplicationInsights } from 'applicationinsights-web'; + +interface IConfig { + instrumentationKey?: string; + endpointUrl?: string; + emitLineDelimitedJson?: boolean; + accountId?: string; + sessionRenewalMs?: number; + sessionExpirationMs?: number; + maxBatchSizeInBytes?: number; + maxBatchInterval?: number; + enableDebug?: boolean; + disableExceptionTracking?: boolean; + disableTelemetry?: boolean; + verboseLogging?: boolean; + diagnosticLogInterval?: number; + samplingPercentage?: number; + autoTrackPageVisitTime?: boolean; + disableAjaxTracking?: boolean; + overridePageViewDuration?: boolean; + maxAjaxCallsPerView?: number; + disableDataLossAnalysis?: boolean; + disableCorrelationHeaders?: boolean; + correlationHeaderExcludedDomains?: string[]; + disableFlushOnBeforeUnload?: boolean; + enableSessionStorageBuffer?: boolean; + isCookieUseDisabled?: boolean; + cookieDomain?: string; + isRetryDisabled?: boolean; + url?: string; + isStorageUseDisabled?: boolean; + isBeaconApiDisabled?: boolean; + sdkExtension?: string; + isBrowserLinkTrackingEnabled?: boolean; + appId?: string; + enableCorsCorrelation?: boolean; +} + +declare class Microsoft { + public static ApplicationInsights: { + Initialization: { + new(init: { config: IConfig }): AppInsights; + } + }; +} + +declare interface IAppInsightsClient { + config: IConfig; + + /** Log a user action or other occurrence. */ + trackEvent: (name: string, properties?: { [key: string]: string }, measurements?: { [key: string]: number }) => void; + + /** Immediately send all queued telemetry. Synchronous. */ + flush(): void; +} + +interface AppInsights { + loadAppInsights: () => IAppInsightsClient; +} export class WebTelemetryAppender implements ITelemetryAppender { - private _aiClient?: ApplicationInsights; + private _aiClient?: IAppInsightsClient; constructor(aiKey: string, private _logService: ILogService) { const initConfig = { @@ -32,8 +89,8 @@ export class WebTelemetryAppender implements ITelemetryAppender { } }; - this._aiClient = new ApplicationInsights(initConfig); - this._aiClient.loadAppInsights(); + const appInsights = new Microsoft.ApplicationInsights.Initialization(initConfig); + this._aiClient = appInsights.loadAppInsights(); } log(eventName: string, data: any): void { @@ -44,11 +101,7 @@ export class WebTelemetryAppender implements ITelemetryAppender { data = validateTelemetryData(data); this._logService.trace(`telemetry/${eventName}`, data); - this._aiClient.trackEvent({ - name: 'monacoworkbench/' + eventName, - properties: data.properties, - measurements: data.measurements - }); + this._aiClient.trackEvent('monacoworkbench/' + eventName, data.properties, data.measurements); } flush(): Promise { @@ -114,4 +167,4 @@ export class TelemetryService extends Disposable implements ITelemetryService { } } -registerSingleton(ITelemetryService, TelemetryService); +registerSingleton(ITelemetryService, TelemetryService); \ No newline at end of file diff --git a/tslint.json b/tslint.json index 1ba5a708243..155bd9a4115 100644 --- a/tslint.json +++ b/tslint.json @@ -446,8 +446,7 @@ "**/vs/workbench/{common,browser}/**", "**/vs/workbench/services/**/{common,browser}/**", "vscode-textmate", - "onigasm-umd", - "applicationinsights-web" + "onigasm-umd" ] }, { diff --git a/yarn.lock b/yarn.lock index 717f895a416..1f75b23ba87 100644 --- a/yarn.lock +++ b/yarn.lock @@ -95,69 +95,6 @@ lodash "^4.17.11" to-fast-properties "^2.0.0" -"@microsoft/applicationinsights-analytics-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-2.1.1.tgz#6d09c1915f808026e2d45165d04802f09affed59" - integrity sha512-VKIutoFKY99CyKwxLUuj6Vnq14/QwXo9/QSQDpYnHEjo+uKn7QmLsHqWw0K9uYNfNAXt4BZimX/zDg6jZtzeXg== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-channel-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.1.1.tgz#e205eddd93e49d17d9e0711a612b4bfc9810888f" - integrity sha512-fYr9IAqtaEr9AmaPaL3SLQVT3t3GQzl+n74gpNKyAVakDIm0nYQ/bimjdcAhJMDf1VGNSPg/xICneyuZg7Wxlg== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-common@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.1.1.tgz#27e6074584a7a3a8ca3f11f7ff2b7ff0f395bf2d" - integrity sha512-2hkS1Ia1FmAjCuYZ5JlG20/WgObqdsKtmK5YALAFGHIB4KSQ/Za1qazS+7GsG+E0F9UJivNWL1geUIcNqg5Qjg== - dependencies: - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-core-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.1.1.tgz#30fb6a519cc1c6119c419c4811ce72c260217d9e" - integrity sha512-4t4wf6SKqIcWEQDPg/uOhm+BxtHhu/AFreyEoYZmMfcxzAu33h1FtTQRtxBNbYH1+thiNZCh80yUpnT7d9Hrlw== - dependencies: - tslib "^1.9.3" - -"@microsoft/applicationinsights-dependencies-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-2.1.1.tgz#8154c3efcb24617d015d0bce7c2cc47797a8d3c4" - integrity sha512-yhb4EToBp+aI+qLo0h5NDNtoo3sDFV60uyIOK843YjzXqVotcXX/lRShlghTkJtYH09QhrdzDjViUHnD4sMFSQ== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-properties-js@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-2.1.1.tgz#ca34232766eb16167b5d87693e2ae5d94f2a1559" - integrity sha512-8l+/ppw6xKTam2RL4EHZ52Lcf217olw81j6kyBNKtIcGwSnLNHrFwEeF3vBWIteG2JKzlg1GhGjrkB3oxXsV2g== - dependencies: - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - tslib "^1.9.3" - -"@microsoft/applicationinsights-web@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web/-/applicationinsights-web-2.1.1.tgz#1a44eddda7c244b88d9eb052dab6c855682e4f05" - integrity sha512-crvhCkNsNxkFuPWmttyWNSAA96D5FxBtKS6UA9MV9f9XHevTfchf/E3AuU9JZcsXufWMQLwLrUQ9ZiA1QJ0EWA== - dependencies: - "@microsoft/applicationinsights-analytics-js" "2.1.1" - "@microsoft/applicationinsights-channel-js" "2.1.1" - "@microsoft/applicationinsights-common" "2.1.1" - "@microsoft/applicationinsights-core-js" "2.1.1" - "@microsoft/applicationinsights-dependencies-js" "2.1.1" - "@microsoft/applicationinsights-properties-js" "2.1.1" - "@types/commander@^2.11.0": version "2.12.2" resolved "https://registry.yarnpkg.com/@types/commander/-/commander-2.12.2.tgz#183041a23842d4281478fa5d23c5ca78e6fd08ae" @@ -9024,11 +8961,6 @@ tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== -tslib@^1.9.3: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== - tslint@^5.16.0: version "5.16.0" resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.16.0.tgz#ae61f9c5a98d295b9a4f4553b1b1e831c1984d67" From 4dfac135d0e635ddcf61ba61ee9aea23091bcecf Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Fri, 9 Aug 2019 12:06:56 -0700 Subject: [PATCH 433/861] Update distro commit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 404e64edf2b..ec74a2f6bcb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "7790b9530e2afa8fed5a59c4686e25e9f511c216", + "distro": "b9b380a45ae5d292a9203b1a0ca458796d78abcb", "author": { "name": "Microsoft Corporation" }, From e8c6bfcec7029c83a2dfa691c72cd2e77a932745 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Fri, 9 Aug 2019 15:52:19 -0700 Subject: [PATCH 434/861] Revert "fixes #78167" Breaks custom titlebar and menu This reverts commit a417a060ab396ad8fe4b778a363d62fa08476966. --- src/vs/base/browser/ui/grid/gridview.ts | 1 - src/vs/base/browser/ui/splitview/splitview.css | 3 +-- src/vs/base/browser/ui/splitview/splitview.ts | 7 +------ 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts index ae8c4ed810a..497678cee41 100644 --- a/src/vs/base/browser/ui/grid/gridview.ts +++ b/src/vs/base/browser/ui/grid/gridview.ts @@ -348,7 +348,6 @@ class BranchNode implements ISplitView, IDisposable { } this.splitview.setViewVisible(index, visible); - this._onDidChange.fire(undefined); } getChildCachedVisibleSize(index: number): number | undefined { diff --git a/src/vs/base/browser/ui/splitview/splitview.css b/src/vs/base/browser/ui/splitview/splitview.css index c0f3634d499..6fb8f1c61d0 100644 --- a/src/vs/base/browser/ui/splitview/splitview.css +++ b/src/vs/base/browser/ui/splitview/splitview.css @@ -39,7 +39,6 @@ white-space: initial; flex: none; position: relative; - overflow: hidden; } .monaco-split-view2 > .split-view-container > .split-view-view:not(.visible) { @@ -73,4 +72,4 @@ .monaco-split-view2.separator-border.vertical > .split-view-container > .split-view-view:not(:first-child)::before { height: 1px; width: 100%; -} +} \ No newline at end of file diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index e6eaeae6bdc..4baf9ff4023 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -125,10 +125,7 @@ abstract class ViewItem { dom.addClass(container, 'visible'); } - layout(): void { - this.container.scrollTop = 0; - this.container.scrollLeft = 0; - } + abstract layout(): void; layoutView(orientation: Orientation): void { this.view.layout(this.size, orientation); @@ -143,7 +140,6 @@ abstract class ViewItem { class VerticalViewItem extends ViewItem { layout(): void { - super.layout(); this.container.style.height = `${this.size}px`; this.layoutView(Orientation.VERTICAL); } @@ -152,7 +148,6 @@ class VerticalViewItem extends ViewItem { class HorizontalViewItem extends ViewItem { layout(): void { - super.layout(); this.container.style.width = `${this.size}px`; this.layoutView(Orientation.HORIZONTAL); } From 4d50f8b699bad3a400b98b58782acd6280fff36e Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Fri, 9 Aug 2019 16:24:13 -0700 Subject: [PATCH 435/861] fixes #75999 --- src/vs/base/browser/ui/menu/menu.ts | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index c2b60a5dc92..12d2cfe8369 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -369,6 +369,7 @@ class BaseMenuActionViewItem extends BaseActionViewItem { protected options: IMenuItemOptions; protected item: HTMLElement; + private runOnceToEnableMouseUp: RunOnceScheduler; private label: HTMLElement; private check: HTMLElement; private mnemonic: string; @@ -394,6 +395,20 @@ class BaseMenuActionViewItem extends BaseActionViewItem { } } } + + // Add mouse up listener later to avoid accidental clicks + this.runOnceToEnableMouseUp = new RunOnceScheduler(() => { + if (!this.element) { + return; + } + + this._register(addDisposableListener(this.element, EventType.MOUSE_UP, e => { + EventHelper.stop(e, true); + this.onClick(e); + })); + }, 50); + + this._register(this.runOnceToEnableMouseUp); } render(container: HTMLElement): void { @@ -425,10 +440,8 @@ class BaseMenuActionViewItem extends BaseActionViewItem { append(this.item, $('span.keybinding')).textContent = this.options.keybinding; } - this._register(addDisposableListener(this.element, EventType.MOUSE_UP, e => { - EventHelper.stop(e, true); - this.onClick(e); - })); + // Adds mouse up listener to actually run the action + this.runOnceToEnableMouseUp.schedule(); this.updateClass(); this.updateLabel(); From 98680599a9605bd8e7201860a136fe2d64565158 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Fri, 9 Aug 2019 16:31:17 -0700 Subject: [PATCH 436/861] update mnemonics for remote connection --- .../contrib/remote/electron-browser/remote.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/remote/electron-browser/remote.contribution.ts b/src/vs/workbench/contrib/remote/electron-browser/remote.contribution.ts index 088b2a19f97..99f4eefd121 100644 --- a/src/vs/workbench/contrib/remote/electron-browser/remote.contribution.ts +++ b/src/vs/workbench/contrib/remote/electron-browser/remote.contribution.ts @@ -85,7 +85,7 @@ export class RemoteWindowActiveIndicator extends Disposable implements IWorkbenc group: '6_close', command: { id: CLOSE_REMOTE_COMMAND_ID, - title: nls.localize({ key: 'miCloseRemote', comment: ['&& denotes a mnemonic'] }, "C&&lose Remote Connection") + title: nls.localize({ key: 'miCloseRemote', comment: ['&& denotes a mnemonic'] }, "Close Re&&mote Connection") }, order: 3.5 }); From d93c8c49cb20a5c47e7735c8af1c0e8b9005ba9e Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Fri, 9 Aug 2019 18:13:34 -0700 Subject: [PATCH 437/861] fixes #69655 --- src/vs/base/browser/ui/menu/menu.ts | 42 +++++++++++++------------- src/vs/base/browser/ui/menu/menubar.ts | 31 +++++++++++++++---- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index 12d2cfe8369..49d35fd57a8 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -20,22 +20,8 @@ import { Event, Emitter } from 'vs/base/common/event'; import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview'; import { isLinux, isMacintosh } from 'vs/base/common/platform'; -function createMenuMnemonicRegExp() { - try { - return new RegExp('\\(&([^\\s&])\\)|(?$1'); + label = strings.escape(label); + + // This is global, reset it + MENU_ESCAPED_MNEMONIC_REGEX.lastIndex = 0; + let escMatch = MENU_ESCAPED_MNEMONIC_REGEX.exec(label); + + // We can't use negative lookbehind so if we match our negative and skip + while (escMatch && escMatch[1]) { + escMatch = MENU_ESCAPED_MNEMONIC_REGEX.exec(label); + } + + if (escMatch) { + label = `${label.substr(0, escMatch.index)}${label.substr(escMatch.index + escMatch[0].length)}`; + } + label = label.replace(/&&/g, '&'); - this.item.setAttribute('aria-keyshortcuts', (!!matches[1] ? matches[1] : matches[2]).toLocaleLowerCase()); + this.item.setAttribute('aria-keyshortcuts', (!!matches[1] ? matches[1] : matches[3]).toLocaleLowerCase()); } else { label = label.replace(/&&/g, '&'); } @@ -815,7 +815,7 @@ export function cleanMnemonic(label: string): string { return label; } - const mnemonicInText = matches[0].charAt(0) === '&'; + const mnemonicInText = !matches[1]; - return label.replace(regex, mnemonicInText ? '$2' : '').trim(); + return label.replace(regex, mnemonicInText ? '$2$3' : '').trim(); } diff --git a/src/vs/base/browser/ui/menu/menubar.ts b/src/vs/base/browser/ui/menu/menubar.ts index 1ffcb47b9a1..c6644247b2b 100644 --- a/src/vs/base/browser/ui/menu/menubar.ts +++ b/src/vs/base/browser/ui/menu/menubar.ts @@ -209,7 +209,7 @@ export class MenuBar extends Disposable { // Register mnemonics if (mnemonicMatches) { - let mnemonic = !!mnemonicMatches[1] ? mnemonicMatches[1] : mnemonicMatches[2]; + let mnemonic = !!mnemonicMatches[1] ? mnemonicMatches[1] : mnemonicMatches[3]; this.registerMnemonic(this.menuCache.length, mnemonic); } @@ -472,15 +472,34 @@ export class MenuBar extends Disposable { const cleanMenuLabel = cleanMnemonic(label); // Update the button label to reflect mnemonics - titleElement.innerHTML = this.options.enableMnemonics ? - strings.escape(label).replace(MENU_ESCAPED_MNEMONIC_REGEX, '').replace(/&&/g, '&') : - cleanMenuLabel.replace(/&&/g, '&'); + + if (this.options.enableMnemonics) { + let innerHtml = strings.escape(label); + + // This is global so reset it + MENU_ESCAPED_MNEMONIC_REGEX.lastIndex = 0; + let escMatch = MENU_ESCAPED_MNEMONIC_REGEX.exec(innerHtml); + + // We can't use negative lookbehind so we match our negative and skip + while (escMatch && escMatch[1]) { + escMatch = MENU_ESCAPED_MNEMONIC_REGEX.exec(innerHtml); + } + + if (escMatch) { + innerHtml = `${innerHtml.substr(0, escMatch.index)}${innerHtml.substr(escMatch.index + escMatch[0].length)}`; + } + + innerHtml = innerHtml.replace(/&&/g, '&'); + titleElement.innerHTML = innerHtml; + } else { + titleElement.innerHTML = cleanMenuLabel.replace(/&&/g, '&'); + } let mnemonicMatches = MENU_MNEMONIC_REGEX.exec(label); // Register mnemonics if (mnemonicMatches) { - let mnemonic = !!mnemonicMatches[1] ? mnemonicMatches[1] : mnemonicMatches[2]; + let mnemonic = !!mnemonicMatches[1] ? mnemonicMatches[1] : mnemonicMatches[3]; if (this.options.enableMnemonics) { buttonElement.setAttribute('aria-keyshortcuts', 'Alt+' + mnemonic.toLocaleLowerCase()); @@ -1012,4 +1031,4 @@ class ModifierKeyEmitter extends Emitter { super.dispose(); this._subscriptions.dispose(); } -} \ No newline at end of file +} From 15c7f58a978c0e66e9b9ef082d6d51d6cd36095e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 10 Aug 2019 07:47:00 -0700 Subject: [PATCH 438/861] Copy on select all when copyOnSelection is enabled Fixes #78476 --- .../contrib/terminal/browser/terminalInstance.ts | 9 +++++++++ .../contrib/terminal/browser/terminalPanel.ts | 14 -------------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 1f27f4d08e5..1e1a4af4faf 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -482,6 +482,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } this._xterm.onLineFeed(() => this._onLineFeed()); this._xterm.onKey(e => this._onKey(e.key, e.domEvent)); + this._xterm.onSelectionChange(async () => this._onSelectionChange()); this._processManager.onProcessData(data => this._onProcessData(data)); this._xterm.onData(data => this._processManager.write(data)); @@ -1191,6 +1192,14 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } } + private async _onSelectionChange(): void { + if (this._configurationService.getValue('terminal.integrated.copyOnSelection')) { + if (this.hasSelection()) { + await this.copySelection(); + } + } + } + @debounce(2000) private async _updateProcessCwd(): Promise { // reset cwd if it has changed, so file based url paths can be resolved diff --git a/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts b/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts index 77d6388d0ef..334c3ab0b13 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts @@ -239,20 +239,6 @@ export class TerminalPanel extends Panel { } } })); - this._register(dom.addDisposableListener(parentDomElement, 'mouseup', async (event: MouseEvent) => { - if (this._configurationService.getValue('terminal.integrated.copyOnSelection')) { - if (this._terminalService.terminalInstances.length === 0) { - return; - } - - if (event.which === 1) { - const terminal = this._terminalService.getActiveInstance(); - if (terminal && terminal.hasSelection()) { - await terminal.copySelection(); - } - } - } - })); this._register(dom.addDisposableListener(parentDomElement, 'contextmenu', (event: MouseEvent) => { if (!this._cancelContextMenu) { const standardEvent = new StandardMouseEvent(event); From a996f2a9a56ece1db8bddf0737ba7714b73d7e3c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 10 Aug 2019 07:48:03 -0700 Subject: [PATCH 439/861] Fix async func return type --- src/vs/workbench/contrib/terminal/browser/terminalInstance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 1e1a4af4faf..9ca4fa8fb71 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -1192,7 +1192,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } } - private async _onSelectionChange(): void { + private async _onSelectionChange(): Promise { if (this._configurationService.getValue('terminal.integrated.copyOnSelection')) { if (this.hasSelection()) { await this.copySelection(); From 040a1b52da1163a377cf367baa38d2784e963819 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 11 Aug 2019 08:26:33 -0700 Subject: [PATCH 440/861] Clean up ITerminalService.createInstance interface --- .../contrib/terminal/browser/terminalService.ts | 11 ++++------- .../contrib/terminal/browser/terminalTab.ts | 12 ++---------- src/vs/workbench/contrib/terminal/common/terminal.ts | 2 +- .../contrib/terminal/common/terminalService.ts | 2 +- 4 files changed, 8 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 4f584f6d13a..bfa25469cea 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -5,7 +5,7 @@ import { ITerminalService, TERMINAL_PANEL_ID, ITerminalInstance, IShellLaunchConfig, ITerminalConfigHelper, ITerminalNativeService } from 'vs/workbench/contrib/terminal/common/terminal'; import { TerminalService as CommonTerminalService } from 'vs/workbench/contrib/terminal/common/terminalService'; -import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; @@ -49,18 +49,15 @@ export class TerminalService extends CommonTerminalService implements ITerminalS this._configHelper = this._instantiationService.createInstance(TerminalConfigHelper, this.terminalNativeService.linuxDistro); } - public createInstance(terminalFocusContextKey: IContextKey, configHelper: ITerminalConfigHelper, container: HTMLElement | undefined, shellLaunchConfig: IShellLaunchConfig): ITerminalInstance { - const instance = this._instantiationService.createInstance(TerminalInstance, terminalFocusContextKey, configHelper, container, shellLaunchConfig); + public createInstance(container: HTMLElement | undefined, shellLaunchConfig: IShellLaunchConfig): ITerminalInstance { + const instance = this._instantiationService.createInstance(TerminalInstance, this._terminalFocusContextKey, this._configHelper, container, shellLaunchConfig); this._onInstanceCreated.fire(instance); return instance; } public createTerminal(shell: IShellLaunchConfig = {}): ITerminalInstance { if (shell.hideFromUser) { - const instance = this.createInstance(this._terminalFocusContextKey, - this.configHelper, - undefined, - shell); + const instance = this.createInstance(undefined, shell); this._backgroundedTerminalInstances.push(instance); this._initInstanceListeners(instance); return instance; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalTab.ts b/src/vs/workbench/contrib/terminal/browser/terminalTab.ts index 4b49a00187d..8f2fd4fbaee 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalTab.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalTab.ts @@ -240,11 +240,7 @@ export class TerminalTab extends Disposable implements ITerminalTab { if ('id' in shellLaunchConfigOrInstance) { instance = shellLaunchConfigOrInstance; } else { - instance = this._terminalService.createInstance( - terminalFocusContextKey, - configHelper, - undefined, - shellLaunchConfigOrInstance); + instance = this._terminalService.createInstance(undefined, shellLaunchConfigOrInstance); } this._terminalInstances.push(instance); this._initInstanceListeners(instance); @@ -385,11 +381,7 @@ export class TerminalTab extends Disposable implements ITerminalTab { if (newTerminalSize < TERMINAL_MIN_USEFUL_SIZE) { return undefined; } - const instance = this._terminalService.createInstance( - terminalFocusContextKey, - configHelper, - undefined, - shellLaunchConfig); + const instance = this._terminalService.createInstance(undefined, shellLaunchConfig); this._terminalInstances.splice(this._activeInstanceIndex + 1, 0, instance); this._initInstanceListeners(instance); this._setActiveInstance(instance); diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 9c988c3a6e6..bb99965b26c 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -247,7 +247,7 @@ export interface ITerminalService { /** * Creates a raw terminal instance, this should not be used outside of the terminal part. */ - createInstance(terminalFocusContextKey: IContextKey, configHelper: ITerminalConfigHelper, container: HTMLElement | undefined, shellLaunchConfig: IShellLaunchConfig): ITerminalInstance; + createInstance(container: HTMLElement | undefined, shellLaunchConfig: IShellLaunchConfig): ITerminalInstance; getInstanceFromId(terminalId: number): ITerminalInstance | undefined; getInstanceFromIndex(terminalIndex: number): ITerminalInstance; getTabLabels(): string[]; diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index a9595156654..1b04048fdcc 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -123,7 +123,7 @@ export abstract class TerminalService implements ITerminalService { protected abstract _showBackgroundTerminal(instance: ITerminalInstance): void; public abstract createTerminal(shell?: IShellLaunchConfig, wasNewTerminalAction?: boolean): ITerminalInstance; - public abstract createInstance(terminalFocusContextKey: IContextKey, configHelper: ITerminalConfigHelper, container: HTMLElement, shellLaunchConfig: IShellLaunchConfig): ITerminalInstance; + public abstract createInstance(container: HTMLElement, shellLaunchConfig: IShellLaunchConfig): ITerminalInstance; public abstract setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void; public getActiveOrCreateInstance(wasNewTerminalAction?: boolean): ITerminalInstance { From 8d702679907b1ed67618f27e03c1c258d850bc89 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sun, 11 Aug 2019 17:37:47 +0200 Subject: [PATCH 441/861] fix bad change that prevents editors to restore --- src/vs/workbench/browser/parts/editor/editorPart.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index 4dc5c4a28ad..8bb14cc38a3 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -938,14 +938,14 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro } private updateContainer(): void { - toggleClass(this.container, 'empty', this.isEmpty()); + toggleClass(this.container, 'empty', this.isEmpty); } private notifyGroupIndexChange(): void { this.getGroups(GroupsOrder.GRID_APPEARANCE).forEach((group, index) => group.notifyIndexChanged(index)); } - private isEmpty(): boolean { + private get isEmpty(): boolean { return this.groupViews.size === 1 && this._activeGroup.isEmpty; } From 5117a8e61fc0010f1c9723e34a4f757cb2487202 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 11 Aug 2019 08:44:41 -0700 Subject: [PATCH 442/861] Remove suite.only --- .../contrib/terminal/test/node/terminalEnvironment.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts b/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts index 7fce80a22a2..1f8ecd44171 100644 --- a/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts +++ b/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts @@ -9,7 +9,7 @@ import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/termi import { URI as Uri } from 'vs/base/common/uri'; import { IStringDictionary } from 'vs/base/common/collections'; -suite.only('Workbench - TerminalEnvironment', () => { +suite('Workbench - TerminalEnvironment', () => { test('addTerminalEnvironmentKeys', () => { const env: { [key: string]: any } = { FOO: 'bar' }; const locale = 'en-au'; From 4c2a3af2c8026002388910dc208ea284e05fddbc Mon Sep 17 00:00:00 2001 From: mayaswrath Date: Sun, 11 Aug 2019 13:02:40 -0400 Subject: [PATCH 443/861] #77879 multi cursor support for toggle breakpoint --- .../debug/browser/debugEditorActions.ts | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts b/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts index 060f9197074..2e8409ed9a8 100644 --- a/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts +++ b/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts @@ -35,21 +35,27 @@ class ToggleBreakpointAction extends EditorAction { } public run(accessor: ServicesAccessor, editor: ICodeEditor): Promise { - const debugService = accessor.get(IDebugService); - - const position = editor.getPosition(); - if (editor.hasModel() && position) { + if (editor.hasModel()) { + const debugService = accessor.get(IDebugService); const modelUri = editor.getModel().uri; - const bps = debugService.getModel().getBreakpoints({ lineNumber: position.lineNumber, uri: modelUri }); + const lineNumbers = new Set(editor._getCursors().getAll() + .filter(cs => cs.modelState.position) + .map(cs => cs.modelState.position.lineNumber)); - if (bps.length) { - return Promise.all(bps.map(bp => debugService.removeBreakpoints(bp.getId()))); - } - if (debugService.getConfigurationManager().canSetBreakpointsIn(editor.getModel())) { - return debugService.addBreakpoints(modelUri, [{ lineNumber: position.lineNumber }], 'debugEditorActions.toggleBreakpointAction'); + const promises = Array>(); + lineNumbers.forEach(lineNumber => { + const bps = debugService.getModel().getBreakpoints({ lineNumber: lineNumber, uri: modelUri }); + + if (bps.length) { + bps.map(bp => debugService.removeBreakpoints(bp.getId())).forEach(p => promises.push(p)); + } else if (debugService.getConfigurationManager().canSetBreakpointsIn(editor.getModel())) { + promises.push(debugService.addBreakpoints(modelUri, [{ lineNumber: lineNumber }], 'debugEditorActions.toggleBreakpointAction')); + } + }); + if (promises.length > 0) { + return Promise.all(promises); } } - return Promise.resolve(); } } From a3bff518015b31538e5a4651bc9cfb7fb4562d5d Mon Sep 17 00:00:00 2001 From: mayaswrath Date: Sun, 11 Aug 2019 13:06:23 -0400 Subject: [PATCH 444/861] removed unnecessary check --- src/vs/workbench/contrib/debug/browser/debugEditorActions.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts b/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts index 2e8409ed9a8..53d6608548e 100644 --- a/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts +++ b/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts @@ -52,9 +52,7 @@ class ToggleBreakpointAction extends EditorAction { promises.push(debugService.addBreakpoints(modelUri, [{ lineNumber: lineNumber }], 'debugEditorActions.toggleBreakpointAction')); } }); - if (promises.length > 0) { - return Promise.all(promises); - } + return Promise.all(promises); } return Promise.resolve(); } From 04b8e124c386b4bd9653cabb631921196584538f Mon Sep 17 00:00:00 2001 From: jeanp413 Date: Sun, 11 Aug 2019 21:20:45 -0500 Subject: [PATCH 445/861] Ignore double click on twistie. Fixes #78917 --- src/vs/base/browser/ui/list/listWidget.ts | 2 +- src/vs/base/browser/ui/tree/abstractTree.ts | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index 24fec080908..6e82c6de867 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -618,7 +618,7 @@ export class MouseController implements IDisposable { } } - private onDoubleClick(e: IListMouseEvent): void { + protected onDoubleClick(e: IListMouseEvent): void { if (isInputElement(e.browserEvent.target as HTMLElement)) { return; } diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 05f6841fd72..90def51eed5 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -1063,6 +1063,19 @@ class TreeNodeListMouseController extends MouseController< super.onPointer(e); } + + protected onDoubleClick(e: IListMouseEvent>): void { + if (isInputElement(e.browserEvent.target as HTMLElement)) { + return; + } + + const onTwistie = hasClass(e.browserEvent.target as HTMLElement, 'monaco-tl-twistie'); + if (onTwistie) { + return; + } + + super.onDoubleClick(e); + } } interface ITreeNodeListOptions extends IListOptions> { From 5099e36e3dd2299a0369cbcfc281abc2a0f4d580 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 12 Aug 2019 08:13:10 +0200 Subject: [PATCH 446/861] fix #77735 --- .../src/singlefolder-tests/workspace.test.ts | 90 +++++++++-- extensions/vscode-api-tests/src/utils.ts | 4 + .../textfile/common/textFileEditorModel.ts | 16 +- .../common/textFileEditorModelManager.ts | 16 +- .../textfile/common/textFileService.ts | 141 +++++++++++------- .../services/textfile/common/textfiles.ts | 4 +- .../textfile/test/textFileEditorModel.test.ts | 27 ++++ .../textfile/test/textFileService.test.ts | 25 +++- 8 files changed, 238 insertions(+), 85 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts index 3617b55f41c..738e1406834 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import * as vscode from 'vscode'; -import { createRandomFile, deleteFile, closeAllEditors, pathEquals, rndName, disposeAll, testFs } from '../utils'; +import { createRandomFile, deleteFile, closeAllEditors, pathEquals, rndName, disposeAll, testFs, delay } from '../utils'; import { join, posix, basename } from 'path'; import * as fs from 'fs'; @@ -587,13 +587,15 @@ suite('workspace-namespace', () => { }, cancellation.token); }); - test('applyEdit', () => { + test('applyEdit', async () => { + const doc = await vscode.workspace.openTextDocument(vscode.Uri.parse('untitled:' + join(vscode.workspace.rootPath || '', './new2.txt'))); - return vscode.workspace.openTextDocument(vscode.Uri.parse('untitled:' + join(vscode.workspace.rootPath || '', './new2.txt'))).then(doc => { - let edit = new vscode.WorkspaceEdit(); - edit.insert(doc.uri, new vscode.Position(0, 0), new Array(1000).join('Hello World')); - return vscode.workspace.applyEdit(edit); - }); + let edit = new vscode.WorkspaceEdit(); + edit.insert(doc.uri, new vscode.Position(0, 0), new Array(1000).join('Hello World')); + + let success = await vscode.workspace.applyEdit(edit); + assert.equal(success, true); + assert.equal(doc.isDirty, true); }); test('applyEdit should fail when editing deleted resource', async () => { @@ -630,19 +632,31 @@ suite('workspace-namespace', () => { }); test('applyEdit "edit A -> rename A to B -> edit B"', async () => { + await testEditRenameEdit(oldUri => oldUri.with({ path: oldUri.path + 'NEW' })); + }); + + test('applyEdit "edit A -> rename A to B (different case)" -> edit B', async () => { + await testEditRenameEdit(oldUri => oldUri.with({ path: oldUri.path.toUpperCase() })); + }); + + test('applyEdit "edit A -> rename A to B (same case)" -> edit B', async () => { + await testEditRenameEdit(oldUri => oldUri); + }); + + async function testEditRenameEdit(newUriCreator: (oldUri: vscode.Uri) => vscode.Uri): Promise { const oldUri = await createRandomFile(); - const newUri = oldUri.with({ path: oldUri.path + 'NEW' }); + const newUri = newUriCreator(oldUri); const edit = new vscode.WorkspaceEdit(); edit.insert(oldUri, new vscode.Position(0, 0), 'BEFORE'); edit.renameFile(oldUri, newUri); edit.insert(newUri, new vscode.Position(0, 0), 'AFTER'); - let success = await vscode.workspace.applyEdit(edit); - assert.equal(success, true); + assert.ok(await vscode.workspace.applyEdit(edit)); let doc = await vscode.workspace.openTextDocument(newUri); assert.equal(doc.getText(), 'AFTERBEFORE'); - }); + assert.equal(doc.isDirty, true); + } function nameWithUnderscore(uri: vscode.Uri) { return uri.with({ path: posix.join(posix.dirname(uri.path), `_${posix.basename(uri.path)}`) }); @@ -807,7 +821,7 @@ suite('workspace-namespace', () => { assert.ok(await vscode.workspace.applyEdit(we)); }); - test('The api workspace.applyEdit drops the TextEdit if there is a RenameFile later #77735', async function () { + test('WorkspaceEdit: insert & rename multiple', async function () { let [f1, f2, f3] = await Promise.all([createRandomFile(), createRandomFile(), createRandomFile()]); @@ -831,4 +845,56 @@ suite('workspace-namespace', () => { assert.ok(true); } }); + + test('workspace.applyEdit drops the TextEdit if there is a RenameFile later #77735 (with opened editor)', async function () { + await test77735(true); + }); + + test('workspace.applyEdit drops the TextEdit if there is a RenameFile later #77735 (without opened editor)', async function () { + await test77735(false); + }); + + async function test77735(withOpenedEditor: boolean): Promise { + const docUriOriginal = await createRandomFile(); + const docUriMoved = docUriOriginal.with({ path: `${docUriOriginal.path}.moved` }); + + if (withOpenedEditor) { + const document = await vscode.workspace.openTextDocument(docUriOriginal); + await vscode.window.showTextDocument(document); + } else { + await vscode.commands.executeCommand('workbench.action.closeAllEditors'); + } + + for (let i = 0; i < 4; i++) { + let we = new vscode.WorkspaceEdit(); + let oldUri: vscode.Uri; + let newUri: vscode.Uri; + let expected: string; + + if (i % 2 === 0) { + oldUri = docUriOriginal; + newUri = docUriMoved; + we.insert(oldUri, new vscode.Position(0, 0), 'Hello'); + expected = 'Hello'; + } else { + oldUri = docUriMoved; + newUri = docUriOriginal; + we.delete(oldUri, new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 5))); + expected = ''; + } + + we.renameFile(oldUri, newUri); + assert.ok(await vscode.workspace.applyEdit(we)); + + const document = await vscode.workspace.openTextDocument(newUri); + assert.equal(document.isDirty, true); + + await document.save(); + assert.equal(document.isDirty, false); + + assert.equal(document.getText(), expected); + + await delay(10); + } + } }); diff --git a/extensions/vscode-api-tests/src/utils.ts b/extensions/vscode-api-tests/src/utils.ts index 38ede848840..969a7cd0051 100644 --- a/extensions/vscode-api-tests/src/utils.ts +++ b/extensions/vscode-api-tests/src/utils.ts @@ -67,3 +67,7 @@ export function conditionalTest(name: string, testCallback: (done: MochaDone) => function isTestTypeActive(): boolean { return !!vscode.extensions.getExtension('vscode-resolver-test'); } + +export function delay(ms: number) { + return new Promise(resolve => setTimeout(resolve, ms)); +} diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index 3ece543b7d3..4fa61e19c83 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -470,7 +470,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // We also want to trigger auto save if it is enabled to simulate the exact same behaviour // you would get if manually making the model dirty (fixes https://github.com/Microsoft/vscode/issues/16977) if (fromBackup) { - this.makeDirty(); + this.doMakeDirty(); if (this.autoSaveAfterMilliesEnabled) { this.doAutoSave(this.versionId); } @@ -549,7 +549,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil this.logService.trace('onModelContentChanged() - model content changed and marked as dirty', this.resource); // Mark as dirty - this.makeDirty(); + this.doMakeDirty(); // Start auto save process unless we are in conflict resolution mode and unless it is disabled if (this.autoSaveAfterMilliesEnabled) { @@ -564,7 +564,15 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil this.contentChangeEventScheduler.schedule(); } - private makeDirty(): void { + makeDirty(): void { + if (!this.isResolved()) { + return; // only resolved models can be marked dirty + } + + this.doMakeDirty(); + } + + private doMakeDirty(): void { // Track dirty state and version id const wasDirty = this.dirty; @@ -913,7 +921,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil TextFileEditorModel.saveErrorHandler.onSaveError(error, this); } - isDirty(): boolean { + isDirty(): this is IResolvedTextFileEditorModel { return this.dirty; } diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts b/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts index 13f60f4629b..4de574861a0 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts @@ -74,11 +74,11 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE return this._onModelsReverted; } - private mapResourceToDisposeListener: ResourceMap; - private mapResourceToStateChangeListener: ResourceMap; - private mapResourceToModelContentChangeListener: ResourceMap; - private mapResourceToModel: ResourceMap; - private mapResourceToPendingModelLoaders: ResourceMap>; + private mapResourceToDisposeListener = new ResourceMap(); + private mapResourceToStateChangeListener = new ResourceMap(); + private mapResourceToModelContentChangeListener = new ResourceMap(); + private mapResourceToModel = new ResourceMap(); + private mapResourceToPendingModelLoaders = new ResourceMap>(); constructor( @ILifecycleService private readonly lifecycleService: ILifecycleService, @@ -86,12 +86,6 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE ) { super(); - this.mapResourceToModel = new ResourceMap(); - this.mapResourceToDisposeListener = new ResourceMap(); - this.mapResourceToStateChangeListener = new ResourceMap(); - this.mapResourceToModelContentChangeListener = new ResourceMap(); - this.mapResourceToPendingModelLoaders = new ResourceMap>(); - this.registerListeners(); } diff --git a/src/vs/workbench/services/textfile/common/textFileService.ts b/src/vs/workbench/services/textfile/common/textFileService.ts index a061414b910..713ef13e395 100644 --- a/src/vs/workbench/services/textfile/common/textFileService.ts +++ b/src/vs/workbench/services/textfile/common/textFileService.ts @@ -443,9 +443,94 @@ export abstract class TextFileService extends Disposable implements ITextFileSer } async move(source: URI, target: URI, overwrite?: boolean): Promise { + + // await onWillMove event joiners + await this.notifyOnWillMove(source, target); + + // find all models that related to either source or target (can be many if resource is a folder) + const sourceModels: ITextFileEditorModel[] = []; + const conflictingModels: ITextFileEditorModel[] = []; + for (const model of this.getFileModels()) { + const resource = model.getResource(); + + if (isEqualOrParent(resource, target, false /* do not ignorecase, see https://github.com/Microsoft/vscode/issues/56384 */)) { + conflictingModels.push(model); + } + + if (isEqualOrParent(resource, source)) { + sourceModels.push(model); + } + } + + // remember each source model to load again after move is done + // with optional content to restore if it was dirty + type ModelToRestore = { resource: URI; snapshot?: ITextSnapshot }; + const modelsToRestore: ModelToRestore[] = []; + for (const sourceModel of sourceModels) { + const sourceModelResource = sourceModel.getResource(); + + // If the source is the actual model, just use target as new resource + let modelToRestoreResource: URI; + if (isEqual(sourceModelResource, source)) { + modelToRestoreResource = target; + } + + // Otherwise a parent folder of the source is being moved, so we need + // to compute the target resource based on that + else { + modelToRestoreResource = joinPath(target, sourceModelResource.path.substr(source.path.length + 1)); + } + + const modelToRestore: ModelToRestore = { resource: modelToRestoreResource }; + if (sourceModel.isDirty()) { + modelToRestore.snapshot = sourceModel.createSnapshot(); + } + + modelsToRestore.push(modelToRestore); + } + + // in order to move, we need to soft revert all dirty models, + // both from the source as well as the target if any + const dirtyModels = [...sourceModels, ...conflictingModels].filter(model => model.isDirty()); + await this.revertAll(dirtyModels.map(dirtyModel => dirtyModel.getResource()), { soft: true }); + + // now we can rename the source to target via file operation + let stat: IFileStatWithMetadata; + try { + stat = await this.fileService.move(source, target, overwrite); + } catch (error) { + + // in case of any error, ensure to set dirty flag back + dirtyModels.forEach(dirtyModel => dirtyModel.makeDirty()); + + throw error; + } + + // finally, restore models that we had loaded previously + await Promise.all(modelsToRestore.map(async modelToRestore => { + + // restore the model, forcing a reload. this is important because + // we know the file has changed on disk after the move and the + // model might have still existed with the previous state. this + // ensures we are not tracking a stale state. + const restoredModel = await this.models.loadOrCreate(modelToRestore.resource, { reload: { async: false } }); + + // restore previous dirty content if any and ensure to mark + // the model as dirty + if (modelToRestore.snapshot && restoredModel.isResolved()) { + this.modelService.updateModel(restoredModel.textEditorModel, createTextBufferFactoryFromSnapshot(modelToRestore.snapshot)); + + restoredModel.makeDirty(); + } + })); + + return stat; + } + + private async notifyOnWillMove(source: URI, target: URI): Promise { const waitForPromises: Promise[] = []; - // Event + // fire event this._onWillMove.fire({ oldResource: source, newResource: target, @@ -458,58 +543,6 @@ export abstract class TextFileService extends Disposable implements ITextFileSer Object.freeze(waitForPromises); await Promise.all(waitForPromises); - - // Handle target models if existing (if target URI is a folder, this can be multiple) - const dirtyTargetModels = this.getDirtyFileModels().filter(model => isEqualOrParent(model.getResource(), target, false /* do not ignorecase, see https://github.com/Microsoft/vscode/issues/56384 */)); - if (dirtyTargetModels.length) { - await this.revertAll(dirtyTargetModels.map(targetModel => targetModel.getResource()), { soft: true }); - } - - // Handle dirty source models if existing (if source URI is a folder, this can be multiple) - const dirtySourceModels = this.getDirtyFileModels().filter(model => isEqualOrParent(model.getResource(), source)); - const dirtyTargetModelUris: URI[] = []; - if (dirtySourceModels.length) { - await Promise.all(dirtySourceModels.map(async sourceModel => { - const sourceModelResource = sourceModel.getResource(); - let targetModelResource: URI; - - // If the source is the actual model, just use target as new resource - if (isEqual(sourceModelResource, source)) { - targetModelResource = target; - } - - // Otherwise a parent folder of the source is being moved, so we need - // to compute the target resource based on that - else { - targetModelResource = sourceModelResource.with({ path: joinPath(target, sourceModelResource.path.substr(source.path.length + 1)).path }); - } - - // Remember as dirty target model to load after the operation - dirtyTargetModelUris.push(targetModelResource); - - // Backup dirty source model to the target resource it will become later - await sourceModel.backup(targetModelResource); - })); - } - - // Soft revert the dirty source files if any - await this.revertAll(dirtySourceModels.map(dirtySourceModel => dirtySourceModel.getResource()), { soft: true }); - - // Rename to target - try { - const stat = await this.fileService.move(source, target, overwrite); - - // Load models that were dirty before - await Promise.all(dirtyTargetModelUris.map(dirtyTargetModel => this.models.loadOrCreate(dirtyTargetModel))); - - return stat; - } catch (error) { - - // In case of an error, discard any dirty target backups that were made - await Promise.all(dirtyTargetModelUris.map(dirtyTargetModel => this.backupFileService.discardResourceBackup(dirtyTargetModel))); - - throw error; - } } //#endregion @@ -857,7 +890,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer return false; } - // take over encoding, mode (only if more specific) and model value from source model + // take over model value, encoding and mode (only if more specific) from source model targetModel.updatePreferredEncoding(sourceModel.getEncoding()); if (sourceModel.isResolved() && targetModel.isResolved()) { this.modelService.updateModel(targetModel.textEditorModel, createTextBufferFactoryFromSnapshot(sourceModel.createSnapshot())); diff --git a/src/vs/workbench/services/textfile/common/textfiles.ts b/src/vs/workbench/services/textfile/common/textfiles.ts index 5438af0f575..02956fd1cdd 100644 --- a/src/vs/workbench/services/textfile/common/textfiles.ts +++ b/src/vs/workbench/services/textfile/common/textfiles.ts @@ -470,7 +470,9 @@ export interface ITextFileEditorModel extends ITextEditorModel, IEncodingSupport hasBackup(): boolean; - isDirty(): boolean; + isDirty(): this is IResolvedTextFileEditorModel; + + makeDirty(): void; isResolved(): this is IResolvedTextFileEditorModel; diff --git a/src/vs/workbench/services/textfile/test/textFileEditorModel.test.ts b/src/vs/workbench/services/textfile/test/textFileEditorModel.test.ts index e22cbe034db..b5609d42d32 100644 --- a/src/vs/workbench/services/textfile/test/textFileEditorModel.test.ts +++ b/src/vs/workbench/services/textfile/test/textFileEditorModel.test.ts @@ -219,6 +219,33 @@ suite('Files - TextFileEditorModel', () => { assert.ok(model.isDirty()); }); + test('Make Dirty', async function () { + let eventCounter = 0; + + const model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/index_async.txt'), 'utf8', undefined); + + model.makeDirty(); + assert.ok(!model.isDirty()); // needs to be resolved + + await model.load(); + model.textEditorModel!.setValue('foo'); + assert.ok(model.isDirty()); + + await model.revert(true /* soft revert */); + assert.ok(!model.isDirty()); + + model.onDidStateChange(e => { + if (e === StateChange.DIRTY) { + eventCounter++; + } + }); + + model.makeDirty(); + assert.ok(model.isDirty()); + assert.equal(eventCounter, 1); + model.dispose(); + }); + test('File not modified error is handled gracefully', async function () { let model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/index_async.txt'), 'utf8', undefined); diff --git a/src/vs/workbench/services/textfile/test/textFileService.test.ts b/src/vs/workbench/services/textfile/test/textFileService.test.ts index 30079948c80..07676420066 100644 --- a/src/vs/workbench/services/textfile/test/textFileService.test.ts +++ b/src/vs/workbench/services/textfile/test/textFileService.test.ts @@ -272,8 +272,16 @@ suite('Files - TextFileService', () => { }); test('move - dirty file', async function () { - let sourceModel: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8', undefined); - let targetModel: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file_target.txt'), 'utf8', undefined); + await testMove(toResource.call(this, '/path/file.txt'), toResource.call(this, '/path/file_target.txt')); + }); + + test('move - dirty file (target exists and is dirty)', async function () { + await testMove(toResource.call(this, '/path/file.txt'), toResource.call(this, '/path/file_target.txt'), true); + }); + + async function testMove(source: URI, target: URI, targetDirty?: boolean): Promise { + let sourceModel: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, source, 'utf8', undefined); + let targetModel: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, target, 'utf8', undefined); (accessor.textFileService.models).add(sourceModel.getResource(), sourceModel); (accessor.textFileService.models).add(targetModel.getResource(), targetModel); @@ -283,11 +291,22 @@ suite('Files - TextFileService', () => { sourceModel.textEditorModel!.setValue('foo'); assert.ok(service.isDirty(sourceModel.getResource())); + if (targetDirty) { + await targetModel.load(); + targetModel.textEditorModel!.setValue('bar'); + assert.ok(service.isDirty(targetModel.getResource())); + } + await service.move(sourceModel.getResource(), targetModel.getResource(), true); + + assert.equal(targetModel.textEditorModel!.getValue(), 'foo'); + assert.ok(!service.isDirty(sourceModel.getResource())); + assert.ok(service.isDirty(targetModel.getResource())); + sourceModel.dispose(); targetModel.dispose(); - }); + } suite('Hot Exit', () => { suite('"onExit" setting', () => { From c327c4fcb79db984bcf34d84ea57f673b6f2cf14 Mon Sep 17 00:00:00 2001 From: Robo Date: Sun, 11 Aug 2019 23:14:18 -0700 Subject: [PATCH 447/861] chore: Bump electron@4.2.9 (#78836) --- .yarnrc | 2 +- cgmanifest.json | 4 ++-- src/typings/electron.d.ts | 2 +- test/smoke/package.json | 2 +- test/smoke/yarn.lock | 8 ++++---- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.yarnrc b/.yarnrc index c45abdbacad..98712ee2b43 100644 --- a/.yarnrc +++ b/.yarnrc @@ -1,3 +1,3 @@ disturl "https://atom.io/download/electron" -target "4.2.7" +target "4.2.9" runtime "electron" diff --git a/cgmanifest.json b/cgmanifest.json index 638303702ae..5ba2e166267 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -60,12 +60,12 @@ "git": { "name": "electron", "repositoryUrl": "https://github.com/electron/electron", - "commitHash": "36ea114ac0616e469e75ae94e6d53af48925e036" + "commitHash": "3d4d6454007f14fa9a5f0e1fa49206fb91b676cc" } }, "isOnlyProductionDependency": true, "license": "MIT", - "version": "4.2.7" + "version": "4.2.9" }, { "component": { diff --git a/src/typings/electron.d.ts b/src/typings/electron.d.ts index 5be0ac0e3fe..cc80376a765 100644 --- a/src/typings/electron.d.ts +++ b/src/typings/electron.d.ts @@ -1,4 +1,4 @@ -// Type definitions for Electron 4.2.7 +// Type definitions for Electron 4.2.9 // Project: http://electronjs.org/ // Definitions by: The Electron Team // Definitions: https://github.com/electron/electron-typescript-definitions diff --git a/test/smoke/package.json b/test/smoke/package.json index 11b5662b207..19378e70a50 100644 --- a/test/smoke/package.json +++ b/test/smoke/package.json @@ -22,7 +22,7 @@ "@types/webdriverio": "4.6.1", "concurrently": "^3.5.1", "cpx": "^1.5.0", - "electron": "4.2.7", + "electron": "4.2.9", "htmlparser2": "^3.9.2", "mkdirp": "^0.5.1", "mocha": "^5.2.0", diff --git a/test/smoke/yarn.lock b/test/smoke/yarn.lock index b86356d3ac3..3935a9baa4b 100644 --- a/test/smoke/yarn.lock +++ b/test/smoke/yarn.lock @@ -676,10 +676,10 @@ electron-download@^4.1.0: semver "^5.4.1" sumchecker "^2.0.2" -electron@4.2.7: - version "4.2.7" - resolved "https://registry.yarnpkg.com/electron/-/electron-4.2.7.tgz#bdd2dbf489a4a4255405bd8330cc8509831d29ba" - integrity sha512-Azpkw0OPzKVipSsN9/0DrBQhXOpG48Q1gTG7Akchtv37s8TijMe403TUgHxGGhw2ti117ek51kYf7NXLhjXqoA== +electron@4.2.9: + version "4.2.9" + resolved "https://registry.yarnpkg.com/electron/-/electron-4.2.9.tgz#81226aa1ba58e1b05388474faf5a815010a11ea2" + integrity sha512-zC7K3GOiZKmxqllVG/qq/Gx+qQvyolKj5xKKwXMqIGekfokEW2hvoIO5Yh7KCoAh5dqBtpzOJjS4fj1se+YBcg== dependencies: "@types/node" "^10.12.18" electron-download "^4.1.0" From 07e9310f56e54f18ecae387eaf21fb77455ac472 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 12 Aug 2019 08:22:29 +0200 Subject: [PATCH 448/861] file commands :lipstick: async/await --- .../contrib/files/browser/fileCommands.ts | 267 +++++++++--------- 1 file changed, 138 insertions(+), 129 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/fileCommands.ts b/src/vs/workbench/contrib/files/browser/fileCommands.ts index 38835200d54..384d6735830 100644 --- a/src/vs/workbench/contrib/files/browser/fileCommands.ts +++ b/src/vs/workbench/contrib/files/browser/fileCommands.ts @@ -37,7 +37,6 @@ import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { ILabelService } from 'vs/platform/label/common/label'; -import { onUnexpectedError } from 'vs/base/common/errors'; import { basename, toLocalResource, joinPath } from 'vs/base/common/resources'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; @@ -106,7 +105,7 @@ export const newWindowCommand = (accessor: ServicesAccessor, options?: INewWindo windowsService.openNewWindow(options); }; -function save( +async function save( resource: URI | null, isSaveAs: boolean, options: ISaveOptions | undefined, @@ -117,99 +116,110 @@ function save( editorGroupService: IEditorGroupsService, environmentService: IWorkbenchEnvironmentService ): Promise { - - function ensureForcedSave(options?: ISaveOptions): ISaveOptions { - if (!options) { - options = { force: true }; - } else { - options.force = true; - } - - return options; + if (!resource || (!fileService.canHandleResource(resource) && resource.scheme !== Schemas.untitled)) { + return; // save is not supported } - if (resource && (fileService.canHandleResource(resource) || resource.scheme === Schemas.untitled)) { - - // Save As (or Save untitled with associated path) - if (isSaveAs || resource.scheme === Schemas.untitled) { - let encodingOfSource: string | undefined; - if (resource.scheme === Schemas.untitled) { - encodingOfSource = untitledEditorService.getEncoding(resource); - } else if (fileService.canHandleResource(resource)) { - const textModel = textFileService.models.get(resource); - encodingOfSource = textModel && textModel.getEncoding(); // text model can be null e.g. if this is a binary file! - } - - let viewStateOfSource: IEditorViewState | null; - const activeTextEditorWidget = getCodeEditor(editorService.activeTextEditorWidget); - if (activeTextEditorWidget) { - const activeResource = toResource(editorService.activeEditor, { supportSideBySide: SideBySideEditor.MASTER }); - if (activeResource && (fileService.canHandleResource(activeResource) || resource.scheme === Schemas.untitled) && activeResource.toString() === resource.toString()) { - viewStateOfSource = activeTextEditorWidget.saveViewState(); - } - } - - // Special case: an untitled file with associated path gets saved directly unless "saveAs" is true - let savePromise: Promise; - if (!isSaveAs && resource.scheme === Schemas.untitled && untitledEditorService.hasAssociatedFilePath(resource)) { - savePromise = textFileService.save(resource, options).then(result => { - if (result) { - return toLocalResource(resource, environmentService.configuration.remoteAuthority); - } - - return undefined; - }); - } - - // Otherwise, really "Save As..." - else { - - // Force a change to the file to trigger external watchers if any - // fixes https://github.com/Microsoft/vscode/issues/59655 - options = ensureForcedSave(options); - - savePromise = textFileService.saveAs(resource, undefined, options); - } - - return savePromise.then(target => { - if (!target || target.toString() === resource.toString()) { - return false; // save canceled or same resource used - } - - const replacement: IResourceInput = { - resource: target, - encoding: encodingOfSource, - options: { - pinned: true, - viewState: viewStateOfSource || undefined - } - }; - - return Promise.all(editorGroupService.groups.map(g => - editorService.replaceEditors([{ - editor: { resource }, - replacement - }], g))).then(() => true); - }); - } - - // Pin the active editor if we are saving it - const activeControl = editorService.activeControl; - const activeEditorResource = activeControl && activeControl.input && activeControl.input.getResource(); - if (activeControl && activeEditorResource && activeEditorResource.toString() === resource.toString()) { - activeControl.group.pinEditor(activeControl.input); - } - - // Just save (force a change to the file to trigger external watchers if any) - options = ensureForcedSave(options); - - return textFileService.save(resource, options); + // Save As (or Save untitled with associated path) + if (isSaveAs || resource.scheme === Schemas.untitled) { + return doSaveAs(resource, isSaveAs, options, editorService, fileService, untitledEditorService, textFileService, editorGroupService, environmentService); } - return Promise.resolve(false); + // Save + return doSave(resource, options, editorService, textFileService); } -function saveAll(saveAllArguments: any, editorService: IEditorService, untitledEditorService: IUntitledEditorService, +async function doSaveAs( + resource: URI, + isSaveAs: boolean, + options: ISaveOptions | undefined, + editorService: IEditorService, + fileService: IFileService, + untitledEditorService: IUntitledEditorService, + textFileService: ITextFileService, + editorGroupService: IEditorGroupsService, + environmentService: IWorkbenchEnvironmentService +): Promise { + let viewStateOfSource: IEditorViewState | null = null; + const activeTextEditorWidget = getCodeEditor(editorService.activeTextEditorWidget); + if (activeTextEditorWidget) { + const activeResource = toResource(editorService.activeEditor, { supportSideBySide: SideBySideEditor.MASTER }); + if (activeResource && (fileService.canHandleResource(activeResource) || resource.scheme === Schemas.untitled) && activeResource.toString() === resource.toString()) { + viewStateOfSource = activeTextEditorWidget.saveViewState(); + } + } + + // Special case: an untitled file with associated path gets saved directly unless "saveAs" is true + let target: URI | undefined; + if (!isSaveAs && resource.scheme === Schemas.untitled && untitledEditorService.hasAssociatedFilePath(resource)) { + const result = await textFileService.save(resource, options); + if (result) { + target = toLocalResource(resource, environmentService.configuration.remoteAuthority); + } + } + + // Otherwise, really "Save As..." + else { + + // Force a change to the file to trigger external watchers if any + // fixes https://github.com/Microsoft/vscode/issues/59655 + options = ensureForcedSave(options); + + target = await textFileService.saveAs(resource, undefined, options); + } + + if (!target || target.toString() === resource.toString()) { + return false; // save canceled or same resource used + } + + const replacement: IResourceInput = { + resource: target, + options: { + pinned: true, + viewState: viewStateOfSource || undefined + } + }; + + await Promise.all(editorGroupService.groups.map(group => + editorService.replaceEditors([{ + editor: { resource }, + replacement + }], group))); + + return true; +} + +async function doSave( + resource: URI, + options: ISaveOptions | undefined, + editorService: IEditorService, + textFileService: ITextFileService +): Promise { + + // Pin the active editor if we are saving it + const activeControl = editorService.activeControl; + const activeEditorResource = activeControl && activeControl.input && activeControl.input.getResource(); + if (activeControl && activeEditorResource && activeEditorResource.toString() === resource.toString()) { + activeControl.group.pinEditor(activeControl.input); + } + + // Just save (force a change to the file to trigger external watchers if any) + options = ensureForcedSave(options); + + return textFileService.save(resource, options); +} + +function ensureForcedSave(options?: ISaveOptions): ISaveOptions { + if (!options) { + options = { force: true }; + } else { + options.force = true; + } + + return options; +} + +async function saveAll(saveAllArguments: any, editorService: IEditorService, untitledEditorService: IUntitledEditorService, textFileService: ITextFileService, editorGroupService: IEditorGroupsService): Promise { // Store some properties per untitled file to restore later after save is completed @@ -239,17 +249,18 @@ function saveAll(saveAllArguments: any, editorService: IEditorService, untitledE }); // Save all - return textFileService.saveAll(saveAllArguments).then(result => { - groupIdToUntitledResourceInput.forEach((inputs, groupId) => { - // Update untitled resources to the saved ones, so we open the proper files - inputs.forEach(i => { - const targetResult = result.results.filter(r => r.success && r.source.toString() === i.resource.toString()).pop(); - if (targetResult && targetResult.target) { - i.resource = targetResult.target; - } - }); - editorService.openEditors(inputs, groupId); + const result = await textFileService.saveAll(saveAllArguments); + + // Update untitled resources to the saved ones, so we open the proper files + groupIdToUntitledResourceInput.forEach((inputs, groupId) => { + inputs.forEach(i => { + const targetResult = result.results.filter(r => r.success && r.source.toString() === i.resource.toString()).pop(); + if (targetResult && targetResult.target) { + i.resource = targetResult.target; + } }); + + editorService.openEditors(inputs, groupId); }); } @@ -257,7 +268,7 @@ function saveAll(saveAllArguments: any, editorService: IEditorService, untitledE CommandsRegistry.registerCommand({ id: REVERT_FILE_COMMAND_ID, - handler: (accessor, resource: URI | object) => { + handler: async (accessor, resource: URI | object) => { const editorService = accessor.get(IEditorService); const textFileService = accessor.get(ITextFileService); const notificationService = accessor.get(INotificationService); @@ -265,12 +276,12 @@ CommandsRegistry.registerCommand({ .filter(resource => resource.scheme !== Schemas.untitled); if (resources.length) { - return textFileService.revertAll(resources, { force: true }).then(undefined, error => { + try { + await textFileService.revertAll(resources, { force: true }); + } catch (error) { notificationService.error(nls.localize('genericRevertError', "Failed to revert '{0}': {1}", resources.map(r => basename(r)).join(', '), toErrorMessage(error, false))); - }); + } } - - return Promise.resolve(true); } }); @@ -281,7 +292,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ mac: { primary: KeyMod.WinCtrl | KeyCode.Enter }, - id: OPEN_TO_SIDE_COMMAND_ID, handler: (accessor, resource: URI | object) => { + id: OPEN_TO_SIDE_COMMAND_ID, handler: async (accessor, resource: URI | object) => { const editorService = accessor.get(IEditorService); const listService = accessor.get(IListService); const fileService = accessor.get(IFileService); @@ -289,16 +300,13 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ // Set side input if (resources.length) { - return fileService.resolveAll(resources.map(resource => ({ resource }))).then(resolved => { - const editors = resolved.filter(r => r.stat && r.success && !r.stat.isDirectory).map(r => ({ - resource: r.stat!.resource - })); + const resolved = await fileService.resolveAll(resources.map(resource => ({ resource }))); + const editors = resolved.filter(r => r.stat && r.success && !r.stat.isDirectory).map(r => ({ + resource: r.stat!.resource + })); - return editorService.openEditors(editors, SIDE_GROUP); - }); + await editorService.openEditors(editors, SIDE_GROUP); } - - return Promise.resolve(true); } }); @@ -393,7 +401,7 @@ CommandsRegistry.registerCommand({ editorService.openEditor({ leftResource: globalResourceToCompare, rightResource - }).then(undefined, onUnexpectedError); + }); } } }); @@ -492,27 +500,28 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ CommandsRegistry.registerCommand({ id: REVEAL_IN_EXPLORER_COMMAND_ID, - handler: (accessor, resource: URI | object) => { + handler: async (accessor, resource: URI | object) => { const viewletService = accessor.get(IViewletService); const contextService = accessor.get(IWorkspaceContextService); const explorerService = accessor.get(IExplorerService); const uri = getResourceForCommand(resource, accessor.get(IListService), accessor.get(IEditorService)); - viewletService.openViewlet(VIEWLET_ID, false).then((viewlet: ExplorerViewlet) => { - if (uri && contextService.isInsideWorkspace(uri)) { - const explorerView = viewlet.getExplorerView(); - if (explorerView) { - explorerView.setExpanded(true); - explorerService.select(uri, true).then(() => explorerView.focus(), onUnexpectedError); - } - } else { - const openEditorsView = viewlet.getOpenEditorsView(); - if (openEditorsView) { - openEditorsView.setExpanded(true); - openEditorsView.focus(); - } + const viewlet = await viewletService.openViewlet(VIEWLET_ID, false) as ExplorerViewlet; + + if (uri && contextService.isInsideWorkspace(uri)) { + const explorerView = viewlet.getExplorerView(); + if (explorerView) { + explorerView.setExpanded(true); + await explorerService.select(uri, true); + explorerView.focus(); } - }); + } else { + const openEditorsView = viewlet.getOpenEditorsView(); + if (openEditorsView) { + openEditorsView.setExpanded(true); + openEditorsView.focus(); + } + } } }); From 956208bb05ac9cc75579f6a1c282575351485afa Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 12 Aug 2019 08:23:31 +0200 Subject: [PATCH 449/861] Revert "debt - adopt new fs.readdir with stat info" This reverts commit da5fb7d5b865aa522abc7e82c10b746834b98639. --- src/vs/base/node/pfs.ts | 14 -------- src/vs/base/test/node/pfs/pfs.test.ts | 26 --------------- .../files/node/diskFileSystemProvider.ts | 33 ++++++++----------- 3 files changed, 13 insertions(+), 60 deletions(-) diff --git a/src/vs/base/node/pfs.ts b/src/vs/base/node/pfs.ts index 1af9f028c70..14dca3d5f49 100644 --- a/src/vs/base/node/pfs.ts +++ b/src/vs/base/node/pfs.ts @@ -138,20 +138,6 @@ export async function readdir(path: string): Promise { return handleDirectoryChildren(await promisify(fs.readdir)(path)); } -export async function readdirWithFileTypes(path: string): Promise { - const children = await promisify(fs.readdir)(path, { withFileTypes: true }); - - // Mac: uses NFD unicode form on disk, but we want NFC - // See also https://github.com/nodejs/node/issues/2165 - if (platform.isMacintosh) { - for (const child of children) { - child.name = normalizeNFC(child.name); - } - } - - return children; -} - export function readdirSync(path: string): string[] { return handleDirectoryChildren(fs.readdirSync(path)); } diff --git a/src/vs/base/test/node/pfs/pfs.test.ts b/src/vs/base/test/node/pfs/pfs.test.ts index 060913bbe72..4f09ad2b56d 100644 --- a/src/vs/base/test/node/pfs/pfs.test.ts +++ b/src/vs/base/test/node/pfs/pfs.test.ts @@ -16,7 +16,6 @@ import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { isWindows, isLinux } from 'vs/base/common/platform'; import { canNormalize } from 'vs/base/common/normalization'; import { VSBuffer } from 'vs/base/common/buffer'; -import { join } from 'path'; const chunkSize = 64 * 1024; const readError = 'Error while reading'; @@ -387,31 +386,6 @@ suite('PFS', () => { } }); - test('readdirWithFileTypes', async () => { - if (canNormalize && typeof process.versions['electron'] !== 'undefined' /* needs electron */) { - const id = uuid.generateUuid(); - const parentDir = path.join(os.tmpdir(), 'vsctests', id); - const testDir = join(parentDir, 'pfs', id); - - const newDir = path.join(testDir, 'öäü'); - await pfs.mkdirp(newDir, 493); - - await pfs.writeFile(join(testDir, 'somefile.txt'), 'contents'); - - assert.ok(fs.existsSync(newDir)); - - const children = await pfs.readdirWithFileTypes(testDir); - - assert.equal(children.some(n => n.name === 'öäü'), true); // Mac always converts to NFD, so - assert.equal(children.some(n => n.isDirectory()), true); - - assert.equal(children.some(n => n.name === 'somefile.txt'), true); - assert.equal(children.some(n => n.isFile()), true); - - await pfs.rimraf(parentDir); - } - }); - test('writeFile (string)', async () => { const smallData = 'Hello World'; const bigData = (new Array(100 * 1024)).join('Large String\n'); diff --git a/src/vs/platform/files/node/diskFileSystemProvider.ts b/src/vs/platform/files/node/diskFileSystemProvider.ts index 0ab6883d353..12d5847389d 100644 --- a/src/vs/platform/files/node/diskFileSystemProvider.ts +++ b/src/vs/platform/files/node/diskFileSystemProvider.ts @@ -3,14 +3,14 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { mkdir, open, close, read, write, fdatasync, Dirent, Stats } from 'fs'; +import { mkdir, open, close, read, write, fdatasync } from 'fs'; import { promisify } from 'util'; import { IDisposable, Disposable, toDisposable, dispose, combinedDisposable } from 'vs/base/common/lifecycle'; import { IFileSystemProvider, FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileType, FileDeleteOptions, FileOverwriteOptions, FileWriteOptions, FileOpenOptions, FileSystemProviderErrorCode, createFileSystemProviderError, FileSystemProviderError } from 'vs/platform/files/common/files'; import { URI } from 'vs/base/common/uri'; import { Event, Emitter } from 'vs/base/common/event'; import { isLinux, isWindows } from 'vs/base/common/platform'; -import { statLink, unlink, move, copy, readFile, truncate, rimraf, RimRafMode, exists, readdirWithFileTypes } from 'vs/base/node/pfs'; +import { statLink, readdir, unlink, move, copy, readFile, truncate, rimraf, RimRafMode, exists } from 'vs/base/node/pfs'; import { normalize, basename, dirname } from 'vs/base/common/path'; import { joinPath } from 'vs/base/common/resources'; import { isEqual } from 'vs/base/common/extpath'; @@ -62,8 +62,15 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro try { const { stat, isSymbolicLink } = await statLink(this.toFilePath(resource)); // cannot use fs.stat() here to support links properly + let type: number; + if (isSymbolicLink) { + type = FileType.SymbolicLink | (stat.isDirectory() ? FileType.Directory : FileType.File); + } else { + type = stat.isFile() ? FileType.File : stat.isDirectory() ? FileType.Directory : FileType.Unknown; + } + return { - type: this.toType(stat, isSymbolicLink), + type, ctime: stat.ctime.getTime(), mtime: stat.mtime.getTime(), size: stat.size @@ -75,19 +82,13 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro async readdir(resource: URI): Promise<[string, FileType][]> { try { - const children = await readdirWithFileTypes(this.toFilePath(resource)); + const children = await readdir(this.toFilePath(resource)); const result: [string, FileType][] = []; await Promise.all(children.map(async child => { try { - let type: FileType; - if (child.isSymbolicLink()) { - type = (await this.stat(joinPath(resource, child.name))).type; // always resolve target the link points to if any - } else { - type = this.toType(child); - } - - result.push([child.name, type]); + const stat = await this.stat(joinPath(resource, child)); + result.push([child, stat.type]); } catch (error) { this.logService.trace(error); // ignore errors for individual entries that can arise from permission denied } @@ -99,14 +100,6 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro } } - private toType(entry: Stats | Dirent, isSymbolicLink = entry.isSymbolicLink()): FileType { - if (isSymbolicLink) { - return FileType.SymbolicLink | (entry.isDirectory() ? FileType.Directory : FileType.File); - } - - return entry.isFile() ? FileType.File : entry.isDirectory() ? FileType.Directory : FileType.Unknown; - } - //#endregion //#region File Reading/Writing From de320052255d136673fc5eee358f6e2551d6573e Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 12 Aug 2019 08:49:19 +0200 Subject: [PATCH 450/861] fixes #78832 --- build/gulpfile.vscode.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index b4c8db80ad7..189cf4f560e 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -365,12 +365,15 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op .pipe(electron(_.extend({}, config, { platform, arch, ffmpegChromium: true }))) .pipe(filter(['**', '!LICENSE', '!LICENSES.chromium.html', '!version'], { dot: true })); - result = es.merge(result, gulp.src('resources/completions/bash/code', { base: '.' }) - .pipe(replace('@@APPNAME@@', product.applicationName)) - .pipe(rename(function (f) { f.basename = product.applicationName; }))); - result = es.merge(result, gulp.src('resources/completions/zsh/_code', { base: '.' }) - .pipe(replace('@@APPNAME@@', product.applicationName)) - .pipe(rename(function (f) { f.basename = '_' + product.applicationName; }))); + if (platform === 'linux') { + result = es.merge(result, gulp.src('resources/completions/bash/code', { base: '.' }) + .pipe(replace('@@APPNAME@@', product.applicationName)) + .pipe(rename(function (f) { f.basename = product.applicationName; }))); + + result = es.merge(result, gulp.src('resources/completions/zsh/_code', { base: '.' }) + .pipe(replace('@@APPNAME@@', product.applicationName)) + .pipe(rename(function (f) { f.basename = '_' + product.applicationName; }))); + } if (platform === 'win32') { result = es.merge(result, gulp.src('resources/win32/bin/code.js', { base: 'resources/win32', allowEmpty: true })); From 4eb850d80dc47156d13bcd51157127ab95963b06 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 12 Aug 2019 09:35:19 +0200 Subject: [PATCH 451/861] clarify trigger characters, #78781 --- src/vs/vscode.d.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index d1e2a6c8167..25271cbcf99 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -8092,9 +8092,14 @@ declare module 'vscode' { * result. A failing provider (rejected promise or exception) will not fail the whole * operation. * + * A completion item provider can be associated with a set of `triggerCharacters`. When trigger + * characters are being typed, completions are requested but only from providers that registered + * the typed character. Because of that trigger characters should be different than [word characters](#LanguageConfiguration.wordPattern), + * a common trigger character is `.` to trigger member completions. + * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A completion provider. - * @param triggerCharacters Trigger completion when the user types one of the characters, like `.` or `:`. + * @param triggerCharacters Trigger completion when the user types one of the characters. * @return A [disposable](#Disposable) that unregisters this provider when being disposed. */ export function registerCompletionItemProvider(selector: DocumentSelector, provider: CompletionItemProvider, ...triggerCharacters: string[]): Disposable; From 9d709b8ddded896015680179370ccd9b4a2b99f8 Mon Sep 17 00:00:00 2001 From: jeanp413 Date: Mon, 12 Aug 2019 03:11:56 -0500 Subject: [PATCH 452/861] Force refresh on setInput in settingEditor. Fixes #78931 --- src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts index ab5ec782a39..986cef51818 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts @@ -846,7 +846,7 @@ export class SettingsEditor2 extends BaseEditor { this._register(model.onDidChangeGroups(() => this.onConfigUpdate())); this.defaultSettingsEditorModel = model; - return this.onConfigUpdate(); + return this.onConfigUpdate(undefined, true); }); } return Promise.resolve(null); From 756c90de9d0edef64dafd6dbd504aa5a6e09e3c0 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 12 Aug 2019 10:32:18 +0200 Subject: [PATCH 453/861] fix #78883 --- src/vs/editor/contrib/snippet/snippetParser.ts | 16 ++++++++++++---- .../contrib/snippet/test/snippetParser.test.ts | 13 +++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/snippet/snippetParser.ts b/src/vs/editor/contrib/snippet/snippetParser.ts index c4b568d38fd..61e0fd2a802 100644 --- a/src/vs/editor/contrib/snippet/snippetParser.ts +++ b/src/vs/editor/contrib/snippet/snippetParser.ts @@ -667,16 +667,24 @@ export class SnippetParser { if (this._token.type === TokenType.EOF) { return false; } - let start = this._token; - while (this._token.type !== type) { + let res = ''; + let pos = this._token.pos; + let prevToken = { type: TokenType.EOF, pos: 0, len: 0 }; + + while (this._token.type !== type || prevToken.type === TokenType.Backslash) { + if (this._token.type === type) { + res += this._scanner.value.substring(pos, prevToken.pos); + pos = this._token.pos; + } + prevToken = this._token; this._token = this._scanner.next(); if (this._token.type === TokenType.EOF) { return false; } } - let value = this._scanner.value.substring(start.pos, this._token.pos); + res += this._scanner.value.substring(pos, this._token.pos); this._token = this._scanner.next(); - return value; + return res; } private _parse(marker: Marker): boolean { diff --git a/src/vs/editor/contrib/snippet/test/snippetParser.test.ts b/src/vs/editor/contrib/snippet/test/snippetParser.test.ts index 165be28f1c7..f999da850bc 100644 --- a/src/vs/editor/contrib/snippet/test/snippetParser.test.ts +++ b/src/vs/editor/contrib/snippet/test/snippetParser.test.ts @@ -754,4 +754,17 @@ suite('SnippetParser', () => { let snippet = new SnippetParser().parse('namespace ${TM_DIRECTORY/[\\/]/\\\\/g};'); assertMarker(snippet, Text, Variable, Text); }); + + test('Snippet cannot escape closing bracket inside conditional insertion variable replacement #78883', function () { + + let snippet = new SnippetParser().parse('${TM_DIRECTORY/(.+)/${1:+import { hello \\} from world}/}'); + let variable = snippet.children[0]; + assert.equal(snippet.children.length, 1); + assert.ok(variable instanceof Variable); + assert.ok(variable.transform); + assert.equal(variable.transform!.children.length, 1); + assert.ok(variable.transform!.children[0] instanceof FormatString); + assert.equal((variable.transform!.children[0]).ifValue, 'import { hello } from world'); + assert.equal((variable.transform!.children[0]).elseValue, undefined); + }); }); From 7099b785c73ad44170d9869e9f8ff6486b763049 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Mon, 12 Aug 2019 10:50:51 +0200 Subject: [PATCH 454/861] Fixes #78527: Remove odd/even quote counting --- .../common/controller/cursorTypeOperations.ts | 10 ------- .../test/browser/controller/cursor.test.ts | 28 +++++++++++++++++++ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/vs/editor/common/controller/cursorTypeOperations.ts b/src/vs/editor/common/controller/cursorTypeOperations.ts index efa30c1b5cc..7ea1d26dffd 100644 --- a/src/vs/editor/common/controller/cursorTypeOperations.ts +++ b/src/vs/editor/common/controller/cursorTypeOperations.ts @@ -437,8 +437,6 @@ export class TypeOperations { return false; } - const isEqualPair = (ch === config.autoClosingPairsClose[ch]); - for (let i = 0, len = selections.length; i < len; i++) { const selection = selections[i]; @@ -454,14 +452,6 @@ export class TypeOperations { return false; } - if (isEqualPair) { - const lineTextBeforeCursor = lineText.substr(0, position.column - 1); - const chCntBefore = this._countNeedlesInHaystack(lineTextBeforeCursor, ch); - if (chCntBefore % 2 === 0) { - return false; - } - } - // Must over-type a closing character typed by the editor let found = false; for (let j = 0, lenJ = autoClosedCharacters.length; j < lenJ; j++) { diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index 6335cdddf8c..a42bd6d06c3 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -4664,6 +4664,34 @@ suite('autoClosingPairs', () => { mode.dispose(); }); + test('issue #78527 - does not close quote on odd count', () => { + let mode = new AutoClosingMode(); + usingCursor({ + text: [ + 'std::cout << \'"\' << entryMap' + ], + languageIdentifier: mode.getLanguageIdentifier() + }, (model, cursor) => { + cursor.setSelections('test', [new Selection(1, 29, 1, 29)]); + + cursorCommand(cursor, H.Type, { text: '[' }, 'keyboard'); + assert.strictEqual(model.getLineContent(1), 'std::cout << \'"\' << entryMap[]'); + + cursorCommand(cursor, H.Type, { text: '"' }, 'keyboard'); + assert.strictEqual(model.getLineContent(1), 'std::cout << \'"\' << entryMap[""]'); + + cursorCommand(cursor, H.Type, { text: 'a' }, 'keyboard'); + assert.strictEqual(model.getLineContent(1), 'std::cout << \'"\' << entryMap["a"]'); + + cursorCommand(cursor, H.Type, { text: '"' }, 'keyboard'); + assert.strictEqual(model.getLineContent(1), 'std::cout << \'"\' << entryMap["a"]'); + + cursorCommand(cursor, H.Type, { text: ']' }, 'keyboard'); + assert.strictEqual(model.getLineContent(1), 'std::cout << \'"\' << entryMap["a"]'); + }); + mode.dispose(); + }); + test('issue #15825: accents on mac US intl keyboard', () => { let mode = new AutoClosingMode(); usingCursor({ From f41f8a8d077b591fa8f2acbea08fb6af25d970ea Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 12 Aug 2019 10:55:41 +0200 Subject: [PATCH 455/861] move webWorkerExtHostStarter --- .../webWorkerExtensionHostStarter.ts | 0 .../services/extensions/electron-browser/extensionService.ts | 2 +- tslint.json | 3 ++- 3 files changed, 3 insertions(+), 2 deletions(-) rename src/vs/workbench/services/extensions/{electron-browser => browser}/webWorkerExtensionHostStarter.ts (100%) diff --git a/src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts similarity index 100% rename from src/vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter.ts rename to src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index 8d8b85b0f01..ec33b228a2c 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -34,7 +34,7 @@ import { IFileService } from 'vs/platform/files/common/files'; import { PersistentConnectionEventType } from 'vs/platform/remote/common/remoteAgentConnection'; import { IProductService } from 'vs/platform/product/common/product'; import { Logger } from 'vs/workbench/services/extensions/common/extensionPoints'; -import { WebWorkerExtensionHostStarter } from 'vs/workbench/services/extensions/electron-browser/webWorkerExtensionHostStarter'; +import { WebWorkerExtensionHostStarter } from 'vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter'; class DeltaExtensionsQueueItem { constructor( diff --git a/tslint.json b/tslint.json index cb43495ba08..f5d3c5ba2ab 100644 --- a/tslint.json +++ b/tslint.json @@ -452,11 +452,12 @@ "restrictions": [ "vs/nls", "vs/css!./**/*", - "**/vs/base/**/{common,browser}/**", + "**/vs/base/**/{common,browser,worker}/**", "**/vs/platform/**/{common,browser}/**", "**/vs/editor/{common,browser}/**", "**/vs/workbench/workbench.web.api", "**/vs/workbench/{common,browser}/**", + "**/vs/workbench/api/{common,browser}/**", "**/vs/workbench/services/**/{common,browser}/**", "vscode-textmate", "onigasm-umd" From 7212908c2c2687b55f20cff0ca9c10cad7579f90 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 12 Aug 2019 11:00:37 +0200 Subject: [PATCH 456/861] some clean up --- .../browser/webWorkerExtensionHostStarter.ts | 41 +++++-------------- 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts index 4c8492f1409..ae158efeae8 100644 --- a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts +++ b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts @@ -3,12 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IWorkbenchContribution, Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; -import { Registry } from 'vs/platform/registry/common/platform'; -import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { DefaultWorkerFactory } from 'vs/base/worker/defaultWorkerFactory'; import { Emitter, Event } from 'vs/base/common/event'; -import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { DisposableStore } from 'vs/base/common/lifecycle'; import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; import { VSBuffer } from 'vs/base/common/buffer'; import { createMessageOfType, MessageType, isMessageOfType } from 'vs/workbench/services/extensions/common/extensionHostProtocol'; @@ -26,9 +23,9 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { + private _toDispose = new DisposableStore(); + private _isTerminating: boolean = false; private _protocol?: IMessagePassingProtocol; - private _isTerminating?: boolean; - private _toDispose: IDisposable[] = []; private readonly _onDidExit = new Emitter<[number, string | null]>(); readonly onExit: Event<[number, string | null]> = this._onDidExit.event; @@ -67,7 +64,8 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { ); // keep for cleanup - this._toDispose.push(worker, emitter); + this._toDispose.add(emitter); + this._toDispose.add(worker); const protocol: IMessagePassingProtocol = { onMessage: emitter.event, @@ -94,16 +92,15 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { dispose(): void { if (!this._protocol) { - // nothing else to do - dispose(this._toDispose); + this._toDispose.dispose(); return; } - if (!this._isTerminating) { - this._isTerminating = true; - - this._protocol.send(createMessageOfType(MessageType.Terminate)); - setTimeout(() => dispose(this._toDispose), 10 * 1000); + if (this._isTerminating) { + return; } + this._isTerminating = true; + this._protocol.send(createMessageOfType(MessageType.Terminate)); + setTimeout(() => this._toDispose.dispose(), 10 * 1000); } getInspectPort(): number | undefined { @@ -153,19 +150,3 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { }); } } - -class WorkerExtensionHost extends Disposable implements IWorkbenchContribution { - - constructor() { - super(); - // new ExtensionHostWebWorker().start().then(protocol => { - - // }); - } -} - -Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution( - WorkerExtensionHost, - LifecyclePhase.Ready -); - From 777c424d5c50d72e372a451c321f4f4b14731048 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 12 Aug 2019 11:03:29 +0200 Subject: [PATCH 457/861] no process, prefer async/await --- .../browser/webWorkerExtensionHostStarter.ts | 79 +++++++++---------- 1 file changed, 38 insertions(+), 41 deletions(-) diff --git a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts index ae158efeae8..e8c1d06dd9e 100644 --- a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts +++ b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts @@ -107,46 +107,43 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { return undefined; } - private _createExtHostInitData(): Promise { - return Promise.all([this._telemetryService.getTelemetryInfo(), this._extensions]) - .then(([telemetryInfo, extensionDescriptions]) => { - const workspace = this._contextService.getWorkspace(); - const r: IInitData = { - commit: this._productService.commit, - version: this._productService.version, - parentPid: process.pid, - environment: { - isExtensionDevelopmentDebug: false, // < todo@joh - appRoot: this._environmentService.appRoot ? URI.file(this._environmentService.appRoot) : undefined, - appSettingsHome: this._environmentService.appSettingsHome ? this._environmentService.appSettingsHome : undefined, - appName: this._productService.nameLong, - appUriScheme: this._productService.urlProtocol, - appLanguage: platform.language, - extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI, - extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI, - globalStorageHome: URI.file(this._environmentService.globalStorageHome), - userHome: URI.file(this._environmentService.userHome), - webviewResourceRoot: this._environmentService.webviewResourceRoot, - webviewCspSource: this._environmentService.webviewCspSource, - }, - workspace: this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? undefined : { - configuration: workspace.configuration || undefined, - id: workspace.id, - name: this._labelService.getWorkspaceLabel(workspace) - }, - resolvedExtensions: [], - hostExtensions: [], - extensions: extensionDescriptions, - telemetryInfo, - logLevel: this._logService.getLevel(), - logsLocation: this._extensionHostLogsLocation, - autoStart: true,// < todo@joh this._autoStart, - remote: { - authority: this._environmentService.configuration.remoteAuthority, - isRemote: false - }, - }; - return r; - }); + private async _createExtHostInitData(): Promise { + const [telemetryInfo, extensionDescriptions] = await Promise.all([this._telemetryService.getTelemetryInfo(), this._extensions]); + const workspace = this._contextService.getWorkspace(); + return { + commit: this._productService.commit, + version: this._productService.version, + parentPid: -1, + environment: { + isExtensionDevelopmentDebug: false, + appRoot: this._environmentService.appRoot ? URI.file(this._environmentService.appRoot) : undefined, + appSettingsHome: this._environmentService.appSettingsHome ? this._environmentService.appSettingsHome : undefined, + appName: this._productService.nameLong, + appUriScheme: this._productService.urlProtocol, + appLanguage: platform.language, + extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI, + extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI, + globalStorageHome: URI.file(this._environmentService.globalStorageHome), + userHome: URI.file(this._environmentService.userHome), + webviewResourceRoot: this._environmentService.webviewResourceRoot, + webviewCspSource: this._environmentService.webviewCspSource, + }, + workspace: this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? undefined : { + configuration: workspace.configuration || undefined, + id: workspace.id, + name: this._labelService.getWorkspaceLabel(workspace) + }, + resolvedExtensions: [], + hostExtensions: [], + extensions: extensionDescriptions, + telemetryInfo, + logLevel: this._logService.getLevel(), + logsLocation: this._extensionHostLogsLocation, + autoStart: true, + remote: { + authority: this._environmentService.configuration.remoteAuthority, + isRemote: false + }, + }; } } From eeef7938483549b250ee3cf49daca5b1e3c72611 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 12 Aug 2019 11:04:12 +0200 Subject: [PATCH 458/861] web - add support for showing about dialog --- .../product/browser/productService.ts | 8 ++-- src/vs/platform/product/common/product.ts | 9 +++-- .../browser/actions/windowActions.ts | 37 +++++++++++++++++-- .../workbench/browser/web.simpleservices.ts | 26 +++++++++++-- .../electron-browser/actions/windowActions.ts | 20 ---------- .../electron-browser/main.contribution.ts | 35 ++++++------------ 6 files changed, 78 insertions(+), 57 deletions(-) diff --git a/src/vs/platform/product/browser/productService.ts b/src/vs/platform/product/browser/productService.ts index 34ad8bb76b5..0c851b04fc1 100644 --- a/src/vs/platform/product/browser/productService.ts +++ b/src/vs/platform/product/browser/productService.ts @@ -8,6 +8,8 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio export class ProductService implements IProductService { + _serviceBrand!: ServiceIdentifier; + private readonly productConfiguration: IProductConfiguration | null; constructor() { @@ -15,13 +17,11 @@ export class ProductService implements IProductService { this.productConfiguration = element ? JSON.parse(element.getAttribute('data-settings')!) : null; } - _serviceBrand!: ServiceIdentifier; - - get version(): string { return '1.35.0'; } + get version(): string { return this.productConfiguration ? this.productConfiguration.version : 'Unknown'; } get commit(): string | undefined { return this.productConfiguration ? this.productConfiguration.commit : undefined; } - get nameLong(): string { return ''; } + get nameLong(): string { return this.productConfiguration ? this.productConfiguration.nameLong : 'Unknown'; } get urlProtocol(): string { return ''; } diff --git a/src/vs/platform/product/common/product.ts b/src/vs/platform/product/common/product.ts index d39dd65c08f..05048ee0908 100644 --- a/src/vs/platform/product/common/product.ts +++ b/src/vs/platform/product/common/product.ts @@ -3,15 +3,17 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; export const IProductService = createDecorator('productService'); export interface IProductService { - _serviceBrand: any; + + _serviceBrand: ServiceIdentifier; readonly version: string; readonly commit?: string; + readonly date?: string; readonly nameLong: string; readonly urlProtocol: string; @@ -44,6 +46,7 @@ export interface IProductService { } export interface IProductConfiguration { + readonly version: string; nameShort: string; nameLong: string; readonly applicationName: string; @@ -134,4 +137,4 @@ export interface ISurveyData { languageId: string; editCount: number; userProbability: number; -} \ No newline at end of file +} diff --git a/src/vs/workbench/browser/actions/windowActions.ts b/src/vs/workbench/browser/actions/windowActions.ts index 838875097c8..928ab7ae0af 100644 --- a/src/vs/workbench/browser/actions/windowActions.ts +++ b/src/vs/workbench/browser/actions/windowActions.ts @@ -7,11 +7,11 @@ import 'vs/css!./media/actions'; import * as nls from 'vs/nls'; import { Action } from 'vs/base/common/actions'; -import { IWindowService, IURIToOpen } from 'vs/platform/windows/common/windows'; +import { IWindowService, IURIToOpen, IWindowsService } from 'vs/platform/windows/common/windows'; import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { Registry } from 'vs/platform/registry/common/platform'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; -import { IsFullscreenContext, IsDevelopmentContext } from 'vs/workbench/browser/contextkeys'; +import { IsFullscreenContext, IsDevelopmentContext, IsMacNativeContext } from 'vs/workbench/browser/contextkeys'; import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; @@ -226,6 +226,24 @@ export class ReloadWindowAction extends Action { } } +export class ShowAboutDialogAction extends Action { + + static readonly ID = 'workbench.action.showAboutDialog'; + static readonly LABEL = nls.localize('about', "About"); + + constructor( + id: string, + label: string, + @IWindowsService private readonly windowsService: IWindowsService + ) { + super(id, label); + } + + run(): Promise { + return this.windowsService.openAboutDialog(); + } +} + const registry = Registry.as(Extensions.WorkbenchActions); // --- Actions Registration @@ -240,6 +258,9 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleFullScreenAction const developerCategory = nls.localize('developer', "Developer"); registry.registerWorkbenchAction(new SyncActionDescriptor(ReloadWindowAction, ReloadWindowAction.ID, ReloadWindowAction.LABEL), 'Developer: Reload Window', developerCategory); +const helpCategory = nls.localize('help', "Help"); +registry.registerWorkbenchAction(new SyncActionDescriptor(ShowAboutDialogAction, ShowAboutDialogAction.ID, ShowAboutDialogAction.LABEL), `Help: About`, helpCategory); + // --- Commands/Keybindings Registration const recentFilesPickerContext = ContextKeyExpr.and(inQuickOpenContext, ContextKeyExpr.has(inRecentFilesPickerContextKey)); @@ -297,4 +318,14 @@ MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, { toggled: IsFullscreenContext }, order: 1 -}); \ No newline at end of file +}); + +MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { + group: 'z_about', + command: { + id: ShowAboutDialogAction.ID, + title: nls.localize({ key: 'miAbout', comment: ['&& denotes a mnemonic'] }, "&&About") + }, + order: 1, + when: IsMacNativeContext.toNegated() +}); diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index f60961dbdff..b32f33c6bd0 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -35,6 +35,11 @@ import { toStoreData, restoreRecentlyOpened } from 'vs/platform/history/common/h // tslint:disable-next-line: import-patterns import { IExperimentService, IExperiment, ExperimentActionType, ExperimentState } from 'vs/workbench/contrib/experiments/common/experimentService'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; +import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; +import { IProductService } from 'vs/platform/product/common/product'; +import Severity from 'vs/base/common/severity'; +import { localize } from 'vs/nls'; +import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; //#region Extension Tips @@ -516,7 +521,10 @@ export class SimpleWindowsService implements IWindowsService { readonly onRecentlyOpenedChange: Event = Event.None; constructor( - @IWorkbenchEnvironmentService private readonly workbenchEnvironmentService: IWorkbenchEnvironmentService + @IWorkbenchEnvironmentService private readonly workbenchEnvironmentService: IWorkbenchEnvironmentService, + @IDialogService private readonly dialogService: IDialogService, + @IProductService private readonly productService: IProductService, + @IClipboardService private readonly clipboardService: IClipboardService ) { } isFocused(_windowId: number): Promise { @@ -772,8 +780,20 @@ export class SimpleWindowsService implements IWindowsService { throw new Error('not implemented'); } - openAboutDialog(): Promise { - return Promise.resolve(); + async openAboutDialog(): Promise { + const detail = localize('aboutDetail', + "Version: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}", + this.productService.version || 'Unknown', + this.productService.commit || 'Unknown', + this.productService.date || 'Unknown', + navigator.userAgent + ); + + const result = await this.dialogService.show(Severity.Info, this.productService.nameLong, [localize('copy', "Copy"), localize('ok', "OK")], { detail }); + + if (result === 0) { + this.clipboardService.writeText(detail); + } } resolveProxy(windowId: number, url: string): Promise { diff --git a/src/vs/workbench/electron-browser/actions/windowActions.ts b/src/vs/workbench/electron-browser/actions/windowActions.ts index bc094a193fd..3203c32d897 100644 --- a/src/vs/workbench/electron-browser/actions/windowActions.ts +++ b/src/vs/workbench/electron-browser/actions/windowActions.ts @@ -15,7 +15,6 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { IModeService } from 'vs/editor/common/services/modeService'; import { IQuickInputService, IQuickInputButton } from 'vs/platform/quickinput/common/quickInput'; import { getIconClasses } from 'vs/editor/common/services/getIconClasses'; -import product from 'vs/platform/product/node/product'; import { ICommandHandler } from 'vs/platform/commands/common/commands'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -275,25 +274,6 @@ export class QuickSwitchWindow extends BaseSwitchWindow { } } - -export class ShowAboutDialogAction extends Action { - - static readonly ID = 'workbench.action.showAboutDialog'; - static LABEL = nls.localize('about', "About {0}", product.applicationName); - - constructor( - id: string, - label: string, - @IWindowsService private readonly windowsService: IWindowsService - ) { - super(id, label); - } - - run(): Promise { - return this.windowsService.openAboutDialog(); - } -} - export const NewWindowTabHandler: ICommandHandler = function (accessor: ServicesAccessor) { return accessor.get(IWindowsService).newWindowTab(); }; diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index fd3b1bf5bab..4545d9ba830 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -13,7 +13,7 @@ import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes'; import { isWindows, isLinux, isMacintosh } from 'vs/base/common/platform'; import { KeybindingsReferenceAction, OpenDocumentationUrlAction, OpenIntroductoryVideosUrlAction, OpenTipsAndTricksUrlAction, OpenTwitterUrlAction, OpenRequestFeatureUrlAction, OpenPrivacyStatementUrlAction, OpenLicenseUrlAction, OpenNewsletterSignupUrlAction } from 'vs/workbench/electron-browser/actions/helpActions'; import { ToggleSharedProcessAction, ToggleDevToolsAction } from 'vs/workbench/electron-browser/actions/developerActions'; -import { ShowAboutDialogAction, ZoomResetAction, ZoomOutAction, ZoomInAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, QuickSwitchWindow, ReloadWindowWithExtensionsDisabledAction, NewWindowTabHandler, ShowPreviousWindowTabHandler, ShowNextWindowTabHandler, MoveWindowTabToNewWindowHandler, MergeWindowTabsHandlerHandler, ToggleWindowTabsBarHandler } from 'vs/workbench/electron-browser/actions/windowActions'; +import { ZoomResetAction, ZoomOutAction, ZoomInAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, QuickSwitchWindow, ReloadWindowWithExtensionsDisabledAction, NewWindowTabHandler, ShowPreviousWindowTabHandler, ShowNextWindowTabHandler, MoveWindowTabToNewWindowHandler, MergeWindowTabsHandlerHandler, ToggleWindowTabsBarHandler } from 'vs/workbench/electron-browser/actions/windowActions'; import { AddRootFolderAction, GlobalRemoveRootFolderAction, SaveWorkspaceAsAction, OpenWorkspaceConfigFileAction, DuplicateWorkspaceInNewWindowAction, CloseWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; @@ -23,7 +23,6 @@ import { ADD_ROOT_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/workspa import { SupportsWorkspacesContext, IsMacContext, HasMacNativeTabsContext, IsDevelopmentContext, WorkbenchStateContext, WorkspaceFolderCountContext } from 'vs/workbench/browser/contextkeys'; import { NoEditorsVisibleContext, SingleEditorGroupsContext } from 'vs/workbench/common/editor'; import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows'; -import product from 'vs/platform/product/node/product'; // Actions (function registerActions(): void { @@ -53,7 +52,7 @@ import product from 'vs/platform/product/node/product'; registry.registerWorkbenchAction(new SyncActionDescriptor(QuickSwitchWindow, QuickSwitchWindow.ID, QuickSwitchWindow.LABEL), 'Quick Switch Window...'); KeybindingsRegistry.registerCommandAndKeybindingRule({ - id: 'workbench.action.closeWindow', // close the window when the last editor is closed by reusing the same keybinding + id: CloseCurrentWindowAction.ID, // close the window when the last editor is closed by reusing the same keybinding weight: KeybindingWeight.WorkbenchContrib, when: ContextKeyExpr.and(NoEditorsVisibleContext, SingleEditorGroupsContext), primary: KeyMod.CtrlCmd | KeyCode.KEY_W, @@ -163,7 +162,6 @@ import product from 'vs/platform/product/node/product'; registry.registerWorkbenchAction(new SyncActionDescriptor(OpenRequestFeatureUrlAction, OpenRequestFeatureUrlAction.ID, OpenRequestFeatureUrlAction.LABEL), 'Help: Search Feature Requests', helpCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(OpenLicenseUrlAction, OpenLicenseUrlAction.ID, OpenLicenseUrlAction.LABEL), 'Help: View License', helpCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(OpenPrivacyStatementUrlAction, OpenPrivacyStatementUrlAction.ID, OpenPrivacyStatementUrlAction.LABEL), 'Help: Privacy Statement', helpCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(ShowAboutDialogAction, ShowAboutDialogAction.ID, ShowAboutDialogAction.LABEL), `Help: About ${product.applicationName}`, helpCategory); })(); })(); @@ -272,7 +270,7 @@ import product from 'vs/platform/product/node/product'; MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { group: '1_welcome', command: { - id: 'workbench.action.openDocumentationUrl', + id: OpenDocumentationUrlAction.ID, title: nls.localize({ key: 'miDocumentation', comment: ['&& denotes a mnemonic'] }, "&&Documentation") }, order: 3 @@ -291,7 +289,7 @@ import product from 'vs/platform/product/node/product'; MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { group: '2_reference', command: { - id: 'workbench.action.keybindingsReference', + id: KeybindingsReferenceAction.ID, title: nls.localize({ key: 'miKeyboardShortcuts', comment: ['&& denotes a mnemonic'] }, "&&Keyboard Shortcuts Reference") }, order: 1 @@ -300,7 +298,7 @@ import product from 'vs/platform/product/node/product'; MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { group: '2_reference', command: { - id: 'workbench.action.openIntroductoryVideosUrl', + id: OpenIntroductoryVideosUrlAction.ID, title: nls.localize({ key: 'miIntroductoryVideos', comment: ['&& denotes a mnemonic'] }, "Introductory &&Videos") }, order: 2 @@ -309,7 +307,7 @@ import product from 'vs/platform/product/node/product'; MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { group: '2_reference', command: { - id: 'workbench.action.openTipsAndTricksUrl', + id: OpenTipsAndTricksUrlAction.ID, title: nls.localize({ key: 'miTipsAndTricks', comment: ['&& denotes a mnemonic'] }, "Tips and Tri&&cks") }, order: 3 @@ -319,7 +317,7 @@ import product from 'vs/platform/product/node/product'; MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { group: '3_feedback', command: { - id: 'workbench.action.openTwitterUrl', + id: OpenTwitterUrlAction.ID, title: nls.localize({ key: 'miTwitter', comment: ['&& denotes a mnemonic'] }, "&&Join Us on Twitter") }, order: 1 @@ -328,7 +326,7 @@ import product from 'vs/platform/product/node/product'; MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { group: '3_feedback', command: { - id: 'workbench.action.openRequestFeatureUrl', + id: OpenRequestFeatureUrlAction.ID, title: nls.localize({ key: 'miUserVoice', comment: ['&& denotes a mnemonic'] }, "&&Search Feature Requests") }, order: 2 @@ -347,7 +345,7 @@ import product from 'vs/platform/product/node/product'; MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { group: '4_legal', command: { - id: 'workbench.action.openLicenseUrl', + id: OpenLicenseUrlAction.ID, title: nls.localize({ key: 'miLicense', comment: ['&& denotes a mnemonic'] }, "View &&License") }, order: 1 @@ -356,7 +354,7 @@ import product from 'vs/platform/product/node/product'; MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { group: '4_legal', command: { - id: 'workbench.action.openPrivacyStatementUrl', + id: OpenPrivacyStatementUrlAction.ID, title: nls.localize({ key: 'miPrivacyStatement', comment: ['&& denotes a mnemonic'] }, "Privac&&y Statement") }, order: 2 @@ -366,7 +364,7 @@ import product from 'vs/platform/product/node/product'; MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { group: '5_tools', command: { - id: 'workbench.action.toggleDevTools', + id: ToggleDevToolsAction.ID, title: nls.localize({ key: 'miToggleDevTools', comment: ['&& denotes a mnemonic'] }, "&&Toggle Developer Tools") }, order: 1 @@ -380,17 +378,6 @@ import product from 'vs/platform/product/node/product'; }, order: 2 }); - - // About - MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { - group: 'z_about', - command: { - id: 'workbench.action.showAboutDialog', - title: nls.localize({ key: 'miAbout', comment: ['&& denotes a mnemonic'] }, "&&About") - }, - order: 1, - when: IsMacContext.toNegated() - }); })(); // Configuration From 94c69e0a4b2d1b223a69ae5c89d5abc72a37c972 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 12 Aug 2019 11:19:10 +0200 Subject: [PATCH 459/861] web ext host in web client, not in desktop client --- .../services/extensions/browser/extensionService.ts | 6 ++++++ .../extensions/browser/webWorkerExtensionHostStarter.ts | 4 ++-- .../extensions/electron-browser/extensionService.ts | 8 +------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/services/extensions/browser/extensionService.ts b/src/vs/workbench/services/extensions/browser/extensionService.ts index 077598d16d6..9969f284234 100644 --- a/src/vs/workbench/services/extensions/browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/browser/extensionService.ts @@ -18,6 +18,8 @@ import { ExtensionHostProcessManager } from 'vs/workbench/services/extensions/co import { RemoteExtensionHostClient, IInitDataProvider } from 'vs/workbench/services/extensions/common/remoteExtensionHostClient'; import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; +import { WebWorkerExtensionHostStarter } from 'vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter'; +import { URI } from 'vs/base/common/uri'; export class ExtensionService extends AbstractExtensionService implements IExtensionService { @@ -61,6 +63,10 @@ export class ExtensionService extends AbstractExtensionService implements IExten protected _createExtensionHosts(isInitialStart: boolean, initialActivationEvents: string[]): ExtensionHostProcessManager[] { const result: ExtensionHostProcessManager[] = []; + const webHostProcessWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, Promise.resolve([]), URI.parse('empty:value')); + const webHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, webHostProcessWorker, null, initialActivationEvents); + result.push(webHostProcessManager); + const remoteAgentConnection = this._remoteAgentService.getConnection()!; const remoteExtHostProcessWorker = this._instantiationService.createInstance(RemoteExtensionHostClient, this.getExtensions(), this._createProvider(remoteAgentConnection.remoteAuthority), this._remoteAgentService.socketFactory); const remoteExtHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, remoteExtHostProcessWorker, remoteAgentConnection.remoteAuthority, initialActivationEvents); diff --git a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts index e8c1d06dd9e..a88545f4e31 100644 --- a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts +++ b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts @@ -123,8 +123,8 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { appLanguage: platform.language, extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI, extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI, - globalStorageHome: URI.file(this._environmentService.globalStorageHome), - userHome: URI.file(this._environmentService.userHome), + globalStorageHome: URI.parse('fake:globalStorageHome'), //todo@joh URI.file(this._environmentService.globalStorageHome), + userHome: URI.parse('fake:userHome'), //todo@joh URI.file(this._environmentService.userHome), webviewResourceRoot: this._environmentService.webviewResourceRoot, webviewCspSource: this._environmentService.webviewCspSource, }, diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index ec33b228a2c..272f399268f 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -34,7 +34,6 @@ import { IFileService } from 'vs/platform/files/common/files'; import { PersistentConnectionEventType } from 'vs/platform/remote/common/remoteAgentConnection'; import { IProductService } from 'vs/platform/product/common/product'; import { Logger } from 'vs/workbench/services/extensions/common/extensionPoints'; -import { WebWorkerExtensionHostStarter } from 'vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter'; class DeltaExtensionsQueueItem { constructor( @@ -350,16 +349,11 @@ export class ExtensionService extends AbstractExtensionService implements IExten } const result: ExtensionHostProcessManager[] = []; - const workerExtensions: Record = { ['jrieken.helloworld']: true }; - const extHostProcessWorker = this._instantiationService.createInstance(ExtensionHostProcessWorker, autoStart, extensions.then(e => e.filter(e => !workerExtensions[e.identifier.value])), this._extensionHostLogsLocation); + const extHostProcessWorker = this._instantiationService.createInstance(ExtensionHostProcessWorker, autoStart, extensions, this._extensionHostLogsLocation); const extHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, true, extHostProcessWorker, null, initialActivationEvents); result.push(extHostProcessManager); - const webHostProcessWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, extensions.then(e => e.filter(e => workerExtensions[e.identifier.value])), this._extensionHostLogsLocation); - const webHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, webHostProcessWorker, null, initialActivationEvents); - result.push(webHostProcessManager); - const remoteAgentConnection = this._remoteAgentService.getConnection(); if (remoteAgentConnection) { const remoteExtHostProcessWorker = this._instantiationService.createInstance(RemoteExtensionHostClient, this.getExtensions(), this._createProvider(remoteAgentConnection.remoteAuthority), this._remoteAgentService.socketFactory); From 2ffbf2fc6c15b3aebde63307968ffc75cc9cc443 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Mon, 12 Aug 2019 11:21:21 +0200 Subject: [PATCH 460/861] Fix #78777 --- .../contrib/extensions/browser/media/extensionsViewlet.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css b/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css index cfc659bbbdf..ede6bff2a64 100644 --- a/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css +++ b/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css @@ -61,6 +61,10 @@ padding-left: 5px; } +.extensions-viewlet > .extensions .message-container .severity-icon { + flex-shrink: 0; +} + .extensions-viewlet > .extensions .monaco-list-row > .bookmark { display: inline-block; height: 20px; From f4a09e5eb8fda87661d68a5f7900ff9a22cbd954 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 12 Aug 2019 11:28:10 +0200 Subject: [PATCH 461/861] don't use Buffer in /common/ --- .../extensions/common/extensionHostProcessManager.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/services/extensions/common/extensionHostProcessManager.ts b/src/vs/workbench/services/extensions/common/extensionHostProcessManager.ts index 68c824b46c3..f8067e33e0d 100644 --- a/src/vs/workbench/services/extensions/common/extensionHostProcessManager.ts +++ b/src/vs/workbench/services/extensions/common/extensionHostProcessManager.ts @@ -154,9 +154,13 @@ export class ExtensionHostProcessManager extends Disposable { private async _measureUp(proxy: ExtHostExtensionServiceShape): Promise { const SIZE = 10 * 1024 * 1024; // 10MB - let b = Buffer.alloc(SIZE, Math.random() % 256); + let buff = VSBuffer.alloc(SIZE); + let value = Math.ceil(Math.random() * 256); + for (let i = 0; i < buff.byteLength; i++) { + buff.writeUInt8(i, value); + } const sw = StopWatch.create(true); - await proxy.$test_up(VSBuffer.wrap(b)); + await proxy.$test_up(buff); sw.stop(); return ExtensionHostProcessManager._convert(SIZE, sw.elapsed()); } From 493d512f0b91b738f0ea0830d72bfe4029e284ab Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 12 Aug 2019 11:56:30 +0200 Subject: [PATCH 462/861] properly expose remote info --- .../services/extensions/browser/extensionService.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/services/extensions/browser/extensionService.ts b/src/vs/workbench/services/extensions/browser/extensionService.ts index 9969f284234..cd80cb266fa 100644 --- a/src/vs/workbench/services/extensions/browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/browser/extensionService.ts @@ -63,11 +63,12 @@ export class ExtensionService extends AbstractExtensionService implements IExten protected _createExtensionHosts(isInitialStart: boolean, initialActivationEvents: string[]): ExtensionHostProcessManager[] { const result: ExtensionHostProcessManager[] = []; - const webHostProcessWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, Promise.resolve([]), URI.parse('empty:value')); - const webHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, webHostProcessWorker, null, initialActivationEvents); + const remoteAgentConnection = this._remoteAgentService.getConnection()!; + + const webHostProcessWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, Promise.resolve([]), URI.parse('empty:value')); //todo@joh + const webHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, webHostProcessWorker, remoteAgentConnection.remoteAuthority, initialActivationEvents); result.push(webHostProcessManager); - const remoteAgentConnection = this._remoteAgentService.getConnection()!; const remoteExtHostProcessWorker = this._instantiationService.createInstance(RemoteExtensionHostClient, this.getExtensions(), this._createProvider(remoteAgentConnection.remoteAuthority), this._remoteAgentService.socketFactory); const remoteExtHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, remoteExtHostProcessWorker, remoteAgentConnection.remoteAuthority, initialActivationEvents); result.push(remoteExtHostProcessManager); From 524646514e5cd68c6c930f1b0b3ae0957fc08c29 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 12 Aug 2019 11:58:15 +0200 Subject: [PATCH 463/861] web - first cut workbench.common.main to share dependencies between web and desktop --- .../contrib/tasks/browser/taskService.ts | 7 +- .../tasks/electron-browser/taskService.ts | 7 +- .../browser/terminalInstanceService.ts | 3 + .../terminal/browser/terminalNativeService.ts | 5 +- .../webview/browser/webviewEditorService.ts | 3 + .../contrib/webview/browser/webviewService.ts | 3 + src/vs/workbench/workbench.common.main.ts | 168 ++++++++++++++ src/vs/workbench/workbench.main.ts | 156 ++----------- src/vs/workbench/workbench.web.main.ts | 214 ++---------------- 9 files changed, 227 insertions(+), 339 deletions(-) create mode 100644 src/vs/workbench/workbench.common.main.ts diff --git a/src/vs/workbench/contrib/tasks/browser/taskService.ts b/src/vs/workbench/contrib/tasks/browser/taskService.ts index 17442169909..a7dbc2aaa3f 100644 --- a/src/vs/workbench/contrib/tasks/browser/taskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/taskService.ts @@ -9,7 +9,8 @@ import { ITaskSystem } from 'vs/workbench/contrib/tasks/common/taskSystem'; import { ExecutionEngine, TaskRunSource } from 'vs/workbench/contrib/tasks/common/tasks'; import { TerminalTaskSystem } from './terminalTaskSystem'; import { AbstractTaskService, WorkspaceFolderConfigurationResult } from 'vs/workbench/contrib/tasks/browser/abstractTaskService'; -import { TaskFilter } from 'vs/workbench/contrib/tasks/common/taskService'; +import { TaskFilter, ITaskService } from 'vs/workbench/contrib/tasks/common/taskService'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export class TaskService extends AbstractTaskService { private static readonly ProcessTaskSystemSupportMessage = nls.localize('taskService.processTaskSystem', 'Process task system is not support in the web.'); @@ -48,4 +49,6 @@ export class TaskService extends AbstractTaskService { protected versionAndEngineCompatible(filter?: TaskFilter): boolean { return this.executionEngine === ExecutionEngine.Terminal; } -} \ No newline at end of file +} + +registerSingleton(ITaskService, TaskService, true); diff --git a/src/vs/workbench/contrib/tasks/electron-browser/taskService.ts b/src/vs/workbench/contrib/tasks/electron-browser/taskService.ts index decffe55e63..4dbac3fbf91 100644 --- a/src/vs/workbench/contrib/tasks/electron-browser/taskService.ts +++ b/src/vs/workbench/contrib/tasks/electron-browser/taskService.ts @@ -13,7 +13,8 @@ import * as TaskConfig from '../common/taskConfiguration'; import { ProcessTaskSystem } from 'vs/workbench/contrib/tasks/node/processTaskSystem'; import { ProcessRunnerDetector } from 'vs/workbench/contrib/tasks/node/processRunnerDetector'; import { AbstractTaskService } from 'vs/workbench/contrib/tasks/browser/abstractTaskService'; -import { TaskFilter } from 'vs/workbench/contrib/tasks/common/taskService'; +import { TaskFilter, ITaskService } from 'vs/workbench/contrib/tasks/common/taskService'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; interface WorkspaceFolderConfigurationResult { workspaceFolder: IWorkspaceFolder; @@ -132,4 +133,6 @@ export class TaskService extends AbstractTaskService { } return result; } -} \ No newline at end of file +} + +registerSingleton(ITaskService, TaskService, true); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts index 3ed29f8f3bc..8eff2daf466 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts @@ -10,6 +10,7 @@ import { WebLinksAddon as XTermWebLinksAddon } from 'xterm-addon-web-links'; import { SearchAddon as XTermSearchAddon } from 'xterm-addon-search'; import { IProcessEnvironment } from 'vs/base/common/platform'; import { Emitter, Event } from 'vs/base/common/event'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; let Terminal: typeof XTermTerminal; let WebLinksAddon: typeof XTermWebLinksAddon; @@ -63,3 +64,5 @@ export class TerminalInstanceService implements ITerminalInstanceService { return {}; } } + +registerSingleton(ITerminalInstanceService, TerminalInstanceService, true); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalNativeService.ts b/src/vs/workbench/contrib/terminal/browser/terminalNativeService.ts index 2ed3246317c..ce98262677e 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalNativeService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalNativeService.ts @@ -6,6 +6,7 @@ import { IOpenFileRequest } from 'vs/platform/windows/common/windows'; import { ITerminalNativeService, LinuxDistro } from 'vs/workbench/contrib/terminal/common/terminal'; import { Emitter, Event } from 'vs/base/common/event'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export class TerminalNativeService implements ITerminalNativeService { public _serviceBrand: any; @@ -30,4 +31,6 @@ export class TerminalNativeService implements ITerminalNativeService { public getWindowsBuildNumber(): number { throw new Error('Not implemented'); } -} \ No newline at end of file +} + +registerSingleton(ITerminalNativeService, TerminalNativeService, true); diff --git a/src/vs/workbench/contrib/webview/browser/webviewEditorService.ts b/src/vs/workbench/contrib/webview/browser/webviewEditorService.ts index e81418df66a..fb0354fab1a 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewEditorService.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewEditorService.ts @@ -15,6 +15,7 @@ import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor import { ACTIVE_GROUP_TYPE, IEditorService, SIDE_GROUP_TYPE } from 'vs/workbench/services/editor/common/editorService'; import { RevivedWebviewEditorInput, WebviewEditorInput } from './webviewEditorInput'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export const IWebviewEditorService = createDecorator('webviewEditorService'); @@ -264,3 +265,5 @@ export class WebviewEditorService implements IWebviewEditorService { return rootPaths; } } + +registerSingleton(IWebviewEditorService, WebviewEditorService, true); diff --git a/src/vs/workbench/contrib/webview/browser/webviewService.ts b/src/vs/workbench/contrib/webview/browser/webviewService.ts index 1995a857f5e..44ef4a15f1e 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewService.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewService.ts @@ -7,6 +7,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IFrameWebview } from 'vs/workbench/contrib/webview/browser/webviewElement'; import { IWebviewService, WebviewContentOptions, WebviewEditorOverlay, WebviewElement, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview'; import { DynamicWebviewEditorOverlay } from './dynamicWebviewEditorOverlay'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export class WebviewService implements IWebviewService { _serviceBrand: any; @@ -31,3 +32,5 @@ export class WebviewService implements IWebviewService { return this._instantiationService.createInstance(DynamicWebviewEditorOverlay, id, options, contentOptions); } } + +registerSingleton(IWebviewService, WebviewService, true); diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts new file mode 100644 index 00000000000..b3f4bd63f11 --- /dev/null +++ b/src/vs/workbench/workbench.common.main.ts @@ -0,0 +1,168 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +//#region --- editor/workbench core + +import 'vs/editor/editor.all'; + +import 'vs/workbench/api/browser/extensionHost.contribution'; +import 'vs/workbench/browser/workbench.contribution'; + +//#endregion + + +//#region --- workbench actions + +import 'vs/workbench/browser/actions/layoutActions'; +import 'vs/workbench/browser/actions/windowActions'; +import 'vs/workbench/browser/actions/developerActions'; +import 'vs/workbench/browser/actions/listCommands'; +import 'vs/workbench/browser/actions/navigationActions'; +import 'vs/workbench/browser/parts/quickopen/quickOpenActions'; +import 'vs/workbench/browser/parts/quickinput/quickInputActions'; + +//#endregion + + +//#region --- API Extension Points + +import 'vs/workbench/api/common/menusExtensionPoint'; +import 'vs/workbench/api/common/configurationExtensionPoint'; +import 'vs/workbench/api/browser/viewsExtensionPoint'; + +//#endregion + + +//#region --- workbench parts + +import 'vs/workbench/browser/parts/quickinput/quickInput'; +import 'vs/workbench/browser/parts/quickopen/quickOpenController'; +import 'vs/workbench/browser/parts/titlebar/titlebarPart'; +import 'vs/workbench/browser/parts/editor/editorPart'; +import 'vs/workbench/browser/parts/activitybar/activitybarPart'; +import 'vs/workbench/browser/parts/panel/panelPart'; +import 'vs/workbench/browser/parts/sidebar/sidebarPart'; +import 'vs/workbench/browser/parts/statusbar/statusbarPart'; + +//#endregion + + +//#region --- workbench contributions + +// Workspace File Watching +import 'vs/workbench/services/files/common/workspaceWatcher'; + +// Telemetry +import 'vs/workbench/contrib/telemetry/browser/telemetry.contribution'; + +// Preferences +import 'vs/workbench/contrib/preferences/browser/preferences.contribution'; +import 'vs/workbench/contrib/preferences/browser/keybindingsEditorContribution'; +import { IPreferencesSearchService } from 'vs/workbench/contrib/preferences/common/preferences'; +import { PreferencesSearchService } from 'vs/workbench/contrib/preferences/browser/preferencesSearch'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +registerSingleton(IPreferencesSearchService, PreferencesSearchService, true); + +// Logs +import 'vs/workbench/contrib/logs/common/logs.contribution'; + +// Quick Open Handlers +import 'vs/workbench/contrib/quickopen/browser/quickopen.contribution'; + +// Explorer +import 'vs/workbench/contrib/files/browser/explorerViewlet'; +import 'vs/workbench/contrib/files/browser/fileActions.contribution'; +import 'vs/workbench/contrib/files/browser/files.contribution'; + +// Backup +import 'vs/workbench/contrib/backup/common/backup.contribution'; + +// Search +import 'vs/workbench/contrib/search/browser/search.contribution'; +import 'vs/workbench/contrib/search/browser/searchView'; +import 'vs/workbench/contrib/search/browser/openAnythingHandler'; + +// SCM +import 'vs/workbench/contrib/scm/browser/scm.contribution'; +import 'vs/workbench/contrib/scm/browser/scmViewlet'; + +// Debug +import 'vs/workbench/contrib/debug/browser/debug.contribution'; +import 'vs/workbench/contrib/debug/browser/debugQuickOpen'; +import 'vs/workbench/contrib/debug/browser/debugEditorContribution'; +import 'vs/workbench/contrib/debug/browser/repl'; +import 'vs/workbench/contrib/debug/browser/debugViewlet'; + +// Markers +import 'vs/workbench/contrib/markers/browser/markers.contribution'; + +// Comments +import 'vs/workbench/contrib/comments/browser/comments.contribution'; + +// URL Support +import 'vs/workbench/contrib/url/common/url.contribution'; + +// Webview +import 'vs/workbench/contrib/webview/browser/webview.contribution'; + +// Extensions Management +import 'vs/workbench/contrib/extensions/browser/extensions.contribution'; +import 'vs/workbench/contrib/extensions/browser/extensionsQuickOpen'; +import 'vs/workbench/contrib/extensions/browser/extensionsViewlet'; + +// Output Panel +import 'vs/workbench/contrib/output/browser/output.contribution'; +import 'vs/workbench/contrib/output/browser/outputPanel'; + +// Terminal +import 'vs/workbench/contrib/terminal/browser/terminal.contribution'; +import 'vs/workbench/contrib/terminal/browser/terminalQuickOpen'; +import 'vs/workbench/contrib/terminal/browser/terminalPanel'; + +// Relauncher +import 'vs/workbench/contrib/relauncher/common/relauncher.contribution'; + +// Tasks +import 'vs/workbench/contrib/tasks/browser/task.contribution'; + +// Remote +import 'vs/workbench/contrib/remote/common/remote.contribution'; + +// Emmet +import 'vs/workbench/contrib/emmet/browser/emmet.contribution'; + +// CodeEditor Contributions +import 'vs/workbench/contrib/codeEditor/browser/codeEditor.contribution'; + +// Execution +import 'vs/workbench/contrib/externalTerminal/browser/externalTerminal.contribution'; + +// Snippets +import 'vs/workbench/contrib/snippets/browser/snippets.contribution'; +import 'vs/workbench/contrib/snippets/browser/snippetsService'; +import 'vs/workbench/contrib/snippets/browser/insertSnippet'; +import 'vs/workbench/contrib/snippets/browser/configureSnippets'; +import 'vs/workbench/contrib/snippets/browser/tabCompletion'; + +// Formatter Help +import 'vs/workbench/contrib/format/browser/format.contribution'; + +// Themes +import 'vs/workbench/contrib/themes/browser/themes.contribution'; + +// Watermark +import 'vs/workbench/contrib/watermark/browser/watermark'; + +// Welcome +import 'vs/workbench/contrib/welcome/walkThrough/browser/walkThrough.contribution'; +import 'vs/workbench/contrib/welcome/overlay/browser/welcomeOverlay'; + +// Call Hierarchy +import 'vs/workbench/contrib/callHierarchy/browser/callHierarchy.contribution'; + +// Outline +import 'vs/workbench/contrib/outline/browser/outline.contribution'; + +//#endregion diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index 840b1caa979..e1cce16c4b9 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -3,42 +3,29 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -//#region --- workbench/editor core -import 'vs/editor/editor.all'; +// ####################################################################### +// ### ### +// ### !!! PLEASE ADD COMMON IMPORTS INTO WORKBENCH.COMMON.MAIN.TS !!! ### +// ### ### +// ####################################################################### -import 'vs/workbench/api/browser/extensionHost.contribution'; + +//#region --- workbench common + +import 'vs/workbench/workbench.common.main'; + +//#endregion + + +//#region --- workbench (desktop main) import 'vs/workbench/electron-browser/main.contribution'; -import 'vs/workbench/browser/workbench.contribution'; - import 'vs/workbench/electron-browser/main'; //#endregion -//#region --- workbench actions - -import 'vs/workbench/browser/actions/layoutActions'; -import 'vs/workbench/browser/actions/windowActions'; -import 'vs/workbench/browser/actions/developerActions'; -import 'vs/workbench/browser/actions/listCommands'; -import 'vs/workbench/browser/actions/navigationActions'; -import 'vs/workbench/browser/parts/quickopen/quickOpenActions'; -import 'vs/workbench/browser/parts/quickinput/quickInputActions'; - -//#endregion - - -//#region --- API Extension Points - -import 'vs/workbench/api/common/menusExtensionPoint'; -import 'vs/workbench/api/common/configurationExtensionPoint'; -import 'vs/workbench/api/browser/viewsExtensionPoint'; - -//#endregion - - //#region --- workbench services import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IMenuService } from 'vs/platform/actions/common/actions'; @@ -93,6 +80,7 @@ import { ITunnelService } from 'vs/platform/remote/common/tunnel'; import { TunnelService } from 'vs/workbench/services/remote/node/tunnelService'; import { ICredentialsService } from 'vs/platform/credentials/common/credentials'; import { KeytarCredentialsService } from 'vs/platform/credentials/node/credentialsService'; +import { IWorkspaceStatsService, WorkspaceStatsService } from 'vs/workbench/contrib/stats/electron-browser/workspaceStatsService'; import 'vs/workbench/services/bulkEdit/browser/bulkEditService'; import 'vs/workbench/services/integrity/node/integrityService'; @@ -172,138 +160,40 @@ registerSingleton(IWorkspaceStatsService, WorkspaceStatsService, true); //#endregion -//#region --- workbench parts - -import 'vs/workbench/browser/parts/quickinput/quickInput'; -import 'vs/workbench/browser/parts/quickopen/quickOpenController'; -import 'vs/workbench/browser/parts/titlebar/titlebarPart'; -import 'vs/workbench/browser/parts/editor/editorPart'; -import 'vs/workbench/browser/parts/activitybar/activitybarPart'; -import 'vs/workbench/browser/parts/panel/panelPart'; -import 'vs/workbench/browser/parts/sidebar/sidebarPart'; -import 'vs/workbench/browser/parts/statusbar/statusbarPart'; - -//#endregion - - //#region --- workbench contributions -// Workspace File Watching -import 'vs/workbench/services/files/common/workspaceWatcher'; - -// Telemetry -import 'vs/workbench/contrib/telemetry/browser/telemetry.contribution'; - // Localizations import 'vs/workbench/contrib/localizations/browser/localizations.contribution'; -// Preferences -import 'vs/workbench/contrib/preferences/browser/preferences.contribution'; -import 'vs/workbench/contrib/preferences/browser/keybindingsEditorContribution'; -import { IPreferencesSearchService } from 'vs/workbench/contrib/preferences/common/preferences'; -import { PreferencesSearchService } from 'vs/workbench/contrib/preferences/browser/preferencesSearch'; -registerSingleton(IPreferencesSearchService, PreferencesSearchService, true); - // Logs -import 'vs/workbench/contrib/logs/common/logs.contribution'; import 'vs/workbench/contrib/logs/electron-browser/logs.contribution'; -// Quick Open Handlers -import 'vs/workbench/contrib/quickopen/browser/quickopen.contribution'; - -// Explorer -import 'vs/workbench/contrib/files/browser/explorerViewlet'; -import 'vs/workbench/contrib/files/browser/fileActions.contribution'; -import 'vs/workbench/contrib/files/browser/files.contribution'; - -// Backup -import 'vs/workbench/contrib/backup/common/backup.contribution'; - // Stats import 'vs/workbench/contrib/stats/electron-browser/stats.contribution'; // Rapid Render Splash import 'vs/workbench/contrib/splash/electron-browser/partsSplash.contribution'; -// Search -import 'vs/workbench/contrib/search/browser/search.contribution'; -import 'vs/workbench/contrib/search/browser/searchView'; -import 'vs/workbench/contrib/search/browser/openAnythingHandler'; - -// SCM -import 'vs/workbench/contrib/scm/browser/scm.contribution'; -import 'vs/workbench/contrib/scm/browser/scmViewlet'; - // Debug -import 'vs/workbench/contrib/debug/browser/debug.contribution'; -import 'vs/workbench/contrib/debug/browser/debugQuickOpen'; -import 'vs/workbench/contrib/debug/browser/debugEditorContribution'; -import 'vs/workbench/contrib/debug/browser/repl'; -import 'vs/workbench/contrib/debug/browser/debugViewlet'; import 'vs/workbench/contrib/debug/node/debugHelperService'; -// Markers -import 'vs/workbench/contrib/markers/browser/markers.contribution'; - -// Comments -import 'vs/workbench/contrib/comments/browser/comments.contribution'; - -// URL Support -import 'vs/workbench/contrib/url/common/url.contribution'; - // Webview -import 'vs/workbench/contrib/webview/browser/webview.contribution'; import 'vs/workbench/contrib/webview/electron-browser/webview.contribution'; // Extensions Management -import 'vs/workbench/contrib/extensions/browser/extensions.contribution'; import 'vs/workbench/contrib/extensions/electron-browser/extensions.contribution'; -import 'vs/workbench/contrib/extensions/browser/extensionsQuickOpen'; -import 'vs/workbench/contrib/extensions/browser/extensionsViewlet'; - -// Output Panel -import 'vs/workbench/contrib/output/browser/output.contribution'; -import 'vs/workbench/contrib/output/browser/outputPanel'; // Terminal -import 'vs/workbench/contrib/terminal/browser/terminal.contribution'; import 'vs/workbench/contrib/terminal/electron-browser/terminal.contribution'; -import 'vs/workbench/contrib/terminal/browser/terminalQuickOpen'; -import 'vs/workbench/contrib/terminal/browser/terminalPanel'; - -// Relauncher -import 'vs/workbench/contrib/relauncher/common/relauncher.contribution'; - -// Tasks -import 'vs/workbench/contrib/tasks/browser/task.contribution'; -import { TaskService } from 'vs/workbench/contrib/tasks/electron-browser/taskService'; -import { ITaskService } from 'vs/workbench/contrib/tasks/common/taskService'; -registerSingleton(ITaskService, TaskService, true); // Remote -import 'vs/workbench/contrib/remote/common/remote.contribution'; import 'vs/workbench/contrib/remote/electron-browser/remote.contribution'; -// Emmet -import 'vs/workbench/contrib/emmet/browser/emmet.contribution'; - // CodeEditor Contributions -import 'vs/workbench/contrib/codeEditor/browser/codeEditor.contribution'; import 'vs/workbench/contrib/codeEditor/electron-browser/codeEditor.contribution'; // Execution import 'vs/workbench/contrib/externalTerminal/node/externalTerminalService'; -import 'vs/workbench/contrib/externalTerminal/browser/externalTerminal.contribution'; - -// Snippets -import 'vs/workbench/contrib/snippets/browser/snippets.contribution'; -import 'vs/workbench/contrib/snippets/browser/snippetsService'; -import 'vs/workbench/contrib/snippets/browser/insertSnippet'; -import 'vs/workbench/contrib/snippets/browser/configureSnippets'; -import 'vs/workbench/contrib/snippets/browser/tabCompletion'; - -// Formatter Help -import 'vs/workbench/contrib/format/browser/format.contribution'; // Send a Smile import 'vs/workbench/contrib/feedback/browser/feedback.contribution'; @@ -322,29 +212,19 @@ import 'vs/workbench/contrib/performance/electron-browser/performance.contributi import 'vs/workbench/contrib/cli/node/cli.contribution'; // Themes Support -import 'vs/workbench/contrib/themes/browser/themes.contribution'; import 'vs/workbench/contrib/themes/test/electron-browser/themes.test.contribution'; -// Watermark -import 'vs/workbench/contrib/watermark/browser/watermark'; - // Welcome -import 'vs/workbench/contrib/welcome/walkThrough/browser/walkThrough.contribution'; import 'vs/workbench/contrib/welcome/gettingStarted/electron-browser/gettingStarted.contribution'; -import 'vs/workbench/contrib/welcome/overlay/browser/welcomeOverlay'; import 'vs/workbench/contrib/welcome/page/browser/welcomePage.contribution'; -// Call Hierarchy -import 'vs/workbench/contrib/callHierarchy/browser/callHierarchy.contribution'; - -// Outline -import 'vs/workbench/contrib/outline/browser/outline.contribution'; - // Experiments import 'vs/workbench/contrib/experiments/electron-browser/experiments.contribution'; // Issues import 'vs/workbench/contrib/issue/electron-browser/issue.contribution'; -import { IWorkspaceStatsService, WorkspaceStatsService } from 'vs/workbench/contrib/stats/electron-browser/workspaceStatsService'; + +// Tasks +import 'vs/workbench/contrib/tasks/electron-browser/taskService'; //#endregion diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 1a11ef19d75..322b6b01bff 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -3,41 +3,28 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -//#region --- workbench/editor core -import 'vs/editor/editor.all'; +// ####################################################################### +// ### ### +// ### !!! PLEASE ADD COMMON IMPORTS INTO WORKBENCH.COMMON.MAIN.TS !!! ### +// ### ### +// ####################################################################### -import 'vs/workbench/api/browser/extensionHost.contribution'; -import 'vs/workbench/browser/workbench.contribution'; +//#region --- workbench common + +import 'vs/workbench/workbench.common.main'; + +//#endregion + + +//#region --- workbench (web main) import 'vs/workbench/browser/web.main'; //#endregion -//#region --- workbench actions - -import 'vs/workbench/browser/actions/layoutActions'; -import 'vs/workbench/browser/actions/windowActions'; -import 'vs/workbench/browser/actions/developerActions'; -import 'vs/workbench/browser/actions/listCommands'; -import 'vs/workbench/browser/actions/navigationActions'; -import 'vs/workbench/browser/parts/quickopen/quickOpenActions'; -import 'vs/workbench/browser/parts/quickinput/quickInputActions'; - -//#endregion - - -//#region --- API Extension Points - -import 'vs/workbench/api/common/menusExtensionPoint'; -import 'vs/workbench/api/common/configurationExtensionPoint'; -import 'vs/workbench/api/browser/viewsExtensionPoint'; - -//#endregion - - //#region --- workbench services import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IMenuService } from 'vs/platform/actions/common/actions'; @@ -168,191 +155,26 @@ registerSingleton(IContextMenuService, ContextMenuService); //#endregion -//#region --- workbench parts - -import 'vs/workbench/browser/parts/quickinput/quickInput'; -import 'vs/workbench/browser/parts/quickopen/quickOpenController'; -import 'vs/workbench/browser/parts/titlebar/titlebarPart'; -import 'vs/workbench/browser/parts/editor/editorPart'; -import 'vs/workbench/browser/parts/activitybar/activitybarPart'; -import 'vs/workbench/browser/parts/panel/panelPart'; -import 'vs/workbench/browser/parts/sidebar/sidebarPart'; -import 'vs/workbench/browser/parts/statusbar/statusbarPart'; - -//#endregion - - //#region --- workbench contributions // Resource Service Worker import 'vs/workbench/contrib/resources/browser/resourceServiceWorkerClient'; -// Workspace File Watching -import 'vs/workbench/services/files/common/workspaceWatcher'; - -// Telemetry -import 'vs/workbench/contrib/telemetry/browser/telemetry.contribution'; - -// Localizations -// import 'vs/workbench/contrib/localizations/browser/localizations.contribution'; - // Preferences -import 'vs/workbench/contrib/preferences/browser/preferences.contribution'; -import 'vs/workbench/contrib/preferences/browser/keybindingsEditorContribution'; import 'vs/workbench/contrib/preferences/browser/keyboardLayoutPicker'; -import { IPreferencesSearchService } from 'vs/workbench/contrib/preferences/common/preferences'; -import { PreferencesSearchService } from 'vs/workbench/contrib/preferences/browser/preferencesSearch'; -registerSingleton(IPreferencesSearchService, PreferencesSearchService, true); - -// Logs -import 'vs/workbench/contrib/logs/common/logs.contribution'; - -// Quick Open Handlers -import 'vs/workbench/contrib/quickopen/browser/quickopen.contribution'; - -// Explorer -import 'vs/workbench/contrib/files/browser/explorerViewlet'; -import 'vs/workbench/contrib/files/browser/fileActions.contribution'; -import 'vs/workbench/contrib/files/browser/files.contribution'; - -// Backup -import 'vs/workbench/contrib/backup/common/backup.contribution'; - -// Stats -// import 'vs/workbench/contrib/stats/electron-browser/stats.contribution'; - -// Rapid Render Splash -// import 'vs/workbench/contrib/splash/electron-browser/partsSplash.contribution'; - -// Search -import 'vs/workbench/contrib/search/browser/search.contribution'; -import 'vs/workbench/contrib/search/browser/searchView'; -import 'vs/workbench/contrib/search/browser/openAnythingHandler'; - -// SCM -import 'vs/workbench/contrib/scm/browser/scm.contribution'; -import 'vs/workbench/contrib/scm/browser/scmViewlet'; // Debug -import 'vs/workbench/contrib/debug/browser/debug.contribution'; -import 'vs/workbench/contrib/debug/browser/debugQuickOpen'; -import 'vs/workbench/contrib/debug/browser/debugEditorContribution'; -import 'vs/workbench/contrib/debug/browser/repl'; -import 'vs/workbench/contrib/debug/browser/debugViewlet'; import 'vs/workbench/contrib/debug/browser/extensionHostDebugService'; -// Markers -import 'vs/workbench/contrib/markers/browser/markers.contribution'; - -// Comments -import 'vs/workbench/contrib/comments/browser/comments.contribution'; - -// URL Support -import 'vs/workbench/contrib/url/common/url.contribution'; - // Webview -import 'vs/workbench/contrib/webview/browser/webview.contribution'; - -import { IWebviewService } from 'vs/workbench/contrib/webview/common/webview'; -import { WebviewService } from 'vs/workbench/contrib/webview/browser/webviewService'; -import { IWebviewEditorService, WebviewEditorService } from 'vs/workbench/contrib/webview/browser/webviewEditorService'; -registerSingleton(IWebviewService, WebviewService, true); -registerSingleton(IWebviewEditorService, WebviewEditorService, true); - -// Extensions Management -import 'vs/workbench/contrib/extensions/browser/extensions.contribution'; -import 'vs/workbench/contrib/extensions/browser/extensionsQuickOpen'; -import 'vs/workbench/contrib/extensions/browser/extensionsViewlet'; - -// Output Panel -import 'vs/workbench/contrib/output/browser/output.contribution'; -import 'vs/workbench/contrib/output/browser/outputPanel'; +import 'vs/workbench/contrib/webview/browser/webviewService'; +import 'vs/workbench/contrib/webview/browser/webviewEditorService'; // Terminal -import 'vs/workbench/contrib/terminal/browser/terminal.contribution'; -// import 'vs/workbench/contrib/terminal/electron-browser/terminal.contribution'; -import 'vs/workbench/contrib/terminal/browser/terminalQuickOpen'; -import 'vs/workbench/contrib/terminal/browser/terminalPanel'; - -import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; -import { ITerminalNativeService } from 'vs/workbench/contrib/terminal/common/terminal'; -import { TerminalNativeService } from 'vs/workbench/contrib/terminal/browser/terminalNativeService'; -import { TerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminalInstanceService'; -registerSingleton(ITerminalNativeService, TerminalNativeService, true); -registerSingleton(ITerminalInstanceService, TerminalInstanceService, true); - -// Relauncher -import 'vs/workbench/contrib/relauncher/common/relauncher.contribution'; +import 'vs/workbench/contrib/terminal/browser/terminalNativeService'; +import 'vs/workbench/contrib/terminal/browser/terminalInstanceService'; // Tasks -import 'vs/workbench/contrib/tasks/browser/task.contribution'; -import { TaskService } from 'vs/workbench/contrib/tasks/browser/taskService'; -import { ITaskService } from 'vs/workbench/contrib/tasks/common/taskService'; -registerSingleton(ITaskService, TaskService, true); - -// Remote -import 'vs/workbench/contrib/remote/common/remote.contribution'; -// import 'vs/workbench/contrib/remote/electron-browser/remote.contribution'; - -// Emmet -import 'vs/workbench/contrib/emmet/browser/emmet.contribution'; - -// CodeEditor Contributions -import 'vs/workbench/contrib/codeEditor/browser/codeEditor.contribution'; -// import 'vs/workbench/contrib/codeEditor/electron-browser/codeEditor.contribution'; - -// External terminal -import 'vs/workbench/contrib/externalTerminal/browser/externalTerminal.contribution'; - -// Snippets -import 'vs/workbench/contrib/snippets/browser/snippets.contribution'; -import 'vs/workbench/contrib/snippets/browser/snippetsService'; -import 'vs/workbench/contrib/snippets/browser/insertSnippet'; -import 'vs/workbench/contrib/snippets/browser/configureSnippets'; -import 'vs/workbench/contrib/snippets/browser/tabCompletion'; - -// Formatter Help -import 'vs/workbench/contrib/format/browser/format.contribution'; - -// Send a Smile -// import 'vs/workbench/contrib/feedback/browser/feedback.contribution'; - -// Update -// import 'vs/workbench/contrib/update/electron-browser/update.contribution'; - -// Surveys -// import 'vs/workbench/contrib/surveys/electron-browser/nps.contribution'; -// import 'vs/workbench/contrib/surveys/electron-browser/languageSurveys.contribution'; - -// Performance -// import 'vs/workbench/contrib/performance/electron-browser/performance.contribution'; - -// CLI -// import 'vs/workbench/contrib/cli/node/cli.contribution'; - -// Themes Support -import 'vs/workbench/contrib/themes/browser/themes.contribution'; -// import 'vs/workbench/contrib/themes/test/electron-browser/themes.test.contribution'; - -// Watermark -import 'vs/workbench/contrib/watermark/browser/watermark'; - -// Welcome -import 'vs/workbench/contrib/welcome/walkThrough/browser/walkThrough.contribution'; -// import 'vs/workbench/contrib/welcome/gettingStarted/electron-browser/gettingStarted.contribution'; -import 'vs/workbench/contrib/welcome/overlay/browser/welcomeOverlay'; -// import 'vs/workbench/contrib/welcome/page/browser/welcomePage.contribution'; - -// Call Hierarchy -import 'vs/workbench/contrib/callHierarchy/browser/callHierarchy.contribution'; - -// Outline -import 'vs/workbench/contrib/outline/browser/outline.contribution'; - -// Experiments -// import 'vs/workbench/contrib/experiments/electron-browser/experiments.contribution'; - -// Issues -// import 'vs/workbench/contrib/issue/electron-browser/issue.contribution'; +import 'vs/workbench/contrib/tasks/browser/taskService'; //#endregion From bf94bedcfeaea7388a290b61e7f81b06eded1bbb Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 12 Aug 2019 12:06:44 +0200 Subject: [PATCH 464/861] build - workbench.main => workbench.desktop.main --- build/gulpfile.vscode.js | 6 +++--- src/buildfile.js | 2 +- src/vs/code/electron-browser/workbench/workbench.js | 6 +++--- src/vs/workbench/browser/web.main.ts | 2 +- src/vs/workbench/browser/workbench.ts | 2 +- .../contrib/performance/electron-browser/perfviewEditor.ts | 4 ++-- src/vs/workbench/electron-browser/main.ts | 2 +- .../services/timer/electron-browser/timerService.ts | 4 ++-- .../{workbench.main.css => workbench.desktop.main.css} | 0 ...{workbench.main.nls.js => workbench.desktop.main.nls.js} | 0 .../{workbench.main.ts => workbench.desktop.main.ts} | 0 tslint.json | 2 +- 12 files changed, 15 insertions(+), 15 deletions(-) rename src/vs/workbench/{workbench.main.css => workbench.desktop.main.css} (100%) rename src/vs/workbench/{workbench.main.nls.js => workbench.desktop.main.nls.js} (100%) rename src/vs/workbench/{workbench.main.ts => workbench.desktop.main.ts} (100%) diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 189cf4f560e..98f776abb7e 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -47,7 +47,7 @@ const nodeModules = ['electron', 'original-fs'] // Build const vscodeEntryPoints = _.flatten([ - buildfile.entrypoint('vs/workbench/workbench.main'), + buildfile.entrypoint('vs/workbench/workbench.desktop.main'), buildfile.base, buildfile.serviceWorker, buildfile.workbench, @@ -250,8 +250,8 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op const out = sourceFolderName; const checksums = computeChecksums(out, [ - 'vs/workbench/workbench.main.js', - 'vs/workbench/workbench.main.css', + 'vs/workbench/workbench.desktop.main.js', + 'vs/workbench/workbench.desktop.main.css', 'vs/code/electron-browser/workbench/workbench.html', 'vs/code/electron-browser/workbench/workbench.js' ]); diff --git a/src/buildfile.js b/src/buildfile.js index 0c77f1ae5fa..e45dbc27461 100644 --- a/src/buildfile.js +++ b/src/buildfile.js @@ -19,7 +19,7 @@ exports.serviceWorker = [{ dest: 'vs/workbench/contrib/resources/browser/resourceServiceWorkerMain.js' }]; -exports.workbench = require('./vs/workbench/buildfile').collectModules(['vs/workbench/workbench.main']); +exports.workbench = require('./vs/workbench/buildfile').collectModules(['vs/workbench/workbench.desktop.main']); exports.workbenchWeb = require('./vs/workbench/buildfile').collectModules(['vs/workbench/workbench.web.api']); exports.code = require('./vs/code/buildfile').collectModules(); diff --git a/src/vs/code/electron-browser/workbench/workbench.js b/src/vs/code/electron-browser/workbench/workbench.js index dfe41b3d93d..cdbe49c1b3a 100644 --- a/src/vs/code/electron-browser/workbench/workbench.js +++ b/src/vs/code/electron-browser/workbench/workbench.js @@ -16,9 +16,9 @@ process['lazyEnv'] = getLazyEnv(); // Load workbench main bootstrapWindow.load([ - 'vs/workbench/workbench.main', - 'vs/nls!vs/workbench/workbench.main', - 'vs/css!vs/workbench/workbench.main' + 'vs/workbench/workbench.desktop.main', + 'vs/nls!vs/workbench/workbench.desktop.main', + 'vs/css!vs/workbench/workbench.desktop.main' ], function (workbench, configuration) { perf.mark('didLoadWorkbenchMain'); diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index 95e333e55f9..8a2b43a5378 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -109,7 +109,7 @@ class CodeRendererMain extends Disposable { // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // NOTE: DO NOT ADD ANY OTHER SERVICE INTO THE COLLECTION HERE. - // CONTRIBUTE IT VIA WORKBENCH.MAIN.TS AND registerSingleton(). + // CONTRIBUTE IT VIA WORKBENCH.WEB.MAIN.TS AND registerSingleton(). // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Log diff --git a/src/vs/workbench/browser/workbench.ts b/src/vs/workbench/browser/workbench.ts index 014e2cb0686..0e61b26920d 100644 --- a/src/vs/workbench/browser/workbench.ts +++ b/src/vs/workbench/browser/workbench.ts @@ -185,7 +185,7 @@ export class Workbench extends Layout { // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // NOTE: DO NOT ADD ANY OTHER SERVICE INTO THE COLLECTION HERE. - // CONTRIBUTE IT VIA WORKBENCH.MAIN.TS AND registerSingleton(). + // CONTRIBUTE IT VIA WORKBENCH.DESKTOP.MAIN.TS AND registerSingleton(). // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // All Contributed Services diff --git a/src/vs/workbench/contrib/performance/electron-browser/perfviewEditor.ts b/src/vs/workbench/contrib/performance/electron-browser/perfviewEditor.ts index f0f73e07083..b0a1861b2c5 100644 --- a/src/vs/workbench/contrib/performance/electron-browser/perfviewEditor.ts +++ b/src/vs/workbench/contrib/performance/electron-browser/perfviewEditor.ts @@ -152,8 +152,8 @@ class PerfModelContentProvider implements ITextModelContentProvider { table.push(['nls:start => nls:end', metrics.timers.ellapsedNlsGeneration, '[main]', `initial startup: ${metrics.initialStartup}`]); table.push(['require(main.bundle.js)', metrics.initialStartup ? perf.getDuration('willLoadMainBundle', 'didLoadMainBundle') : undefined, '[main]', `initial startup: ${metrics.initialStartup}`]); table.push(['app.isReady => window.loadUrl()', metrics.timers.ellapsedWindowLoad, '[main]', `initial startup: ${metrics.initialStartup}`]); - table.push(['window.loadUrl() => begin to require(workbench.main.js)', metrics.timers.ellapsedWindowLoadToRequire, '[main->renderer]', StartupKindToString(metrics.windowKind)]); - table.push(['require(workbench.main.js)', metrics.timers.ellapsedRequire, '[renderer]', `cached data: ${(metrics.didUseCachedData ? 'YES' : 'NO')}${stats ? `, node_modules took ${stats.nodeRequireTotal}ms` : ''}`]); + table.push(['window.loadUrl() => begin to require(workbench.desktop.main.js)', metrics.timers.ellapsedWindowLoadToRequire, '[main->renderer]', StartupKindToString(metrics.windowKind)]); + table.push(['require(workbench.desktop.main.js)', metrics.timers.ellapsedRequire, '[renderer]', `cached data: ${(metrics.didUseCachedData ? 'YES' : 'NO')}${stats ? `, node_modules took ${stats.nodeRequireTotal}ms` : ''}`]); table.push(['require & init workspace storage', metrics.timers.ellapsedWorkspaceStorageInit, '[renderer]', undefined]); table.push(['init workspace service', metrics.timers.ellapsedWorkspaceServiceInit, '[renderer]', undefined]); table.push(['register extensions & spawn extension host', metrics.timers.ellapsedExtensions, '[renderer]', undefined]); diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts index 82769037076..40ea992a2a1 100644 --- a/src/vs/workbench/electron-browser/main.ts +++ b/src/vs/workbench/electron-browser/main.ts @@ -167,7 +167,7 @@ class CodeRendererMain extends Disposable { // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // NOTE: DO NOT ADD ANY OTHER SERVICE INTO THE COLLECTION HERE. - // CONTRIBUTE IT VIA WORKBENCH.MAIN.TS AND registerSingleton(). + // CONTRIBUTE IT VIA WORKBENCH.DESKTOP.MAIN.TS AND registerSingleton(). // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Main Process diff --git a/src/vs/workbench/services/timer/electron-browser/timerService.ts b/src/vs/workbench/services/timer/electron-browser/timerService.ts index 45d1e342b76..139822af63b 100644 --- a/src/vs/workbench/services/timer/electron-browser/timerService.ts +++ b/src/vs/workbench/services/timer/electron-browser/timerService.ts @@ -180,7 +180,7 @@ export interface IStartupMetrics { /** * The time it took to create a new renderer (browser window) and to initialize that to the point - * of load the main-bundle (`workbench.main.js`). + * of load the main-bundle (`workbench.desktop.main.js`). * * * Happens in the main-process *and* the renderer-process * * Measured with the `main:loadWindow` and `willLoadWorkbenchMain` performance marks. @@ -208,7 +208,7 @@ export interface IStartupMetrics { readonly ellapsedWorkspaceServiceInit: number; /** - * The time it took to load the main-bundle of the workbench, e.g. `workbench.main.js`. + * The time it took to load the main-bundle of the workbench, e.g. `workbench.desktop.main.js`. * * * Happens in the renderer-process * * Measured with the `willLoadWorkbenchMain` and `didLoadWorkbenchMain` performance marks. diff --git a/src/vs/workbench/workbench.main.css b/src/vs/workbench/workbench.desktop.main.css similarity index 100% rename from src/vs/workbench/workbench.main.css rename to src/vs/workbench/workbench.desktop.main.css diff --git a/src/vs/workbench/workbench.main.nls.js b/src/vs/workbench/workbench.desktop.main.nls.js similarity index 100% rename from src/vs/workbench/workbench.main.nls.js rename to src/vs/workbench/workbench.desktop.main.nls.js diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.desktop.main.ts similarity index 100% rename from src/vs/workbench/workbench.main.ts rename to src/vs/workbench/workbench.desktop.main.ts diff --git a/tslint.json b/tslint.json index 155bd9a4115..733a56ac409 100644 --- a/tslint.json +++ b/tslint.json @@ -371,7 +371,7 @@ ] }, { - "target": "**/vs/workbench/workbench.main.ts", + "target": "**/vs/workbench/workbench.desktop.main.ts", "restrictions": [ "**" ] From 2b8a397e45669ae15c1771d638d08640cb45f47e Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 12 Aug 2019 12:07:56 +0200 Subject: [PATCH 465/861] Fix #78734 --- .../contrib/markers/browser/markersTreeViewer.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/markers/browser/markersTreeViewer.ts b/src/vs/workbench/contrib/markers/browser/markersTreeViewer.ts index 06148b3c5ff..156c52dd125 100644 --- a/src/vs/workbench/contrib/markers/browser/markersTreeViewer.ts +++ b/src/vs/workbench/contrib/markers/browser/markersTreeViewer.ts @@ -334,9 +334,11 @@ class MarkerWidget extends Disposable { const sourceMatches = filterData && filterData.sourceMatches || []; source.set(marker.source, sourceMatches); - const code = new HighlightedLabel(dom.append(parent, dom.$('.marker-code')), false); - const codeMatches = filterData && filterData.codeMatches || []; - code.set(marker.code, codeMatches); + if (marker.code) { + const code = new HighlightedLabel(dom.append(parent, dom.$('.marker-code')), false); + const codeMatches = filterData && filterData.codeMatches || []; + code.set(marker.code, codeMatches); + } } const lnCol = dom.append(parent, dom.$('span.marker-line')); From 54a4c0005504fba573657434ade318e3bf6f1bcf Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 12 Aug 2019 12:38:43 +0200 Subject: [PATCH 466/861] web - more cleanup of main files --- .../electron-browser/workspaceStatsService.ts | 3 + .../node/accessibilityService.ts | 9 +- .../services/backup/node/backupFileService.ts | 8 +- .../node/extensionManagementService.ts | 6 +- .../services/remote/node/tunnelService.ts | 3 + src/vs/workbench/workbench.common.main.ts | 67 +++++++++- src/vs/workbench/workbench.desktop.main.ts | 113 ++++------------- src/vs/workbench/workbench.web.main.ts | 117 ++---------------- 8 files changed, 126 insertions(+), 200 deletions(-) diff --git a/src/vs/workbench/contrib/stats/electron-browser/workspaceStatsService.ts b/src/vs/workbench/contrib/stats/electron-browser/workspaceStatsService.ts index ef0dc08081c..9d0e84928f0 100644 --- a/src/vs/workbench/contrib/stats/electron-browser/workspaceStatsService.ts +++ b/src/vs/workbench/contrib/stats/electron-browser/workspaceStatsService.ts @@ -19,6 +19,7 @@ import { localize } from 'vs/nls'; import Severity from 'vs/base/common/severity'; import { joinPath } from 'vs/base/common/resources'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export type Tags = { [index: string]: boolean | number | string | undefined }; @@ -503,3 +504,5 @@ export class WorkspaceStatsService implements IWorkspaceStatsService { return arr.some(v => v.search(regEx) > -1) || undefined; } } + +registerSingleton(IWorkspaceStatsService, WorkspaceStatsService, true); diff --git a/src/vs/workbench/services/accessibility/node/accessibilityService.ts b/src/vs/workbench/services/accessibility/node/accessibilityService.ts index 02b215b5a09..983db9c1e67 100644 --- a/src/vs/workbench/services/accessibility/node/accessibilityService.ts +++ b/src/vs/workbench/services/accessibility/node/accessibilityService.ts @@ -9,9 +9,12 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { AbstractAccessibilityService } from 'vs/platform/accessibility/common/abstractAccessibilityService'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; export class AccessibilityService extends AbstractAccessibilityService implements IAccessibilityService { - _serviceBrand: any; + + _serviceBrand!: ServiceIdentifier; private _accessibilitySupport = AccessibilitySupport.Unknown; @@ -59,4 +62,6 @@ export class AccessibilityService extends AbstractAccessibilityService implement return this._accessibilitySupport; } -} \ No newline at end of file +} + +registerSingleton(IAccessibilityService, AccessibilityService, true); diff --git a/src/vs/workbench/services/backup/node/backupFileService.ts b/src/vs/workbench/services/backup/node/backupFileService.ts index 30b5c5acf51..74beddef46f 100644 --- a/src/vs/workbench/services/backup/node/backupFileService.ts +++ b/src/vs/workbench/services/backup/node/backupFileService.ts @@ -7,13 +7,14 @@ import { BackupFileService as CommonBackupFileService } from 'vs/workbench/servi import { URI } from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; import * as crypto from 'crypto'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; export class BackupFileService extends CommonBackupFileService { protected hashPath(resource: URI): string { return hashPath(resource); } - } /* @@ -21,5 +22,8 @@ export class BackupFileService extends CommonBackupFileService { */ export function hashPath(resource: URI): string { const str = resource.scheme === Schemas.file || resource.scheme === Schemas.untitled ? resource.fsPath : resource.toString(); + return crypto.createHash('md5').update(str).digest('hex'); -} \ No newline at end of file +} + +registerSingleton(IBackupFileService, BackupFileService); diff --git a/src/vs/workbench/services/extensionManagement/node/extensionManagementService.ts b/src/vs/workbench/services/extensionManagement/node/extensionManagementService.ts index 46db06b9d1a..b2b5e78f90e 100644 --- a/src/vs/workbench/services/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/node/extensionManagementService.ts @@ -3,12 +3,13 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { ILocalExtension, IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { isLanguagePackExtension } from 'vs/platform/extensions/common/extensions'; import { URI } from 'vs/base/common/uri'; import { getManifest } from 'vs/platform/extensionManagement/node/extensionManagementUtil'; import { isUIExtension } from 'vs/workbench/services/extensions/common/extensionsUtil'; import { ExtensionManagementService as BaseExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagementService'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export class ExtensionManagementService extends BaseExtensionManagementService { @@ -32,5 +33,6 @@ export class ExtensionManagementService extends BaseExtensionManagementService { } return Promise.reject('No Servers to Install'); } - } + +registerSingleton(IExtensionManagementService, ExtensionManagementService); diff --git a/src/vs/workbench/services/remote/node/tunnelService.ts b/src/vs/workbench/services/remote/node/tunnelService.ts index 87b657be6a5..457411cd670 100644 --- a/src/vs/workbench/services/remote/node/tunnelService.ts +++ b/src/vs/workbench/services/remote/node/tunnelService.ts @@ -14,6 +14,7 @@ import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remot import { ITunnelService, RemoteTunnel } from 'vs/platform/remote/common/tunnel'; import { nodeSocketFactory } from 'vs/platform/remote/node/nodeSocketFactory'; import { ISignService } from 'vs/platform/sign/common/sign'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export async function createRemoteTunnel(options: IConnectionOptions, tunnelRemotePort: number): Promise { const tunnel = new NodeRemoteTunnel(options, tunnelRemotePort); @@ -113,3 +114,5 @@ export class TunnelService implements ITunnelService { return createRemoteTunnel(options, remotePort); } } + +registerSingleton(ITunnelService, TunnelService, true); diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index b3f4bd63f11..3558c2ffef3 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -45,6 +45,72 @@ import 'vs/workbench/browser/parts/activitybar/activitybarPart'; import 'vs/workbench/browser/parts/panel/panelPart'; import 'vs/workbench/browser/parts/sidebar/sidebarPart'; import 'vs/workbench/browser/parts/statusbar/statusbarPart'; +import 'vs/workbench/browser/parts/views/views'; + +//#endregion + + +//#region --- workbench services + +import 'vs/workbench/services/bulkEdit/browser/bulkEditService'; +import 'vs/workbench/services/keybinding/common/keybindingEditing'; +import 'vs/workbench/services/decorations/browser/decorationsService'; +import 'vs/workbench/services/progress/browser/progressService'; +import 'vs/workbench/services/editor/browser/codeEditorService'; +import 'vs/workbench/services/preferences/browser/preferencesService'; +import 'vs/workbench/services/configuration/common/jsonEditingService'; +import 'vs/workbench/services/textmodelResolver/common/textModelResolverService'; +import 'vs/workbench/services/dialogs/browser/fileDialogService'; +import 'vs/workbench/services/editor/browser/editorService'; +import 'vs/workbench/services/history/browser/history'; +import 'vs/workbench/services/activity/browser/activityService'; +import 'vs/workbench/services/keybinding/browser/keybindingService'; +import 'vs/workbench/services/untitled/common/untitledEditorService'; +import 'vs/workbench/services/textfile/common/textResourcePropertiesService'; +import 'vs/workbench/services/mode/common/workbenchModeService'; +import 'vs/workbench/services/commands/common/commandService'; +import 'vs/workbench/services/themes/browser/workbenchThemeService'; +import 'vs/workbench/services/label/common/labelService'; +import 'vs/workbench/services/extensionManagement/common/extensionEnablementService'; +import 'vs/workbench/services/notification/common/notificationService'; + +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; +import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService'; +import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; +import { IListService, ListService } from 'vs/platform/list/browser/listService'; +import { OpenerService } from 'vs/editor/browser/services/openerService'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService'; +import { EditorWorkerServiceImpl } from 'vs/editor/common/services/editorWorkerServiceImpl'; +import { MarkerDecorationsService } from 'vs/editor/common/services/markerDecorationsServiceImpl'; +import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDecorationService'; +import { IMarkerService } from 'vs/platform/markers/common/markers'; +import { MarkerService } from 'vs/platform/markers/common/markerService'; +import { ContextKeyService } from 'vs/platform/contextkey/browser/contextKeyService'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IModelService } from 'vs/editor/common/services/modelService'; +import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl'; +import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration'; +import { TextResourceConfigurationService } from 'vs/editor/common/services/resourceConfigurationImpl'; +import { IMenuService } from 'vs/platform/actions/common/actions'; +import { MenuService } from 'vs/platform/actions/common/menuService'; +import { IDownloadService } from 'vs/platform/download/common/download'; +import { DownloadService } from 'vs/platform/download/common/downloadService'; + +registerSingleton(IExtensionGalleryService, ExtensionGalleryService, true); +registerSingleton(IContextViewService, ContextViewService, true); +registerSingleton(IListService, ListService, true); +registerSingleton(IOpenerService, OpenerService, true); +registerSingleton(IEditorWorkerService, EditorWorkerServiceImpl); +registerSingleton(IMarkerDecorationsService, MarkerDecorationsService); +registerSingleton(IMarkerService, MarkerService, true); +registerSingleton(IContextKeyService, ContextKeyService); +registerSingleton(IModelService, ModelServiceImpl, true); +registerSingleton(ITextResourceConfigurationService, TextResourceConfigurationService); +registerSingleton(IMenuService, MenuService, true); +registerSingleton(IDownloadService, DownloadService, true); //#endregion @@ -62,7 +128,6 @@ import 'vs/workbench/contrib/preferences/browser/preferences.contribution'; import 'vs/workbench/contrib/preferences/browser/keybindingsEditorContribution'; import { IPreferencesSearchService } from 'vs/workbench/contrib/preferences/common/preferences'; import { PreferencesSearchService } from 'vs/workbench/contrib/preferences/browser/preferencesSearch'; -import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; registerSingleton(IPreferencesSearchService, PreferencesSearchService, true); // Logs diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index e1cce16c4b9..74d06356a54 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -27,34 +27,33 @@ import 'vs/workbench/electron-browser/main'; //#region --- workbench services +import 'vs/workbench/services/integrity/node/integrityService'; +import 'vs/workbench/services/textMate/electron-browser/textMateService'; +import 'vs/workbench/services/workspace/electron-browser/workspaceEditingService'; +import 'vs/workbench/services/extensions/common/inactiveExtensionUrlHandler'; +import 'vs/workbench/services/search/node/searchService'; +import 'vs/workbench/services/extensions/electron-browser/extensionHostDebugService'; +import 'vs/workbench/services/output/node/outputChannelModelService'; +import 'vs/workbench/services/textfile/node/textFileService'; +import 'vs/workbench/services/dialogs/electron-browser/dialogService'; +import 'vs/workbench/services/keybinding/electron-browser/nativeKeymapService'; +import 'vs/workbench/services/keybinding/electron-browser/keybinding.contribution'; +import 'vs/workbench/services/extensions/electron-browser/extensionService'; +import 'vs/workbench/services/contextmenu/electron-browser/contextmenuService'; +import 'vs/workbench/services/extensionManagement/electron-browser/extensionManagementServerService'; +import 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl'; +import 'vs/workbench/services/window/electron-browser/windowService'; +import 'vs/workbench/services/telemetry/electron-browser/telemetryService'; +import 'vs/workbench/services/configurationResolver/electron-browser/configurationResolverService'; +import 'vs/workbench/services/extensionManagement/node/extensionManagementService'; +import 'vs/workbench/services/accessibility/node/accessibilityService'; +import 'vs/workbench/services/remote/node/tunnelService'; +import 'vs/workbench/contrib/stats/electron-browser/workspaceStatsService'; +import 'vs/workbench/services/backup/node/backupFileService'; + import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IMenuService } from 'vs/platform/actions/common/actions'; -import { MenuService } from 'vs/platform/actions/common/menuService'; -import { IListService, ListService } from 'vs/platform/list/browser/listService'; -import { OpenerService } from 'vs/editor/browser/services/openerService'; -import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService'; -import { EditorWorkerServiceImpl } from 'vs/editor/common/services/editorWorkerServiceImpl'; -import { MarkerDecorationsService } from 'vs/editor/common/services/markerDecorationsServiceImpl'; -import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDecorationService'; -import { IMarkerService } from 'vs/platform/markers/common/markers'; -import { MarkerService } from 'vs/platform/markers/common/markerService'; -import { IDownloadService } from 'vs/platform/download/common/download'; -import { DownloadService } from 'vs/platform/download/common/downloadService'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { ClipboardService } from 'vs/platform/clipboard/electron-browser/clipboardService'; -import { ContextKeyService } from 'vs/platform/contextkey/browser/contextKeyService'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { IModelService } from 'vs/editor/common/services/modelService'; -import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl'; -import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration'; -import { TextResourceConfigurationService } from 'vs/editor/common/services/resourceConfigurationImpl'; -import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; -import { AccessibilityService } from 'vs/workbench/services/accessibility/node/accessibilityService'; -import { IExtensionGalleryService, IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; -import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService'; -import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; import { IRequestService } from 'vs/platform/request/common/request'; import { RequestService } from 'vs/platform/request/browser/requestService'; import { LifecycleService } from 'vs/platform/lifecycle/electron-browser/lifecycleService'; @@ -76,72 +75,10 @@ import { IMenubarService } from 'vs/platform/menubar/common/menubar'; import { MenubarService } from 'vs/platform/menubar/electron-browser/menubarService'; import { IURLService } from 'vs/platform/url/common/url'; import { RelayURLService } from 'vs/platform/url/electron-browser/urlService'; -import { ITunnelService } from 'vs/platform/remote/common/tunnel'; -import { TunnelService } from 'vs/workbench/services/remote/node/tunnelService'; import { ICredentialsService } from 'vs/platform/credentials/common/credentials'; import { KeytarCredentialsService } from 'vs/platform/credentials/node/credentialsService'; -import { IWorkspaceStatsService, WorkspaceStatsService } from 'vs/workbench/contrib/stats/electron-browser/workspaceStatsService'; -import 'vs/workbench/services/bulkEdit/browser/bulkEditService'; -import 'vs/workbench/services/integrity/node/integrityService'; -import 'vs/workbench/services/keybinding/common/keybindingEditing'; -import 'vs/workbench/services/textMate/electron-browser/textMateService'; -import 'vs/workbench/services/workspace/electron-browser/workspaceEditingService'; -import 'vs/workbench/services/extensions/common/inactiveExtensionUrlHandler'; -import 'vs/workbench/services/decorations/browser/decorationsService'; -import 'vs/workbench/services/search/node/searchService'; -import 'vs/workbench/services/progress/browser/progressService'; -import 'vs/workbench/services/editor/browser/codeEditorService'; -import 'vs/workbench/services/extensions/electron-browser/extensionHostDebugService'; -import 'vs/workbench/services/preferences/browser/preferencesService'; -import 'vs/workbench/services/output/node/outputChannelModelService'; -import 'vs/workbench/services/configuration/common/jsonEditingService'; -import 'vs/workbench/services/textmodelResolver/common/textModelResolverService'; -import 'vs/workbench/services/textfile/node/textFileService'; -import 'vs/workbench/services/dialogs/browser/fileDialogService'; -import 'vs/workbench/services/dialogs/electron-browser/dialogService'; -import 'vs/workbench/services/editor/browser/editorService'; -import 'vs/workbench/services/history/browser/history'; -import 'vs/workbench/services/activity/browser/activityService'; -import 'vs/workbench/browser/parts/views/views'; -import 'vs/workbench/services/keybinding/electron-browser/nativeKeymapService'; -import 'vs/workbench/services/keybinding/electron-browser/keybinding.contribution'; -import 'vs/workbench/services/keybinding/browser/keybindingService'; -import 'vs/workbench/services/untitled/common/untitledEditorService'; -import 'vs/workbench/services/textfile/common/textResourcePropertiesService'; -import 'vs/workbench/services/mode/common/workbenchModeService'; -import 'vs/workbench/services/commands/common/commandService'; -import 'vs/workbench/services/themes/browser/workbenchThemeService'; -import 'vs/workbench/services/extensions/electron-browser/extensionService'; -import 'vs/workbench/services/contextmenu/electron-browser/contextmenuService'; -import 'vs/workbench/services/label/common/labelService'; -import 'vs/workbench/services/extensionManagement/electron-browser/extensionManagementServerService'; -import 'vs/workbench/services/extensionManagement/common/extensionEnablementService'; -import 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl'; -import 'vs/workbench/services/notification/common/notificationService'; -import 'vs/workbench/services/window/electron-browser/windowService'; -import 'vs/workbench/services/telemetry/electron-browser/telemetryService'; -import 'vs/workbench/services/configurationResolver/electron-browser/configurationResolverService'; -import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; -import { BackupFileService } from 'vs/workbench/services/backup/node/backupFileService'; -import { ExtensionManagementService } from 'vs/workbench/services/extensionManagement/node/extensionManagementService'; - -registerSingleton(IExtensionManagementService, ExtensionManagementService); -registerSingleton(IBackupFileService, BackupFileService); -registerSingleton(IMenuService, MenuService, true); -registerSingleton(IListService, ListService, true); -registerSingleton(IOpenerService, OpenerService, true); -registerSingleton(IEditorWorkerService, EditorWorkerServiceImpl); -registerSingleton(IMarkerDecorationsService, MarkerDecorationsService); -registerSingleton(IMarkerService, MarkerService, true); -registerSingleton(IDownloadService, DownloadService, true); registerSingleton(IClipboardService, ClipboardService, true); -registerSingleton(IContextKeyService, ContextKeyService); -registerSingleton(IModelService, ModelServiceImpl, true); -registerSingleton(ITextResourceConfigurationService, TextResourceConfigurationService); -registerSingleton(IAccessibilityService, AccessibilityService, true); -registerSingleton(IContextViewService, ContextViewService, true); -registerSingleton(IExtensionGalleryService, ExtensionGalleryService, true); registerSingleton(IRequestService, RequestService, true); registerSingleton(ILifecycleService, LifecycleService); registerSingleton(ILocalizationsService, LocalizationsService); @@ -153,9 +90,7 @@ registerSingleton(IIssueService, IssueService); registerSingleton(IWorkspacesService, WorkspacesService); registerSingleton(IMenubarService, MenubarService); registerSingleton(IURLService, RelayURLService); -registerSingleton(ITunnelService, TunnelService, true); registerSingleton(ICredentialsService, KeytarCredentialsService, true); -registerSingleton(IWorkspaceStatsService, WorkspaceStatsService, true); //#endregion diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 322b6b01bff..9695a47cfe1 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -26,130 +26,39 @@ import 'vs/workbench/browser/web.main'; //#region --- workbench services +import 'vs/workbench/services/textMate/browser/textMateService'; +import 'vs/workbench/services/search/common/searchService'; +import 'vs/workbench/services/output/common/outputChannelModelService'; +import 'vs/workbench/services/textfile/browser/textFileService'; +import 'vs/workbench/services/keybinding/browser/keymapService'; +import 'vs/workbench/services/extensions/browser/extensionService'; +import 'vs/workbench/services/extensionManagement/common/extensionManagementServerService'; +import 'vs/workbench/services/telemetry/browser/telemetryService'; +import 'vs/workbench/services/configurationResolver/browser/configurationResolverService'; +import 'vs/workbench/browser/web.simpleservices'; + import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IMenuService } from 'vs/platform/actions/common/actions'; -import { MenuService } from 'vs/platform/actions/common/menuService'; -import { IListService, ListService } from 'vs/platform/list/browser/listService'; -import { OpenerService } from 'vs/editor/browser/services/openerService'; -import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService'; -import { EditorWorkerServiceImpl } from 'vs/editor/common/services/editorWorkerServiceImpl'; -import { MarkerDecorationsService } from 'vs/editor/common/services/markerDecorationsServiceImpl'; -import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDecorationService'; -import { IMarkerService } from 'vs/platform/markers/common/markers'; -import { MarkerService } from 'vs/platform/markers/common/markerService'; -import { IDownloadService } from 'vs/platform/download/common/download'; -import { DownloadService } from 'vs/platform/download/common/downloadService'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { BrowserClipboardService } from 'vs/platform/clipboard/browser/clipboardService'; -import { ContextKeyService } from 'vs/platform/contextkey/browser/contextKeyService'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { IModelService } from 'vs/editor/common/services/modelService'; -import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl'; -import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration'; -import { TextResourceConfigurationService } from 'vs/editor/common/services/resourceConfigurationImpl'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { BrowserAccessibilityService } from 'vs/platform/accessibility/common/accessibilityService'; -import { IExtensionGalleryService, IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService'; -import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; +import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { BrowserLifecycleService } from 'vs/platform/lifecycle/browser/lifecycleService'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { DialogService } from 'vs/platform/dialogs/browser/dialogService'; -// import { ILocalizationsService } from 'vs/platform/localizations/common/localizations'; -// import { LocalizationsService } from 'vs/platform/localizations/electron-browser/localizationsService'; -// import { ISharedProcessService, SharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; -// import { IWindowsService } from 'vs/platform/windows/common/windows'; -// import { WindowsService } from 'vs/platform/windows/electron-browser/windowsService'; -// import { IUpdateService } from 'vs/platform/update/common/update'; -// import { UpdateService } from 'vs/platform/update/electron-browser/updateService'; -// import { IIssueService } from 'vs/platform/issue/common/issue'; -// import { IssueService } from 'vs/platform/issue/electron-browser/issueService'; -// import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces'; -// import { WorkspacesService } from 'vs/platform/workspaces/electron-browser/workspacesService'; -// import { IMenubarService } from 'vs/platform/menubar/common/menubar'; -// import { MenubarService } from 'vs/platform/menubar/electron-browser/menubarService'; -// import { IURLService } from 'vs/platform/url/common/url'; -// import { RelayURLService } from 'vs/platform/url/electron-browser/urlService'; -// import { ITunnelService } from 'vs/platform/remote/common/tunnel'; -// import { TunnelService } from 'vs/workbench/services/remote/node/tunnelService'; -// import { ICredentialsService } from 'vs/platform/credentials/common/credentials'; -// import { KeytarCredentialsService } from 'vs/platform/credentials/node/credentialsService'; -import 'vs/workbench/services/bulkEdit/browser/bulkEditService'; -// import 'vs/workbench/services/integrity/node/integrityService'; -import 'vs/workbench/services/keybinding/common/keybindingEditing'; -import 'vs/workbench/services/textMate/browser/textMateService'; -// import 'vs/workbench/services/workspace/electron-browser/workspaceEditingService'; -// import 'vs/workbench/services/extensions/electron-browser/inactiveExtensionUrlHandler'; -import 'vs/workbench/services/decorations/browser/decorationsService'; -import 'vs/workbench/services/search/common/searchService'; -import 'vs/workbench/services/progress/browser/progressService'; -import 'vs/workbench/services/editor/browser/codeEditorService'; -import 'vs/workbench/services/preferences/browser/preferencesService'; -import 'vs/workbench/services/output/common/outputChannelModelService'; -import 'vs/workbench/services/configuration/common/jsonEditingService'; -import 'vs/workbench/services/textmodelResolver/common/textModelResolverService'; -import 'vs/workbench/services/textfile/browser/textFileService'; -import 'vs/workbench/services/dialogs/browser/fileDialogService'; -// import 'vs/workbench/services/dialogs/electron-browser/dialogService'; -import 'vs/workbench/services/editor/browser/editorService'; -import 'vs/workbench/services/history/browser/history'; -import 'vs/workbench/services/activity/browser/activityService'; -import 'vs/workbench/browser/parts/views/views'; -import 'vs/workbench/services/keybinding/browser/keymapService'; -import 'vs/workbench/services/keybinding/browser/keybindingService'; -import 'vs/workbench/services/untitled/common/untitledEditorService'; -import 'vs/workbench/services/textfile/common/textResourcePropertiesService'; -import 'vs/workbench/services/mode/common/workbenchModeService'; -import 'vs/workbench/services/commands/common/commandService'; -import 'vs/workbench/services/themes/browser/workbenchThemeService'; -import 'vs/workbench/services/extensions/browser/extensionService'; -// import 'vs/workbench/services/contextmenu/electron-browser/contextmenuService'; -import 'vs/workbench/services/label/common/labelService'; -import 'vs/workbench/services/extensionManagement/common/extensionManagementServerService'; -import 'vs/workbench/services/extensionManagement/common/extensionEnablementService'; -// import 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl'; -import 'vs/workbench/services/notification/common/notificationService'; -// import 'vs/workbench/services/window/electron-browser/windowService'; -import 'vs/workbench/services/telemetry/browser/telemetryService'; -import 'vs/workbench/services/configurationResolver/browser/configurationResolverService'; -import { IContextViewService, IContextMenuService } from 'vs/platform/contextview/browser/contextView'; +import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { ContextMenuService } from 'vs/platform/contextview/browser/contextMenuService'; import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; import { BackupFileService } from 'vs/workbench/services/backup/common/backupFileService'; import { ExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagementService'; -import 'vs/workbench/browser/web.simpleservices'; - registerSingleton(IExtensionManagementService, ExtensionManagementService); registerSingleton(IBackupFileService, BackupFileService); registerSingleton(IDialogService, DialogService, true); -registerSingleton(IMenuService, MenuService, true); -registerSingleton(IListService, ListService, true); -registerSingleton(IOpenerService, OpenerService, true); -registerSingleton(IEditorWorkerService, EditorWorkerServiceImpl); -registerSingleton(IMarkerDecorationsService, MarkerDecorationsService); -registerSingleton(IMarkerService, MarkerService, true); -registerSingleton(IDownloadService, DownloadService, true); registerSingleton(IClipboardService, BrowserClipboardService, true); -registerSingleton(IContextKeyService, ContextKeyService); -registerSingleton(IModelService, ModelServiceImpl, true); -registerSingleton(ITextResourceConfigurationService, TextResourceConfigurationService); registerSingleton(IAccessibilityService, BrowserAccessibilityService, true); -registerSingleton(IContextViewService, ContextViewService, true); -registerSingleton(IExtensionGalleryService, ExtensionGalleryService, true); registerSingleton(ILifecycleService, BrowserLifecycleService); -// registerSingleton(ILocalizationsService, LocalizationsService); -// registerSingleton(ISharedProcessService, SharedProcessService, true); -// registerSingleton(IWindowsService, WindowsService); -// registerSingleton(IUpdateService, UpdateService); -// registerSingleton(IIssueService, IssueService); -// registerSingleton(IWorkspacesService, WorkspacesService); -// registerSingleton(IMenubarService, MenubarService); -// registerSingleton(IURLService, RelayURLService); -// registerSingleton(ITunnelService, TunnelService, true); -// registerSingleton(ICredentialsService, KeytarCredentialsService, true); registerSingleton(IContextMenuService, ContextMenuService); //#endregion From 3ecbf67c015d9597b6fb5173525680c47c9665b4 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 12 Aug 2019 12:53:24 +0200 Subject: [PATCH 467/861] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ec74a2f6bcb..98e285ab5af 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "b9b380a45ae5d292a9203b1a0ca458796d78abcb", + "distro": "44929aed2f9b37ed5c248effd1de004f84e2106c", "author": { "name": "Microsoft Corporation" }, From 71fcfc46832a403aa8b46357a24639c678743c12 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Mon, 12 Aug 2019 13:15:47 +0200 Subject: [PATCH 468/861] support empty window when debugging extensions --- src/vs/code/electron-main/windows.ts | 9 ++++--- .../workbench/browser/web.simpleservices.ts | 24 +++++++++++++++---- .../environment/browser/environmentService.ts | 2 +- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index c98f1958018..d4defa1962e 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -1256,10 +1256,9 @@ export class WindowsManager extends Disposable implements IWindowsMainService { openConfig.cli['file-uri'] = fileUris; // if there are no files or folders cli args left, use the "remote" cli argument - if (!cliArgs.length && !folderUris.length && !fileUris.length) { - if (authority) { - openConfig.cli.remote = authority; - } + const noFilesOrFolders = !cliArgs.length && !folderUris.length && !fileUris.length; + if (noFilesOrFolders && authority) { + openConfig.cli.remote = authority; } // Open it @@ -1267,7 +1266,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService { context: openConfig.context, cli: openConfig.cli, forceNewWindow: true, - forceEmpty: !cliArgs.length && !folderUris.length && !fileUris.length, + forceEmpty: noFilesOrFolders, userEnv: openConfig.userEnv, noRecentEntry: true, waitMarkerFileURI: openConfig.waitMarkerFileURI diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index b32f33c6bd0..e31a873b221 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -658,6 +658,15 @@ export class SimpleWindowsService implements IWindowsService { // we pass the "ParsedArgs" as query parameters of the URL let newAddress = `${document.location.origin}/?`; + let gotFolder = false; + + const addQueryParameter = (key: string, value: string) => { + const lastChar = newAddress.charAt(newAddress.length - 1); + if (lastChar !== '?' && lastChar !== '&') { + newAddress += '&'; + } + newAddress += `${key}=${encodeURIComponent(value)}`; + }; const f = args['folder-uri']; if (f) { @@ -670,9 +679,14 @@ export class SimpleWindowsService implements IWindowsService { u = URI.parse(f); } if (u) { - newAddress += `folder=${encodeURIComponent(u.path)}`; + gotFolder = true; + addQueryParameter('folder', u.path); } } + if (!gotFolder) { + // request empty window + addQueryParameter('ew', 'true'); + } const ep = args['extensionDevelopmentPath']; if (ep) { @@ -685,23 +699,23 @@ export class SimpleWindowsService implements IWindowsService { u = ep; } if (u) { - newAddress += `&edp=${encodeURIComponent(u)}`; + addQueryParameter('edp', u); } } const di = args['debugId']; if (di) { - newAddress += `&di=${encodeURIComponent(di)}`; + addQueryParameter('di', di); } const ibe = args['inspect-brk-extensions']; if (ibe) { - newAddress += `&ibe=${encodeURIComponent(ibe)}`; + addQueryParameter('ibe', ibe); } // add connection token if (this.workbenchEnvironmentService.configuration.connectionToken) { - newAddress += `&tkn=${this.workbenchEnvironmentService.configuration.connectionToken}`; + addQueryParameter('tkn', this.workbenchEnvironmentService.configuration.connectionToken); } window.open(newAddress); diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts index b6c34540a10..250fd43582e 100644 --- a/src/vs/workbench/services/environment/browser/environmentService.ts +++ b/src/vs/workbench/services/environment/browser/environmentService.ts @@ -105,7 +105,7 @@ export class BrowserWorkbenchEnvironmentService implements IEnvironmentService { for (let p of vars) { const pair = p.split('='); if (pair.length >= 2) { - map.set(decodeURIComponent(pair[0]), decodeURIComponent(pair[1])); + map.set(pair[0], decodeURIComponent(pair[1])); } } From 9564bf10f6992efe424cacf815b21db7ea5c0e0a Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Mon, 12 Aug 2019 13:22:13 +0200 Subject: [PATCH 469/861] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 98e285ab5af..21f6cf8ec4c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "44929aed2f9b37ed5c248effd1de004f84e2106c", + "distro": "cefe99a704b186add6f59357a54daa389f5be07d", "author": { "name": "Microsoft Corporation" }, From 264d6ac8290aad1605c6855c541ebd5ba15c42d9 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 12 Aug 2019 14:06:53 +0200 Subject: [PATCH 470/861] :lipstick: --- extensions/git/src/api/git.d.ts | 3 ++- extensions/git/src/git.ts | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index 21195974fc1..a0b2d3dad7f 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -238,5 +238,6 @@ export const enum GitErrorCodes { CantLockRef = 'CantLockRef', CantRebaseMultipleBranches = 'CantRebaseMultipleBranches', PatchDoesNotApply = 'PatchDoesNotApply', - NoPathFound = 'NoPathFound' + NoPathFound = 'NoPathFound', + UnknownPath = 'UnknownPath', } diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 5a0dd96af77..c03c1239722 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -801,7 +801,7 @@ export class Repository { const elements = await this.lsfiles(path); if (elements.length === 0) { - throw new GitError({ message: 'Error running ls-files' }); + throw new GitError({ message: 'Path not known by git', gitErrorCode: GitErrorCodes.UnknownPath }); } const { mode, object } = elements[0]; @@ -814,7 +814,7 @@ export class Repository { const elements = await this.lstree(treeish, path); if (elements.length === 0) { - throw new GitError({ message: 'Error running ls-files' }); + throw new GitError({ message: 'Path not known by git', gitErrorCode: GitErrorCodes.UnknownPath }); } const { mode, object, size } = elements[0]; @@ -1134,6 +1134,10 @@ export class Repository { const details = await this.getObjectDetails('HEAD', path); mode = details.mode; } catch (err) { + if (err.gitErrorCode !== GitErrorCodes.UnknownPath) { + throw err; + } + mode = '100644'; add = '--add'; } From e15a88875ab543917f8bf6aa46113db7fa7204de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Mon, 12 Aug 2019 14:12:18 +0200 Subject: [PATCH 471/861] Fixes #78949 (#78950) --- src/vs/workbench/api/common/extHostDocumentContentProviders.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/api/common/extHostDocumentContentProviders.ts b/src/vs/workbench/api/common/extHostDocumentContentProviders.ts index b6f46b8f759..56fda7f3a90 100644 --- a/src/vs/workbench/api/common/extHostDocumentContentProviders.ts +++ b/src/vs/workbench/api/common/extHostDocumentContentProviders.ts @@ -50,7 +50,7 @@ export class ExtHostDocumentContentProvider implements ExtHostDocumentContentPro } if (this._documentsAndEditors.getDocument(uri)) { this.$provideTextDocumentContent(handle, uri).then(value => { - if (!value) { + if (!value && typeof value !== 'string') { return; } From b0650697162f9e0ad03e55c869b7faa89a9eaea7 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 12 Aug 2019 14:32:54 +0200 Subject: [PATCH 472/861] :lipstick: --- src/vs/base/browser/ui/tree/abstractTree.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index ebc90a0f9a7..7402d493a98 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -1066,11 +1066,8 @@ class TreeNodeListMouseController extends MouseController< } protected onDoubleClick(e: IListMouseEvent>): void { - if (isInputElement(e.browserEvent.target as HTMLElement)) { - return; - } - const onTwistie = hasClass(e.browserEvent.target as HTMLElement, 'monaco-tl-twistie'); + if (onTwistie) { return; } From 2700f41dab7a4edfd0263876feba74c5e55423fe Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 12 Aug 2019 14:47:20 +0200 Subject: [PATCH 473/861] use desktop and web ext host logging service --- .../workbench/api/common/extHost.api.impl.ts | 11 +-- .../api/common/extHostExtensionService.ts | 23 +++-- .../workbench/api/common/extHostLogService.ts | 34 -------- src/vs/workbench/api/node/extHost.services.ts | 3 + .../api/node/extHostExtensionService.ts | 4 +- .../workbench/api/node/extHostLogService.ts | 36 ++++++++ .../workbench/api/worker/extHostLogService.ts | 84 +++++++++++++++++++ .../extensions/common/extensionHostMain.ts | 11 ++- .../services/extensions/node/proxyResolver.ts | 10 +-- .../extensions/worker/extHost.services.ts | 5 +- tslint.json | 8 ++ 11 files changed, 160 insertions(+), 69 deletions(-) delete mode 100644 src/vs/workbench/api/common/extHostLogService.ts create mode 100644 src/vs/workbench/api/node/extHostLogService.ts create mode 100644 src/vs/workbench/api/worker/extHostLogService.ts diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index e8fec875029..0c4b489095d 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -15,7 +15,7 @@ import { OverviewRulerLane } from 'vs/editor/common/model'; import * as languageConfiguration from 'vs/editor/common/modes/languageConfiguration'; import { score } from 'vs/editor/common/modes/languageSelector'; import * as files from 'vs/platform/files/common/files'; -import { ExtHostContext, MainContext } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostContext, MainContext, ExtHostLogServiceShape } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostApiCommands } from 'vs/workbench/api/common/extHostApiCommands'; import { ExtHostClipboard } from 'vs/workbench/api/common/extHostClipboard'; import { IExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; @@ -33,7 +33,6 @@ import { ExtHostFileSystem } from 'vs/workbench/api/common/extHostFileSystem'; import { ExtHostFileSystemEventService } from 'vs/workbench/api/common/extHostFileSystemEventService'; import { ExtHostLanguageFeatures } from 'vs/workbench/api/common/extHostLanguageFeatures'; import { ExtHostLanguages } from 'vs/workbench/api/common/extHostLanguages'; -import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; import { ExtHostMessageService } from 'vs/workbench/api/common/extHostMessageService'; import { IExtHostOutputService } from 'vs/workbench/api/common/extHostOutput'; import { ExtHostProgress } from 'vs/workbench/api/common/extHostProgress'; @@ -95,10 +94,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I const uriTransformer = accessor.get(IURITransformerService); const rpcProtocol = accessor.get(IExtHostRpcService); const extHostStorage = accessor.get(IExtHostStorage); - const extHostLogService = accessor.get(ILogService); + const extHostLogService = accessor.get(ILogService); // register addressable instances - rpcProtocol.set(ExtHostContext.ExtHostLogService, extHostLogService); + rpcProtocol.set(ExtHostContext.ExtHostLogService, extHostLogService); rpcProtocol.set(ExtHostContext.ExtHostWorkspace, extHostWorkspace); rpcProtocol.set(ExtHostContext.ExtHostConfiguration, extHostConfiguration); rpcProtocol.set(ExtHostContext.ExtHostExtensionService, extensionService); @@ -145,10 +144,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I const extHostStatusBar = new ExtHostStatusBar(rpcProtocol); const extHostLanguages = new ExtHostLanguages(rpcProtocol, extHostDocuments); - // Register an output channel for exthost log - const outputChannelName = initData.remote.isRemote ? nls.localize('remote extension host Log', "Remote Extension Host") : nls.localize('extension host Log', "Extension Host"); - extHostOutputService.createOutputChannelFromLogFile(outputChannelName, extHostLogService.logFile); - // Register API-ish commands ExtHostApiCommands.register(extHostCommands); diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts index cd25ceb4bba..3b59d2d692d 100644 --- a/src/vs/workbench/api/common/extHostExtensionService.ts +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -14,7 +14,6 @@ import { ILogService } from 'vs/platform/log/common/log'; import { ExtHostExtensionServiceShape, IInitData, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape, IResolveAuthorityResult } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostConfiguration, IExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionModule, HostExtension, ExtensionActivationTimesFragment } from 'vs/workbench/api/common/extHostExtensionActivator'; -import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; import { ExtHostStorage, IExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; import { ExtHostWorkspace, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import { ExtensionActivationError } from 'vs/workbench/services/extensions/common/extensions'; @@ -75,7 +74,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio protected readonly _instaService: IInstantiationService; protected readonly _extHostWorkspace: ExtHostWorkspace; protected readonly _extHostConfiguration: ExtHostConfiguration; - protected readonly _extHostLogService: ExtHostLogService; + protected readonly _logService: ILogService; protected readonly _mainThreadWorkspaceProxy: MainThreadWorkspaceShape; protected readonly _mainThreadTelemetryProxy: MainThreadTelemetryShape; @@ -102,7 +101,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio @IExtHostRpcService extHostContext: IExtHostRpcService, @IExtHostWorkspace extHostWorkspace: IExtHostWorkspace, @IExtHostConfiguration extHostConfiguration: IExtHostConfiguration, - @ILogService extHostLogService: ExtHostLogService, + @ILogService logService: ILogService, @IExtHostInitDataService initData: IExtHostInitDataService, @IExtensionStoragePaths storagePath: IExtensionStoragePaths ) { @@ -112,7 +111,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio this._extHostWorkspace = extHostWorkspace; this._extHostConfiguration = extHostConfiguration; - this._extHostLogService = extHostLogService; + this._logService = logService; this._disposables = new DisposableStore(); this._mainThreadWorkspaceProxy = this._extHostContext.getProxy(MainContext.MainThreadWorkspace); @@ -329,14 +328,14 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio return Promise.resolve(new EmptyExtension(ExtensionActivationTimes.NONE)); } - this._extHostLogService.info(`ExtensionService#_doActivateExtension ${extensionDescription.identifier.value} ${JSON.stringify(reason)}`); + this._logService.info(`ExtensionService#_doActivateExtension ${extensionDescription.identifier.value} ${JSON.stringify(reason)}`); const activationTimesBuilder = new ExtensionActivationTimesBuilder(reason.startup); return Promise.all([ this._loadCommonJSModule(extensionDescription.main, activationTimesBuilder), this._loadExtensionContext(extensionDescription) ]).then(values => { - return AbstractExtHostExtensionService._callActivate(this._extHostLogService, extensionDescription.identifier, values[0], values[1], activationTimesBuilder); + return AbstractExtHostExtensionService._callActivate(this._logService, extensionDescription.identifier, values[0], values[1], activationTimesBuilder); }); } @@ -347,7 +346,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio const globalState = new ExtensionMemento(extensionDescription.identifier.value, true, this._storage); const workspaceState = new ExtensionMemento(extensionDescription.identifier.value, false, this._storage); - this._extHostLogService.trace(`ExtensionService#loadExtensionContext ${extensionDescription.identifier.value}`); + this._logService.trace(`ExtensionService#loadExtensionContext ${extensionDescription.identifier.value}`); return Promise.all([ globalState.whenReady, workspaceState.whenReady, @@ -359,10 +358,10 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio workspaceState, subscriptions: [], get extensionPath() { return extensionDescription.extensionLocation.fsPath; }, - storagePath: this._storagePath.workspaceValue(extensionDescription), - globalStoragePath: this._storagePath.globalValue(extensionDescription), + get storagePath() { return that._storagePath.workspaceValue(extensionDescription); }, + get globalStoragePath() { return that._storagePath.globalValue(extensionDescription); }, asAbsolutePath: (relativePath: string) => { return path.join(extensionDescription.extensionLocation.fsPath, relativePath); }, - logPath: that._extHostLogService.getLogDirectory(extensionDescription.identifier), + get logPath() { return path.join(that._initData.logsLocation.fsPath, extensionDescription.identifier.value); }, executionContext: this._initData.remote.isRemote ? ExtensionExecutionContext.Remote : ExtensionExecutionContext.Local, }); }); @@ -479,7 +478,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio } private async _activateIfGlobPatterns(folders: ReadonlyArray, extensionId: ExtensionIdentifier, globPatterns: string[]): Promise { - this._extHostLogService.trace(`extensionHostMain#activateIfGlobPatterns: fileSearch, extension: ${extensionId.value}, entryPoint: workspaceContains`); + this._logService.trace(`extensionHostMain#activateIfGlobPatterns: fileSearch, extension: ${extensionId.value}, entryPoint: workspaceContains`); if (globPatterns.length === 0) { return Promise.resolve(undefined); @@ -606,7 +605,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio .then(() => this._handleEagerExtensions()) .then(() => this._handleExtensionTests()) .then(() => { - this._extHostLogService.info(`eager extensions activated`); + this._logService.info(`eager extensions activated`); }); } diff --git a/src/vs/workbench/api/common/extHostLogService.ts b/src/vs/workbench/api/common/extHostLogService.ts deleted file mode 100644 index d67a19801d3..00000000000 --- a/src/vs/workbench/api/common/extHostLogService.ts +++ /dev/null @@ -1,34 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { join } from 'vs/base/common/path'; -import { ILogService, DelegatedLogService, LogLevel } from 'vs/platform/log/common/log'; -import { ExtHostLogServiceShape } from 'vs/workbench/api/common/extHost.protocol'; -import { ExtensionHostLogFileName } from 'vs/workbench/services/extensions/common/extensions'; -import { URI } from 'vs/base/common/uri'; -import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; - -export class ExtHostLogService extends DelegatedLogService implements ILogService, ExtHostLogServiceShape { - - private _logsPath: string; - readonly logFile: URI; - - constructor( - delegate: ILogService, - logsPath: string, - ) { - super(delegate); - this._logsPath = logsPath; - this.logFile = URI.file(join(logsPath, `${ExtensionHostLogFileName}.log`)); - } - - $setLevel(level: LogLevel): void { - this.setLevel(level); - } - - getLogDirectory(extensionID: ExtensionIdentifier): string { - return join(this._logsPath, extensionID.value); - } -} diff --git a/src/vs/workbench/api/node/extHost.services.ts b/src/vs/workbench/api/node/extHost.services.ts index 153413e086e..a227d8a67b3 100644 --- a/src/vs/workbench/api/node/extHost.services.ts +++ b/src/vs/workbench/api/node/extHost.services.ts @@ -24,8 +24,11 @@ import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePa import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService'; import { IExtHostStorage, ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; +import { ILogService } from 'vs/platform/log/common/log'; +import { ExtHostLogService } from 'vs/workbench/api/node/extHostLogService'; // register singleton services +registerSingleton(ILogService, ExtHostLogService); registerSingleton(IExtHostOutputService, ExtHostOutputService2); registerSingleton(IExtHostWorkspace, ExtHostWorkspace); registerSingleton(IExtHostDecorations, ExtHostDecorations); diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index efbf84cf641..99c3a6629d4 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -41,14 +41,14 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { } // Do this when extension service exists, but extensions are not being activated yet. - await connectProxyResolver(this._extHostWorkspace, configProvider, this, this._extHostLogService, this._mainThreadTelemetryProxy); + await connectProxyResolver(this._extHostWorkspace, configProvider, this, this._logService, this._mainThreadTelemetryProxy); } protected _loadCommonJSModule(modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { let r: T | null = null; activationTimesBuilder.codeLoadingStart(); - this._extHostLogService.info(`ExtensionService#loadCommonJSModule ${modulePath}`); + this._logService.info(`ExtensionService#loadCommonJSModule ${modulePath}`); try { r = require.__$__nodeRequire(modulePath); } catch (e) { diff --git a/src/vs/workbench/api/node/extHostLogService.ts b/src/vs/workbench/api/node/extHostLogService.ts new file mode 100644 index 00000000000..f29d417620d --- /dev/null +++ b/src/vs/workbench/api/node/extHostLogService.ts @@ -0,0 +1,36 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize } from 'vs/nls'; +import { join } from 'vs/base/common/path'; +import { ILogService, DelegatedLogService, LogLevel } from 'vs/platform/log/common/log'; +import { ExtHostLogServiceShape } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtensionHostLogFileName } from 'vs/workbench/services/extensions/common/extensions'; +import { URI } from 'vs/base/common/uri'; +import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; +import { Schemas } from 'vs/base/common/network'; +import { SpdLogService } from 'vs/platform/log/node/spdlogService'; +import { IExtHostOutputService } from 'vs/workbench/api/common/extHostOutput'; + +export class ExtHostLogService extends DelegatedLogService implements ILogService, ExtHostLogServiceShape { + + constructor( + @IExtHostInitDataService initData: IExtHostInitDataService, + @IExtHostOutputService extHostOutputService: IExtHostOutputService + ) { + if (initData.logsLocation.scheme !== Schemas.file) { throw new Error('Only file-logging supported'); } + super(new SpdLogService(ExtensionHostLogFileName, initData.logsLocation.fsPath, initData.logLevel)); + + // Register an output channel for exthost log + extHostOutputService.createOutputChannelFromLogFile( + initData.remote.isRemote ? localize('remote extension host Log', "Remote Extension Host") : localize('extension host Log', "Extension Host"), + URI.file(join(initData.logsLocation.fsPath, `${ExtensionHostLogFileName}.log`)) + ); + } + + $setLevel(level: LogLevel): void { + this.setLevel(level); + } +} diff --git a/src/vs/workbench/api/worker/extHostLogService.ts b/src/vs/workbench/api/worker/extHostLogService.ts new file mode 100644 index 00000000000..79211c61945 --- /dev/null +++ b/src/vs/workbench/api/worker/extHostLogService.ts @@ -0,0 +1,84 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ILogService, LogLevel, AbstractLogService } from 'vs/platform/log/common/log'; +import { ExtHostLogServiceShape } from 'vs/workbench/api/common/extHost.protocol'; +import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; +import { IExtHostOutputService } from 'vs/workbench/api/common/extHostOutput'; +import * as vscode from 'vscode'; + +export class ExtHostLogService extends AbstractLogService implements ILogService, ExtHostLogServiceShape { + + _serviceBrand: any; + + private readonly _logChannel: vscode.OutputChannel; + + constructor( + @IExtHostInitDataService initData: IExtHostInitDataService, + @IExtHostOutputService extHostOutputService: IExtHostOutputService + ) { + super(); + this.setLevel(initData.logLevel); + this._logChannel = extHostOutputService.createOutputChannel('Log (Worker Extension Host)'); + } + + $setLevel(level: LogLevel): void { + this.setLevel(level); + } + + trace(_message: string, ..._args: any[]): void { + if (this.getLevel() <= LogLevel.Trace) { + this._logChannel.appendLine(this._format(arguments)); + } + } + + debug(_message: string, ..._args: any[]): void { + if (this.getLevel() <= LogLevel.Debug) { + this._logChannel.appendLine(this._format(arguments)); + } + } + + info(_message: string, ..._args: any[]): void { + if (this.getLevel() <= LogLevel.Info) { + this._logChannel.appendLine(this._format(arguments)); + } + } + + warn(_message: string, ..._args: any[]): void { + if (this.getLevel() <= LogLevel.Warning) { + this._logChannel.appendLine(this._format(arguments)); + } + } + + error(_message: string | Error, ..._args: any[]): void { + if (this.getLevel() <= LogLevel.Error) { + this._logChannel.appendLine(this._format(arguments)); + } + } + + critical(_message: string | Error, ..._args: any[]): void { + if (this.getLevel() <= LogLevel.Critical) { + this._logChannel.appendLine(String(arguments)); + } + } + + private _format(args: any): string { + let result = ''; + + for (let i = 0; i < args.length; i++) { + let a = args[i]; + + if (typeof a === 'object') { + try { + a = JSON.stringify(a); + } catch (e) { } + } + + result += (i > 0 ? ' ' : '') + a; + } + + return result; + } +} diff --git a/src/vs/workbench/services/extensions/common/extensionHostMain.ts b/src/vs/workbench/services/extensions/common/extensionHostMain.ts index d1c8e25185b..555d4f2f7c8 100644 --- a/src/vs/workbench/services/extensions/common/extensionHostMain.ts +++ b/src/vs/workbench/services/extensions/common/extensionHostMain.ts @@ -10,7 +10,6 @@ import { URI, setUriThrowOnMissingScheme } from 'vs/base/common/uri'; import { IURITransformer } from 'vs/base/common/uriIpc'; import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; import { IInitData, MainContext, MainThreadConsoleShape } from 'vs/workbench/api/common/extHost.protocol'; -import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; import { RPCProtocol } from 'vs/workbench/services/extensions/common/rpcProtocol'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { ILogService } from 'vs/platform/log/common/log'; @@ -65,21 +64,21 @@ export class ExtensionHostMain { consolePatchFn(rpcProtocol.getProxy(MainContext.MainThreadConsole)); // services - const extHostLogService = new ExtHostLogService(logServiceFn(initData), initData.logsLocation.fsPath); - this._disposables.add(extHostLogService); // bootstrap services const services = new ServiceCollection(...getSingletonServiceDescriptors()); services.set(IExtHostInitDataService, { _serviceBrand: undefined, ...initData }); services.set(IExtHostRpcService, new ExtHostRpcService(rpcProtocol)); - services.set(ILogService, extHostLogService); services.set(IURITransformerService, new URITransformerService(uriTransformer)); services.set(IHostUtils, hostUtils); const instaService: IInstantiationService = new InstantiationService(services, true); - extHostLogService.info('extension host started'); - extHostLogService.trace('initData', initData); + const logService = instaService.invokeFunction(accessor => accessor.get(ILogService)); + this._disposables.add(logService); + + logService.info('extension host started'); + logService.trace('initData', initData); // todo@joh -> not soo nice... this._extensionService = instaService.invokeFunction(accessor => accessor.get(IExtHostExtensionService)); diff --git a/src/vs/workbench/services/extensions/node/proxyResolver.ts b/src/vs/workbench/services/extensions/node/proxyResolver.ts index 6aa6ba1e617..64c2e0a526e 100644 --- a/src/vs/workbench/services/extensions/node/proxyResolver.ts +++ b/src/vs/workbench/services/extensions/node/proxyResolver.ts @@ -17,11 +17,11 @@ import { IExtHostWorkspaceProvider } from 'vs/workbench/api/common/extHostWorksp import { ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration'; import { ProxyAgent } from 'vscode-proxy-agent'; import { MainThreadTelemetryShape } from 'vs/workbench/api/common/extHost.protocol'; -import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService'; import { URI } from 'vs/base/common/uri'; import { promisify } from 'util'; +import { ILogService } from 'vs/platform/log/common/log'; interface ConnectionResult { proxy: string; @@ -34,7 +34,7 @@ export function connectProxyResolver( extHostWorkspace: IExtHostWorkspaceProvider, configProvider: ExtHostConfigProvider, extensionService: ExtHostExtensionService, - extHostLogService: ExtHostLogService, + extHostLogService: ILogService, mainThreadTelemetry: MainThreadTelemetryShape ) { const resolveProxy = setupProxyResolution(extHostWorkspace, configProvider, extHostLogService, mainThreadTelemetry); @@ -47,7 +47,7 @@ const maxCacheEntries = 5000; // Cache can grow twice that much due to 'oldCache function setupProxyResolution( extHostWorkspace: IExtHostWorkspaceProvider, configProvider: ExtHostConfigProvider, - extHostLogService: ExtHostLogService, + extHostLogService: ILogService, mainThreadTelemetry: MainThreadTelemetryShape ) { const env = process.env; @@ -421,7 +421,7 @@ function configureModuleLoading(extensionService: ExtHostExtensionService, looku }); } -function useSystemCertificates(extHostLogService: ExtHostLogService, useSystemCertificates: boolean, opts: http.RequestOptions, callback: () => void) { +function useSystemCertificates(extHostLogService: ILogService, useSystemCertificates: boolean, opts: http.RequestOptions, callback: () => void) { if (useSystemCertificates) { getCaCertificates(extHostLogService) .then(caCertificates => { @@ -443,7 +443,7 @@ function useSystemCertificates(extHostLogService: ExtHostLogService, useSystemCe } let _caCertificates: ReturnType | Promise; -async function getCaCertificates(extHostLogService: ExtHostLogService) { +async function getCaCertificates(extHostLogService: ILogService) { if (!_caCertificates) { _caCertificates = readCaCertificates() .then(res => res && res.certs.length ? res : undefined) diff --git a/src/vs/workbench/services/extensions/worker/extHost.services.ts b/src/vs/workbench/services/extensions/worker/extHost.services.ts index 127250f83be..bf4a7791554 100644 --- a/src/vs/workbench/services/extensions/worker/extHost.services.ts +++ b/src/vs/workbench/services/extensions/worker/extHost.services.ts @@ -19,8 +19,11 @@ import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensi import { IExtHostStorage, ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; import { ExtHostExtensionService } from 'vs/workbench/api/worker/extHostExtensionService'; import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import { ILogService } from 'vs/platform/log/common/log'; +import { ExtHostLogService } from 'vs/workbench/api/worker/extHostLogService'; // register singleton services +registerSingleton(ILogService, ExtHostLogService); registerSingleton(IExtHostOutputService, ExtHostOutputService); registerSingleton(IExtHostWorkspace, ExtHostWorkspace); registerSingleton(IExtHostDecorations, ExtHostDecorations); @@ -51,6 +54,4 @@ registerSingleton(IExtHostDebugService, class extends NotImplementedProxy(IExtHo registerSingleton(IExtHostSearch, class extends NotImplementedProxy(IExtHostSearch) { }); registerSingleton(IExtensionStoragePaths, class extends NotImplementedProxy(IExtensionStoragePaths) { whenReady = Promise.resolve(); - globalValue = () => ''; - workspaceValue = () => ''; }); diff --git a/tslint.json b/tslint.json index f5d3c5ba2ab..a85f54758d4 100644 --- a/tslint.json +++ b/tslint.json @@ -391,6 +391,14 @@ "**/vs/workbench/contrib/*/common/**" ] }, + { + "target": "**/vs/workbench/api/worker/**", + "restrictions": [ + "vscode", + "vs/nls", + "**/vs/**/{common,worker}/**" + ] + }, { "target": "**/vs/workbench/electron-browser/**", "restrictions": [ From 8ed95311cdf869c36aa14835487aeb5a34ea15a9 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 12 Aug 2019 14:50:44 +0200 Subject: [PATCH 474/861] remove ILogServiceFn function --- .../services/extensions/common/extensionHostMain.ts | 5 ----- .../extensions/node/extensionHostProcessSetup.ts | 9 ++------- .../services/extensions/worker/extensionHostWorker.ts | 2 -- 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/services/extensions/common/extensionHostMain.ts b/src/vs/workbench/services/extensions/common/extensionHostMain.ts index 555d4f2f7c8..7f6cd8d0278 100644 --- a/src/vs/workbench/services/extensions/common/extensionHostMain.ts +++ b/src/vs/workbench/services/extensions/common/extensionHostMain.ts @@ -34,10 +34,6 @@ export interface IConsolePatchFn { (mainThreadConsole: MainThreadConsoleShape): any; } -export interface ILogServiceFn { - (initData: IInitData): ILogService; -} - export class ExtensionHostMain { private _isTerminating: boolean; @@ -50,7 +46,6 @@ export class ExtensionHostMain { initData: IInitData, hostUtils: IHostUtils, consolePatchFn: IConsolePatchFn, - logServiceFn: ILogServiceFn, uriTransformer: IURITransformer | null ) { this._isTerminating = false; diff --git a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts index f708e29da7c..0a067fb0a9f 100644 --- a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts +++ b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts @@ -14,14 +14,12 @@ import { NodeSocket, WebSocketNodeSocket } from 'vs/base/parts/ipc/node/ipc.net' import product from 'vs/platform/product/node/product'; import { IInitData, MainThreadConsoleShape } from 'vs/workbench/api/common/extHost.protocol'; import { MessageType, createMessageOfType, isMessageOfType, IExtHostSocketMessage, IExtHostReadyMessage } from 'vs/workbench/services/extensions/common/extensionHostProtocol'; -import { ExtensionHostMain, IExitFn, ILogServiceFn } from 'vs/workbench/services/extensions/common/extensionHostMain'; +import { ExtensionHostMain, IExitFn } from 'vs/workbench/services/extensions/common/extensionHostMain'; import { VSBuffer } from 'vs/base/common/buffer'; -import { ExtensionHostLogFileName } from 'vs/workbench/services/extensions/common/extensions'; import { IURITransformer, URITransformer, IRawURITransformer } from 'vs/base/common/uriIpc'; import { exists } from 'vs/base/node/pfs'; import { realpath } from 'vs/base/node/extpath'; import { IHostUtils } from 'vs/workbench/api/common/extHostExtensionService'; -import { SpdLogService } from 'vs/platform/log/node/spdlogService'; import 'vs/workbench/api/node/extHost.services'; interface ParsedExtHostArgs { @@ -83,8 +81,6 @@ function patchPatchedConsole(mainThreadConsole: MainThreadConsoleShape): void { }; } -const createLogService: ILogServiceFn = initData => new SpdLogService(ExtensionHostLogFileName, initData.logsLocation.fsPath, initData.logLevel); - interface IRendererConnection { protocol: IMessagePassingProtocol; initData: IInitData; @@ -206,7 +202,7 @@ async function createExtHostProtocol(): Promise { } function connectToRenderer(protocol: IMessagePassingProtocol): Promise { - return new Promise((c, e) => { + return new Promise((c) => { // Listen init data message const first = protocol.onMessage(raw => { @@ -336,7 +332,6 @@ export async function startExtensionHostProcess(): Promise { initData, hostUtils, patchPatchedConsole, - createLogService, uriTransformer ); diff --git a/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts b/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts index 7d42bf2044d..49bba4083da 100644 --- a/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts +++ b/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts @@ -10,7 +10,6 @@ import { Emitter } from 'vs/base/common/event'; import { isMessageOfType, MessageType, createMessageOfType } from 'vs/workbench/services/extensions/common/extensionHostProtocol'; import { IInitData } from 'vs/workbench/api/common/extHost.protocol'; import { ExtensionHostMain } from 'vs/workbench/services/extensions/common/extensionHostMain'; -import { ConsoleLogService } from 'vs/platform/log/common/log'; import { IHostUtils } from 'vs/workbench/api/common/extHostExtensionService'; import 'vs/workbench/services/extensions/worker/extHost.services'; @@ -114,7 +113,6 @@ export function create(postMessage: (message: any, transfer?: Transferable[]) => data.initData, hostUtil, () => { }, - () => new ConsoleLogService(), null, ); From 91da8dc7002d1485d53d46b867e7a21dfb6a6ae7 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 12 Aug 2019 15:01:26 +0200 Subject: [PATCH 475/861] Update C++ grammar for insiders to get hang fix Fixes #78769 --- build/npm/update-grammar.js | 2 +- extensions/cpp/build/update-grammars.js | 4 +- extensions/cpp/cgmanifest.json | 2 +- extensions/cpp/syntaxes/c.tmLanguage.json | 4 +- extensions/cpp/syntaxes/cpp.tmLanguage.json | 5560 +++++++++-------- .../test/colorize-results/test-23630_cpp.json | 26 +- .../test/colorize-results/test-23850_cpp.json | 26 +- .../cpp/test/colorize-results/test_cc.json | 30 +- .../cpp/test/colorize-results/test_cpp.json | 2 +- 9 files changed, 2995 insertions(+), 2661 deletions(-) diff --git a/build/npm/update-grammar.js b/build/npm/update-grammar.js index 5321b7b1dcd..ff568a613c8 100644 --- a/build/npm/update-grammar.js +++ b/build/npm/update-grammar.js @@ -132,7 +132,7 @@ exports.update = function (repoId, repoPath, dest, modifyGrammar, version = 'mas if (packageJsonPathOverride) { packageJsonPath += packageJsonPathOverride; } - packageJsonPath += '/package.json'; + packageJsonPath += 'package.json'; for (let i = 0; i < cgmanifestRead.registrations.length; i++) { if (cgmanifestRead.registrations[i].component.git.repositoryUrl.substr(cgmanifestRead.registrations[i].component.git.repositoryUrl.length - repoId.length, repoId.length) === repoId) { cgmanifestRead.registrations[i].component.git.commitHash = info.commitSha; diff --git a/extensions/cpp/build/update-grammars.js b/extensions/cpp/build/update-grammars.js index 29761cdaf95..d02d53810ca 100644 --- a/extensions/cpp/build/update-grammars.js +++ b/extensions/cpp/build/update-grammars.js @@ -6,8 +6,8 @@ var updateGrammar = require('../../../build/npm/update-grammar'); -updateGrammar.update('jeff-hykin/cpp-textmate-grammar', '/syntaxes/c.tmLanguage.json', './syntaxes/c.tmLanguage.json', undefined, 'master', 'source/languages/cpp'); -updateGrammar.update('jeff-hykin/cpp-textmate-grammar', '/syntaxes/cpp.tmLanguage.json', './syntaxes/cpp.tmLanguage.json', undefined, 'master', 'source/languages/cpp'); +updateGrammar.update('jeff-hykin/cpp-textmate-grammar', '/syntaxes/c.tmLanguage.json', './syntaxes/c.tmLanguage.json', undefined, 'master', 'source/languages/cpp/'); +updateGrammar.update('jeff-hykin/cpp-textmate-grammar', '/syntaxes/cpp.tmLanguage.json', './syntaxes/cpp.tmLanguage.json', undefined, 'master', 'source/languages/cpp/'); // `source.c.platform` which is still included by other grammars updateGrammar.update('textmate/c.tmbundle', 'Syntaxes/Platform.tmLanguage', './syntaxes/platform.tmLanguage.json'); diff --git a/extensions/cpp/cgmanifest.json b/extensions/cpp/cgmanifest.json index 768ca68ecbc..8ab81224b2a 100644 --- a/extensions/cpp/cgmanifest.json +++ b/extensions/cpp/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "jeff-hykin/cpp-textmate-grammar", "repositoryUrl": "https://github.com/jeff-hykin/cpp-textmate-grammar", - "commitHash": "cbd71f90cd9be0f99ddc9b0f65cec62fc3ada6d1" + "commitHash": "218448eb46260864352d569db13be6cb20767e92" } }, "license": "MIT", diff --git a/extensions/cpp/syntaxes/c.tmLanguage.json b/extensions/cpp/syntaxes/c.tmLanguage.json index 1a95c101984..fbfac34d19d 100644 --- a/extensions/cpp/syntaxes/c.tmLanguage.json +++ b/extensions/cpp/syntaxes/c.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/jeff-hykin/cpp-textmate-grammar/commit/5209e7f9df7661db6f163753141eeb3de6fb02b3", + "version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/218448eb46260864352d569db13be6cb20767e92", "name": "C", "scopeName": "source.c", "patterns": [ @@ -1892,7 +1892,7 @@ "name": "entity.name.other.preprocessor.macro.predefined._Float16.c" }, { - "match": "(\\b__([A-Z_])__\\b)", + "match": "(\\b__([A-Z_]+)__\\b)", "captures": { "1": { "name": "entity.name.other.preprocessor.macro.predefined.probably.$2.c" diff --git a/extensions/cpp/syntaxes/cpp.tmLanguage.json b/extensions/cpp/syntaxes/cpp.tmLanguage.json index 5e0af3c03ef..963a7c6cc28 100644 --- a/extensions/cpp/syntaxes/cpp.tmLanguage.json +++ b/extensions/cpp/syntaxes/cpp.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/jeff-hykin/cpp-textmate-grammar/commit/cbd71f90cd9be0f99ddc9b0f65cec62fc3ada6d1", + "version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/74c2c0eaad8f647e98a188da0f95a64f7239cbe0", "name": "C++", "scopeName": "source.cpp", "patterns": [ @@ -50,9 +50,6 @@ { "include": "#typedef_union" }, - { - "include": "#typedef_function_pointer" - }, { "include": "#typedef_keyword" }, @@ -120,6 +117,750 @@ } } }, + "macro_name": { + "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(#)\\s*pragma\\s+mark)\\s+(.*)", + "captures": { + "1": { + "name": "keyword.control.directive.pragma.pragma-mark.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "punctuation.definition.directive.cpp" + }, + "7": { + "name": "entity.name.tag.pragma-mark.cpp" + } + }, + "name": "meta.preprocessor.pragma.cpp" + }, + "pragma": { + "name": "meta.preprocessor.pragma.cpp", + "begin": "((?:^)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(#)\\s*pragma\\b)", + "beginCaptures": { + "1": { + "name": "keyword.control.directive.pragma.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "punctuation.definition.directive.cpp" + } + }, + "end": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((#)\\s*((?:(?:include|include_next)|import))\\b)\\s*(?:(?:(?:((<)[^>]*(>?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:\\n|$)|(?=\\/\\/)))|((\\\")[^\\\"]*(\\\"?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:\\n|$)|(?=\\/\\/))))|((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:\\n|$)|(?=\\/\\/))))|((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:\\n|$)|(?=\\/\\/)))", + "captures": { + "1": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "2": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "3": { + "name": "comment.block.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "5": { + "name": "keyword.control.directive.$7.cpp" + }, + "6": { + "name": "punctuation.definition.directive.cpp" + }, + "8": { + "name": "string.quoted.other.lt-gt.include.cpp" + }, + "9": { + "name": "punctuation.definition.string.begin.cpp" + }, + "10": { + "name": "punctuation.definition.string.end.cpp" + }, + "11": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "12": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "13": { + "name": "comment.block.cpp" + }, + "14": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "15": { + "name": "string.quoted.double.include.cpp" + }, + "16": { + "name": "punctuation.definition.string.begin.cpp" + }, + "17": { + "name": "punctuation.definition.string.end.cpp" + }, + "18": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "19": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "20": { + "name": "comment.block.cpp" + }, + "21": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "22": { + "name": "entity.name.other.preprocessor.macro.include.cpp" + }, + "23": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "24": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "25": { + "name": "comment.block.cpp" + }, + "26": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "27": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "28": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "29": { + "name": "comment.block.cpp" + }, + "30": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + } + }, + "name": "meta.preprocessor.include.cpp" + }, + "line": { + "name": "meta.preprocessor.line.cpp", + "begin": "((?:^)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(#)\\s*line\\b)", + "beginCaptures": { + "1": { + "name": "keyword.control.directive.line.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "punctuation.definition.directive.cpp" + } + }, + "end": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(#)\\s*((?:error|warning)))\\b\\s*", + "beginCaptures": { + "1": { + "name": "keyword.control.directive.diagnostic.$7.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "punctuation.definition.directive.cpp" + } + }, + "end": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(#)\\s*undef\\b)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))#define.*(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(#)\\s*define\\b)\\s*((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(#)\\s*((?:(?:ifndef|ifdef)|if)))", + "beginCaptures": { + "1": { + "name": "keyword.control.directive.conditional.$7.cpp" + }, + "2": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "3": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "4": { + "name": "comment.block.cpp" + }, + "5": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "6": { + "name": "punctuation.definition.directive.cpp" + } + }, + "patterns": [ + { + "name": "meta.conditional.preprocessor.cpp", + "begin": "\\G(?<=ifndef|ifdef|if)", + "end": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(#)\\s*((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?(?:(?>[^<>]*)\\g<3>?)+)>)\\s*)?(\\()", @@ -6900,9 +7629,6 @@ } }, "patterns": [ - { - "include": "#ever_present_context" - }, { "include": "#evaluation_context" } @@ -6926,9 +7652,6 @@ } }, "patterns": [ - { - "include": "#ever_present_context" - }, { "include": "#evaluation_context" } @@ -7239,9 +7962,6 @@ }, "end": "(?=\\{)", "patterns": [ - { - "include": "#ever_present_context" - }, { "contentName": "meta.parameter.initialization.cpp", "begin": "((?(?:(?>[^<>]*)\\g<3>?)+)>)\\s*)?(\\()", @@ -7268,9 +7988,6 @@ } }, "patterns": [ - { - "include": "#ever_present_context" - }, { "include": "#evaluation_context" } @@ -7294,9 +8011,6 @@ } }, "patterns": [ - { - "include": "#ever_present_context" - }, { "include": "#evaluation_context" } @@ -8236,15 +8950,15 @@ { "include": "#builtin_storage_type_initilizer" }, - { - "include": "#storage_types" - }, { "include": "#qualifiers_and_specifiers_post_parameters" }, { "include": "#functional_specifiers_pre_parameters" }, + { + "include": "#storage_types" + }, { "include": "#misc_storage_modifiers" }, @@ -9660,7 +10374,7 @@ ] }, { - "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\)|,|\\[|=|\\n)", + "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=(?:\\)|,|\\[|=|\\/\\/|(?:\\n|$)))", "captures": { "1": { "patterns": [ @@ -10807,10 +11521,6 @@ } ] }, - "macro_argument": { - "match": "##?(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?!\\w)", - "name": "variable.other.macro.argument.cpp" - }, "lambdas": { "begin": "((?:(?<=[^\\s]|^)(?])|(?<=\\Wreturn|^return))\\s*(\\[(?!\\[))((?:[^\\]\\[]*\\[.*?\\](?!\\s*\\[)[^\\]\\[]*?)*[^\\]\\[]*?)(\\](?!\\[)))", "beginCaptures": { @@ -11075,6 +11785,9 @@ { "include": "#enumerator_list" }, + { + "include": "#comments" + }, { "include": "#comma" }, @@ -11097,6 +11810,9 @@ }, "inheritance_context": { "patterns": [ + { + "include": "#ever_present_context" + }, { "match": ",", "name": "punctuation.separator.delimiter.comma.inheritance.cpp" @@ -11283,7 +11999,7 @@ }, "class_block": { "name": "meta.block.class.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))|((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\))))|(?={))(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(final)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(:)((?>[^{]*)))?))", "beginCaptures": { "1": { "name": "meta.head.class.cpp" @@ -11294,67 +12010,29 @@ "4": { "patterns": [ { - "include": "#attributes_context" - }, - { - "include": "#number_literal" + "include": "#inline_comment" } ] }, "5": { - "patterns": [ - { - "include": "#inline_comment" - } - ] + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "6": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + "name": "comment.block.cpp" }, "7": { - "name": "comment.block.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "8": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "9": { - "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" - }, - "10": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "11": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "12": { - "name": "comment.block.cpp" - }, - "13": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "14": { "patterns": [ { "include": "#attributes_context" @@ -11364,16 +12042,179 @@ } ] }, + "9": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "10": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "11": { + "name": "comment.block.cpp" + }, + "12": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "13": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "14": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, "15": { - "name": "entity.name.type.$3.cpp" + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "16": { - "name": "storage.type.modifier.final.cpp" + "name": "comment.block.cpp" }, "17": { - "name": "punctuation.separator.colon.inheritance.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "18": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "19": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "20": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "21": { + "name": "comment.block.cpp" + }, + "22": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "23": { + "name": "entity.name.type.$3.cpp" + }, + "24": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "25": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "26": { + "name": "comment.block.cpp" + }, + "27": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "28": { + "name": "storage.type.modifier.final.cpp" + }, + "29": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "30": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "31": { + "name": "comment.block.cpp" + }, + "32": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "33": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "34": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "35": { + "name": "comment.block.cpp" + }, + "36": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "37": { + "name": "punctuation.separator.colon.inheritance.cpp" + }, + "38": { "patterns": [ { "include": "#inheritance_context" @@ -11453,7 +12294,7 @@ }, "struct_block": { "name": "meta.block.struct.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))|((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\))))|(?={))(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(final)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(:)((?>[^{]*)))?))", "beginCaptures": { "1": { "name": "meta.head.struct.cpp" @@ -11464,67 +12305,29 @@ "4": { "patterns": [ { - "include": "#attributes_context" - }, - { - "include": "#number_literal" + "include": "#inline_comment" } ] }, "5": { - "patterns": [ - { - "include": "#inline_comment" - } - ] + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "6": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + "name": "comment.block.cpp" }, "7": { - "name": "comment.block.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "8": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "9": { - "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" - }, - "10": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "11": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "12": { - "name": "comment.block.cpp" - }, - "13": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "14": { "patterns": [ { "include": "#attributes_context" @@ -11534,16 +12337,179 @@ } ] }, + "9": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "10": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "11": { + "name": "comment.block.cpp" + }, + "12": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "13": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "14": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, "15": { - "name": "entity.name.type.$3.cpp" + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "16": { - "name": "storage.type.modifier.final.cpp" + "name": "comment.block.cpp" }, "17": { - "name": "punctuation.separator.colon.inheritance.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "18": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "19": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "20": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "21": { + "name": "comment.block.cpp" + }, + "22": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "23": { + "name": "entity.name.type.$3.cpp" + }, + "24": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "25": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "26": { + "name": "comment.block.cpp" + }, + "27": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "28": { + "name": "storage.type.modifier.final.cpp" + }, + "29": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "30": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "31": { + "name": "comment.block.cpp" + }, + "32": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "33": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "34": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "35": { + "name": "comment.block.cpp" + }, + "36": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "37": { + "name": "punctuation.separator.colon.inheritance.cpp" + }, + "38": { "patterns": [ { "include": "#inheritance_context" @@ -11623,7 +12589,7 @@ }, "union_block": { "name": "meta.block.union.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))|((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\))))|(?={))(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(final)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(:)((?>[^{]*)))?))", "beginCaptures": { "1": { "name": "meta.head.union.cpp" @@ -11634,67 +12600,29 @@ "4": { "patterns": [ { - "include": "#attributes_context" - }, - { - "include": "#number_literal" + "include": "#inline_comment" } ] }, "5": { - "patterns": [ - { - "include": "#inline_comment" - } - ] + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "6": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + "name": "comment.block.cpp" }, "7": { - "name": "comment.block.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "8": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "9": { - "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" - }, - "10": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "11": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "12": { - "name": "comment.block.cpp" - }, - "13": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "14": { "patterns": [ { "include": "#attributes_context" @@ -11704,16 +12632,179 @@ } ] }, + "9": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "10": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "11": { + "name": "comment.block.cpp" + }, + "12": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "13": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "14": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, "15": { - "name": "entity.name.type.$3.cpp" + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "16": { - "name": "storage.type.modifier.final.cpp" + "name": "comment.block.cpp" }, "17": { - "name": "punctuation.separator.colon.inheritance.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "18": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "19": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "20": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "21": { + "name": "comment.block.cpp" + }, + "22": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "23": { + "name": "entity.name.type.$3.cpp" + }, + "24": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "25": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "26": { + "name": "comment.block.cpp" + }, + "27": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "28": { + "name": "storage.type.modifier.final.cpp" + }, + "29": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "30": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "31": { + "name": "comment.block.cpp" + }, + "32": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "33": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "34": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "35": { + "name": "comment.block.cpp" + }, + "36": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "37": { + "name": "punctuation.separator.colon.inheritance.cpp" + }, + "38": { "patterns": [ { "include": "#inheritance_context" @@ -11893,7 +12984,7 @@ "patterns": [ { "name": "meta.block.class.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))|((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\))))|(?={))(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(final)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(:)((?>[^{]*)))?))", "beginCaptures": { "1": { "name": "meta.head.class.cpp" @@ -11904,67 +12995,29 @@ "4": { "patterns": [ { - "include": "#attributes_context" - }, - { - "include": "#number_literal" + "include": "#inline_comment" } ] }, "5": { - "patterns": [ - { - "include": "#inline_comment" - } - ] + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "6": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + "name": "comment.block.cpp" }, "7": { - "name": "comment.block.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "8": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "9": { - "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" - }, - "10": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "11": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "12": { - "name": "comment.block.cpp" - }, - "13": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "14": { "patterns": [ { "include": "#attributes_context" @@ -11974,16 +13027,179 @@ } ] }, + "9": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "10": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "11": { + "name": "comment.block.cpp" + }, + "12": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "13": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "14": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, "15": { - "name": "entity.name.type.$3.cpp" + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "16": { - "name": "storage.type.modifier.final.cpp" + "name": "comment.block.cpp" }, "17": { - "name": "punctuation.separator.colon.inheritance.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "18": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "19": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "20": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "21": { + "name": "comment.block.cpp" + }, + "22": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "23": { + "name": "entity.name.type.$3.cpp" + }, + "24": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "25": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "26": { + "name": "comment.block.cpp" + }, + "27": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "28": { + "name": "storage.type.modifier.final.cpp" + }, + "29": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "30": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "31": { + "name": "comment.block.cpp" + }, + "32": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "33": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "34": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "35": { + "name": "comment.block.cpp" + }, + "36": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "37": { + "name": "punctuation.separator.colon.inheritance.cpp" + }, + "38": { "patterns": [ { "include": "#inheritance_context" @@ -12200,7 +13416,7 @@ "patterns": [ { "name": "meta.block.struct.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))|((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\))))|(?={))(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(final)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(:)((?>[^{]*)))?))", "beginCaptures": { "1": { "name": "meta.head.struct.cpp" @@ -12211,67 +13427,29 @@ "4": { "patterns": [ { - "include": "#attributes_context" - }, - { - "include": "#number_literal" + "include": "#inline_comment" } ] }, "5": { - "patterns": [ - { - "include": "#inline_comment" - } - ] + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "6": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + "name": "comment.block.cpp" }, "7": { - "name": "comment.block.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "8": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "9": { - "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" - }, - "10": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "11": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "12": { - "name": "comment.block.cpp" - }, - "13": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "14": { "patterns": [ { "include": "#attributes_context" @@ -12281,16 +13459,179 @@ } ] }, + "9": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "10": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "11": { + "name": "comment.block.cpp" + }, + "12": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "13": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "14": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, "15": { - "name": "entity.name.type.$3.cpp" + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "16": { - "name": "storage.type.modifier.final.cpp" + "name": "comment.block.cpp" }, "17": { - "name": "punctuation.separator.colon.inheritance.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "18": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "19": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "20": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "21": { + "name": "comment.block.cpp" + }, + "22": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "23": { + "name": "entity.name.type.$3.cpp" + }, + "24": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "25": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "26": { + "name": "comment.block.cpp" + }, + "27": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "28": { + "name": "storage.type.modifier.final.cpp" + }, + "29": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "30": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "31": { + "name": "comment.block.cpp" + }, + "32": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "33": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "34": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "35": { + "name": "comment.block.cpp" + }, + "36": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "37": { + "name": "punctuation.separator.colon.inheritance.cpp" + }, + "38": { "patterns": [ { "include": "#inheritance_context" @@ -12507,7 +13848,7 @@ "patterns": [ { "name": "meta.block.union.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))|((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\))))|(?={))(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(final)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(:)((?>[^{]*)))?))", "beginCaptures": { "1": { "name": "meta.head.union.cpp" @@ -12518,67 +13859,29 @@ "4": { "patterns": [ { - "include": "#attributes_context" - }, - { - "include": "#number_literal" + "include": "#inline_comment" } ] }, "5": { - "patterns": [ - { - "include": "#inline_comment" - } - ] + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "6": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + "name": "comment.block.cpp" }, "7": { - "name": "comment.block.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "8": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "9": { - "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" - }, - "10": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "11": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "12": { - "name": "comment.block.cpp" - }, - "13": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "14": { "patterns": [ { "include": "#attributes_context" @@ -12588,16 +13891,179 @@ } ] }, + "9": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "10": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "11": { + "name": "comment.block.cpp" + }, + "12": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "13": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "14": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, "15": { - "name": "entity.name.type.$3.cpp" + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "16": { - "name": "storage.type.modifier.final.cpp" + "name": "comment.block.cpp" }, "17": { - "name": "punctuation.separator.colon.inheritance.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "18": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "19": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "20": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "21": { + "name": "comment.block.cpp" + }, + "22": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "23": { + "name": "entity.name.type.$3.cpp" + }, + "24": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "25": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "26": { + "name": "comment.block.cpp" + }, + "27": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "28": { + "name": "storage.type.modifier.final.cpp" + }, + "29": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "30": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "31": { + "name": "comment.block.cpp" + }, + "32": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "33": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "34": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "35": { + "name": "comment.block.cpp" + }, + "36": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "37": { + "name": "punctuation.separator.colon.inheritance.cpp" + }, + "38": { "patterns": [ { "include": "#inheritance_context" @@ -14591,62 +16057,6 @@ } ] }, - "hacky_fix_for_stray_directive": { - "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))#define.*(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((#)\\s*define\\b)\\s+((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)(?:(\\()([^()\\\\]+)(\\)))?", - "beginCaptures": { - "1": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "2": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "3": { - "name": "comment.block.cpp" - }, - "4": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "5": { - "name": "keyword.control.directive.define.cpp" - }, - "6": { - "name": "punctuation.definition.directive.cpp" - }, - "7": { - "name": "entity.name.function.preprocessor.cpp" - }, - "8": { - "name": "punctuation.definition.parameters.begin.cpp" - }, - "9": { - "patterns": [ - { - "match": "(?<=[(,])\\s*((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*", - "captures": { - "1": { - "name": "variable.parameter.preprocessor.cpp" - } - } - }, - { - "match": ",", - "name": "punctuation.separator.parameters.cpp" - }, - { - "match": "\\.\\.\\.", - "name": "punctuation.vararg-ellipses.variable.parameter.preprocessor.cpp" - } - ] - }, - "10": { - "name": "punctuation.definition.parameters.end.cpp" - } - }, - "end": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((#)\\s*((?:(?:include|include_next)|import))\\b)\\s*(?:(?:(?:((<)[^>]*(>?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:\\n|$)|(?=\\/\\/)))|((\\\")[^\\\"]*(\\\"?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:\\n|$)|(?=\\/\\/))))|((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:\\n|$)|(?=\\/\\/))))|((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:\\n|$)|(?=\\/\\/)))", - "captures": { - "1": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "2": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "3": { - "name": "comment.block.cpp" - }, - "4": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "5": { - "name": "keyword.control.directive.$7.cpp" - }, - "6": { - "name": "punctuation.definition.directive.cpp" - }, - "8": { - "name": "string.quoted.other.lt-gt.include.cpp" - }, - "9": { - "name": "punctuation.definition.string.begin.cpp" - }, - "10": { - "name": "punctuation.definition.string.end.cpp" - }, - "11": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "12": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "13": { - "name": "comment.block.cpp" - }, - "14": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "15": { - "name": "string.quoted.double.include.cpp" - }, - "16": { - "name": "punctuation.definition.string.begin.cpp" - }, - "17": { - "name": "punctuation.definition.string.end.cpp" - }, - "18": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "19": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "20": { - "name": "comment.block.cpp" - }, - "21": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "22": { - "name": "entity.name.other.preprocessor.macro.include.cpp" - }, - "23": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "24": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "25": { - "name": "comment.block.cpp" - }, - "26": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "27": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "28": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "29": { - "name": "comment.block.cpp" - }, - "30": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - } - }, - "name": "meta.preprocessor.include.cpp" - }, - "meta_preprocessor_line": { - "name": "meta.preprocessor.cpp", - "begin": "^\\s*((#)\\s*line)\\b", - "beginCaptures": { - "1": { - "name": "keyword.control.directive.line.cpp" - }, - "2": { - "name": "punctuation.definition.directive.cpp" - } - }, - "end": "(?=(?://|/\\*))|(?=+!]+|\\(\\)|\\[\\]))\\s*\\(\n)", - "end": "(?<=\\))(?!\\w)|(?=+!]+|\\(\\)|\\[\\]))\n)\n\\s*(\\()", - "beginCaptures": { - "1": { - "name": "entity.name.function.cpp" - }, - "2": { - "name": "punctuation.section.arguments.begin.bracket.round.cpp" - } - }, - "end": "(\\))|(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<14>?)+)>)\\s*)?::)*)(((?>(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))::((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\16((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\()))", @@ -16735,9 +16694,6 @@ }, "end": "(?=\\{)", "patterns": [ - { - "include": "#ever_present_context" - }, { "contentName": "meta.parameter.initialization.cpp", "begin": "((?(?:(?>[^<>]*)\\g<3>?)+)>)\\s*)?(\\()", @@ -16764,9 +16720,6 @@ } }, "patterns": [ - { - "include": "#ever_present_context" - }, { "include": "#evaluation_context" } @@ -16790,9 +16743,6 @@ } }, "patterns": [ - { - "include": "#ever_present_context" - }, { "include": "#evaluation_context" } @@ -17653,9 +17603,6 @@ } ] }, - { - "include": "#qualifiers_and_specifiers_post_parameters" - }, { "include": "$self" } @@ -18621,7 +18568,7 @@ "patterns": [ { "name": "meta.block.class.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))|((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\))))|(?={))(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(final)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(:)((?>[^{]*)))?))", "beginCaptures": { "1": { "name": "meta.head.class.cpp" @@ -18632,67 +18579,29 @@ "4": { "patterns": [ { - "include": "#attributes_context" - }, - { - "include": "#number_literal" + "include": "#inline_comment" } ] }, "5": { - "patterns": [ - { - "include": "#inline_comment" - } - ] + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "6": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + "name": "comment.block.cpp" }, "7": { - "name": "comment.block.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "8": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "9": { - "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" - }, - "10": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "11": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "12": { - "name": "comment.block.cpp" - }, - "13": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "14": { "patterns": [ { "include": "#attributes_context" @@ -18702,16 +18611,179 @@ } ] }, + "9": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "10": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "11": { + "name": "comment.block.cpp" + }, + "12": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "13": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "14": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, "15": { - "name": "entity.name.type.$3.cpp" + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "16": { - "name": "storage.type.modifier.final.cpp" + "name": "comment.block.cpp" }, "17": { - "name": "punctuation.separator.colon.inheritance.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "18": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "19": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "20": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "21": { + "name": "comment.block.cpp" + }, + "22": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "23": { + "name": "entity.name.type.$3.cpp" + }, + "24": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "25": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "26": { + "name": "comment.block.cpp" + }, + "27": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "28": { + "name": "storage.type.modifier.final.cpp" + }, + "29": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "30": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "31": { + "name": "comment.block.cpp" + }, + "32": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "33": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "34": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "35": { + "name": "comment.block.cpp" + }, + "36": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "37": { + "name": "punctuation.separator.colon.inheritance.cpp" + }, + "38": { "patterns": [ { "include": "#inheritance_context" @@ -18928,7 +19000,7 @@ "patterns": [ { "name": "meta.block.struct.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))|((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\))))|(?={))(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(final)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(:)((?>[^{]*)))?))", "beginCaptures": { "1": { "name": "meta.head.struct.cpp" @@ -18939,67 +19011,29 @@ "4": { "patterns": [ { - "include": "#attributes_context" - }, - { - "include": "#number_literal" + "include": "#inline_comment" } ] }, "5": { - "patterns": [ - { - "include": "#inline_comment" - } - ] + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "6": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + "name": "comment.block.cpp" }, "7": { - "name": "comment.block.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "8": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "9": { - "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" - }, - "10": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "11": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "12": { - "name": "comment.block.cpp" - }, - "13": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "14": { "patterns": [ { "include": "#attributes_context" @@ -19009,16 +19043,179 @@ } ] }, + "9": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "10": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "11": { + "name": "comment.block.cpp" + }, + "12": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "13": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "14": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, "15": { - "name": "entity.name.type.$3.cpp" + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "16": { - "name": "storage.type.modifier.final.cpp" + "name": "comment.block.cpp" }, "17": { - "name": "punctuation.separator.colon.inheritance.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "18": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "19": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "20": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "21": { + "name": "comment.block.cpp" + }, + "22": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "23": { + "name": "entity.name.type.$3.cpp" + }, + "24": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "25": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "26": { + "name": "comment.block.cpp" + }, + "27": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "28": { + "name": "storage.type.modifier.final.cpp" + }, + "29": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "30": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "31": { + "name": "comment.block.cpp" + }, + "32": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "33": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "34": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "35": { + "name": "comment.block.cpp" + }, + "36": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "37": { + "name": "punctuation.separator.colon.inheritance.cpp" + }, + "38": { "patterns": [ { "include": "#inheritance_context" @@ -19235,7 +19432,7 @@ "patterns": [ { "name": "meta.block.union.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))|((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\))))|(?={))(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(final)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(:)((?>[^{]*)))?))", "beginCaptures": { "1": { "name": "meta.head.union.cpp" @@ -19246,67 +19443,29 @@ "4": { "patterns": [ { - "include": "#attributes_context" - }, - { - "include": "#number_literal" + "include": "#inline_comment" } ] }, "5": { - "patterns": [ - { - "include": "#inline_comment" - } - ] + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "6": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + "name": "comment.block.cpp" }, "7": { - "name": "comment.block.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "8": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "9": { - "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" - }, - "10": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "11": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "12": { - "name": "comment.block.cpp" - }, - "13": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "14": { "patterns": [ { "include": "#attributes_context" @@ -19316,16 +19475,179 @@ } ] }, + "9": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "10": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "11": { + "name": "comment.block.cpp" + }, + "12": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "13": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "14": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, "15": { - "name": "entity.name.type.$3.cpp" + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "16": { - "name": "storage.type.modifier.final.cpp" + "name": "comment.block.cpp" }, "17": { - "name": "punctuation.separator.colon.inheritance.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "18": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "19": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "20": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "21": { + "name": "comment.block.cpp" + }, + "22": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "23": { + "name": "entity.name.type.$3.cpp" + }, + "24": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "25": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "26": { + "name": "comment.block.cpp" + }, + "27": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "28": { + "name": "storage.type.modifier.final.cpp" + }, + "29": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "30": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "31": { + "name": "comment.block.cpp" + }, + "32": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "33": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "34": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "35": { + "name": "comment.block.cpp" + }, + "36": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "37": { + "name": "punctuation.separator.colon.inheritance.cpp" + }, + "38": { "patterns": [ { "include": "#inheritance_context" @@ -19531,372 +19853,9 @@ } ] }, - "macro_safe_typedef_function_pointer": { - "begin": "((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()(\\*)\\s*((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)\\s*(?:(\\[)(\\w*)(\\])\\s*)*(\\))\\s*(\\()", - "beginCaptures": { - "1": { - "name": "meta.qualified_type.cpp", - "patterns": [ - { - "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))){2,}\\&", - "captures": { - "1": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "2": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "3": { - "name": "comment.block.cpp" - }, - "4": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - } - }, - "name": "invalid.illegal.reference-type.cpp" - }, - { - "match": "\\&", - "name": "storage.modifier.reference.cpp" - } - ] - }, - "29": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "30": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "31": { - "name": "comment.block.cpp" - }, - "32": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "33": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "34": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "35": { - "name": "comment.block.cpp" - }, - "36": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "37": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "38": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "39": { - "name": "comment.block.cpp" - }, - "40": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "41": { - "name": "punctuation.section.parens.begin.bracket.round.function.pointer.cpp" - }, - "42": { - "name": "punctuation.definition.function.pointer.dereference.cpp" - }, - "43": { - "name": "entity.name.type.alias.cpp entity.name.type.pointer.function.cpp" - }, - "44": { - "name": "punctuation.definition.begin.bracket.square.cpp" - }, - "45": { - "patterns": [ - { - "include": "#evaluation_context" - } - ] - }, - "46": { - "name": "punctuation.definition.end.bracket.square.cpp" - }, - "47": { - "name": "punctuation.section.parens.end.bracket.round.function.pointer.cpp" - }, - "48": { - "name": "punctuation.section.parameters.begin.bracket.round.function.pointer.cpp" - } - }, - "end": "(\\))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=[{=,);]|\\n)(?!\\()", - "endCaptures": { - "1": { - "name": "punctuation.section.parameters.end.bracket.round.function.pointer.cpp" - }, - "2": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "3": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "4": { - "name": "comment.block.cpp" - }, - "5": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - } - }, - "patterns": [ - { - "include": "#function_parameter_context" - } - ] - } - ] - }, "macro_safe_class_block": { "name": "meta.block.class.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))|((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\))))|(?={))(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(final)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(:)((?>[^{]*)))?))", "beginCaptures": { "1": { "name": "meta.head.class.cpp" @@ -19907,67 +19866,29 @@ "4": { "patterns": [ { - "include": "#attributes_context" - }, - { - "include": "#number_literal" + "include": "#inline_comment" } ] }, "5": { - "patterns": [ - { - "include": "#inline_comment" - } - ] + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "6": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + "name": "comment.block.cpp" }, "7": { - "name": "comment.block.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "8": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "9": { - "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" - }, - "10": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "11": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "12": { - "name": "comment.block.cpp" - }, - "13": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "14": { "patterns": [ { "include": "#attributes_context" @@ -19977,16 +19898,179 @@ } ] }, + "9": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "10": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "11": { + "name": "comment.block.cpp" + }, + "12": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "13": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "14": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, "15": { - "name": "entity.name.type.$3.cpp" + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "16": { - "name": "storage.type.modifier.final.cpp" + "name": "comment.block.cpp" }, "17": { - "name": "punctuation.separator.colon.inheritance.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "18": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "19": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "20": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "21": { + "name": "comment.block.cpp" + }, + "22": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "23": { + "name": "entity.name.type.$3.cpp" + }, + "24": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "25": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "26": { + "name": "comment.block.cpp" + }, + "27": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "28": { + "name": "storage.type.modifier.final.cpp" + }, + "29": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "30": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "31": { + "name": "comment.block.cpp" + }, + "32": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "33": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "34": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "35": { + "name": "comment.block.cpp" + }, + "36": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "37": { + "name": "punctuation.separator.colon.inheritance.cpp" + }, + "38": { "patterns": [ { "include": "#inheritance_context" @@ -20066,7 +20150,7 @@ }, "macro_safe_struct_block": { "name": "meta.block.struct.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))|((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\))))|(?={))(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(final)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(:)((?>[^{]*)))?))", "beginCaptures": { "1": { "name": "meta.head.struct.cpp" @@ -20077,67 +20161,29 @@ "4": { "patterns": [ { - "include": "#attributes_context" - }, - { - "include": "#number_literal" + "include": "#inline_comment" } ] }, "5": { - "patterns": [ - { - "include": "#inline_comment" - } - ] + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "6": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + "name": "comment.block.cpp" }, "7": { - "name": "comment.block.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "8": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "9": { - "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" - }, - "10": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "11": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "12": { - "name": "comment.block.cpp" - }, - "13": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "14": { "patterns": [ { "include": "#attributes_context" @@ -20147,16 +20193,179 @@ } ] }, + "9": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "10": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "11": { + "name": "comment.block.cpp" + }, + "12": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "13": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "14": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, "15": { - "name": "entity.name.type.$3.cpp" + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "16": { - "name": "storage.type.modifier.final.cpp" + "name": "comment.block.cpp" }, "17": { - "name": "punctuation.separator.colon.inheritance.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "18": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "19": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "20": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "21": { + "name": "comment.block.cpp" + }, + "22": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "23": { + "name": "entity.name.type.$3.cpp" + }, + "24": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "25": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "26": { + "name": "comment.block.cpp" + }, + "27": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "28": { + "name": "storage.type.modifier.final.cpp" + }, + "29": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "30": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "31": { + "name": "comment.block.cpp" + }, + "32": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "33": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "34": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "35": { + "name": "comment.block.cpp" + }, + "36": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "37": { + "name": "punctuation.separator.colon.inheritance.cpp" + }, + "38": { "patterns": [ { "include": "#inheritance_context" @@ -20236,7 +20445,7 @@ }, "macro_safe_union_block": { "name": "meta.block.union.cpp", - "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?\\s*((?:(?\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:short|signed|unsigned|long)|(?:class|struct|union|enum))(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:(?:(?:::)?(?:(?:(?-mix:(?!\\b(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|class|struct|union|enum|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?::)*\\s*+)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?:::))?(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|NULL|true|false|nullptr|const|static|volatile|register|restrict|extern|inline|constexpr|mutable|friend|explicit|virtual|final|override|volatile|const|noexcept|constexpr|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|concept|requires|export|thread_local|atomic_cancel|atomic_commit|atomic_noexcept|co_await|co_return|co_yield|import|module|reflexpr|synchronized|audit|axiom|transaction_safe|transaction_safe_dynamic)\\b)(?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?:(?:(?(?:(?>[^<>]*)?)+)>)\\s*)?(?![\\w<:.])))+)*))?))", + "begin": "((((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))|((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\))))|(?={))(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(DLLEXPORT)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(final)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(:)((?>[^{]*)))?))", "beginCaptures": { "1": { "name": "meta.head.union.cpp" @@ -20247,67 +20456,29 @@ "4": { "patterns": [ { - "include": "#attributes_context" - }, - { - "include": "#number_literal" + "include": "#inline_comment" } ] }, "5": { - "patterns": [ - { - "include": "#inline_comment" - } - ] + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "6": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + "name": "comment.block.cpp" }, "7": { - "name": "comment.block.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "8": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "9": { - "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" - }, - "10": { - "patterns": [ - { - "include": "#inline_comment" - } - ] - }, - "11": { - "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" - }, - "12": { - "name": "comment.block.cpp" - }, - "13": { - "patterns": [ - { - "match": "\\*\\/", - "name": "comment.block.cpp punctuation.definition.comment.end.cpp" - }, - { - "match": "\\*", - "name": "comment.block.cpp" - } - ] - }, - "14": { "patterns": [ { "include": "#attributes_context" @@ -20317,16 +20488,179 @@ } ] }, + "9": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "10": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "11": { + "name": "comment.block.cpp" + }, + "12": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "13": { + "name": "entity.name.other.preprocessor.macro.predefined.DLLEXPORT.cpp" + }, + "14": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, "15": { - "name": "entity.name.type.$3.cpp" + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" }, "16": { - "name": "storage.type.modifier.final.cpp" + "name": "comment.block.cpp" }, "17": { - "name": "punctuation.separator.colon.inheritance.cpp" + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] }, "18": { + "patterns": [ + { + "include": "#attributes_context" + }, + { + "include": "#number_literal" + } + ] + }, + "19": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "20": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "21": { + "name": "comment.block.cpp" + }, + "22": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "23": { + "name": "entity.name.type.$3.cpp" + }, + "24": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "25": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "26": { + "name": "comment.block.cpp" + }, + "27": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "28": { + "name": "storage.type.modifier.final.cpp" + }, + "29": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "30": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "31": { + "name": "comment.block.cpp" + }, + "32": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "33": { + "patterns": [ + { + "include": "#inline_comment" + } + ] + }, + "34": { + "name": "comment.block.cpp punctuation.definition.comment.begin.cpp" + }, + "35": { + "name": "comment.block.cpp" + }, + "36": { + "patterns": [ + { + "match": "\\*\\/", + "name": "comment.block.cpp punctuation.definition.comment.end.cpp" + }, + { + "match": "\\*", + "name": "comment.block.cpp" + } + ] + }, + "37": { + "name": "punctuation.separator.colon.inheritance.cpp" + }, + "38": { "patterns": [ { "include": "#inheritance_context" @@ -20510,6 +20844,9 @@ { "include": "#enumerator_list" }, + { + "include": "#comments" + }, { "include": "#comma" }, @@ -21172,9 +21509,6 @@ { "include": "#macro_safe_typedef_union" }, - { - "include": "#macro_safe_typedef_function_pointer" - }, { "include": "#typedef_keyword" }, diff --git a/extensions/cpp/test/colorize-results/test-23630_cpp.json b/extensions/cpp/test/colorize-results/test-23630_cpp.json index a58961ae945..6dfdc10983e 100644 --- a/extensions/cpp/test/colorize-results/test-23630_cpp.json +++ b/extensions/cpp/test/colorize-results/test-23630_cpp.json @@ -1,7 +1,7 @@ [ { "c": "#", - "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", + "t": "source.cpp keyword.control.directive.conditional.ifndef.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -12,7 +12,7 @@ }, { "c": "ifndef", - "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", + "t": "source.cpp keyword.control.directive.conditional.ifndef.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -23,23 +23,23 @@ }, { "c": " ", - "t": "source.cpp meta.preprocessor.cpp", + "t": "source.cpp meta.conditional.preprocessor.cpp", "r": { - "dark_plus": "meta.preprocessor: #569CD6", - "light_plus": "meta.preprocessor: #0000FF", - "dark_vs": "meta.preprocessor: #569CD6", - "light_vs": "meta.preprocessor: #0000FF", - "hc_black": "meta.preprocessor: #569CD6" + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" } }, { "c": "_UCRT", - "t": "source.cpp meta.preprocessor.cpp entity.name.function.preprocessor.cpp", + "t": "source.cpp meta.conditional.preprocessor.cpp entity.name.function.preprocessor.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", - "dark_vs": "meta.preprocessor: #569CD6", - "light_vs": "meta.preprocessor: #0000FF", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", "hc_black": "entity.name.function: #DCDCAA" } }, @@ -100,7 +100,7 @@ }, { "c": "#", - "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", + "t": "source.cpp keyword.control.directive.endif.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -111,7 +111,7 @@ }, { "c": "endif", - "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", + "t": "source.cpp keyword.control.directive.endif.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", diff --git a/extensions/cpp/test/colorize-results/test-23850_cpp.json b/extensions/cpp/test/colorize-results/test-23850_cpp.json index 924bbc78243..931989636df 100644 --- a/extensions/cpp/test/colorize-results/test-23850_cpp.json +++ b/extensions/cpp/test/colorize-results/test-23850_cpp.json @@ -1,7 +1,7 @@ [ { "c": "#", - "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", + "t": "source.cpp keyword.control.directive.conditional.ifndef.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -12,7 +12,7 @@ }, { "c": "ifndef", - "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", + "t": "source.cpp keyword.control.directive.conditional.ifndef.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -23,23 +23,23 @@ }, { "c": " ", - "t": "source.cpp meta.preprocessor.cpp", + "t": "source.cpp meta.conditional.preprocessor.cpp", "r": { - "dark_plus": "meta.preprocessor: #569CD6", - "light_plus": "meta.preprocessor: #0000FF", - "dark_vs": "meta.preprocessor: #569CD6", - "light_vs": "meta.preprocessor: #0000FF", - "hc_black": "meta.preprocessor: #569CD6" + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" } }, { "c": "_UCRT", - "t": "source.cpp meta.preprocessor.cpp entity.name.function.preprocessor.cpp", + "t": "source.cpp meta.conditional.preprocessor.cpp entity.name.function.preprocessor.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", - "dark_vs": "meta.preprocessor: #569CD6", - "light_vs": "meta.preprocessor: #0000FF", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", "hc_black": "entity.name.function: #DCDCAA" } }, @@ -89,7 +89,7 @@ }, { "c": "#", - "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", + "t": "source.cpp keyword.control.directive.endif.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -100,7 +100,7 @@ }, { "c": "endif", - "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", + "t": "source.cpp keyword.control.directive.endif.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", diff --git a/extensions/cpp/test/colorize-results/test_cc.json b/extensions/cpp/test/colorize-results/test_cc.json index 4567285df23..23f716798db 100644 --- a/extensions/cpp/test/colorize-results/test_cc.json +++ b/extensions/cpp/test/colorize-results/test_cc.json @@ -1,7 +1,7 @@ [ { "c": "#", - "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", + "t": "source.cpp keyword.control.directive.conditional.if.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -12,7 +12,7 @@ }, { "c": "if", - "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", + "t": "source.cpp keyword.control.directive.conditional.if.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -23,23 +23,23 @@ }, { "c": " ", - "t": "source.cpp meta.preprocessor.cpp", + "t": "source.cpp meta.conditional.preprocessor.cpp", "r": { - "dark_plus": "meta.preprocessor: #569CD6", - "light_plus": "meta.preprocessor: #0000FF", - "dark_vs": "meta.preprocessor: #569CD6", - "light_vs": "meta.preprocessor: #0000FF", - "hc_black": "meta.preprocessor: #569CD6" + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" } }, { "c": "B4G_DEBUG_CHECK", - "t": "source.cpp meta.preprocessor.cpp entity.name.function.preprocessor.cpp", + "t": "source.cpp meta.conditional.preprocessor.cpp entity.name.function.preprocessor.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", - "light_plus": "entity.name.function: #795E26", - "dark_vs": "meta.preprocessor: #569CD6", - "light_vs": "meta.preprocessor: #0000FF", + "light_plus": "entity.name.function: #795codeE26", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", "hc_black": "entity.name.function: #DCDCAA" } }, @@ -650,7 +650,7 @@ }, { "c": "#", - "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", + "t": "source.cpp keyword.control.directive.endif.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -661,7 +661,7 @@ }, { "c": "endif", - "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", + "t": "source.cpp keyword.control.directive.endif.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -1979,4 +1979,4 @@ "hc_black": "default: #FFFFFF" } } -] \ No newline at end of file +] diff --git a/extensions/cpp/test/colorize-results/test_cpp.json b/extensions/cpp/test/colorize-results/test_cpp.json index 025f668b4c9..f84d916afa3 100644 --- a/extensions/cpp/test/colorize-results/test_cpp.json +++ b/extensions/cpp/test/colorize-results/test_cpp.json @@ -276,7 +276,7 @@ }, { "c": " ", - "t": "source.cpp meta.block.class.cpp meta.head.class.cpp", + "t": "source.cpp meta.block.class.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", From 58a32d0b44841a6365cf14a9b07d66755f5c5df6 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 12 Aug 2019 15:04:02 +0200 Subject: [PATCH 476/861] remove IConsolePatchFn function --- .../api/node/extHostExtensionService.ts | 10 ++++++++++ .../extensions/common/extensionHostMain.ts | 4 ---- .../extensions/node/extensionHostProcessSetup.ts | 16 +--------------- .../extensions/worker/extensionHostWorker.ts | 6 ------ 4 files changed, 11 insertions(+), 25 deletions(-) diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 99c3a6629d4..8f1f5d6ee75 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -43,6 +43,16 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { // Do this when extension service exists, but extensions are not being activated yet. await connectProxyResolver(this._extHostWorkspace, configProvider, this, this._logService, this._mainThreadTelemetryProxy); + // Use IPC messages to forward console-calls, note that the console is + // already patched to use`process.send()` + const nativeProcessSend = process.send!; + const mainThreadConsole = this._extHostContext.getProxy(MainContext.MainThreadConsole); + process.send = (...args: any[]) => { + if (args.length === 0 || !args[0] || args[0].type !== '__$console') { + return nativeProcessSend.apply(process, args); + } + mainThreadConsole.$logExtensionHostMessage(args[0]); + }; } protected _loadCommonJSModule(modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { diff --git a/src/vs/workbench/services/extensions/common/extensionHostMain.ts b/src/vs/workbench/services/extensions/common/extensionHostMain.ts index 7f6cd8d0278..625c60db92b 100644 --- a/src/vs/workbench/services/extensions/common/extensionHostMain.ts +++ b/src/vs/workbench/services/extensions/common/extensionHostMain.ts @@ -45,7 +45,6 @@ export class ExtensionHostMain { protocol: IMessagePassingProtocol, initData: IInitData, hostUtils: IHostUtils, - consolePatchFn: IConsolePatchFn, uriTransformer: IURITransformer | null ) { this._isTerminating = false; @@ -55,9 +54,6 @@ export class ExtensionHostMain { // ensure URIs are transformed and revived initData = ExtensionHostMain._transform(initData, rpcProtocol); - // allow to patch console - consolePatchFn(rpcProtocol.getProxy(MainContext.MainThreadConsole)); - // services // bootstrap services diff --git a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts index 0a067fb0a9f..1e887093123 100644 --- a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts +++ b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts @@ -12,7 +12,7 @@ import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; import { PersistentProtocol, ProtocolConstants, createBufferedEvent } from 'vs/base/parts/ipc/common/ipc.net'; import { NodeSocket, WebSocketNodeSocket } from 'vs/base/parts/ipc/node/ipc.net'; import product from 'vs/platform/product/node/product'; -import { IInitData, MainThreadConsoleShape } from 'vs/workbench/api/common/extHost.protocol'; +import { IInitData } from 'vs/workbench/api/common/extHost.protocol'; import { MessageType, createMessageOfType, isMessageOfType, IExtHostSocketMessage, IExtHostReadyMessage } from 'vs/workbench/services/extensions/common/extensionHostProtocol'; import { ExtensionHostMain, IExitFn } from 'vs/workbench/services/extensions/common/extensionHostMain'; import { VSBuffer } from 'vs/base/common/buffer'; @@ -68,19 +68,6 @@ function patchProcess(allowExit: boolean) { }; } -// use IPC messages to forward console-calls -function patchPatchedConsole(mainThreadConsole: MainThreadConsoleShape): void { - // The console is already patched to use `process.send()` - const nativeProcessSend = process.send!; - process.send = (...args: any[]) => { - if (args.length === 0 || !args[0] || args[0].type !== '__$console') { - return nativeProcessSend.apply(process, args); - } - - mainThreadConsole.$logExtensionHostMessage(args[0]); - }; -} - interface IRendererConnection { protocol: IMessagePassingProtocol; initData: IInitData; @@ -331,7 +318,6 @@ export async function startExtensionHostProcess(): Promise { renderer.protocol, initData, hostUtils, - patchPatchedConsole, uriTransformer ); diff --git a/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts b/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts index 49bba4083da..3ed289be397 100644 --- a/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts +++ b/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts @@ -102,17 +102,11 @@ export function create(postMessage: (message: any, transfer?: Transferable[]) => const res = new ExtensionWorker(postMessage); connectToRenderer(res.protocol).then(data => { - // console.log('INIT_DATA', data.initData); - - // data.protocol.onMessage(msg => { - // // console.log('SOME MSG', msg.toString()); - // }); const extHostMain = new ExtensionHostMain( data.protocol, data.initData, hostUtil, - () => { }, null, ); From aac154c718c53d260c8390e7a554dacadd48e995 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 12 Aug 2019 15:08:53 +0200 Subject: [PATCH 477/861] :lipstick: --- .../services/extensions/common/extensionHostMain.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/services/extensions/common/extensionHostMain.ts b/src/vs/workbench/services/extensions/common/extensionHostMain.ts index 625c60db92b..16356a4a96c 100644 --- a/src/vs/workbench/services/extensions/common/extensionHostMain.ts +++ b/src/vs/workbench/services/extensions/common/extensionHostMain.ts @@ -54,8 +54,6 @@ export class ExtensionHostMain { // ensure URIs are transformed and revived initData = ExtensionHostMain._transform(initData, rpcProtocol); - // services - // bootstrap services const services = new ServiceCollection(...getSingletonServiceDescriptors()); services.set(IExtHostInitDataService, { _serviceBrand: undefined, ...initData }); @@ -65,13 +63,18 @@ export class ExtensionHostMain { const instaService: IInstantiationService = new InstantiationService(services, true); + // todo@joh + // ugly self - inject const logService = instaService.invokeFunction(accessor => accessor.get(ILogService)); this._disposables.add(logService); logService.info('extension host started'); logService.trace('initData', initData); - // todo@joh -> not soo nice... + // todo@joh + // ugly self - inject + // must call initialize *after* creating the extension service + // because `initialize` itself creates instances that depend on it this._extensionService = instaService.invokeFunction(accessor => accessor.get(IExtHostExtensionService)); this._extensionService.initialize(); From 3611aaf54fb6bdc1515f010ee932aafc02335221 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 12 Aug 2019 15:21:08 +0200 Subject: [PATCH 478/861] add autoStart property --- .../workbench/services/extensions/browser/extensionService.ts | 2 +- .../extensions/browser/webWorkerExtensionHostStarter.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/services/extensions/browser/extensionService.ts b/src/vs/workbench/services/extensions/browser/extensionService.ts index cd80cb266fa..a32024e35ac 100644 --- a/src/vs/workbench/services/extensions/browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/browser/extensionService.ts @@ -65,7 +65,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten const remoteAgentConnection = this._remoteAgentService.getConnection()!; - const webHostProcessWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, Promise.resolve([]), URI.parse('empty:value')); //todo@joh + const webHostProcessWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, true, Promise.resolve([]), URI.parse('empty:value')); //todo@joh const webHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, webHostProcessWorker, remoteAgentConnection.remoteAuthority, initialActivationEvents); result.push(webHostProcessManager); diff --git a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts index a88545f4e31..1f04364fa5d 100644 --- a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts +++ b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts @@ -31,7 +31,7 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { readonly onExit: Event<[number, string | null]> = this._onDidExit.event; constructor( - // private readonly _autoStart: boolean, + private readonly _autoStart: boolean, private readonly _extensions: Promise, private readonly _extensionHostLogsLocation: URI, @ITelemetryService private readonly _telemetryService: ITelemetryService, @@ -139,7 +139,7 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { telemetryInfo, logLevel: this._logService.getLevel(), logsLocation: this._extensionHostLogsLocation, - autoStart: true, + autoStart: this._autoStart, remote: { authority: this._environmentService.configuration.remoteAuthority, isRemote: false From bd179feeb71a6195b6eab304452dfe7ac534e868 Mon Sep 17 00:00:00 2001 From: Anton Kosyakov Date: Mon, 12 Aug 2019 13:36:45 +0000 Subject: [PATCH 479/861] [monaco] expose missing language providers fix microsoft/monaco-editor#1546 - expose registerDeclarationProvider fix microsoft/monaco-editor#1547 - expose registerSelectionRangeProvider Signed-off-by: Anton Kosyakov --- .../standalone/browser/standaloneLanguages.ts | 16 ++++++++++++++++ src/vs/monaco.d.ts | 10 ++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/vs/editor/standalone/browser/standaloneLanguages.ts b/src/vs/editor/standalone/browser/standaloneLanguages.ts index cfe1ec119f6..e8e9dffbe84 100644 --- a/src/vs/editor/standalone/browser/standaloneLanguages.ts +++ b/src/vs/editor/standalone/browser/standaloneLanguages.ts @@ -482,6 +482,20 @@ export function registerFoldingRangeProvider(languageId: string, provider: modes return modes.FoldingRangeProviderRegistry.register(languageId, provider); } +/** + * Register a declaration provider + */ +export function registerDeclarationProvider(languageId: string, provider: modes.DeclarationProvider): IDisposable { + return modes.DeclarationProviderRegistry.register(languageId, provider); +} + +/** + * Register a selection range provider + */ +export function registerSelectionRangeProvider(languageId: string, provider: modes.SelectionRangeProvider): IDisposable { + return modes.SelectionRangeRegistry.register(languageId, provider); +} + /** * Contains additional diagnostic information about the context in which * a [code action](#CodeActionProvider.provideCodeActions) is run. @@ -542,6 +556,8 @@ export function createMonacoLanguagesAPI(): typeof monaco.languages { registerLinkProvider: registerLinkProvider, registerColorProvider: registerColorProvider, registerFoldingRangeProvider: registerFoldingRangeProvider, + registerDeclarationProvider: registerDeclarationProvider, + registerSelectionRangeProvider: registerSelectionRangeProvider, // enums DocumentHighlightKind: standaloneEnums.DocumentHighlightKind, diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 5cd4257b8a7..a797b72a6f2 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -4455,6 +4455,16 @@ declare namespace monaco.languages { */ export function registerFoldingRangeProvider(languageId: string, provider: FoldingRangeProvider): IDisposable; + /** + * Register a declaration provider + */ + export function registerDeclarationProvider(languageId: string, provider: DeclarationProvider): IDisposable; + + /** + * Register a selection range provider + */ + export function registerSelectionRangeProvider(languageId: string, provider: SelectionRangeProvider): IDisposable; + /** * Contains additional diagnostic information about the context in which * a [code action](#CodeActionProvider.provideCodeActions) is run. From f6ef80200c3256e9f71fc45de7a98d56b438675f Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 12 Aug 2019 15:46:03 +0200 Subject: [PATCH 480/861] fix more strict init errors --- .../contrib/gotoError/gotoErrorWidget.ts | 2 +- .../contrib/referenceSearch/peekViewWidget.ts | 54 +++++++++++-------- src/vs/platform/progress/common/progress.ts | 4 +- src/vs/vscode.d.ts | 2 +- .../common/extHostDocumentSaveParticipant.ts | 2 +- .../workbench/api/common/extHostTextEditor.ts | 10 ++-- .../api/common/extHostTypeConverters.ts | 2 +- src/vs/workbench/api/common/extHostTypes.ts | 34 ++++++------ .../browser/callHierarchyPeek.ts | 2 +- .../contrib/scm/browser/dirtydiffDecorator.ts | 6 +-- 10 files changed, 63 insertions(+), 55 deletions(-) diff --git a/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts b/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts index 89f2f75d243..9da6b13042f 100644 --- a/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts +++ b/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts @@ -228,7 +228,7 @@ export class MarkerNavigationWidget extends PeekViewWidget { protected _fillHead(container: HTMLElement): void { super._fillHead(container); - this._actionbarWidget.push(this.actions, { label: false, icon: true }); + this._actionbarWidget!.push(this.actions, { label: false, icon: true }); } protected _fillTitleIcon(container: HTMLElement): void { diff --git a/src/vs/editor/contrib/referenceSearch/peekViewWidget.ts b/src/vs/editor/contrib/referenceSearch/peekViewWidget.ts index c40368e0311..4dd63cadd03 100644 --- a/src/vs/editor/contrib/referenceSearch/peekViewWidget.ts +++ b/src/vs/editor/contrib/referenceSearch/peekViewWidget.ts @@ -84,12 +84,12 @@ export abstract class PeekViewWidget extends ZoneWidget { private _onDidClose = new Emitter(); - protected _headElement: HTMLDivElement; - protected _primaryHeading: HTMLElement; - protected _secondaryHeading: HTMLElement; - protected _metaHeading: HTMLElement; - protected _actionbarWidget: ActionBar; - protected _bodyElement: HTMLDivElement; + protected _headElement?: HTMLDivElement; + protected _primaryHeading?: HTMLElement; + protected _secondaryHeading?: HTMLElement; + protected _metaHeading?: HTMLElement; + protected _actionbarWidget?: ActionBar; + protected _bodyElement?: HTMLDivElement; constructor(editor: ICodeEditor, options: IPeekViewOptions = {}) { super(editor, options); @@ -139,8 +139,8 @@ export abstract class PeekViewWidget extends ZoneWidget { protected _fillContainer(container: HTMLElement): void { this.setCssClass('peekview-widget'); - this._headElement = dom.$('.head'); - this._bodyElement = dom.$('.body'); + this._headElement = dom.$('.head'); + this._bodyElement = dom.$('.body'); this._fillHead(this._headElement); this._fillBody(this._bodyElement); @@ -151,7 +151,7 @@ export abstract class PeekViewWidget extends ZoneWidget { protected _fillHead(container: HTMLElement): void { const titleElement = dom.$('.peekview-title'); - dom.append(this._headElement, titleElement); + dom.append(this._headElement!, titleElement); dom.addStandardDisposableListener(titleElement, 'click', event => this._onTitleClick(event)); this._fillTitleIcon(titleElement); @@ -161,7 +161,7 @@ export abstract class PeekViewWidget extends ZoneWidget { dom.append(titleElement, this._primaryHeading, this._secondaryHeading, this._metaHeading); const actionsContainer = dom.$('.peekview-actions'); - dom.append(this._headElement, actionsContainer); + dom.append(this._headElement!, actionsContainer); const actionBarOptions = this._getActionBarOptions(); this._actionbarWidget = new ActionBar(actionsContainer, actionBarOptions); @@ -185,20 +185,24 @@ export abstract class PeekViewWidget extends ZoneWidget { } public setTitle(primaryHeading: string, secondaryHeading?: string): void { - this._primaryHeading.innerHTML = strings.escape(primaryHeading); - this._primaryHeading.setAttribute('aria-label', primaryHeading); - if (secondaryHeading) { - this._secondaryHeading.innerHTML = strings.escape(secondaryHeading); - } else { - dom.clearNode(this._secondaryHeading); + if (this._primaryHeading && this._secondaryHeading) { + this._primaryHeading.innerHTML = strings.escape(primaryHeading); + this._primaryHeading.setAttribute('aria-label', primaryHeading); + if (secondaryHeading) { + this._secondaryHeading.innerHTML = strings.escape(secondaryHeading); + } else { + dom.clearNode(this._secondaryHeading); + } } } public setMetaTitle(value: string): void { - if (value) { - this._metaHeading.innerHTML = strings.escape(value); - } else { - dom.clearNode(this._metaHeading); + if (this._metaHeading) { + if (value) { + this._metaHeading.innerHTML = strings.escape(value); + } else { + dom.clearNode(this._metaHeading); + } } } @@ -220,11 +224,15 @@ export abstract class PeekViewWidget extends ZoneWidget { } protected _doLayoutHead(heightInPixel: number, widthInPixel: number): void { - this._headElement.style.height = `${heightInPixel}px`; - this._headElement.style.lineHeight = this._headElement.style.height; + if (this._headElement) { + this._headElement.style.height = `${heightInPixel}px`; + this._headElement.style.lineHeight = this._headElement.style.height; + } } protected _doLayoutBody(heightInPixel: number, widthInPixel: number): void { - this._bodyElement.style.height = `${heightInPixel}px`; + if (this._bodyElement) { + this._bodyElement.style.height = `${heightInPixel}px`; + } } } diff --git a/src/vs/platform/progress/common/progress.ts b/src/vs/platform/progress/common/progress.ts index 117e1af70de..4308c72ce89 100644 --- a/src/vs/platform/progress/common/progress.ts +++ b/src/vs/platform/progress/common/progress.ts @@ -90,13 +90,13 @@ export interface IProgress { export class Progress implements IProgress { private _callback: (data: T) => void; - private _value: T; + private _value?: T; constructor(callback: (data: T) => void) { this._callback = callback; } - get value() { + get value(): T | undefined { return this._value; } diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 25271cbcf99..38ff2ab34d1 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -2786,7 +2786,7 @@ declare module 'vscode' { * *Note* that the eol-sequence will be applied to the * whole document. */ - newEol: EndOfLine; + newEol?: EndOfLine; /** * Create a new TextEdit. diff --git a/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts b/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts index ae129051fe8..f55a89b3f30 100644 --- a/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts +++ b/src/vs/workbench/api/common/extHostDocumentSaveParticipant.ts @@ -153,7 +153,7 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic resourceEdit.edits.push({ range: range && Range.from(range), text: newText, - eol: EndOfLine.from(newEol) + eol: newEol && EndOfLine.from(newEol) }); } } diff --git a/src/vs/workbench/api/common/extHostTextEditor.ts b/src/vs/workbench/api/common/extHostTextEditor.ts index fa10d30014b..1e5404bbf2b 100644 --- a/src/vs/workbench/api/common/extHostTextEditor.ts +++ b/src/vs/workbench/api/common/extHostTextEditor.ts @@ -151,11 +151,11 @@ export class ExtHostTextEditorOptions implements vscode.TextEditorOptions { private _proxy: MainThreadTextEditorsShape; private _id: string; - private _tabSize: number; - private _indentSize: number; - private _insertSpaces: boolean; - private _cursorStyle: TextEditorCursorStyle; - private _lineNumbers: TextEditorLineNumbersStyle; + private _tabSize!: number; + private _indentSize!: number; + private _insertSpaces!: boolean; + private _cursorStyle!: TextEditorCursorStyle; + private _lineNumbers!: TextEditorLineNumbersStyle; constructor(proxy: MainThreadTextEditorsShape, id: string, source: IResolvedTextEditorConfiguration) { this._proxy = proxy; diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index 5da072a265e..f7827afe487 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -442,7 +442,7 @@ export namespace TextEdit { export function from(edit: vscode.TextEdit): modes.TextEdit { return { text: edit.newText, - eol: EndOfLine.from(edit.newEol), + eol: edit.newEol && EndOfLine.from(edit.newEol), range: Range.from(edit.range) }; } diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index 9ad1d38f66e..9b0cd9c9cc8 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -514,7 +514,7 @@ export class TextEdit { protected _range: Range; protected _newText: string | null; - protected _newEol: EndOfLine; + protected _newEol?: EndOfLine; get range(): Range { return this._range; @@ -538,11 +538,11 @@ export class TextEdit { this._newText = value; } - get newEol(): EndOfLine { + get newEol(): EndOfLine | undefined { return this._newEol; } - set newEol(value: EndOfLine) { + set newEol(value: EndOfLine | undefined) { if (value && typeof value !== 'number') { throw illegalArgument('newEol'); } @@ -550,7 +550,7 @@ export class TextEdit { } constructor(range: Range, newText: string | null) { - this.range = range; + this._range = range; this._newText = newText; } @@ -798,7 +798,7 @@ export class Location { } uri: URI; - range: Range; + range!: Range; constructor(uri: URI, rangeOrPosition: Range | Position) { this.uri = uri; @@ -861,10 +861,10 @@ export class Diagnostic { range: Range; message: string; - source: string; - code: string | number; severity: DiagnosticSeverity; - relatedInformation: DiagnosticRelatedInformation[]; + source?: string; + code?: string | number; + relatedInformation?: DiagnosticRelatedInformation[]; tags?: DiagnosticTag[]; constructor(range: Range, message: string, severity: DiagnosticSeverity = DiagnosticSeverity.Error) { @@ -989,7 +989,7 @@ export class SymbolInformation { } name: string; - location: Location; + location!: Location; kind: SymbolKind; containerName: string | undefined; @@ -1253,8 +1253,8 @@ export class SignatureInformation { export class SignatureHelp { signatures: SignatureInformation[]; - activeSignature: number; - activeParameter: number; + activeSignature: number = 0; + activeParameter: number = 0; constructor() { this.signatures = []; @@ -1310,19 +1310,19 @@ export enum CompletionItemKind { export class CompletionItem implements vscode.CompletionItem { label: string; - kind: CompletionItemKind | undefined; + kind?: CompletionItemKind; detail?: string; documentation?: string | MarkdownString; sortText?: string; filterText?: string; preselect?: boolean; - insertText: string | SnippetString; + insertText?: string | SnippetString; keepWhitespace?: boolean; - range: Range; + range?: Range; commitCharacters?: string[]; - textEdit: TextEdit; - additionalTextEdits: TextEdit[]; - command: vscode.Command; + textEdit?: TextEdit; + additionalTextEdits?: TextEdit[]; + command?: vscode.Command; constructor(label: string, kind?: CompletionItemKind) { this.label = label; diff --git a/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyPeek.ts b/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyPeek.ts index 3679e656809..1166da97f9c 100644 --- a/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyPeek.ts +++ b/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyPeek.ts @@ -386,7 +386,7 @@ export class CallHierarchyTreePeekWidget extends PeekViewWidget { }; this._changeDirectionAction = new ChangeHierarchyDirectionAction(this._direction, changeDirection); this._disposables.add(this._changeDirectionAction); - this._actionbarWidget.push(this._changeDirectionAction, { icon: true, label: false }); + this._actionbarWidget!.push(this._changeDirectionAction, { icon: true, label: false }); } } diff --git a/src/vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts b/src/vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts index 97539eb481f..955579069d7 100644 --- a/src/vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts +++ b/src/vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts @@ -234,7 +234,7 @@ class DirtyDiffWidget extends PeekViewWidget { const changeTypeColor = getChangeTypeColor(this.themeService.getTheme(), changeType); this.style({ frameColor: changeTypeColor, arrowColor: changeTypeColor }); - this._actionbarWidget.context = [this.model.modified!.uri, this.model.changes, index]; + this._actionbarWidget!.context = [this.model.modified!.uri, this.model.changes, index]; this.show(position, height); this.editor.focus(); } @@ -255,11 +255,11 @@ class DirtyDiffWidget extends PeekViewWidget { this._disposables.add(previous); this._disposables.add(next); - this._actionbarWidget.push([previous, next], { label: false, icon: true }); + this._actionbarWidget!.push([previous, next], { label: false, icon: true }); const actions: IAction[] = []; this._disposables.add(createAndFillInActionBarActions(this.menu, { shouldForwardArgs: true }, actions)); - this._actionbarWidget.push(actions, { label: false, icon: true }); + this._actionbarWidget!.push(actions, { label: false, icon: true }); } protected _getActionBarOptions(): IActionBarOptions { From bdd162c53ab648601c30937951eb28d2406d2868 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 12 Aug 2019 15:57:29 +0200 Subject: [PATCH 481/861] Fix spaghetti in test file --- extensions/cpp/test/colorize-results/test_cc.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/cpp/test/colorize-results/test_cc.json b/extensions/cpp/test/colorize-results/test_cc.json index 23f716798db..c96fc642474 100644 --- a/extensions/cpp/test/colorize-results/test_cc.json +++ b/extensions/cpp/test/colorize-results/test_cc.json @@ -37,7 +37,7 @@ "t": "source.cpp meta.conditional.preprocessor.cpp entity.name.function.preprocessor.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", - "light_plus": "entity.name.function: #795codeE26", + "light_plus": "entity.name.function: #795E26", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", "hc_black": "entity.name.function: #DCDCAA" From 4163ea208d927c6a381cb30f95a03a131ed9d561 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 12 Aug 2019 16:03:37 +0200 Subject: [PATCH 482/861] fixes #78228 --- src/vs/base/browser/ui/grid/gridview.ts | 4 ++-- src/vs/base/browser/ui/splitview/splitview.ts | 21 +++++++++++-------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts index 497678cee41..1760b6f42a0 100644 --- a/src/vs/base/browser/ui/grid/gridview.ts +++ b/src/vs/base/browser/ui/grid/gridview.ts @@ -549,11 +549,11 @@ class LeafNode implements ISplitView, IDisposable { } } - setVisible(visible: boolean): void { + setVisible(visible: boolean, cachedVisibleSize?: number): void { if (visible) { this._cachedVisibleSize = undefined; } else { - this._cachedVisibleSize = this._size; + this._cachedVisibleSize = typeof cachedVisibleSize === 'number' ? cachedVisibleSize : this._size; } if (this.view.setVisible) { diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index 4baf9ff4023..179b888f95e 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -49,7 +49,7 @@ export interface IView { readonly priority?: LayoutPriority; readonly snap?: boolean; layout(size: number, orientation: Orientation): void; - setVisible?(visible: boolean): void; + setVisible?(visible: boolean, cachedVisibleSize?: number): void; } interface ISashEvent { @@ -79,7 +79,7 @@ abstract class ViewItem { return typeof this._cachedVisibleSize === 'undefined'; } - set visible(visible: boolean) { + setVisible(visible: boolean, size?: number): void { if (visible === this.visible) { return; } @@ -88,14 +88,14 @@ abstract class ViewItem { this.size = clamp(this._cachedVisibleSize!, this.viewMinimumSize, this.viewMaximumSize); this._cachedVisibleSize = undefined; } else { - this._cachedVisibleSize = this.size; + this._cachedVisibleSize = typeof size === 'number' ? size : this.size; this.size = 0; } dom.toggleClass(this.container, 'visible', visible); if (this.view.setVisible) { - this.view.setVisible(visible); + this.view.setVisible(visible, this._cachedVisibleSize); } } @@ -161,6 +161,7 @@ interface ISashItem { interface ISashDragSnapState { readonly index: number; readonly limitDelta: number; + readonly size: number; } interface ISashDragState { @@ -453,7 +454,7 @@ export class SplitView extends Disposable { } const viewItem = this.viewItems[index]; - viewItem.visible = visible; + viewItem.setVisible(visible); this.distributeEmptySpace(index); this.layoutViews(); @@ -552,7 +553,8 @@ export class SplitView extends Disposable { snapBefore = { index: snapBeforeIndex, - limitDelta: viewItem.visible ? minDelta - halfSize : minDelta + halfSize + limitDelta: viewItem.visible ? minDelta - halfSize : minDelta + halfSize, + size: viewItem.size }; } @@ -562,7 +564,8 @@ export class SplitView extends Disposable { snapAfter = { index: snapAfterIndex, - limitDelta: viewItem.visible ? maxDelta + halfSize : maxDelta - halfSize + limitDelta: viewItem.visible ? maxDelta + halfSize : maxDelta - halfSize, + size: viewItem.size }; } } @@ -740,14 +743,14 @@ export class SplitView extends Disposable { const snapView = this.viewItems[snapBefore.index]; const visible = delta >= snapBefore.limitDelta; snapped = visible !== snapView.visible; - snapView.visible = visible; + snapView.setVisible(visible, snapBefore.size); } if (!snapped && snapAfter) { const snapView = this.viewItems[snapAfter.index]; const visible = delta < snapAfter.limitDelta; snapped = visible !== snapView.visible; - snapView.visible = visible; + snapView.setVisible(visible, snapAfter.size); } if (snapped) { From 561f3ae73c315f4d5d53d1b27c53fea301f36047 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 12 Aug 2019 16:23:57 +0200 Subject: [PATCH 483/861] fixes #78338 --- src/vs/base/browser/ui/grid/gridview.ts | 28 ++++++++----------- src/vs/base/browser/ui/splitview/splitview.ts | 4 +-- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts index 1760b6f42a0..7283617d69c 100644 --- a/src/vs/base/browser/ui/grid/gridview.ts +++ b/src/vs/base/browser/ui/grid/gridview.ts @@ -439,9 +439,6 @@ class LeafNode implements ISplitView, IDisposable { private _size: number = 0; get size(): number { return this._size; } - private _cachedVisibleSize: number | undefined; - get cachedVisibleSize(): number | undefined { return this._cachedVisibleSize; } - private _orthogonalSize: number; get orthogonalSize(): number { return this._orthogonalSize; } @@ -549,13 +546,7 @@ class LeafNode implements ISplitView, IDisposable { } } - setVisible(visible: boolean, cachedVisibleSize?: number): void { - if (visible) { - this._cachedVisibleSize = undefined; - } else { - this._cachedVisibleSize = typeof cachedVisibleSize === 'number' ? cachedVisibleSize : this._size; - } - + setVisible(visible: boolean): void { if (this.view.setVisible) { this.view.setVisible(visible); } @@ -877,13 +868,14 @@ export class GridView implements IDisposable { } getViewCachedVisibleSize(location: number[]): number | undefined { - const [, node] = this.getNode(location); + const [rest, index] = tail(location); + const [, parent] = this.getNode(rest); - if (!(node instanceof LeafNode)) { - throw new Error('Invalid node'); + if (!(parent instanceof BranchNode)) { + throw new Error('Invalid location'); } - return node.cachedVisibleSize; + return parent.getChildCachedVisibleSize(index); } maximizeViewSize(location: number[]): void { @@ -942,12 +934,13 @@ export class GridView implements IDisposable { return this._getViews(node, this.orientation, { top: 0, left: 0, width: this.width, height: this.height }); } - private _getViews(node: Node, orientation: Orientation, box: Box): GridNode { + private _getViews(node: Node, orientation: Orientation, box: Box, cachedVisibleSize?: number): GridNode { if (node instanceof LeafNode) { - return { view: node.view, box, cachedVisibleSize: node.cachedVisibleSize }; + return { view: node.view, box, cachedVisibleSize }; } const children: GridNode[] = []; + let i = 0; let offset = 0; for (const child of node.children) { @@ -955,8 +948,9 @@ export class GridView implements IDisposable { const childBox: Box = orientation === Orientation.HORIZONTAL ? { top: box.top, left: box.left + offset, width: child.width, height: box.height } : { top: box.top + offset, left: box.left, width: box.width, height: child.height }; + const cachedVisibleSize = node.getChildCachedVisibleSize(i++); - children.push(this._getViews(child, childOrientation, childBox)); + children.push(this._getViews(child, childOrientation, childBox, cachedVisibleSize)); offset += orientation === Orientation.HORIZONTAL ? child.width : child.height; } diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index 179b888f95e..bdf42e5a7e1 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -49,7 +49,7 @@ export interface IView { readonly priority?: LayoutPriority; readonly snap?: boolean; layout(size: number, orientation: Orientation): void; - setVisible?(visible: boolean, cachedVisibleSize?: number): void; + setVisible?(visible: boolean): void; } interface ISashEvent { @@ -95,7 +95,7 @@ abstract class ViewItem { dom.toggleClass(this.container, 'visible', visible); if (this.view.setVisible) { - this.view.setVisible(visible, this._cachedVisibleSize); + this.view.setVisible(visible); } } From 2278f87c1c43f1738b03c62de5e86e5bace89a8d Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 12 Aug 2019 16:45:12 +0200 Subject: [PATCH 484/861] fixes #78159 --- build/lib/extensions.js | 18 ++++++++++++------ build/lib/extensions.ts | 19 ++++++++++++++----- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/build/lib/extensions.js b/build/lib/extensions.js index 73d2c7acef3..a98f3b890cf 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -29,12 +29,18 @@ const commit = util.getVersion(root); const sourceMappingURLBase = `https://ticino.blob.core.windows.net/sourcemaps/${commit}`; function fromLocal(extensionPath) { const webpackFilename = path.join(extensionPath, 'extension.webpack.config.js'); - if (fs.existsSync(webpackFilename)) { - return fromLocalWebpack(extensionPath); - } - else { - return fromLocalNormal(extensionPath); - } + const input = fs.existsSync(webpackFilename) + ? fromLocalWebpack(extensionPath) + : fromLocalNormal(extensionPath); + const tmLanguageJsonFilter = filter('**/*.tmLanguage.json', { restore: true }); + return input + .pipe(tmLanguageJsonFilter) + .pipe(buffer()) + .pipe(es.mapSync((f) => { + f.contents = Buffer.from(JSON.stringify(JSON.parse(f.contents.toString('utf8')))); + return f; + })) + .pipe(tmLanguageJsonFilter.restore); } function fromLocalWebpack(extensionPath) { const result = es.through(); diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 4b185aff681..05bc7094846 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -30,11 +30,20 @@ const sourceMappingURLBase = `https://ticino.blob.core.windows.net/sourcemaps/${ function fromLocal(extensionPath: string): Stream { const webpackFilename = path.join(extensionPath, 'extension.webpack.config.js'); - if (fs.existsSync(webpackFilename)) { - return fromLocalWebpack(extensionPath); - } else { - return fromLocalNormal(extensionPath); - } + const input = fs.existsSync(webpackFilename) + ? fromLocalWebpack(extensionPath) + : fromLocalNormal(extensionPath); + + const tmLanguageJsonFilter = filter('**/*.tmLanguage.json', { restore: true }); + + return input + .pipe(tmLanguageJsonFilter) + .pipe(buffer()) + .pipe(es.mapSync((f: File) => { + f.contents = Buffer.from(JSON.stringify(JSON.parse(f.contents.toString('utf8')))); + return f; + })) + .pipe(tmLanguageJsonFilter.restore); } function fromLocalWebpack(extensionPath: string): Stream { From 3ff362c06df1d6392bb7009b0c7842adc1342a7d Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 12 Aug 2019 07:46:14 -0700 Subject: [PATCH 485/861] xterm@3.15.0-beta98 Diff: https://github.com/xtermjs/xterm.js/compare/30161c3...f3b9dc0 Changes: - Fix cursor blink for non-block cursor in DOM renderer - Remove applyAddon - Re-enable buffer tests - Fix dom -> canvas renderer not drawing viewport Fixes #77559 Fixes #78882 --- package.json | 2 +- remote/package.json | 2 +- remote/yarn.lock | 8 ++++---- yarn.lock | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 21f6cf8ec4c..e6986bff50a 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "vscode-ripgrep": "^1.5.6", "vscode-sqlite3": "4.0.8", "vscode-textmate": "^4.2.2", - "xterm": "3.15.0-beta94", + "xterm": "3.15.0-beta98", "xterm-addon-search": "0.2.0-beta3", "xterm-addon-web-links": "0.1.0-beta10", "yauzl": "^2.9.2", diff --git a/remote/package.json b/remote/package.json index a057fcb87cd..4547f9eed80 100644 --- a/remote/package.json +++ b/remote/package.json @@ -20,7 +20,7 @@ "vscode-proxy-agent": "0.4.0", "vscode-ripgrep": "^1.5.5", "vscode-textmate": "^4.2.2", - "xterm": "3.15.0-beta94", + "xterm": "3.15.0-beta98", "xterm-addon-search": "0.2.0-beta3", "xterm-addon-web-links": "0.1.0-beta10", "yauzl": "^2.9.2", diff --git a/remote/yarn.lock b/remote/yarn.lock index 4c1a99d899c..3e5d4690cf7 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -1159,10 +1159,10 @@ xterm-addon-web-links@0.1.0-beta10: resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23" integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg== -xterm@3.15.0-beta94: - version "3.15.0-beta94" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta94.tgz#a2c48db73252021adc9d33d75f1f91c859b81b5f" - integrity sha512-JScndNQV90vicwBDsZiF2BAxMdruzXvVaN8TY6jFqMPC+YjXTXFDBFUij8iCONnGcTZBfNjbrVng+zLheAKphg== +xterm@3.15.0-beta98: + version "3.15.0-beta98" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta98.tgz#37f37c35577422880e7ef673cc37f9d2a45dd40c" + integrity sha512-vZbg2LcRvoiJOgr1MyeLFM9mF4uib3BWUWDHyFc+vZ58CTuK0iczOvFXgk/ySo23ZLqwmHQSigLgmWvZ8J5G0Q== yauzl@^2.9.2: version "2.10.0" diff --git a/yarn.lock b/yarn.lock index 1f75b23ba87..6eafd48d052 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9888,10 +9888,10 @@ xterm-addon-web-links@0.1.0-beta10: resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23" integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg== -xterm@3.15.0-beta94: - version "3.15.0-beta94" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta94.tgz#a2c48db73252021adc9d33d75f1f91c859b81b5f" - integrity sha512-JScndNQV90vicwBDsZiF2BAxMdruzXvVaN8TY6jFqMPC+YjXTXFDBFUij8iCONnGcTZBfNjbrVng+zLheAKphg== +xterm@3.15.0-beta98: + version "3.15.0-beta98" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta98.tgz#37f37c35577422880e7ef673cc37f9d2a45dd40c" + integrity sha512-vZbg2LcRvoiJOgr1MyeLFM9mF4uib3BWUWDHyFc+vZ58CTuK0iczOvFXgk/ySo23ZLqwmHQSigLgmWvZ8J5G0Q== y18n@^3.2.1: version "3.2.1" From 192e15b613dd4f4dab9c735b7556e175580c6011 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 12 Aug 2019 16:53:50 +0200 Subject: [PATCH 486/861] remove support for markdown message in tree view, only support plain string --- src/vs/vscode.proposed.d.ts | 2 +- .../api/browser/mainThreadTreeViews.ts | 3 +- .../workbench/api/common/extHost.protocol.ts | 2 +- .../workbench/api/common/extHostTreeViews.ts | 13 ++-- .../browser/parts/views/customView.ts | 71 +++---------------- src/vs/workbench/common/views.ts | 3 +- 6 files changed, 20 insertions(+), 74 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 09c48270a26..6328f593b3f 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1012,7 +1012,7 @@ declare module 'vscode' { /** * An optional human-readable message that will be rendered in the view. */ - message?: string | MarkdownString; + message?: string; } diff --git a/src/vs/workbench/api/browser/mainThreadTreeViews.ts b/src/vs/workbench/api/browser/mainThreadTreeViews.ts index f7024269742..2a1e3f5bc5f 100644 --- a/src/vs/workbench/api/browser/mainThreadTreeViews.ts +++ b/src/vs/workbench/api/browser/mainThreadTreeViews.ts @@ -10,7 +10,6 @@ import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { distinct } from 'vs/base/common/arrays'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { isUndefinedOrNull, isNumber } from 'vs/base/common/types'; -import { IMarkdownString } from 'vs/base/common/htmlContent'; import { Registry } from 'vs/platform/registry/common/platform'; @extHostNamedCustomer(MainContext.MainThreadTreeViews) @@ -63,7 +62,7 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie return Promise.resolve(); } - $setMessage(treeViewId: string, message: string | IMarkdownString): void { + $setMessage(treeViewId: string, message: string): void { const viewer = this.getTreeView(treeViewId); if (viewer) { viewer.message = message; diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index dc50dfafa7c..e4a618d695b 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -245,7 +245,7 @@ export interface MainThreadTreeViewsShape extends IDisposable { $registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean }): void; $refresh(treeViewId: string, itemsToRefresh?: { [treeItemHandle: string]: ITreeItem }): Promise; $reveal(treeViewId: string, treeItem: ITreeItem, parentChain: ITreeItem[], options: IRevealOptions): Promise; - $setMessage(treeViewId: string, message: string | IMarkdownString): void; + $setMessage(treeViewId: string, message: string): void; } export interface MainThreadDownloadServiceShape extends IDisposable { diff --git a/src/vs/workbench/api/common/extHostTreeViews.ts b/src/vs/workbench/api/common/extHostTreeViews.ts index f8d6dbb5906..71c8ecf346f 100644 --- a/src/vs/workbench/api/common/extHostTreeViews.ts +++ b/src/vs/workbench/api/common/extHostTreeViews.ts @@ -13,7 +13,7 @@ import { ExtHostTreeViewsShape, MainThreadTreeViewsShape } from './extHost.proto import { ITreeItem, TreeViewItemHandleArg, ITreeItemLabel, IRevealOptions } from 'vs/workbench/common/views'; import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/common/extHostCommands'; import { asPromise } from 'vs/base/common/async'; -import { TreeItemCollapsibleState, ThemeIcon, MarkdownString } from 'vs/workbench/api/common/extHostTypes'; +import { TreeItemCollapsibleState, ThemeIcon } from 'vs/workbench/api/common/extHostTypes'; import { isUndefinedOrNull, isString } from 'vs/base/common/types'; import { equals, coalesce } from 'vs/base/common/arrays'; import { ILogService } from 'vs/platform/log/common/log'; @@ -81,7 +81,10 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape { get visible() { return treeView.visible; }, get onDidChangeVisibility() { return treeView.onDidChangeVisibility; }, get message() { return treeView.message; }, - set message(message: string | MarkdownString) { checkProposedApiEnabled(extension); treeView.message = message; }, + set message(message: string) { + checkProposedApiEnabled(extension); + treeView.message = message; + }, reveal: (element: T, options?: IRevealOptions): Promise => { return treeView.reveal(element, options); }, @@ -250,12 +253,12 @@ class ExtHostTreeView extends Disposable { .then(treeNode => this.proxy.$reveal(this.viewId, treeNode.item, parentChain.map(p => p.item), { select, focus, expand })), error => this.logService.error(error)); } - private _message: string | MarkdownString = ''; - get message(): string | MarkdownString { + private _message: string = ''; + get message(): string { return this._message; } - set message(message: string | MarkdownString) { + set message(message: string) { this._message = message; this._onDidChangeData.fire({ message: true, element: false }); } diff --git a/src/vs/workbench/browser/parts/views/customView.ts b/src/vs/workbench/browser/parts/views/customView.ts index 2822d5c08a5..1163a294920 100644 --- a/src/vs/workbench/browser/parts/views/customView.ts +++ b/src/vs/workbench/browser/parts/views/customView.ts @@ -5,7 +5,7 @@ import 'vs/css!./media/views'; import { Event, Emitter } from 'vs/base/common/event'; -import { IDisposable, Disposable, toDisposable, DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, Disposable, toDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IAction, IActionViewItem, ActionRunner, Action } from 'vs/base/common/actions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; @@ -33,18 +33,14 @@ import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/v import { localize } from 'vs/nls'; import { timeout } from 'vs/base/common/async'; import { editorFindMatchHighlight, editorFindMatchHighlightBorder, textLinkForeground, textCodeBlockBackground, focusBorder } from 'vs/platform/theme/common/colorRegistry'; -import { IMarkdownString } from 'vs/base/common/htmlContent'; import { isString } from 'vs/base/common/types'; -import { renderMarkdown, RenderOptions } from 'vs/base/browser/htmlContentRenderer'; -import { onUnexpectedError } from 'vs/base/common/errors'; -import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { IMarkdownRenderResult } from 'vs/editor/contrib/markdown/markdownRenderer'; import { ILabelService } from 'vs/platform/label/common/label'; import { Registry } from 'vs/platform/registry/common/platform'; import { IListVirtualDelegate, IIdentityProvider } from 'vs/base/browser/ui/list/list'; import { ITreeRenderer, ITreeNode, IAsyncDataSource, ITreeContextMenuEvent } from 'vs/base/browser/ui/tree/tree'; import { FuzzyScore, createMatches } from 'vs/base/common/filters'; import { CollapseAllAction } from 'vs/base/browser/ui/tree/treeDefaults'; +import { isFalsyOrWhitespace } from 'vs/base/common/strings'; export class CustomTreeViewPanel extends ViewletPanel { @@ -167,7 +163,7 @@ export class CustomTreeView extends Disposable implements ITreeView { private focused: boolean = false; private domNode: HTMLElement; private treeContainer: HTMLElement; - private _messageValue: string | IMarkdownString | undefined; + private _messageValue: string | undefined; private messageElement: HTMLDivElement; private tree: WorkbenchAsyncDataTree; private treeLabels: ResourceLabels; @@ -175,9 +171,6 @@ export class CustomTreeView extends Disposable implements ITreeView { private elementsToRefresh: ITreeItem[] = []; private menus: TitleMenus; - private markdownRenderer: MarkdownRenderer; - private markdownResult: IMarkdownRenderResult | null; - private readonly _onDidExpandItem: Emitter = this._register(new Emitter()); readonly onDidExpandItem: Event = this._onDidExpandItem.event; @@ -217,12 +210,6 @@ export class CustomTreeView extends Disposable implements ITreeView { this.doRefresh([this.root]); /** soft refresh **/ } })); - this.markdownRenderer = instantiationService.createInstance(MarkdownRenderer); - this._register(toDisposable(() => { - if (this.markdownResult) { - this.markdownResult.dispose(); - } - })); this._register(Registry.as(Extensions.ViewsRegistry).onDidChangeContainer(({ views, from, to }) => { if (from === this.viewContainer && views.some(v => v.id === this.id)) { this.viewContainer = to; @@ -256,12 +243,12 @@ export class CustomTreeView extends Disposable implements ITreeView { } } - private _message: string | IMarkdownString | undefined; - get message(): string | IMarkdownString | undefined { + private _message: string | undefined; + get message(): string | undefined { return this._message; } - set message(message: string | IMarkdownString | undefined) { + set message(message: string | undefined) { this._message = message; this.updateMessage(); } @@ -470,16 +457,13 @@ export class CustomTreeView extends Disposable implements ITreeView { this.updateContentAreas(); } - private showMessage(message: string | IMarkdownString): void { + private showMessage(message: string): void { DOM.removeClass(this.messageElement, 'hide'); if (this._messageValue !== message) { this.resetMessageElement(); this._messageValue = message; - if (isString(this._messageValue)) { + if (!isFalsyOrWhitespace(this._message)) { this.messageElement.textContent = this._messageValue; - } else { - this.markdownResult = this.markdownRenderer.render(this._messageValue); - DOM.append(this.messageElement, this.markdownResult.element); } this.layout(this._height, this._width); } @@ -492,10 +476,6 @@ export class CustomTreeView extends Disposable implements ITreeView { } private resetMessageElement(): void { - if (this.markdownResult) { - this.markdownResult.dispose(); - this.markdownResult = null; - } DOM.clearNode(this.messageElement); } @@ -893,38 +873,3 @@ class TreeMenus extends Disposable implements IDisposable { } } -class MarkdownRenderer { - - constructor( - @IOpenerService private readonly _openerService: IOpenerService - ) { - } - - private getOptions(disposeables: DisposableStore): RenderOptions { - return { - actionHandler: { - callback: (content) => { - let uri: URI | undefined; - try { - uri = URI.parse(content); - } catch { - // ignore - } - if (uri && this._openerService) { - this._openerService.open(uri).catch(onUnexpectedError); - } - }, - disposeables - } - }; - } - - render(markdown: IMarkdownString): IMarkdownRenderResult { - const disposeables = new DisposableStore(); - const element: HTMLElement = markdown ? renderMarkdown(markdown, this.getOptions(disposeables)) : document.createElement('span'); - return { - element, - dispose: () => disposeables.dispose() - }; - } -} diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index ed734711561..c9ec1a841f6 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -17,7 +17,6 @@ import { values, keys } from 'vs/base/common/map'; import { Registry } from 'vs/platform/registry/common/platform'; import { IKeybindings } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { IAction } from 'vs/base/common/actions'; -import { IMarkdownString } from 'vs/base/common/htmlContent'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; export const TEST_VIEW_CONTAINER_ID = 'workbench.view.extension.test'; @@ -305,7 +304,7 @@ export interface ITreeView extends IDisposable { showCollapseAllAction: boolean; - message?: string | IMarkdownString; + message?: string; readonly visible: boolean; From 3c52a6d396393e6a03c1582695e9dc7af556a6d6 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 12 Aug 2019 16:54:05 +0200 Subject: [PATCH 487/861] adopted latest references view extension --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index 3ae1ace01c1..27467db5743 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -31,7 +31,7 @@ }, { "name": "ms-vscode.references-view", - "version": "0.0.29", + "version": "0.0.30", "repo": "https://github.com/Microsoft/vscode-reference-view", "metadata": { "id": "dc489f46-520d-4556-ae85-1f9eab3c412d", From d701242cc57428628626e0b652f5cae6f100d643 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 12 Aug 2019 16:58:40 +0200 Subject: [PATCH 488/861] update distro --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index e6986bff50a..1b67313a916 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "cefe99a704b186add6f59357a54daa389f5be07d", + "distro": "03e1c530daa9335223a27209e25905f53b6a1545", "author": { "name": "Microsoft Corporation" }, @@ -157,4 +157,4 @@ "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} +} \ No newline at end of file From 54d131e840ea2ced8934f6f220752568812f81b2 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 12 Aug 2019 17:10:31 +0200 Subject: [PATCH 489/861] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1b67313a916..076ad75b4b7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "03e1c530daa9335223a27209e25905f53b6a1545", + "distro": "462afd2bf9dd37b39205412486925bc10b7fbf69", "author": { "name": "Microsoft Corporation" }, From 209e7920d280ae71687180a3b876aa6f2efc9f77 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Mon, 12 Aug 2019 17:27:30 +0200 Subject: [PATCH 490/861] move EH debug service to better location --- .../debug}/electron-browser/extensionHostDebugService.ts | 0 src/vs/workbench/workbench.desktop.main.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/vs/workbench/{services/extensions => contrib/debug}/electron-browser/extensionHostDebugService.ts (100%) diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHostDebugService.ts b/src/vs/workbench/contrib/debug/electron-browser/extensionHostDebugService.ts similarity index 100% rename from src/vs/workbench/services/extensions/electron-browser/extensionHostDebugService.ts rename to src/vs/workbench/contrib/debug/electron-browser/extensionHostDebugService.ts diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index 74d06356a54..cb1fd2b2a2e 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -32,7 +32,7 @@ import 'vs/workbench/services/textMate/electron-browser/textMateService'; import 'vs/workbench/services/workspace/electron-browser/workspaceEditingService'; import 'vs/workbench/services/extensions/common/inactiveExtensionUrlHandler'; import 'vs/workbench/services/search/node/searchService'; -import 'vs/workbench/services/extensions/electron-browser/extensionHostDebugService'; +import 'vs/workbench/contrib/debug/electron-browser/extensionHostDebugService'; import 'vs/workbench/services/output/node/outputChannelModelService'; import 'vs/workbench/services/textfile/node/textFileService'; import 'vs/workbench/services/dialogs/electron-browser/dialogService'; From d83eabbd312404f341dff735543bb543a7c61108 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 12 Aug 2019 17:25:43 +0200 Subject: [PATCH 491/861] :lipstick: - move some more things over to web --- .../browser/actions/developerActions.ts | 28 ++++++++++++++ .../browser/actions/workspaceActions.ts | 21 +++++++++- .../electron-browser/main.contribution.ts | 38 +------------------ 3 files changed, 50 insertions(+), 37 deletions(-) diff --git a/src/vs/workbench/browser/actions/developerActions.ts b/src/vs/workbench/browser/actions/developerActions.ts index 34438be4643..42b78700c7a 100644 --- a/src/vs/workbench/browser/actions/developerActions.ts +++ b/src/vs/workbench/browser/actions/developerActions.ts @@ -25,6 +25,7 @@ import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/action import { IStorageService } from 'vs/platform/storage/common/storage'; import { clamp } from 'vs/base/common/numbers'; import { KeyCode } from 'vs/base/common/keyCodes'; +import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry'; export class InspectContextKeysAction extends Action { @@ -215,8 +216,35 @@ export class LogStorageAction extends Action { } } +// --- Actions Registration + const developerCategory = nls.localize('developer', "Developer"); const registry = Registry.as(Extensions.WorkbenchActions); registry.registerWorkbenchAction(new SyncActionDescriptor(InspectContextKeysAction, InspectContextKeysAction.ID, InspectContextKeysAction.LABEL), 'Developer: Inspect Context Keys', developerCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleScreencastModeAction, ToggleScreencastModeAction.ID, ToggleScreencastModeAction.LABEL), 'Developer: Toggle Screencast Mode', developerCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(LogStorageAction, LogStorageAction.ID, LogStorageAction.LABEL), 'Developer: Log Storage Database Contents', developerCategory); + +// --- Menu Registration + +// Screencast Mode +const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); +configurationRegistry.registerConfiguration({ + id: 'screencastMode', + order: 9, + title: nls.localize('screencastModeConfigurationTitle', "Screencast Mode"), + type: 'object', + properties: { + 'screencastMode.verticalOffset': { + type: 'number', + default: 20, + minimum: 0, + maximum: 90, + description: nls.localize('screencastMode.location.verticalPosition', "Controls the vertical offset of the screencast mode overlay from the bottom as a percentage of the workbench height.") + }, + 'screencastMode.onlyKeyboardShortcuts': { + type: 'boolean', + description: nls.localize('screencastMode.onlyKeyboardShortcuts', "Only show keyboard shortcuts in Screencast Mode."), + default: false + } + } +}); diff --git a/src/vs/workbench/browser/actions/workspaceActions.ts b/src/vs/workbench/browser/actions/workspaceActions.ts index 3cd1005e09d..1d6ee2b796f 100644 --- a/src/vs/workbench/browser/actions/workspaceActions.ts +++ b/src/vs/workbench/browser/actions/workspaceActions.ts @@ -11,7 +11,7 @@ import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder } from 'vs/p import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing'; import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { ICommandService, ICommandHandler } from 'vs/platform/commands/common/commands'; +import { ICommandService, ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands'; import { ADD_ROOT_FOLDER_COMMAND_ID, ADD_ROOT_FOLDER_LABEL, PICK_WORKSPACE_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/workspaceCommands'; import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs'; import { INotificationService } from 'vs/platform/notification/common/notification'; @@ -20,6 +20,9 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/ import { ITextFileService, ISaveOptions } from 'vs/workbench/services/textfile/common/textfiles'; import { toResource } from 'vs/workbench/common/editor'; import { URI } from 'vs/base/common/uri'; +import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; +import { WorkbenchStateContext } from 'vs/workbench/browser/contextkeys'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; export class OpenFileAction extends Action { @@ -305,3 +308,19 @@ export class DuplicateWorkspaceInNewWindowAction extends Action { return this.windowService.openWindow([{ workspaceUri: newWorkspace.configPath }], { forceNewWindow: true }); } } + +// --- Menu Registration + +const workspacesCategory = nls.localize('workspaces', "Workspaces"); + +CommandsRegistry.registerCommand(OpenWorkspaceConfigFileAction.ID, serviceAccessor => { + serviceAccessor.get(IInstantiationService).createInstance(OpenWorkspaceConfigFileAction, OpenWorkspaceConfigFileAction.ID, OpenWorkspaceConfigFileAction.LABEL).run(); +}); + +MenuRegistry.appendMenuItem(MenuId.CommandPalette, { + command: { + id: OpenWorkspaceConfigFileAction.ID, + title: { value: `${workspacesCategory}: ${OpenWorkspaceConfigFileAction.LABEL}`, original: 'Workspaces: Open Workspace Configuration File' }, + }, + when: WorkbenchStateContext.isEqualTo('workspace') +}); diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 4545d9ba830..6cc5770cf50 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -14,11 +14,11 @@ import { isWindows, isLinux, isMacintosh } from 'vs/base/common/platform'; import { KeybindingsReferenceAction, OpenDocumentationUrlAction, OpenIntroductoryVideosUrlAction, OpenTipsAndTricksUrlAction, OpenTwitterUrlAction, OpenRequestFeatureUrlAction, OpenPrivacyStatementUrlAction, OpenLicenseUrlAction, OpenNewsletterSignupUrlAction } from 'vs/workbench/electron-browser/actions/helpActions'; import { ToggleSharedProcessAction, ToggleDevToolsAction } from 'vs/workbench/electron-browser/actions/developerActions'; import { ZoomResetAction, ZoomOutAction, ZoomInAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, QuickSwitchWindow, ReloadWindowWithExtensionsDisabledAction, NewWindowTabHandler, ShowPreviousWindowTabHandler, ShowNextWindowTabHandler, MoveWindowTabToNewWindowHandler, MergeWindowTabsHandlerHandler, ToggleWindowTabsBarHandler } from 'vs/workbench/electron-browser/actions/windowActions'; -import { AddRootFolderAction, GlobalRemoveRootFolderAction, SaveWorkspaceAsAction, OpenWorkspaceConfigFileAction, DuplicateWorkspaceInNewWindowAction, CloseWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions'; +import { AddRootFolderAction, GlobalRemoveRootFolderAction, SaveWorkspaceAsAction, DuplicateWorkspaceInNewWindowAction, CloseWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; -import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { ADD_ROOT_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/workspaceCommands'; import { SupportsWorkspacesContext, IsMacContext, HasMacNativeTabsContext, IsDevelopmentContext, WorkbenchStateContext, WorkspaceFolderCountContext } from 'vs/workbench/browser/contextkeys'; import { NoEditorsVisibleContext, SingleEditorGroupsContext } from 'vs/workbench/common/editor'; @@ -83,18 +83,6 @@ import { IWindowService, IWindowsService } from 'vs/platform/windows/common/wind registry.registerWorkbenchAction(new SyncActionDescriptor(GlobalRemoveRootFolderAction, GlobalRemoveRootFolderAction.ID, GlobalRemoveRootFolderAction.LABEL), 'Workspaces: Remove Folder from Workspace...', workspacesCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(SaveWorkspaceAsAction, SaveWorkspaceAsAction.ID, SaveWorkspaceAsAction.LABEL), 'Workspaces: Save Workspace As...', workspacesCategory, SupportsWorkspacesContext); registry.registerWorkbenchAction(new SyncActionDescriptor(DuplicateWorkspaceInNewWindowAction, DuplicateWorkspaceInNewWindowAction.ID, DuplicateWorkspaceInNewWindowAction.LABEL), 'Workspaces: Duplicate Workspace in New Window', workspacesCategory); - - CommandsRegistry.registerCommand(OpenWorkspaceConfigFileAction.ID, serviceAccessor => { - serviceAccessor.get(IInstantiationService).createInstance(OpenWorkspaceConfigFileAction, OpenWorkspaceConfigFileAction.ID, OpenWorkspaceConfigFileAction.LABEL).run(); - }); - - MenuRegistry.appendMenuItem(MenuId.CommandPalette, { - command: { - id: OpenWorkspaceConfigFileAction.ID, - title: { value: `${workspacesCategory}: ${OpenWorkspaceConfigFileAction.LABEL}`, original: 'Workspaces: Open Workspace Configuration File' }, - }, - when: WorkbenchStateContext.isEqualTo('workspace') - }); })(); // Actions: macOS Native Tabs @@ -505,28 +493,6 @@ import { IWindowService, IWindowsService } from 'vs/platform/windows/common/wind } }); - // Screencast Mode - registry.registerConfiguration({ - id: 'screencastMode', - order: 9, - title: nls.localize('screencastModeConfigurationTitle', "Screencast Mode"), - type: 'object', - properties: { - 'screencastMode.verticalOffset': { - type: 'number', - default: 20, - minimum: 0, - maximum: 90, - description: nls.localize('screencastMode.location.verticalPosition', "Controls the vertical offset of the screencast mode overlay from the bottom as a percentage of the workbench height.") - }, - 'screencastMode.onlyKeyboardShortcuts': { - type: 'boolean', - description: nls.localize('screencastMode.onlyKeyboardShortcuts', "Only show keyboard shortcuts in Screencast Mode."), - default: false - } - } - }); - // Telemetry registry.registerConfiguration({ 'id': 'telemetry', From 1b79be4890baee1c91445dc44e91aa3b27b18204 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 12 Aug 2019 17:35:28 +0200 Subject: [PATCH 492/861] web - fix product version regression --- src/vs/platform/product/browser/productService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/product/browser/productService.ts b/src/vs/platform/product/browser/productService.ts index 0c851b04fc1..70bc0b31bcc 100644 --- a/src/vs/platform/product/browser/productService.ts +++ b/src/vs/platform/product/browser/productService.ts @@ -17,7 +17,7 @@ export class ProductService implements IProductService { this.productConfiguration = element ? JSON.parse(element.getAttribute('data-settings')!) : null; } - get version(): string { return this.productConfiguration ? this.productConfiguration.version : 'Unknown'; } + get version(): string { return this.productConfiguration && this.productConfiguration.version ? this.productConfiguration.version : '1.38.0-unknown'; } get commit(): string | undefined { return this.productConfiguration ? this.productConfiguration.commit : undefined; } From c76a7e69a638c64720ef3c0bfdb0c1aa78dd17cb Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 12 Aug 2019 17:34:19 +0200 Subject: [PATCH 493/861] remove request handler api and make web request service self registerable --- src/vs/workbench/browser/web.main.ts | 9 ++------- .../workbench/services/request/browser/requestService.ts | 6 +----- src/vs/workbench/workbench.web.api.ts | 7 ------- src/vs/workbench/workbench.web.main.ts | 3 +++ 4 files changed, 6 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index 8a2b43a5378..909f7578e4c 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -40,8 +40,6 @@ import { joinPath } from 'vs/base/common/resources'; import { BrowserStorageService } from 'vs/platform/storage/browser/storageService'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { getThemeTypeSelector, DARK, HIGH_CONTRAST, LIGHT } from 'vs/platform/theme/common/themeService'; -import { IRequestService } from 'vs/platform/request/common/request'; -import { RequestService } from 'vs/workbench/services/request/browser/requestService'; import { InMemoryUserDataProvider } from 'vs/workbench/services/userData/common/inMemoryUserDataProvider'; class CodeRendererMain extends Disposable { @@ -170,7 +168,7 @@ class CodeRendererMain extends Disposable { // User Data Provider fileService.registerProvider(Schemas.userData, userDataProvider); - const [configurationService, storageService] = await Promise.all([ + const services = await Promise.all([ this.createWorkspaceService(payload, environmentService, fileService, remoteAgentService, logService).then(service => { // Workspace @@ -191,10 +189,7 @@ class CodeRendererMain extends Disposable { }) ]); - // Request Service - serviceCollection.set(IRequestService, new RequestService(this.configuration.requestHandler, remoteAgentService, configurationService, logService)); - - return { serviceCollection, logService, storageService }; + return { serviceCollection, logService, storageService: services[1] }; } private async createStorageService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, fileService: IFileService, logService: ILogService): Promise { diff --git a/src/vs/workbench/services/request/browser/requestService.ts b/src/vs/workbench/services/request/browser/requestService.ts index dca97347c35..cebf1654eca 100644 --- a/src/vs/workbench/services/request/browser/requestService.ts +++ b/src/vs/workbench/services/request/browser/requestService.ts @@ -16,7 +16,6 @@ export class RequestService extends BrowserRequestService { private readonly remoteRequestChannel: RequestChannelClient | null; constructor( - private readonly requestHandler: ((options: IRequestOptions) => Promise) | undefined, @IRemoteAgentService remoteAgentService: IRemoteAgentService, @IConfigurationService configurationService: IConfigurationService, @ILogService logService: ILogService @@ -27,9 +26,6 @@ export class RequestService extends BrowserRequestService { } async request(options: IRequestOptions, token: CancellationToken): Promise { - if (this.requestHandler) { - return this.requestHandler(options); - } try { const context = await super.request(options, token); if (this.remoteRequestChannel && context.res.statusCode === 405) { @@ -45,4 +41,4 @@ export class RequestService extends BrowserRequestService { } } -} \ No newline at end of file +} diff --git a/src/vs/workbench/workbench.web.api.ts b/src/vs/workbench/workbench.web.api.ts index b1be3bab964..bc4b9d1d767 100644 --- a/src/vs/workbench/workbench.web.api.ts +++ b/src/vs/workbench/workbench.web.api.ts @@ -7,7 +7,6 @@ import 'vs/workbench/workbench.web.main'; import { main } from 'vs/workbench/browser/web.main'; import { UriComponents } from 'vs/base/common/uri'; import { IFileSystemProvider } from 'vs/platform/files/common/files'; -import { IRequestOptions, IRequestContext } from 'vs/platform/request/common/request'; import { IWebSocketFactory } from 'vs/platform/remote/browser/browserSocketFactory'; export interface IWorkbenchConstructionOptions { @@ -45,12 +44,6 @@ export interface IWorkbenchConstructionOptions { */ userDataProvider?: IFileSystemProvider; - /** - * Experimental: Optional request handler to handle http requests. - * In case not provided, workbench uses XMLHttpRequest. - */ - requestHandler?: (requestOptions: IRequestOptions) => Promise; - /** * A factory for web sockets. */ diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 9695a47cfe1..1a41fc77ac4 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -38,6 +38,8 @@ import 'vs/workbench/services/configurationResolver/browser/configurationResolve import 'vs/workbench/browser/web.simpleservices'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IRequestService } from 'vs/platform/request/common/request'; +import { RequestService } from 'vs/workbench/services/request/browser/requestService'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { BrowserClipboardService } from 'vs/platform/clipboard/browser/clipboardService'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; @@ -53,6 +55,7 @@ import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; import { BackupFileService } from 'vs/workbench/services/backup/common/backupFileService'; import { ExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagementService'; +registerSingleton(IRequestService, RequestService, true); registerSingleton(IExtensionManagementService, ExtensionManagementService); registerSingleton(IBackupFileService, BackupFileService); registerSingleton(IDialogService, DialogService, true); From 0ed08672efb5149e2573c6a72e3766ba99d0ed9a Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 12 Aug 2019 17:51:31 +0200 Subject: [PATCH 494/861] Revert "Revert "fixes #78167"" This reverts commit e8c6bfcec7029c83a2dfa691c72cd2e77a932745. --- src/vs/base/browser/ui/grid/gridview.ts | 1 + src/vs/base/browser/ui/splitview/splitview.css | 3 ++- src/vs/base/browser/ui/splitview/splitview.ts | 7 ++++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts index 7283617d69c..5cefe23c549 100644 --- a/src/vs/base/browser/ui/grid/gridview.ts +++ b/src/vs/base/browser/ui/grid/gridview.ts @@ -348,6 +348,7 @@ class BranchNode implements ISplitView, IDisposable { } this.splitview.setViewVisible(index, visible); + this._onDidChange.fire(undefined); } getChildCachedVisibleSize(index: number): number | undefined { diff --git a/src/vs/base/browser/ui/splitview/splitview.css b/src/vs/base/browser/ui/splitview/splitview.css index 6fb8f1c61d0..c0f3634d499 100644 --- a/src/vs/base/browser/ui/splitview/splitview.css +++ b/src/vs/base/browser/ui/splitview/splitview.css @@ -39,6 +39,7 @@ white-space: initial; flex: none; position: relative; + overflow: hidden; } .monaco-split-view2 > .split-view-container > .split-view-view:not(.visible) { @@ -72,4 +73,4 @@ .monaco-split-view2.separator-border.vertical > .split-view-container > .split-view-view:not(:first-child)::before { height: 1px; width: 100%; -} \ No newline at end of file +} diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index bdf42e5a7e1..02c583d1e06 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -125,7 +125,10 @@ abstract class ViewItem { dom.addClass(container, 'visible'); } - abstract layout(): void; + layout(): void { + this.container.scrollTop = 0; + this.container.scrollLeft = 0; + } layoutView(orientation: Orientation): void { this.view.layout(this.size, orientation); @@ -140,6 +143,7 @@ abstract class ViewItem { class VerticalViewItem extends ViewItem { layout(): void { + super.layout(); this.container.style.height = `${this.size}px`; this.layoutView(Orientation.VERTICAL); } @@ -148,6 +152,7 @@ class VerticalViewItem extends ViewItem { class HorizontalViewItem extends ViewItem { layout(): void { + super.layout(); this.container.style.width = `${this.size}px`; this.layoutView(Orientation.HORIZONTAL); } From b6a4220a98cdf874df3feaa16f73559fe708c3b8 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 12 Aug 2019 17:56:10 +0200 Subject: [PATCH 495/861] fix #78768 --- src/vs/base/browser/ui/splitview/splitview.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/base/browser/ui/splitview/splitview.css b/src/vs/base/browser/ui/splitview/splitview.css index c0f3634d499..2988cfef8eb 100644 --- a/src/vs/base/browser/ui/splitview/splitview.css +++ b/src/vs/base/browser/ui/splitview/splitview.css @@ -39,7 +39,6 @@ white-space: initial; flex: none; position: relative; - overflow: hidden; } .monaco-split-view2 > .split-view-container > .split-view-view:not(.visible) { From 6861a68ec4edd9fa9af6af951d33a8789e1e1451 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 12 Aug 2019 17:05:24 +0200 Subject: [PATCH 496/861] Use env path to resolve executable in TerminalProcess (#78940) Candidate fix for #78898 --- src/vs/workbench/contrib/terminal/node/terminalProcess.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts index 2fbc8a25e74..86a63a0b843 100644 --- a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts +++ b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts @@ -89,7 +89,9 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess }, async (err) => { if (err && err.code === 'ENOENT') { let cwd = shellLaunchConfig.cwd instanceof URI ? shellLaunchConfig.cwd.path : shellLaunchConfig.cwd!; - const executable = await findExecutable(shellLaunchConfig.executable!, cwd); + // Try to get path + const envPaths: string[] | undefined = (shellLaunchConfig.env && shellLaunchConfig.env.PATH) ? shellLaunchConfig.env.PATH.split(path.delimiter) : undefined; + const executable = await findExecutable(shellLaunchConfig.executable!, cwd, envPaths); if (!executable) { return Promise.reject(SHELL_PATH_INVALID_EXIT_CODE); } From 2b40fd525c193396bfa0ab2cc79963adfe56dff2 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 12 Aug 2019 09:41:13 -0700 Subject: [PATCH 497/861] Update distro --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 076ad75b4b7..5e9d2b52437 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "462afd2bf9dd37b39205412486925bc10b7fbf69", + "distro": "361c5503f7168938c8752fa5964f1b658fa75178", "author": { "name": "Microsoft Corporation" }, @@ -157,4 +157,4 @@ "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} \ No newline at end of file +} From 4106fe8259fad9da00dba64e8b58afff212b5d34 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Fri, 21 Jun 2019 01:03:50 +0000 Subject: [PATCH 498/861] merge conflicts --- src/buildfile.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/buildfile.js b/src/buildfile.js index e45dbc27461..f9946efc703 100644 --- a/src/buildfile.js +++ b/src/buildfile.js @@ -3,6 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +function entrypoint (name) { + return [{ name: name, include: [], exclude: ['vs/css', 'vs/nls'] }]; +} + exports.base = [{ name: 'vs/base/common/worker/simpleWorker', include: ['vs/editor/common/services/editorSimpleWorker'], @@ -20,10 +24,14 @@ exports.serviceWorker = [{ }]; exports.workbench = require('./vs/workbench/buildfile').collectModules(['vs/workbench/workbench.desktop.main']); -exports.workbenchWeb = require('./vs/workbench/buildfile').collectModules(['vs/workbench/workbench.web.api']); +exports.workbenchWeb = entrypoint('vs/workbench/workbench.web.api'); + +exports.keyboardMaps = [ + entrypoint('vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.linux'), + entrypoint('vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.darwin'), + entrypoint('vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.win') +]; exports.code = require('./vs/code/buildfile').collectModules(); -exports.entrypoint = function (name) { - return [{ name: name, include: [], exclude: ['vs/css', 'vs/nls'] }]; -}; +exports.entrypoint = entrypoint; From bdb1a49ebba5e8b321a9fd3c623e3d8de99fda45 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Mon, 12 Aug 2019 10:04:12 -0700 Subject: [PATCH 499/861] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5e9d2b52437..bab0d047172 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "361c5503f7168938c8752fa5964f1b658fa75178", + "distro": "99979734e2234cdb1e7f4988339c5df3fd3aa521", "author": { "name": "Microsoft Corporation" }, From dc8bbb259ec78c4f235a8f3d7386b5b6b6551f86 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 12 Aug 2019 10:28:26 -0700 Subject: [PATCH 500/861] Fix #78884 --- src/vs/workbench/browser/workbench.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index 7c36ea51726..8bd0501679d 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -246,7 +246,7 @@ import { isMacintosh, isWindows, isLinux, isWeb } from 'vs/base/common/platform' // Window let windowTitleDescription = nls.localize('windowTitle', "Controls the window title based on the active editor. Variables are substituted based on the context:"); - windowTitleDescription += [ + windowTitleDescription += '\n- ' + [ nls.localize('activeEditorShort', "`\${activeEditorShort}`: the file name (e.g. myFile.txt)."), nls.localize('activeEditorMedium', "`\${activeEditorMedium}`: the path of the file relative to the workspace folder (e.g. myFolder/myFileFolder/myFile.txt)."), nls.localize('activeEditorLong', "`\${activeEditorLong}`: the full path of the file (e.g. /Users/Development/myFolder/myFileFolder/myFile.txt)."), From 8ffdc18c1d6bd9b7a5e5d65a0efb7cf29ae65ba0 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Mon, 12 Aug 2019 10:19:35 -0700 Subject: [PATCH 501/861] Use application insights module, #78475, fixes #78840 --- package.json | 1 + remote/package.json | 1 + remote/web/package.json | 1 + remote/web/yarn.lock | 68 +++++++++++++++++ remote/yarn.lock | 68 +++++++++++++++++ src/typings/applicationinsights-web.d.ts | 59 +++++++++++++++ src/vs/code/browser/workbench/workbench.html | 3 - src/vs/code/browser/workbench/workbench.js | 3 +- .../telemetry/browser/telemetryService.ts | 73 +++---------------- tslint.json | 3 +- yarn.lock | 68 +++++++++++++++++ 11 files changed, 280 insertions(+), 68 deletions(-) create mode 100644 src/typings/applicationinsights-web.d.ts diff --git a/package.json b/package.json index bab0d047172..71f19c8c72a 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "update-distro": "node build/npm/update-distro.js" }, "dependencies": { + "@microsoft/applicationinsights-web": "^2.1.1", "applicationinsights": "1.0.8", "graceful-fs": "4.1.11", "http-proxy-agent": "^2.1.0", diff --git a/remote/package.json b/remote/package.json index 4547f9eed80..8cae3c0ed45 100644 --- a/remote/package.json +++ b/remote/package.json @@ -2,6 +2,7 @@ "name": "vscode-reh", "version": "0.0.0", "dependencies": { + "@microsoft/applicationinsights-web": "^2.1.1", "applicationinsights": "1.0.8", "getmac": "1.4.1", "graceful-fs": "4.1.11", diff --git a/remote/web/package.json b/remote/web/package.json index c7a487b6c2d..f54afe1a3e6 100644 --- a/remote/web/package.json +++ b/remote/web/package.json @@ -2,6 +2,7 @@ "name": "vscode-web", "version": "0.0.0", "dependencies": { + "@microsoft/applicationinsights-web": "^2.1.1", "onigasm-umd": "^2.2.2", "vscode-textmate": "^4.1.1", "xterm": "3.15.0-beta67", diff --git a/remote/web/yarn.lock b/remote/web/yarn.lock index b624eb37290..23ad784a554 100644 --- a/remote/web/yarn.lock +++ b/remote/web/yarn.lock @@ -2,6 +2,69 @@ # yarn lockfile v1 +"@microsoft/applicationinsights-analytics-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-2.1.1.tgz#6d09c1915f808026e2d45165d04802f09affed59" + integrity sha512-VKIutoFKY99CyKwxLUuj6Vnq14/QwXo9/QSQDpYnHEjo+uKn7QmLsHqWw0K9uYNfNAXt4BZimX/zDg6jZtzeXg== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-channel-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.1.1.tgz#e205eddd93e49d17d9e0711a612b4bfc9810888f" + integrity sha512-fYr9IAqtaEr9AmaPaL3SLQVT3t3GQzl+n74gpNKyAVakDIm0nYQ/bimjdcAhJMDf1VGNSPg/xICneyuZg7Wxlg== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-common@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.1.1.tgz#27e6074584a7a3a8ca3f11f7ff2b7ff0f395bf2d" + integrity sha512-2hkS1Ia1FmAjCuYZ5JlG20/WgObqdsKtmK5YALAFGHIB4KSQ/Za1qazS+7GsG+E0F9UJivNWL1geUIcNqg5Qjg== + dependencies: + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-core-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.1.1.tgz#30fb6a519cc1c6119c419c4811ce72c260217d9e" + integrity sha512-4t4wf6SKqIcWEQDPg/uOhm+BxtHhu/AFreyEoYZmMfcxzAu33h1FtTQRtxBNbYH1+thiNZCh80yUpnT7d9Hrlw== + dependencies: + tslib "^1.9.3" + +"@microsoft/applicationinsights-dependencies-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-2.1.1.tgz#8154c3efcb24617d015d0bce7c2cc47797a8d3c4" + integrity sha512-yhb4EToBp+aI+qLo0h5NDNtoo3sDFV60uyIOK843YjzXqVotcXX/lRShlghTkJtYH09QhrdzDjViUHnD4sMFSQ== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-properties-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-2.1.1.tgz#ca34232766eb16167b5d87693e2ae5d94f2a1559" + integrity sha512-8l+/ppw6xKTam2RL4EHZ52Lcf217olw81j6kyBNKtIcGwSnLNHrFwEeF3vBWIteG2JKzlg1GhGjrkB3oxXsV2g== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-web@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web/-/applicationinsights-web-2.1.1.tgz#1a44eddda7c244b88d9eb052dab6c855682e4f05" + integrity sha512-crvhCkNsNxkFuPWmttyWNSAA96D5FxBtKS6UA9MV9f9XHevTfchf/E3AuU9JZcsXufWMQLwLrUQ9ZiA1QJ0EWA== + dependencies: + "@microsoft/applicationinsights-analytics-js" "2.1.1" + "@microsoft/applicationinsights-channel-js" "2.1.1" + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + "@microsoft/applicationinsights-dependencies-js" "2.1.1" + "@microsoft/applicationinsights-properties-js" "2.1.1" + nan@^2.14.0: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" @@ -24,6 +87,11 @@ semver-umd@^5.5.3: resolved "https://registry.yarnpkg.com/semver-umd/-/semver-umd-5.5.3.tgz#b64d7a2d4f5a717b369d56e31940a38e47e34d1e" integrity sha512-HOnQrn2iKnVe/xlqCTzMXQdvSz3rPbD0DmQXYuQ+oK1dpptGFfPghonQrx5JHl2O7EJwDqtQnjhE7ME23q6ngw== +tslib@^1.9.3: + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + vscode-textmate@^4.1.1: version "4.2.2" resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-4.2.2.tgz#0b4dabc69a6fba79a065cb6b615f66eac07c8f4c" diff --git a/remote/yarn.lock b/remote/yarn.lock index 3e5d4690cf7..ca4abc44e37 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -2,6 +2,69 @@ # yarn lockfile v1 +"@microsoft/applicationinsights-analytics-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-2.1.1.tgz#6d09c1915f808026e2d45165d04802f09affed59" + integrity sha512-VKIutoFKY99CyKwxLUuj6Vnq14/QwXo9/QSQDpYnHEjo+uKn7QmLsHqWw0K9uYNfNAXt4BZimX/zDg6jZtzeXg== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-channel-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.1.1.tgz#e205eddd93e49d17d9e0711a612b4bfc9810888f" + integrity sha512-fYr9IAqtaEr9AmaPaL3SLQVT3t3GQzl+n74gpNKyAVakDIm0nYQ/bimjdcAhJMDf1VGNSPg/xICneyuZg7Wxlg== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-common@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.1.1.tgz#27e6074584a7a3a8ca3f11f7ff2b7ff0f395bf2d" + integrity sha512-2hkS1Ia1FmAjCuYZ5JlG20/WgObqdsKtmK5YALAFGHIB4KSQ/Za1qazS+7GsG+E0F9UJivNWL1geUIcNqg5Qjg== + dependencies: + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-core-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.1.1.tgz#30fb6a519cc1c6119c419c4811ce72c260217d9e" + integrity sha512-4t4wf6SKqIcWEQDPg/uOhm+BxtHhu/AFreyEoYZmMfcxzAu33h1FtTQRtxBNbYH1+thiNZCh80yUpnT7d9Hrlw== + dependencies: + tslib "^1.9.3" + +"@microsoft/applicationinsights-dependencies-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-2.1.1.tgz#8154c3efcb24617d015d0bce7c2cc47797a8d3c4" + integrity sha512-yhb4EToBp+aI+qLo0h5NDNtoo3sDFV60uyIOK843YjzXqVotcXX/lRShlghTkJtYH09QhrdzDjViUHnD4sMFSQ== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-properties-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-2.1.1.tgz#ca34232766eb16167b5d87693e2ae5d94f2a1559" + integrity sha512-8l+/ppw6xKTam2RL4EHZ52Lcf217olw81j6kyBNKtIcGwSnLNHrFwEeF3vBWIteG2JKzlg1GhGjrkB3oxXsV2g== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-web@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web/-/applicationinsights-web-2.1.1.tgz#1a44eddda7c244b88d9eb052dab6c855682e4f05" + integrity sha512-crvhCkNsNxkFuPWmttyWNSAA96D5FxBtKS6UA9MV9f9XHevTfchf/E3AuU9JZcsXufWMQLwLrUQ9ZiA1QJ0EWA== + dependencies: + "@microsoft/applicationinsights-analytics-js" "2.1.1" + "@microsoft/applicationinsights-channel-js" "2.1.1" + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + "@microsoft/applicationinsights-dependencies-js" "2.1.1" + "@microsoft/applicationinsights-properties-js" "2.1.1" + agent-base@4, agent-base@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.0.tgz#9838b5c3392b962bad031e6a4c5e1024abec45ce" @@ -1024,6 +1087,11 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" +tslib@^1.9.3: + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + typechecker@^4.3.0: version "4.7.0" resolved "https://registry.yarnpkg.com/typechecker/-/typechecker-4.7.0.tgz#5249f427358f45b7250c4924fd4d01ed9ba435e9" diff --git a/src/typings/applicationinsights-web.d.ts b/src/typings/applicationinsights-web.d.ts new file mode 100644 index 00000000000..5af4903525c --- /dev/null +++ b/src/typings/applicationinsights-web.d.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. + *--------------------------------------------------------------------------------------------*/ + +declare module '@microsoft/applicationinsights-web' { + export interface IConfig { + instrumentationKey?: string; + endpointUrl?: string; + emitLineDelimitedJson?: boolean; + accountId?: string; + sessionRenewalMs?: number; + sessionExpirationMs?: number; + maxBatchSizeInBytes?: number; + maxBatchInterval?: number; + enableDebug?: boolean; + disableExceptionTracking?: boolean; + disableTelemetry?: boolean; + verboseLogging?: boolean; + diagnosticLogInterval?: number; + samplingPercentage?: number; + autoTrackPageVisitTime?: boolean; + disableAjaxTracking?: boolean; + overridePageViewDuration?: boolean; + maxAjaxCallsPerView?: number; + disableDataLossAnalysis?: boolean; + disableCorrelationHeaders?: boolean; + correlationHeaderExcludedDomains?: string[]; + disableFlushOnBeforeUnload?: boolean; + enableSessionStorageBuffer?: boolean; + isCookieUseDisabled?: boolean; + cookieDomain?: string; + isRetryDisabled?: boolean; + url?: string; + isStorageUseDisabled?: boolean; + isBeaconApiDisabled?: boolean; + sdkExtension?: string; + isBrowserLinkTrackingEnabled?: boolean; + appId?: string; + enableCorsCorrelation?: boolean; + } + + export interface ISnippet { + config: IConfig; + } + + export interface IEventTelemetry { + name: string; + properties?: { [key: string]: string }; + measurements?: { [key: string]: number }; + } + + export class ApplicationInsights { + constructor(config: ISnippet); + loadAppInsights(): void; + trackEvent(data: IEventTelemetry): void; + flush(): void; + } +} diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index 5b06636edbb..9b8e42d3a3b 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -24,9 +24,6 @@ - - - diff --git a/src/vs/code/browser/workbench/workbench.js b/src/vs/code/browser/workbench/workbench.js index 65fae7c82df..240ca34df05 100644 --- a/src/vs/code/browser/workbench/workbench.js +++ b/src/vs/code/browser/workbench/workbench.js @@ -16,6 +16,7 @@ 'xterm-addon-search': `${window.location.origin}/node_modules/xterm-addon-search/lib/xterm-addon-search.js`, 'xterm-addon-web-links': `${window.location.origin}/node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js`, 'semver-umd': `${window.location.origin}/node_modules/semver-umd/lib/semver-umd.js`, + '@microsoft/applicationinsights-web': `${window.location.origin}/node_modules/@microsoft/applicationinsights-web/dist/applicationinsights-web.js`, } }); @@ -24,4 +25,4 @@ api.create(document.body, options); }); -})(); \ No newline at end of file +})(); diff --git a/src/vs/workbench/services/telemetry/browser/telemetryService.ts b/src/vs/workbench/services/telemetry/browser/telemetryService.ts index 652aaf3a2de..eac9dcfb1d0 100644 --- a/src/vs/workbench/services/telemetry/browser/telemetryService.ts +++ b/src/vs/workbench/services/telemetry/browser/telemetryService.ts @@ -15,67 +15,10 @@ import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/pla import { IStorageService } from 'vs/platform/storage/common/storage'; import { resolveWorkbenchCommonProperties } from 'vs/platform/telemetry/browser/workbenchCommonProperties'; import { IProductService } from 'vs/platform/product/common/product'; - -interface IConfig { - instrumentationKey?: string; - endpointUrl?: string; - emitLineDelimitedJson?: boolean; - accountId?: string; - sessionRenewalMs?: number; - sessionExpirationMs?: number; - maxBatchSizeInBytes?: number; - maxBatchInterval?: number; - enableDebug?: boolean; - disableExceptionTracking?: boolean; - disableTelemetry?: boolean; - verboseLogging?: boolean; - diagnosticLogInterval?: number; - samplingPercentage?: number; - autoTrackPageVisitTime?: boolean; - disableAjaxTracking?: boolean; - overridePageViewDuration?: boolean; - maxAjaxCallsPerView?: number; - disableDataLossAnalysis?: boolean; - disableCorrelationHeaders?: boolean; - correlationHeaderExcludedDomains?: string[]; - disableFlushOnBeforeUnload?: boolean; - enableSessionStorageBuffer?: boolean; - isCookieUseDisabled?: boolean; - cookieDomain?: string; - isRetryDisabled?: boolean; - url?: string; - isStorageUseDisabled?: boolean; - isBeaconApiDisabled?: boolean; - sdkExtension?: string; - isBrowserLinkTrackingEnabled?: boolean; - appId?: string; - enableCorsCorrelation?: boolean; -} - -declare class Microsoft { - public static ApplicationInsights: { - Initialization: { - new(init: { config: IConfig }): AppInsights; - } - }; -} - -declare interface IAppInsightsClient { - config: IConfig; - - /** Log a user action or other occurrence. */ - trackEvent: (name: string, properties?: { [key: string]: string }, measurements?: { [key: string]: number }) => void; - - /** Immediately send all queued telemetry. Synchronous. */ - flush(): void; -} - -interface AppInsights { - loadAppInsights: () => IAppInsightsClient; -} +import { ApplicationInsights } from '@microsoft/applicationinsights-web'; export class WebTelemetryAppender implements ITelemetryAppender { - private _aiClient?: IAppInsightsClient; + private _aiClient?: ApplicationInsights; constructor(aiKey: string, private _logService: ILogService) { const initConfig = { @@ -89,8 +32,8 @@ export class WebTelemetryAppender implements ITelemetryAppender { } }; - const appInsights = new Microsoft.ApplicationInsights.Initialization(initConfig); - this._aiClient = appInsights.loadAppInsights(); + this._aiClient = new ApplicationInsights(initConfig); + this._aiClient.loadAppInsights(); } log(eventName: string, data: any): void { @@ -101,7 +44,11 @@ export class WebTelemetryAppender implements ITelemetryAppender { data = validateTelemetryData(data); this._logService.trace(`telemetry/${eventName}`, data); - this._aiClient.trackEvent('monacoworkbench/' + eventName, data.properties, data.measurements); + this._aiClient.trackEvent({ + name: 'monacoworkbench/' + eventName, + properties: data.properties, + measurements: data.measurements + }); } flush(): Promise { @@ -167,4 +114,4 @@ export class TelemetryService extends Disposable implements ITelemetryService { } } -registerSingleton(ITelemetryService, TelemetryService); \ No newline at end of file +registerSingleton(ITelemetryService, TelemetryService); diff --git a/tslint.json b/tslint.json index 733a56ac409..e10b559308d 100644 --- a/tslint.json +++ b/tslint.json @@ -446,7 +446,8 @@ "**/vs/workbench/{common,browser}/**", "**/vs/workbench/services/**/{common,browser}/**", "vscode-textmate", - "onigasm-umd" + "onigasm-umd", + "@microsoft/applicationinsights-web" ] }, { diff --git a/yarn.lock b/yarn.lock index 6eafd48d052..62a825ad594 100644 --- a/yarn.lock +++ b/yarn.lock @@ -95,6 +95,69 @@ lodash "^4.17.11" to-fast-properties "^2.0.0" +"@microsoft/applicationinsights-analytics-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-2.1.1.tgz#6d09c1915f808026e2d45165d04802f09affed59" + integrity sha512-VKIutoFKY99CyKwxLUuj6Vnq14/QwXo9/QSQDpYnHEjo+uKn7QmLsHqWw0K9uYNfNAXt4BZimX/zDg6jZtzeXg== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-channel-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.1.1.tgz#e205eddd93e49d17d9e0711a612b4bfc9810888f" + integrity sha512-fYr9IAqtaEr9AmaPaL3SLQVT3t3GQzl+n74gpNKyAVakDIm0nYQ/bimjdcAhJMDf1VGNSPg/xICneyuZg7Wxlg== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-common@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.1.1.tgz#27e6074584a7a3a8ca3f11f7ff2b7ff0f395bf2d" + integrity sha512-2hkS1Ia1FmAjCuYZ5JlG20/WgObqdsKtmK5YALAFGHIB4KSQ/Za1qazS+7GsG+E0F9UJivNWL1geUIcNqg5Qjg== + dependencies: + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-core-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.1.1.tgz#30fb6a519cc1c6119c419c4811ce72c260217d9e" + integrity sha512-4t4wf6SKqIcWEQDPg/uOhm+BxtHhu/AFreyEoYZmMfcxzAu33h1FtTQRtxBNbYH1+thiNZCh80yUpnT7d9Hrlw== + dependencies: + tslib "^1.9.3" + +"@microsoft/applicationinsights-dependencies-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-2.1.1.tgz#8154c3efcb24617d015d0bce7c2cc47797a8d3c4" + integrity sha512-yhb4EToBp+aI+qLo0h5NDNtoo3sDFV60uyIOK843YjzXqVotcXX/lRShlghTkJtYH09QhrdzDjViUHnD4sMFSQ== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-properties-js@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-2.1.1.tgz#ca34232766eb16167b5d87693e2ae5d94f2a1559" + integrity sha512-8l+/ppw6xKTam2RL4EHZ52Lcf217olw81j6kyBNKtIcGwSnLNHrFwEeF3vBWIteG2JKzlg1GhGjrkB3oxXsV2g== + dependencies: + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + tslib "^1.9.3" + +"@microsoft/applicationinsights-web@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web/-/applicationinsights-web-2.1.1.tgz#1a44eddda7c244b88d9eb052dab6c855682e4f05" + integrity sha512-crvhCkNsNxkFuPWmttyWNSAA96D5FxBtKS6UA9MV9f9XHevTfchf/E3AuU9JZcsXufWMQLwLrUQ9ZiA1QJ0EWA== + dependencies: + "@microsoft/applicationinsights-analytics-js" "2.1.1" + "@microsoft/applicationinsights-channel-js" "2.1.1" + "@microsoft/applicationinsights-common" "2.1.1" + "@microsoft/applicationinsights-core-js" "2.1.1" + "@microsoft/applicationinsights-dependencies-js" "2.1.1" + "@microsoft/applicationinsights-properties-js" "2.1.1" + "@types/commander@^2.11.0": version "2.12.2" resolved "https://registry.yarnpkg.com/@types/commander/-/commander-2.12.2.tgz#183041a23842d4281478fa5d23c5ca78e6fd08ae" @@ -8961,6 +9024,11 @@ tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== +tslib@^1.9.3: + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + tslint@^5.16.0: version "5.16.0" resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.16.0.tgz#ae61f9c5a98d295b9a4f4553b1b1e831c1984d67" From 1f4c94ecb81fc00094868dbc214a82ed69653e63 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 12 Aug 2019 10:47:42 -0700 Subject: [PATCH 502/861] Pick up TS 3.6 dev For #78973 --- extensions/package.json | 2 +- extensions/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/extensions/package.json b/extensions/package.json index 52ece5e2051..57d5f5da311 100644 --- a/extensions/package.json +++ b/extensions/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "description": "Dependencies shared by all extensions", "dependencies": { - "typescript": "3.5.2" + "typescript": "3.6.0-dev.20190810" }, "scripts": { "postinstall": "node ./postinstall" diff --git a/extensions/yarn.lock b/extensions/yarn.lock index 8e552194c13..233cf189e14 100644 --- a/extensions/yarn.lock +++ b/extensions/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -typescript@3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.2.tgz#a09e1dc69bc9551cadf17dba10ee42cf55e5d56c" - integrity sha512-7KxJovlYhTX5RaRbUdkAXN1KUZ8PwWlTzQdHV6xNqvuFOs7+WBo10TQUqT19Q/Jz2hk5v9TQDIhyLhhJY4p5AA== +typescript@3.6.0-dev.20190810: + version "3.6.0-dev.20190810" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.0-dev.20190810.tgz#dda80279480131eec9b05e3b78182a1ba1efe105" + integrity sha512-gubcQ8Sn2G5AO1KhjvLpoFrutV7o/ZJ7wCDBC1IKgNI8R2vadIxTystJxAFqkb9boQ7tyRrZ6FwM5EL5ZYfJrg== From cafd7658a7835cf7cdf2a2f6b0391e4845f0b3aa Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 12 Aug 2019 11:58:55 -0500 Subject: [PATCH 503/861] Add CURRENT_SECONDS_UNIX snippet variable --- src/vs/editor/contrib/snippet/snippetVariables.ts | 3 +++ src/vs/editor/contrib/snippet/test/snippetVariables.test.ts | 1 + 2 files changed, 4 insertions(+) diff --git a/src/vs/editor/contrib/snippet/snippetVariables.ts b/src/vs/editor/contrib/snippet/snippetVariables.ts index b56f15882dc..a1c080d2b45 100644 --- a/src/vs/editor/contrib/snippet/snippetVariables.ts +++ b/src/vs/editor/contrib/snippet/snippetVariables.ts @@ -27,6 +27,7 @@ export const KnownSnippetVariableNames: { [key: string]: true } = Object.freeze( 'CURRENT_DAY_NAME_SHORT': true, 'CURRENT_MONTH_NAME': true, 'CURRENT_MONTH_NAME_SHORT': true, + 'CURRENT_SECONDS_UNIX': true, 'SELECTION': true, 'CLIPBOARD': true, 'TM_SELECTED_TEXT': true, @@ -245,6 +246,8 @@ export class TimeBasedVariableResolver implements VariableResolver { return TimeBasedVariableResolver.monthNames[new Date().getMonth()]; } else if (name === 'CURRENT_MONTH_NAME_SHORT') { return TimeBasedVariableResolver.monthNamesShort[new Date().getMonth()]; + } else if (name === 'CURRENT_SECONDS_UNIX') { + return String(Math.floor(Date.now() / 1000)); } return undefined; diff --git a/src/vs/editor/contrib/snippet/test/snippetVariables.test.ts b/src/vs/editor/contrib/snippet/test/snippetVariables.test.ts index 7a5367085e7..b4412f1d130 100644 --- a/src/vs/editor/contrib/snippet/test/snippetVariables.test.ts +++ b/src/vs/editor/contrib/snippet/test/snippetVariables.test.ts @@ -281,6 +281,7 @@ suite('Snippet Variables Resolver', function () { assertVariableResolve3(resolver, 'CURRENT_DAY_NAME_SHORT'); assertVariableResolve3(resolver, 'CURRENT_MONTH_NAME'); assertVariableResolve3(resolver, 'CURRENT_MONTH_NAME_SHORT'); + assertVariableResolve3(resolver, 'CURRENT_SECONDS_UNIX'); }); test('creating snippet - format-condition doesn\'t work #53617', function () { From 5ea298a88f8528bfdd0d08fab08dbe1267b0eb7a Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 12 Aug 2019 11:54:39 -0700 Subject: [PATCH 504/861] Bump ripgrep for remote too --- remote/package.json | 2 +- remote/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/remote/package.json b/remote/package.json index 8cae3c0ed45..d3ad3afaed7 100644 --- a/remote/package.json +++ b/remote/package.json @@ -19,7 +19,7 @@ "vscode-chokidar": "2.1.7", "vscode-minimist": "^1.2.1", "vscode-proxy-agent": "0.4.0", - "vscode-ripgrep": "^1.5.5", + "vscode-ripgrep": "^1.5.6", "vscode-textmate": "^4.2.2", "xterm": "3.15.0-beta98", "xterm-addon-search": "0.2.0-beta3", diff --git a/remote/yarn.lock b/remote/yarn.lock index ca4abc44e37..b271a9fd5cc 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -1191,10 +1191,10 @@ vscode-proxy-agent@0.4.0: https-proxy-agent "2.2.1" socks-proxy-agent "4.0.1" -vscode-ripgrep@^1.5.5: - version "1.5.5" - resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.5.5.tgz#24c0e9cb356cf889c98e15ecb58f9cf654a1d961" - integrity sha512-OrPrAmcun4+uZAuNcQvE6CCPskh+5AsjANod/Q3zRcJcGNxgoOSGlQN9RPtatkUNmkN8Nn8mZBnS1jMylu/dKg== +vscode-ripgrep@^1.5.6: + version "1.5.6" + resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.5.6.tgz#93bf5c99ca5f8248950a305e224f6ca153c30af4" + integrity sha512-WRIM9XpUj6dsfdAmuI3ANbmT1ysPUVsYy/2uCLDHJa9kbiB4T7uGvFnnc0Rgx2qQnyRAwL7PeWaFgUljPPxf2g== vscode-textmate@^4.2.2: version "4.2.2" From 0c87c73ce54901bed44df7aa7e1cb3f099c39263 Mon Sep 17 00:00:00 2001 From: Jarnin Fang Date: Mon, 12 Aug 2019 12:00:12 -0700 Subject: [PATCH 505/861] Issue 78480: Clear Filter command link includes dot --- src/vs/workbench/contrib/markers/browser/markersPanel.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/markers/browser/markersPanel.ts b/src/vs/workbench/contrib/markers/browser/markersPanel.ts index 71b13da1413..36f1b9bd365 100644 --- a/src/vs/workbench/contrib/markers/browser/markersPanel.ts +++ b/src/vs/workbench/contrib/markers/browser/markersPanel.ts @@ -534,8 +534,10 @@ export class MarkersPanel extends Panel implements IMarkerFilterController { const span1 = dom.append(container, dom.$('span')); span1.textContent = Messages.MARKERS_PANEL_NO_PROBLEMS_FILTERS; const link = dom.append(container, dom.$('a.messageAction')); - link.textContent = localize('clearFilter', "Clear Filter."); + link.textContent = localize('clearFilter', "Clear Filter"); link.setAttribute('tabIndex', '0'); + const span2 = dom.append(container, dom.$('span')); + span2.textContent = '.'; dom.addStandardDisposableListener(link, dom.EventType.CLICK, () => this.filterAction.filterText = ''); dom.addStandardDisposableListener(link, dom.EventType.KEY_DOWN, (e: IKeyboardEvent) => { if (e.equals(KeyCode.Enter) || e.equals(KeyCode.Space)) { From eb8fe0e1ee38cab923d678314dc2af761da230bc Mon Sep 17 00:00:00 2001 From: Chris May Date: Sat, 10 Aug 2019 21:47:12 +0100 Subject: [PATCH 506/861] Add a configuration option to show/hide icons in the breadcrumbs view --- .../workbench/browser/parts/editor/breadcrumbs.ts | 6 ++++++ .../browser/parts/editor/breadcrumbsControl.ts | 13 ++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts index 85aed7a9bf4..0bd6c69fbdc 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts @@ -71,6 +71,7 @@ export abstract class BreadcrumbsConfig { static FilePath = BreadcrumbsConfig._stub<'on' | 'off' | 'last'>('breadcrumbs.filePath'); static SymbolPath = BreadcrumbsConfig._stub<'on' | 'off' | 'last'>('breadcrumbs.symbolPath'); static SymbolSortOrder = BreadcrumbsConfig._stub<'position' | 'name' | 'type'>('breadcrumbs.symbolSortOrder'); + static Icons = BreadcrumbsConfig._stub('breadcrumbs.icons'); static FileExcludes = BreadcrumbsConfig._stub('files.exclude'); @@ -160,6 +161,11 @@ Registry.as(Extensions.Configuration).registerConfigurat localize('symbolSortOrder.name', "Show symbol outline in alphabetical order."), localize('symbolSortOrder.type', "Show symbol outline in symbol type order."), ] + }, + 'breadcrumbs.icons': { + description: localize('icons', "Render breadcrumb items with icons."), + type: 'boolean', + default: true } } }); diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 0614722d536..60bb6b091a8 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -143,6 +143,7 @@ export class BreadcrumbsControl { private readonly _ckBreadcrumbsActive: IContextKey; private readonly _cfUseQuickPick: BreadcrumbsConfig; + private readonly _cfShowIcons: BreadcrumbsConfig; readonly domNode: HTMLDivElement; private readonly _widget: BreadcrumbsWidget; @@ -185,6 +186,7 @@ export class BreadcrumbsControl { this._ckBreadcrumbsActive = BreadcrumbsControl.CK_BreadcrumbsActive.bindTo(this._contextKeyService); this._cfUseQuickPick = BreadcrumbsConfig.UseQuickPick.bindTo(_configurationService); + this._cfShowIcons = BreadcrumbsConfig.Icons.bindTo(_configurationService); this._disposables.add(breadcrumbsService.register(this._editorGroup.id, this._widget)); } @@ -196,6 +198,7 @@ export class BreadcrumbsControl { this._ckBreadcrumbsVisible.reset(); this._ckBreadcrumbsActive.reset(); this._cfUseQuickPick.dispose(); + this._cfShowIcons.dispose(); this._widget.dispose(); this.domNode.remove(); } @@ -246,15 +249,23 @@ export class BreadcrumbsControl { dom.toggleClass(this.domNode, 'backslash-path', this._labelService.getSeparator(uri.scheme, uri.authority) === '\\'); const updateBreadcrumbs = () => { - const items = model.getElements().map(element => new Item(element, this._options, this._instantiationService)); + const showIcons = this._cfShowIcons.getValue(); + const options: IBreadcrumbsControlOptions = { + ...this._options, + showFileIcons: this._options.showFileIcons && showIcons, + showSymbolIcons: this._options.showSymbolIcons && showIcons + }; + const items = model.getElements().map(element => new Item(element, options, this._instantiationService)); this._widget.setItems(items); this._widget.reveal(items[items.length - 1]); }; const listener = model.onDidUpdate(updateBreadcrumbs); + const configListener = this._cfShowIcons.onDidChange(updateBreadcrumbs); updateBreadcrumbs(); this._breadcrumbsDisposables.clear(); this._breadcrumbsDisposables.add(model); this._breadcrumbsDisposables.add(listener); + this._breadcrumbsDisposables.add(configListener); // close picker on hide/update this._breadcrumbsDisposables.add({ From e133b267684430e3c5be0ce4ea55f90f318b853b Mon Sep 17 00:00:00 2001 From: Chris May Date: Sun, 11 Aug 2019 10:00:41 +0100 Subject: [PATCH 507/861] Modify Breadcrumb Item equality test to include icon display option --- src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 60bb6b091a8..39927e683a4 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -69,7 +69,9 @@ class Item extends BreadcrumbsItem { return false; } if (this.element instanceof FileElement && other.element instanceof FileElement) { - return isEqual(this.element.uri, other.element.uri, false); + return (isEqual(this.element.uri, other.element.uri, false) && + this.options.showFileIcons === other.options.showFileIcons && + this.options.showSymbolIcons === other.options.showSymbolIcons); } if (this.element instanceof TreeElement && other.element instanceof TreeElement) { return this.element.id === other.element.id; From 240c2079c38c76296671fd8e14c6a574efc3c1f0 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Mon, 12 Aug 2019 13:39:21 -0700 Subject: [PATCH 508/861] Add workspace.id property to stats telemetry --- .../diagnostics/common/diagnosticsService.ts | 8 ++- .../diagnostics/node/diagnosticsService.ts | 10 ++-- .../stats/electron-browser/workspaceStats.ts | 15 +++++- .../electron-browser/workspaceStatsService.ts | 50 +++++++++++-------- 4 files changed, 55 insertions(+), 28 deletions(-) diff --git a/src/vs/platform/diagnostics/common/diagnosticsService.ts b/src/vs/platform/diagnostics/common/diagnosticsService.ts index ae854fcfb7c..48cc4eb9081 100644 --- a/src/vs/platform/diagnostics/common/diagnosticsService.ts +++ b/src/vs/platform/diagnostics/common/diagnosticsService.ts @@ -63,6 +63,10 @@ export interface PerformanceInfo { workspaceInfo?: string; } +export interface IWorkspaceInformation extends IWorkspace { + telemetryId: string | undefined; +} + export const ID = 'diagnosticsService'; export const IDiagnosticsService = createDecorator(ID); @@ -72,9 +76,9 @@ export interface IDiagnosticsService { getPerformanceInfo(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise; getSystemInfo(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise; getDiagnostics(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise; - reportWorkspaceStats(workspace: IWorkspace): Promise; + reportWorkspaceStats(workspace: IWorkspaceInformation): Promise; } export function isRemoteDiagnosticError(x: any): x is IRemoteDiagnosticError { return !!x.hostName && !!x.errorMessage; -} \ No newline at end of file +} diff --git a/src/vs/platform/diagnostics/node/diagnosticsService.ts b/src/vs/platform/diagnostics/node/diagnosticsService.ts index 9e74621348c..13552c9ab44 100644 --- a/src/vs/platform/diagnostics/node/diagnosticsService.ts +++ b/src/vs/platform/diagnostics/node/diagnosticsService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as osLib from 'os'; import { virtualMachineHint } from 'vs/base/node/id'; -import { IMachineInfo, WorkspaceStats, WorkspaceStatItem, IDiagnosticsService, PerformanceInfo, SystemInfo, IRemoteDiagnosticInfo, IRemoteDiagnosticError, isRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { IMachineInfo, WorkspaceStats, WorkspaceStatItem, IDiagnosticsService, PerformanceInfo, SystemInfo, IRemoteDiagnosticInfo, IRemoteDiagnosticError, isRemoteDiagnosticError, IWorkspaceInformation } from 'vs/platform/diagnostics/common/diagnosticsService'; import { readdir, stat, exists, readFile } from 'fs'; import { join, basename } from 'vs/base/common/path'; import { parse, ParseError } from 'vs/base/common/json'; @@ -16,7 +16,6 @@ import { isWindows } from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; import { ProcessItem } from 'vs/base/common/processes'; import { IMainProcessInfo } from 'vs/platform/launch/common/launchService'; -import { IWorkspace } from 'vs/platform/workspace/common/workspace'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; export interface VersionInfo { @@ -514,7 +513,7 @@ export class DiagnosticsService implements IDiagnosticsService { } } - public async reportWorkspaceStats(workspace: IWorkspace): Promise { + public async reportWorkspaceStats(workspace: IWorkspaceInformation): Promise { workspace.folders.forEach(folder => { const folderUri = URI.revive(folder.uri); if (folderUri.scheme === 'file') { @@ -525,16 +524,19 @@ export class DiagnosticsService implements IDiagnosticsService { count: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true }; }; type WorkspaceStatsClassification = { + 'workspace.id': { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; fileTypes: WorkspaceStatItemClassification; configTypes: WorkspaceStatItemClassification; launchConfigs: WorkspaceStatItemClassification; }; type WorkspaceStatsEvent = { + 'workspace.id': string | undefined; fileTypes: WorkspaceStatItem[]; configTypes: WorkspaceStatItem[]; launchConfigs: WorkspaceStatItem[]; }; this.telemetryService.publicLog2('workspace.stats', { + 'workspace.id': workspace.telemetryId, fileTypes: stats.fileTypes, configTypes: stats.configFiles, launchConfigs: stats.launchConfigFiles @@ -545,4 +547,4 @@ export class DiagnosticsService implements IDiagnosticsService { } }); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/contrib/stats/electron-browser/workspaceStats.ts b/src/vs/workbench/contrib/stats/electron-browser/workspaceStats.ts index 89baf8b21e4..1eac917c60c 100644 --- a/src/vs/workbench/contrib/stats/electron-browser/workspaceStats.ts +++ b/src/vs/workbench/contrib/stats/electron-browser/workspaceStats.ts @@ -15,6 +15,7 @@ import { endsWith } from 'vs/base/common/strings'; import { ITextFileService, } from 'vs/workbench/services/textfile/common/textfiles'; import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; import { IWorkspaceStatsService, Tags } from 'vs/workbench/contrib/stats/electron-browser/workspaceStatsService'; +import { IWorkspaceInformation } from 'vs/platform/diagnostics/common/diagnosticsService'; const SshProtocolMatcher = /^([^@:]+@)?([^:]+):/; const SshUrlMatcher = /^([^@:]+@)?([^:]+):(.+)$/; @@ -175,10 +176,20 @@ export class WorkspaceStats implements IWorkbenchContribution { this.reportProxyStats(); const diagnosticsChannel = this.sharedProcessService.getChannel('diagnostics'); - diagnosticsChannel.call('reportWorkspaceStats', this.contextService.getWorkspace()); + diagnosticsChannel.call('reportWorkspaceStats', this.getWorkspaceInformation()); } - + private getWorkspaceInformation(): IWorkspaceInformation { + const workspace = this.contextService.getWorkspace(); + const state = this.contextService.getWorkbenchState(); + const id = this.workspaceStatsService.getTelemetryWorkspaceId(workspace, state); + return { + id: workspace.id, + telemetryId: id, + folders: workspace.folders, + configuration: workspace.configuration + }; + } private reportWorkspaceTags(tags: Tags): void { /* __GDPR__ diff --git a/src/vs/workbench/contrib/stats/electron-browser/workspaceStatsService.ts b/src/vs/workbench/contrib/stats/electron-browser/workspaceStatsService.ts index 9d0e84928f0..b56c4a821ca 100644 --- a/src/vs/workbench/contrib/stats/electron-browser/workspaceStatsService.ts +++ b/src/vs/workbench/contrib/stats/electron-browser/workspaceStatsService.ts @@ -5,7 +5,7 @@ import * as crypto from 'crypto'; import { IFileService, IResolveFileResult, IFileStat } from 'vs/platform/files/common/files'; -import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceContextService, WorkbenchState, IWorkspace } from 'vs/platform/workspace/common/workspace'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IWindowService, IWindowConfiguration } from 'vs/platform/windows/common/windows'; import { INotificationService, IPromptChoice } from 'vs/platform/notification/common/notification'; @@ -98,6 +98,12 @@ export const IWorkspaceStatsService = createDecorator('w export interface IWorkspaceStatsService { _serviceBrand: any; getTags(): Promise; + + /** + * Returns an id for the workspace, different from the id returned by the context service. A hash based + * on the folder uri or workspace configuration, not time-based, and undefined for empty workspaces. + */ + getTelemetryWorkspaceId(workspace: IWorkspace, state: WorkbenchState): string | undefined; } @@ -124,6 +130,28 @@ export class WorkspaceStatsService implements IWorkspaceStatsService { return this._tags; } + public getTelemetryWorkspaceId(workspace: IWorkspace, state: WorkbenchState): string | undefined { + function createHash(uri: URI): string { + return crypto.createHash('sha1').update(uri.scheme === Schemas.file ? uri.fsPath : uri.toString()).digest('hex'); + } + + let workspaceId: string | undefined; + switch (state) { + case WorkbenchState.EMPTY: + workspaceId = undefined; + break; + case WorkbenchState.FOLDER: + workspaceId = createHash(workspace.folders[0].uri); + break; + case WorkbenchState.WORKSPACE: + if (workspace.configuration) { + workspaceId = createHash(workspace.configuration); + } + } + + return workspaceId; + } + /* __GDPR__FRAGMENT__ "WorkspaceTags" : { "workbench.filesToOpenOrCreate" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, @@ -226,25 +254,7 @@ export class WorkspaceStatsService implements IWorkspaceStatsService { const state = this.contextService.getWorkbenchState(); const workspace = this.contextService.getWorkspace(); - function createHash(uri: URI): string { - return crypto.createHash('sha1').update(uri.scheme === Schemas.file ? uri.fsPath : uri.toString()).digest('hex'); - } - - let workspaceId: string | undefined; - switch (state) { - case WorkbenchState.EMPTY: - workspaceId = undefined; - break; - case WorkbenchState.FOLDER: - workspaceId = createHash(workspace.folders[0].uri); - break; - case WorkbenchState.WORKSPACE: - if (workspace.configuration) { - workspaceId = createHash(workspace.configuration); - } - } - - tags['workspace.id'] = workspaceId; + tags['workspace.id'] = this.getTelemetryWorkspaceId(workspace, state); const { filesToOpenOrCreate, filesToDiff } = configuration; tags['workbench.filesToOpenOrCreate'] = filesToOpenOrCreate && filesToOpenOrCreate.length || 0; From 02702327c1fea8b6c6425b84adb004c41cb84769 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 12 Aug 2019 13:44:07 -0700 Subject: [PATCH 509/861] Make sure webviews are rendered properly with experimental grid layout Fixes #78729 --- .../contrib/webview/electron-browser/webviewElement.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts index 3c030feb235..20daf1ec4bc 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts @@ -566,7 +566,7 @@ export class ElectronWebviewBasedWebview extends Disposable implements Webview { } public layout(): void { - if (!this._webview) { + if (!this._webview || this._webview.style.width === '0px') { return; } const contents = this._webview.getWebContents(); From 36e113e5a63c7d9179db93e259d3667e1e84b0e8 Mon Sep 17 00:00:00 2001 From: mmulet Date: Mon, 12 Aug 2019 15:49:21 -0500 Subject: [PATCH 510/861] Fixed Issue 78731 (#78732) * Fixed Issue 78731 The error handler for OpenLinkOccurrence handled the case of 'invalid' or 'message', but the function returns an error of new Error('invalid') or new Error('missing') instead of 'invalid' or 'missing'. This causes the editor to throw an unhandled exception instead of a warning message. This fix checks for an err.message as well as err for 'invalid' or 'missing' --- src/vs/editor/contrib/links/links.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/links/links.ts b/src/vs/editor/contrib/links/links.ts index 53ea1177390..f9f19e5211c 100644 --- a/src/vs/editor/contrib/links/links.ts +++ b/src/vs/editor/contrib/links/links.ts @@ -299,10 +299,12 @@ class LinkDetector implements editorCommon.IEditorContribution { return this.openerService.open(uri, { openToSide }); }, err => { + const messageOrError = + err instanceof Error ? (err).message : err; // different error cases - if (err === 'invalid') { + if (messageOrError === 'invalid') { this.notificationService.warn(nls.localize('invalid.url', 'Failed to open this link because it is not well-formed: {0}', link.url!.toString())); - } else if (err === 'missing') { + } else if (messageOrError === 'missing') { this.notificationService.warn(nls.localize('missing.url', 'Failed to open this link because its target is missing.')); } else { onUnexpectedError(err); From b6843f92d0428bb182ce858e6dbee1f1ac3f7e2c Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Mon, 12 Aug 2019 13:47:08 -0700 Subject: [PATCH 511/861] re-enable grid layout by default --- src/vs/workbench/browser/workbench.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index 8bd0501679d..22ca16ef487 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -237,7 +237,7 @@ import { isMacintosh, isWindows, isLinux, isWeb } from 'vs/base/common/platform' 'workbench.useExperimentalGridLayout': { 'type': 'boolean', 'description': nls.localize('workbench.useExperimentalGridLayout', "Enables the grid layout for the workbench. This setting may enable additional layout options for workbench components."), - 'default': false, + 'default': true, 'scope': ConfigurationScope.APPLICATION } } From dacf3319f3c660be883987ac72055cc6d57cd564 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 12 Aug 2019 13:56:48 -0700 Subject: [PATCH 512/861] Update vscode-telemetry-extractor (for vscode-ripgrep) --- build/package.json | 2 +- build/yarn.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/build/package.json b/build/package.json index a382150c3f0..75629888620 100644 --- a/build/package.json +++ b/build/package.json @@ -42,7 +42,7 @@ "tslint": "^5.9.1", "typescript": "3.5.2", "vsce": "1.48.0", - "vscode-telemetry-extractor": "1.5.3", + "vscode-telemetry-extractor": "^1.5.4", "xml2js": "^0.4.17" }, "scripts": { diff --git a/build/yarn.lock b/build/yarn.lock index 23ac4d9b84d..7e4f11d8c60 100644 --- a/build/yarn.lock +++ b/build/yarn.lock @@ -2313,19 +2313,19 @@ vsce@1.48.0: yauzl "^2.3.1" yazl "^2.2.2" -vscode-ripgrep@^1.5.5: - version "1.5.5" - resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.5.5.tgz#24c0e9cb356cf889c98e15ecb58f9cf654a1d961" - integrity sha512-OrPrAmcun4+uZAuNcQvE6CCPskh+5AsjANod/Q3zRcJcGNxgoOSGlQN9RPtatkUNmkN8Nn8mZBnS1jMylu/dKg== +vscode-ripgrep@^1.5.6: + version "1.5.6" + resolved "https://registry.yarnpkg.com/vscode-ripgrep/-/vscode-ripgrep-1.5.6.tgz#93bf5c99ca5f8248950a305e224f6ca153c30af4" + integrity sha512-WRIM9XpUj6dsfdAmuI3ANbmT1ysPUVsYy/2uCLDHJa9kbiB4T7uGvFnnc0Rgx2qQnyRAwL7PeWaFgUljPPxf2g== -vscode-telemetry-extractor@1.5.3: - version "1.5.3" - resolved "https://registry.yarnpkg.com/vscode-telemetry-extractor/-/vscode-telemetry-extractor-1.5.3.tgz#c17f9065a47425edafd23ea161e80c23274e009d" - integrity sha512-feioJ1e1KyMa9rzblnLbSOduo+Ny0l62H3/bSDgfgCSnU/km+tTSYxPBvZHVr7iQfQGC95J61yC/ObqS9EbaQg== +vscode-telemetry-extractor@^1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/vscode-telemetry-extractor/-/vscode-telemetry-extractor-1.5.4.tgz#bcb0d17667fa1b77715e3a3bf372ade18f846782" + integrity sha512-MN9LNPo0Rc6cy3sIWTAG97PTWkEKdRnP0VeYoS8vjKSNtG9CAsrUxHgFfYoHm2vNK/ijd0a4NzETyVGO2kT6hw== dependencies: command-line-args "^5.1.1" ts-morph "^3.1.3" - vscode-ripgrep "^1.5.5" + vscode-ripgrep "^1.5.6" vso-node-api@6.1.2-preview: version "6.1.2-preview" From e1025004f6ced93727cadb16fb75547357fce57f Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 12 Aug 2019 14:34:17 -0700 Subject: [PATCH 513/861] Fix #78598 --- .../contrib/preferences/browser/media/settingsEditor2.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css index 43d1569f305..5e8238fde91 100644 --- a/src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css @@ -143,7 +143,7 @@ max-width: 952px; /* 1000 - 24*2 padding */ margin-left: -476px; - z-index: 1000; + z-index: 11; } .settings-editor > .settings-body .settings-tree-container .setting-toolbar-container { @@ -182,7 +182,7 @@ .settings-editor > .settings-body .settings-toc-container { width: 100%; pointer-events: none; - z-index: 100; + z-index: 10; position: absolute; } @@ -511,4 +511,4 @@ .settings-editor.search-mode > .settings-body .settings-toc-container .monaco-list-row .settings-toc-count { display: block; -} \ No newline at end of file +} From 231da466d59b28ecf1415f72f7a25cd264871225 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 12 Aug 2019 14:39:52 -0700 Subject: [PATCH 514/861] Make sure we also persist webview content options Fixes #78203 --- .../contrib/webview/browser/webviewEditorInputFactory.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/webview/browser/webviewEditorInputFactory.ts b/src/vs/workbench/contrib/webview/browser/webviewEditorInputFactory.ts index b5f3ce40819..a8dbabc2c87 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewEditorInputFactory.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewEditorInputFactory.ts @@ -45,7 +45,7 @@ export class WebviewEditorInputFactory implements IEditorInputFactory { const data: SerializedWebview = { viewType: input.viewType, title: input.getName(), - options: input.webview.options, + options: { ...input.webview.options, ...input.webview.contentOptions }, extensionLocation: input.extension ? input.extension.location : undefined, extensionId: input.extension && input.extension.id ? input.extension.id.value : undefined, state: input.webview.state, @@ -118,4 +118,4 @@ function reviveState(state: unknown | undefined): undefined | string { return (state as any).state; } return undefined; -} \ No newline at end of file +} From 525f927adc26a381690d4a65fd6497707f6efe5a Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Mon, 12 Aug 2019 14:48:19 -0700 Subject: [PATCH 515/861] Adjust line height for decorations on block minimap, fixes #78807 --- src/vs/editor/browser/viewParts/minimap/minimap.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/vs/editor/browser/viewParts/minimap/minimap.ts b/src/vs/editor/browser/viewParts/minimap/minimap.ts index c883223ae31..1182f2ee8ab 100644 --- a/src/vs/editor/browser/viewParts/minimap/minimap.ts +++ b/src/vs/editor/browser/viewParts/minimap/minimap.ts @@ -742,10 +742,6 @@ export class Minimap extends ViewPart { canvasContext.clearRect(0, 0, canvasInnerWidth, canvasInnerHeight); - // If the minimap is rendered using blocks, text takes up half the line height - const lineHeightRatio = renderMinimap === RenderMinimap.LargeBlocks || renderMinimap === RenderMinimap.SmallBlocks ? 0.5 : 1; - const height = lineHeight * lineHeightRatio; - // Loop over decorations, ignoring those that don't have the minimap property set and rendering rectangles for each line the decoration spans const lineOffsetMap = new Map(); for (let i = 0; i < decorations.length; i++) { @@ -756,7 +752,7 @@ export class Minimap extends ViewPart { } for (let line = decoration.range.startLineNumber; line <= decoration.range.endLineNumber; line++) { - this.renderDecorationOnLine(canvasContext, lineOffsetMap, decoration, layout, line, height, lineHeight, tabSize, characterWidth); + this.renderDecorationOnLine(canvasContext, lineOffsetMap, decoration, layout, line, lineHeight, lineHeight, tabSize, characterWidth); } } From a726cef3c3e168b1506c7114ea05f563fb7f50e8 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 12 Aug 2019 14:51:36 -0700 Subject: [PATCH 516/861] Check that modules in both the base package.json and remote/ have the same version installed --- build/npm/postinstall.js | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/build/npm/postinstall.js b/build/npm/postinstall.js index cd41092192c..6b1159bc65c 100644 --- a/build/npm/postinstall.js +++ b/build/npm/postinstall.js @@ -78,4 +78,42 @@ const processTreeDts = path.join('node_modules', 'windows-process-tree', 'typing if (fs.existsSync(processTreeDts)) { console.log('Removing windows-process-tree.d.ts'); fs.unlinkSync(processTreeDts); -} \ No newline at end of file +} + +function getInstalledVersion(packageName, cwd) { + const opts = {}; + if (cwd) { + opts.cwd = cwd; + } + + const result = cp.spawnSync(yarn, ['list', '--pattern', packageName], opts); + const stdout = result.stdout.toString(); + const match = stdout.match(new RegExp(packageName + '@(\\S+)')); + if (!match || !match[1]) { + throw new Error('Unexpected output from yarn list: ' + stdout); + } + + return match[1]; +} + +function assertSameVersionsBetweenFolders(packageName, otherFolder) { + const baseVersion = getInstalledVersion(packageName); + const otherVersion = getInstalledVersion(packageName, otherFolder); + + if (baseVersion !== otherVersion) { + throw new Error(`Mismatched versions installed for ${packageName}: root has ${baseVersion}, ./${otherFolder} has ${otherVersion}. These should be the same!`); + } +} + +// Check that modules in both the base package.json and remote/ have the same version installed +const requireSameVersionsInRemote = [ + 'xterm', + 'xterm-addon-search', + 'xterm-addon-web-links', + 'node-pty', + 'vscode-ripgrep' +]; + +requireSameVersionsInRemote.forEach(packageName => { + assertSameVersionsBetweenFolders(packageName, 'remote'); +}); From 41414c2b5f492d1df445c84f9d2d0ae46aa17f43 Mon Sep 17 00:00:00 2001 From: TypeScript Tools Date: Mon, 12 Aug 2019 15:06:41 -0700 Subject: [PATCH 517/861] Strip a path list out of an error message The error, which happens quite frequently, contains an excessively long path list. The message itself was cleaned up in https://github.com/microsoft/TypeScript/pull/32785 but we add some additional filtering to the editor since older server versions are still in use. --- .../src/tsServer/serverError.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/src/tsServer/serverError.ts b/extensions/typescript-language-features/src/tsServer/serverError.ts index cb5cb8035f1..b51ca545bff 100644 --- a/extensions/typescript-language-features/src/tsServer/serverError.ts +++ b/extensions/typescript-language-features/src/tsServer/serverError.ts @@ -40,7 +40,16 @@ export class TypeScriptServerError extends Error { if (errorText) { const errorPrefix = 'Error processing request. '; if (errorText.startsWith(errorPrefix)) { - const prefixFreeErrorText = errorText.substr(errorPrefix.length); + let prefixFreeErrorText = errorText.substr(errorPrefix.length); + + // Prior to https://github.com/microsoft/TypeScript/pull/32785, this error + // returned and excessively long and detailed list of paths. Since server-side + // filtering doesn't have sufficient granularity to drop these specific + // messages, we sanitize them here. + if (prefixFreeErrorText.indexOf('Could not find sourceFile') >= 0) { + prefixFreeErrorText = prefixFreeErrorText.replace(/ in \[[^\]]*\]/g, ''); + } + const newlineIndex = prefixFreeErrorText.indexOf('\n'); if (newlineIndex >= 0) { // Newline expected between message and stack. From 3f5eee78bce05490546988d6eb7a68e95247bf05 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 12 Aug 2019 15:06:22 -0700 Subject: [PATCH 518/861] Inline renderBody --- .../electron-browser/releaseNotesEditor.ts | 32 +++++++------------ 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/vs/workbench/contrib/update/electron-browser/releaseNotesEditor.ts b/src/vs/workbench/contrib/update/electron-browser/releaseNotesEditor.ts index 65d12c80877..b91e684cfda 100644 --- a/src/vs/workbench/contrib/update/electron-browser/releaseNotesEditor.ts +++ b/src/vs/workbench/contrib/update/electron-browser/releaseNotesEditor.ts @@ -28,24 +28,6 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { generateUuid } from 'vs/base/common/uuid'; -function renderBody( - body: string, - css: string -): string { - const styleSheetPath = require.toUrl('./media/markdown.css').replace('file://', 'vscode-resource://'); - return ` - - - - - - - - - ${body} - `; -} - export class ReleaseNotesManager { private readonly _releaseNotesCache = new Map>(); @@ -188,8 +170,18 @@ export class ReleaseNotesManager { const content = await this.renderContent(text); const colorMap = TokenizationRegistry.getColorMap(); const css = colorMap ? generateTokensCSSForColorMap(colorMap) : ''; - const body = renderBody(content, css); - return body; + const styleSheetPath = require.toUrl('./media/markdown.css').replace('file://', 'vscode-resource://'); + return ` + + + + + + + + + ${content} + `; } private async renderContent(text: string): Promise { From d8d1e872427ed7e3da62e52c4c8127267a6f428c Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 12 Aug 2019 15:08:34 -0700 Subject: [PATCH 519/861] Inline renderBody --- .../extensions/browser/extensionEditor.ts | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index d29d891120b..810bc187d7c 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -54,22 +54,6 @@ import { URI } from 'vs/base/common/uri'; import { IWebviewService, Webview } from 'vs/workbench/contrib/webview/common/webview'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; -function renderBody(body: string): string { - const styleSheetPath = require.toUrl('./media/markdown.css').replace('file://', 'vscode-resource://'); - return ` - - - - - - - - - ${body} - - `; -} - function removeEmbeddedSVGs(documentContent: string): string { const newDocument = new DOMParser().parseFromString(documentContent, 'text/html'); @@ -550,7 +534,7 @@ export class ExtensionEditor extends BaseEditor { private openMarkdown(cacheResult: CacheResult, noContentCopy: string): Promise { return this.loadContents(() => cacheResult) .then(marked.parse) - .then(renderBody) + .then(content => this.renderBody(content)) .then(removeEmbeddedSVGs) .then(body => { const webviewElement = this.webviewService.createWebview('extensionEditor', @@ -588,6 +572,22 @@ export class ExtensionEditor extends BaseEditor { }); } + private renderBody(body: string): string { + const styleSheetPath = require.toUrl('./media/markdown.css').replace('file://', 'vscode-resource://'); + return ` + + + + + + + + + ${body} + + `; + } + private openReadme(): Promise { return this.openMarkdown(this.extensionReadme!.get(), localize('noReadme', "No README available.")); } From 52dcb723a39ae75bee1bd56b3312d7fcdc87aeed Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 12 Aug 2019 15:32:21 -0700 Subject: [PATCH 520/861] Inline the markdown css for release notes Don't depend as much on vscode-resource --- .../extensions/browser/extensionEditor.ts | 187 +++++++++++++++++- .../extensions/browser/media/markdown.css | 175 ---------------- .../contrib/webview/browser/pre/index.html | 5 +- 3 files changed, 179 insertions(+), 188 deletions(-) delete mode 100644 src/vs/workbench/contrib/extensions/browser/media/markdown.css diff --git a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index 810bc187d7c..e7cc0836f23 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -50,9 +50,9 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { getDefaultValue } from 'vs/platform/configuration/common/configurationRegistry'; import { isUndefined } from 'vs/base/common/types'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; -import { URI } from 'vs/base/common/uri'; import { IWebviewService, Webview } from 'vs/workbench/contrib/webview/common/webview'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; +import { generateUuid } from 'vs/base/common/uuid'; function removeEmbeddedSVGs(documentContent: string): string { const newDocument = new DOMParser().parseFromString(documentContent, 'text/html'); @@ -180,7 +180,7 @@ export class ExtensionEditor extends BaseEditor { @IStorageService storageService: IStorageService, @IExtensionService private readonly extensionService: IExtensionService, @IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService, - @IWebviewService private readonly webviewService: IWebviewService + @IWebviewService private readonly webviewService: IWebviewService, ) { super(ExtensionEditor.ID, telemetryService, themeService, storageService); this.extensionReadme = null; @@ -543,9 +543,6 @@ export class ExtensionEditor extends BaseEditor { }, { svgWhiteList: this.extensionsWorkbenchService.allowedBadgeProviders, - localResourceRoots: [ - URI.parse(require.toUrl('./media')) - ] }); webviewElement.mountTo(this.content); this.contentDisposables.add(webviewElement.onDidFocus(() => this.fireOnDidFocus())); @@ -572,14 +569,186 @@ export class ExtensionEditor extends BaseEditor { }); } - private renderBody(body: string): string { - const styleSheetPath = require.toUrl('./media/markdown.css').replace('file://', 'vscode-resource://'); + private async renderBody(body: string): Promise { + const nonce = generateUuid(); return ` - - + + diff --git a/src/vs/workbench/contrib/extensions/browser/media/markdown.css b/src/vs/workbench/contrib/extensions/browser/media/markdown.css deleted file mode 100644 index 521ae95b082..00000000000 --- a/src/vs/workbench/contrib/extensions/browser/media/markdown.css +++ /dev/null @@ -1,175 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -body { - padding: 10px 20px; - line-height: 22px; -} - -img { - max-width: 100%; - max-height: 100%; -} - -a { - text-decoration: none; -} - -a:hover { - text-decoration: underline; -} - -a:focus, -input:focus, -select:focus, -textarea:focus { - outline: 1px solid -webkit-focus-ring-color; - outline-offset: -1px; -} - -hr { - border: 0; - height: 2px; - border-bottom: 2px solid; -} - -h1 { - padding-bottom: 0.3em; - line-height: 1.2; - border-bottom-width: 1px; - border-bottom-style: solid; -} - -h1, h2, h3 { - font-weight: normal; -} - -table { - border-collapse: collapse; -} - -table > thead > tr > th { - text-align: left; - border-bottom: 1px solid; -} - -table > thead > tr > th, -table > thead > tr > td, -table > tbody > tr > th, -table > tbody > tr > td { - padding: 5px 10px; -} - -table > tbody > tr + tr > td { - border-top: 1px solid; -} - -blockquote { - margin: 0 7px 0 5px; - padding: 0 16px 0 10px; - border-left-width: 5px; - border-left-style: solid; -} - -code { - font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback"; - font-size: 14px; - line-height: 19px; -} - -.mac code { - font-size: 12px; - line-height: 18px; -} - -code > div { - padding: 16px; - border-radius: 3px; - overflow: auto; -} - -#scroll-to-top { - position: fixed; - width: 40px; - height: 40px; - right: 25px; - bottom: 25px; - background-color:#444444; - border-radius: 50%; - cursor: pointer; - box-shadow: 1px 1px 1px rgba(0,0,0,.25); - outline: none; - display: flex; - justify-content: center; - align-items: center; -} - -#scroll-to-top:hover { - background-color:#007acc; - box-shadow: 2px 2px 2px rgba(0,0,0,.25); -} - -body.vscode-light #scroll-to-top { - background-color: #949494; -} - -body.vscode-high-contrast #scroll-to-top:hover { - background-color: #007acc; -} - -body.vscode-high-contrast #scroll-to-top { - background-color: black; - border: 2px solid #6fc3df; - box-shadow: none; -} -body.vscode-high-contrast #scroll-to-top:hover { - background-color: #007acc; -} - -#scroll-to-top span.icon::before { - content: ""; - display: block; - /* Chevron up icon */ - background:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE5LjIuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAxNiAxNiIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMTYgMTY7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDojRkZGRkZGO30KCS5zdDF7ZmlsbDpub25lO30KPC9zdHlsZT4KPHRpdGxlPnVwY2hldnJvbjwvdGl0bGU+CjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik04LDUuMWwtNy4zLDcuM0wwLDExLjZsOC04bDgsOGwtMC43LDAuN0w4LDUuMXoiLz4KPHJlY3QgY2xhc3M9InN0MSIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2Ii8+Cjwvc3ZnPgo='); - width: 16px; - height: 16px; -} - -/** Theming */ -.vscode-light code > div { - background-color: rgba(220, 220, 220, 0.4); -} - -.vscode-dark code > div { - background-color: rgba(10, 10, 10, 0.4); -} - -.vscode-high-contrast code > div { - background-color: rgb(0, 0, 0); -} - -.vscode-high-contrast h1 { - border-color: rgb(0, 0, 0); -} - -.vscode-light table > thead > tr > th { - border-color: rgba(0, 0, 0, 0.69); -} - -.vscode-dark table > thead > tr > th { - border-color: rgba(255, 255, 255, 0.69); -} - -.vscode-light h1, -.vscode-light hr, -.vscode-light table > tbody > tr + tr > td { - border-color: rgba(0, 0, 0, 0.18); -} - -.vscode-dark h1, -.vscode-dark hr, -.vscode-dark table > tbody > tr + tr > td { - border-color: rgba(255, 255, 255, 0.18); -} diff --git a/src/vs/workbench/contrib/webview/browser/pre/index.html b/src/vs/workbench/contrib/webview/browser/pre/index.html index ac53ce590e2..e301f5ea90d 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/index.html +++ b/src/vs/workbench/contrib/webview/browser/pre/index.html @@ -3,9 +3,6 @@ - - Virtual Document @@ -16,4 +13,4 @@ - \ No newline at end of file + From b60d3067a29f8cc71b9a5a3a1da5f2203b3d1d7b Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 13 Aug 2019 08:08:45 +0200 Subject: [PATCH 521/861] watermark - fix bad disposable use --- .../contrib/watermark/browser/watermark.ts | 85 +++++++------------ 1 file changed, 33 insertions(+), 52 deletions(-) diff --git a/src/vs/workbench/contrib/watermark/browser/watermark.ts b/src/vs/workbench/contrib/watermark/browser/watermark.ts index 54c9b8620f5..5a1ee63bf03 100644 --- a/src/vs/workbench/contrib/watermark/browser/watermark.ts +++ b/src/vs/workbench/contrib/watermark/browser/watermark.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import 'vs/css!./watermark'; -import { Disposable } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { assign } from 'vs/base/common/objects'; import { isMacintosh, OS } from 'vs/base/common/platform'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; @@ -37,51 +37,17 @@ interface WatermarkEntry { mac?: boolean; } -const showCommands: WatermarkEntry = { - text: nls.localize('watermark.showCommands', "Show All Commands"), - id: ShowAllCommandsAction.ID -}; -const quickOpen: WatermarkEntry = { - text: nls.localize('watermark.quickOpen', "Go to File"), - id: QUICKOPEN_ACTION_ID -}; -const openFileNonMacOnly: WatermarkEntry = { - text: nls.localize('watermark.openFile', "Open File"), - id: OpenFileAction.ID, - mac: false -}; -const openFolderNonMacOnly: WatermarkEntry = { - text: nls.localize('watermark.openFolder', "Open Folder"), - id: OpenFolderAction.ID, - mac: false -}; -const openFileOrFolderMacOnly: WatermarkEntry = { - text: nls.localize('watermark.openFileFolder', "Open File or Folder"), - id: OpenFileFolderAction.ID, - mac: true -}; -const openRecent: WatermarkEntry = { - text: nls.localize('watermark.openRecent', "Open Recent"), - id: 'workbench.action.openRecent' -}; -const newUntitledFile: WatermarkEntry = { - text: nls.localize('watermark.newUntitledFile', "New Untitled File"), - id: GlobalNewUntitledFileAction.ID -}; +const showCommands: WatermarkEntry = { text: nls.localize('watermark.showCommands', "Show All Commands"), id: ShowAllCommandsAction.ID }; +const quickOpen: WatermarkEntry = { text: nls.localize('watermark.quickOpen', "Go to File"), id: QUICKOPEN_ACTION_ID }; +const openFileNonMacOnly: WatermarkEntry = { text: nls.localize('watermark.openFile', "Open File"), id: OpenFileAction.ID, mac: false }; +const openFolderNonMacOnly: WatermarkEntry = { text: nls.localize('watermark.openFolder', "Open Folder"), id: OpenFolderAction.ID, mac: false }; +const openFileOrFolderMacOnly: WatermarkEntry = { text: nls.localize('watermark.openFileFolder', "Open File or Folder"), id: OpenFileFolderAction.ID, mac: true }; +const openRecent: WatermarkEntry = { text: nls.localize('watermark.openRecent', "Open Recent"), id: 'workbench.action.openRecent' }; +const newUntitledFile: WatermarkEntry = { text: nls.localize('watermark.newUntitledFile', "New Untitled File"), id: GlobalNewUntitledFileAction.ID }; const newUntitledFileMacOnly: WatermarkEntry = assign({ mac: true }, newUntitledFile); -const toggleTerminal: WatermarkEntry = { - text: nls.localize({ key: 'watermark.toggleTerminal', comment: ['toggle is a verb here'] }, "Toggle Terminal"), - id: TERMINAL_COMMAND_ID.TOGGLE -}; - -const findInFiles: WatermarkEntry = { - text: nls.localize('watermark.findInFiles', "Find in Files"), - id: FindInFilesActionId -}; -const startDebugging: WatermarkEntry = { - text: nls.localize('watermark.startDebugging', "Start Debugging"), - id: StartAction.ID -}; +const toggleTerminal: WatermarkEntry = { text: nls.localize({ key: 'watermark.toggleTerminal', comment: ['toggle is a verb here'] }, "Toggle Terminal"), id: TERMINAL_COMMAND_ID.TOGGLE }; +const findInFiles: WatermarkEntry = { text: nls.localize('watermark.findInFiles', "Find in Files"), id: FindInFilesActionId }; +const startDebugging: WatermarkEntry = { text: nls.localize('watermark.startDebugging', "Start Debugging"), id: StartAction.ID }; const noFolderEntries = [ showCommands, @@ -103,13 +69,13 @@ const folderEntries = [ const WORKBENCH_TIPS_ENABLED_KEY = 'workbench.tips.enabled'; export class WatermarkContribution extends Disposable implements IWorkbenchContribution { - private watermark: HTMLElement; + private watermarkDisposable = this._register(new DisposableStore()); private enabled: boolean; private workbenchState: WorkbenchState; constructor( - @ILifecycleService lifecycleService: ILifecycleService, + @ILifecycleService private readonly lifecycleService: ILifecycleService, @IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService, @IKeybindingService private readonly keybindingService: IKeybindingService, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, @@ -117,13 +83,20 @@ export class WatermarkContribution extends Disposable implements IWorkbenchContr @IEditorGroupsService private readonly editorGroupsService: IEditorGroupsService ) { super(); - this.workbenchState = contextService.getWorkbenchState(); - lifecycleService.onShutdown(this.dispose, this); + this.workbenchState = contextService.getWorkbenchState(); this.enabled = this.configurationService.getValue(WORKBENCH_TIPS_ENABLED_KEY); + + this.registerListeners(); + if (this.enabled) { this.create(); } + } + + private registerListeners(): void { + this.lifecycleService.onShutdown(this.dispose, this); + this._register(this.configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration(WORKBENCH_TIPS_ENABLED_KEY)) { const enabled = this.configurationService.getValue(WORKBENCH_TIPS_ENABLED_KEY); @@ -137,6 +110,7 @@ export class WatermarkContribution extends Disposable implements IWorkbenchContr } } })); + this._register(this.contextService.onDidChangeWorkbenchState(e => { const previousWorkbenchState = this.workbenchState; this.workbenchState = this.contextService.getWorkbenchState(); @@ -157,6 +131,7 @@ export class WatermarkContribution extends Disposable implements IWorkbenchContr const selected = folder ? folderEntries : noFolderEntries .filter(entry => !('mac' in entry) || entry.mac === isMacintosh) .filter(entry => !!CommandsRegistry.getCommand(entry.id)); + const update = () => { dom.clearNode(box); selected.map(entry => { @@ -169,10 +144,14 @@ export class WatermarkContribution extends Disposable implements IWorkbenchContr dd.innerHTML = keybinding.element.outerHTML; }); }; + update(); + dom.prepend(container.firstElementChild as HTMLElement, this.watermark); - this._register(this.keybindingService.onDidUpdateKeybindings(update)); - this._register(this.editorGroupsService.onDidLayout(dimension => this.handleEditorPartSize(container, dimension))); + + this.watermarkDisposable.add(this.keybindingService.onDidUpdateKeybindings(update)); + this.watermarkDisposable.add(this.editorGroupsService.onDidLayout(dimension => this.handleEditorPartSize(container, dimension))); + this.handleEditorPartSize(container, this.editorGroupsService.contentDimension); } @@ -187,9 +166,11 @@ export class WatermarkContribution extends Disposable implements IWorkbenchContr private destroy(): void { if (this.watermark) { this.watermark.remove(); + const container = this.layoutService.getContainer(Parts.EDITOR_PART); container.classList.remove('has-watermark'); - this.dispose(); + + this.watermarkDisposable.clear(); } } From 5a162ad795378cd339535cb5d80f04af471c9974 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 13 Aug 2019 08:15:57 +0200 Subject: [PATCH 522/861] main.ts => desktop.main.ts --- src/vs/code/electron-browser/workbench/workbench.js | 2 +- .../{main.contribution.ts => desktop.contribution.ts} | 0 .../workbench/electron-browser/{main.ts => desktop.main.ts} | 0 src/vs/workbench/workbench.desktop.main.ts | 4 ++-- 4 files changed, 3 insertions(+), 3 deletions(-) rename src/vs/workbench/electron-browser/{main.contribution.ts => desktop.contribution.ts} (100%) rename src/vs/workbench/electron-browser/{main.ts => desktop.main.ts} (100%) diff --git a/src/vs/code/electron-browser/workbench/workbench.js b/src/vs/code/electron-browser/workbench/workbench.js index cdbe49c1b3a..98e67927fe1 100644 --- a/src/vs/code/electron-browser/workbench/workbench.js +++ b/src/vs/code/electron-browser/workbench/workbench.js @@ -27,7 +27,7 @@ bootstrapWindow.load([ perf.mark('main/startup'); // @ts-ignore - return require('vs/workbench/electron-browser/main').main(configuration); + return require('vs/workbench/electron-browser/desktop.main').main(configuration); }); }, { removeDeveloperKeybindingsAfterLoad: true, diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/desktop.contribution.ts similarity index 100% rename from src/vs/workbench/electron-browser/main.contribution.ts rename to src/vs/workbench/electron-browser/desktop.contribution.ts diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/desktop.main.ts similarity index 100% rename from src/vs/workbench/electron-browser/main.ts rename to src/vs/workbench/electron-browser/desktop.main.ts diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index cb1fd2b2a2e..eade62cbe03 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -20,8 +20,8 @@ import 'vs/workbench/workbench.common.main'; //#region --- workbench (desktop main) -import 'vs/workbench/electron-browser/main.contribution'; -import 'vs/workbench/electron-browser/main'; +import 'vs/workbench/electron-browser/desktop.contribution'; +import 'vs/workbench/electron-browser/desktop.main'; //#endregion From ffa22b268f451b5211abbe2d2a47e6b753b55b1a Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 13 Aug 2019 08:19:29 +0200 Subject: [PATCH 523/861] :lipstick: --- src/vs/workbench/browser/parts/editor/editorGroupView.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index bbf73ff14da..dcfc2b8e358 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -798,7 +798,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { //#region openEditor() - openEditor(editor: EditorInput, options?: EditorOptions): Promise { + async openEditor(editor: EditorInput, options?: EditorOptions): Promise { // Guard against invalid inputs if (!editor) { @@ -814,7 +814,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { } // Proceed with opening - return this.doOpenEditor(editor, options).then(withUndefinedAsNull); + return withUndefinedAsNull(await this.doOpenEditor(editor, options)); } private doOpenEditor(editor: EditorInput, options?: EditorOptions): Promise { From 33656944bd7bb91910fce736c5078bc4c3d2944c Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 13 Aug 2019 09:52:33 +0200 Subject: [PATCH 524/861] Update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 71f19c8c72a..a371ab6f684 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "99979734e2234cdb1e7f4988339c5df3fd3aa521", + "distro": "a7dba33608e7866342d550c5cd6ed038bba999b4", "author": { "name": "Microsoft Corporation" }, From 22a3f3ec839960758c76429f13358b0d5db00980 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 13 Aug 2019 09:54:20 +0200 Subject: [PATCH 525/861] :lipstick: --- extensions/git/package.json | 4 ++-- extensions/git/package.nls.json | 2 +- extensions/git/src/git.ts | 7 +++---- extensions/git/src/repository.ts | 6 +++--- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index cac86ec78b0..66b8731c6d9 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1355,14 +1355,14 @@ "default": false, "description": "%config.supportCancellation%" }, - "git.sortOrderForBranch": { + "git.branchSortOrder": { "type": "string", "enum": [ "committerdate", "alphabetically" ], "default": "committerdate", - "description": "%config.sortOrderForBranch%" + "description": "%config.branchSortOrder%" } } }, diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index e2522335098..7d90b4b15f2 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -127,7 +127,7 @@ "config.confirmForcePush": "Controls whether to ask for confirmation before force-pushing.", "config.openDiffOnClick": "Controls whether the diff editor should be opened when clicking a change. Otherwise the regular editor will be opened.", "config.supportCancellation": "Controls whether a notification comes up when running the Sync action, which allows the user to cancel the operation.", - "config.sortOrderForBranch": "Controls the sort order for branches", + "config.branchSortOrder": "Controls the sort order for branches.", "colors.added": "Color for added resources.", "colors.modified": "Color for modified resources.", "colors.deleted": "Color for deleted resources.", diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index bf2e5cd73c6..412cc5df92f 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -1624,12 +1624,11 @@ export class Repository { .map(([ref]) => ({ name: ref, type: RefType.Head } as Branch)); } - async getRefs(sortBranchListByCommitterDate?: Boolean): Promise { + async getRefs(opts?: { sort?: 'alphabetically' | 'committerdate' }): Promise { const args = ['for-each-ref', '--format', '%(refname) %(objectname)']; - if (sortBranchListByCommitterDate) { - args.push('--sort'); - args.push('-committerdate'); + if (opts && opts.sort && opts.sort !== 'alphabetically') { + args.push('--sort', opts.sort); } const result = await this.run(args); diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index e306d051c9c..bf37d036d5c 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -701,7 +701,7 @@ export class Repository implements Disposable { onConfigListener(updateIndexGroupVisibility, this, this.disposables); updateIndexGroupVisibility(); - const onConfigListenerForBranchSortOrder = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.sortOrderForBranch', root)); + const onConfigListenerForBranchSortOrder = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.branchSortOrder', root)); onConfigListenerForBranchSortOrder(this.updateModelState, this, this.disposables); this.mergeGroup.hideWhenEmpty = true; @@ -1408,7 +1408,6 @@ export class Repository implements Disposable { const config = workspace.getConfiguration('git'); const shouldIgnore = config.get('ignoreLimitWarning') === true; const useIcons = !config.get('decorations.enabled', true); - const sortBranchListByCommitterDate = config.get('sortOrderForBranch') === 'committerdate'; this.isRepositoryHuge = didHitLimit; if (didHitLimit && !shouldIgnore && !this.didWarnAboutLimit) { @@ -1458,7 +1457,8 @@ export class Repository implements Disposable { // noop } - const [refs, remotes, submodules, rebaseCommit] = await Promise.all([this.repository.getRefs(sortBranchListByCommitterDate), this.repository.getRemotes(), this.repository.getSubmodules(), this.getRebaseCommit()]); + const sort = config.get<'alphabetically' | 'committerdate'>('branchSortOrder') || 'alphabetically'; + const [refs, remotes, submodules, rebaseCommit] = await Promise.all([this.repository.getRefs({ sort }), this.repository.getRemotes(), this.repository.getSubmodules(), this.getRebaseCommit()]); this._HEAD = HEAD; this._refs = refs; From 22e31cc37e97be7a8a7ac1424d7f1f9546dde823 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 13 Aug 2019 10:31:12 +0200 Subject: [PATCH 526/861] :lipstick: --- .../workbench/contrib/extensions/browser/extensionsViews.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts index 5f905a190e2..ae585737ab7 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts @@ -17,8 +17,8 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView import { append, $, toggleClass } from 'vs/base/browser/dom'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { Delegate, Renderer, IExtensionsViewState } from 'vs/workbench/contrib/extensions/browser/extensionsList'; -import { IExtension, IExtensionsWorkbenchService, ExtensionState } from '../common/extensions'; -import { Query } from '../common/extensionQuery'; +import { IExtension, IExtensionsWorkbenchService, ExtensionState } from 'vs/workbench/contrib/extensions/common/extensions'; +import { Query } from 'vs/workbench/contrib/extensions/common/extensionQuery'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { attachBadgeStyler } from 'vs/platform/theme/common/styler'; From d0c08100fadd3a7e9c692895e292730d0ec9a80d Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 13 Aug 2019 10:42:35 +0200 Subject: [PATCH 527/861] Update C grammars --- extensions/cpp/cgmanifest.json | 4 +- extensions/cpp/syntaxes/cpp.tmLanguage.json | 262 +++++++++++++++++- .../test/colorize-results/test-23630_cpp.json | 18 +- .../test/colorize-results/test-23850_cpp.json | 18 +- .../cpp/test/colorize-results/test_cc.json | 20 +- 5 files changed, 283 insertions(+), 39 deletions(-) diff --git a/extensions/cpp/cgmanifest.json b/extensions/cpp/cgmanifest.json index 8ab81224b2a..b8eb0579838 100644 --- a/extensions/cpp/cgmanifest.json +++ b/extensions/cpp/cgmanifest.json @@ -6,11 +6,11 @@ "git": { "name": "jeff-hykin/cpp-textmate-grammar", "repositoryUrl": "https://github.com/jeff-hykin/cpp-textmate-grammar", - "commitHash": "218448eb46260864352d569db13be6cb20767e92" + "commitHash": "031ef619bef4c5a1ca46e6fa69d7c913e0c32068" } }, "license": "MIT", - "version": "1.12.21", + "version": "1.13.2", "description": "The files syntaxes/c.json and syntaxes/c++.json were derived from https://github.com/atom/language-c which was originally converted from the C TextMate bundle https://github.com/textmate/c.tmbundle." }, { diff --git a/extensions/cpp/syntaxes/cpp.tmLanguage.json b/extensions/cpp/syntaxes/cpp.tmLanguage.json index 963a7c6cc28..4517b91af42 100644 --- a/extensions/cpp/syntaxes/cpp.tmLanguage.json +++ b/extensions/cpp/syntaxes/cpp.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/jeff-hykin/cpp-textmate-grammar/commit/74c2c0eaad8f647e98a188da0f95a64f7239cbe0", + "version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/031ef619bef4c5a1ca46e6fa69d7c913e0c32068", "name": "C++", "scopeName": "source.cpp", "patterns": [ @@ -121,6 +121,250 @@ "match": "(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(#)\\s*pragma\\s+mark)\\s+(.*)", "captures": { @@ -210,7 +454,7 @@ "name": "entity.other.attribute-name.pragma.preprocessor.cpp" }, { - "include": "#number_literal" + "include": "#preprocessor_number_literal" }, { "include": "#line_continuation_character" @@ -417,7 +661,7 @@ "include": "#string_context_c" }, { - "include": "#number_literal" + "include": "#preprocessor_number_literal" }, { "include": "#line_continuation_character" @@ -425,7 +669,7 @@ ] }, "diagnostic": { - "name": "meta.preprocessor.diagnostic.cpp", + "name": "meta.preprocessor.diagnostic.$reference(directive).cpp", "begin": "((?:^)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(#)\\s*((?:error|warning)))\\b\\s*", "beginCaptures": { "1": { @@ -667,13 +911,13 @@ "begin": "\\G\\s*(\\()", "beginCaptures": { "1": { - "name": "punctuation.definition.parameters.begin.cpp" + "name": "punctuation.definition.parameters.begin.preprocessor.cpp" } }, "end": "(\\))", "endCaptures": { "1": { - "name": "punctuation.definition.parameters.end.cpp" + "name": "punctuation.definition.parameters.end.preprocessor.cpp" } }, "patterns": [ @@ -745,7 +989,7 @@ }, "patterns": [ { - "name": "meta.conditional.preprocessor.cpp", + "name": "meta.preprocessor.conditional.cpp", "begin": "\\G(?<=ifndef|ifdef|if)", "end": "(? Date: Tue, 13 Aug 2019 10:49:21 +0200 Subject: [PATCH 528/861] web - fix formatting of paths on windows --- src/vs/workbench/contrib/remote/common/remote.contribution.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/remote/common/remote.contribution.ts b/src/vs/workbench/contrib/remote/common/remote.contribution.ts index 9235c739fb0..f91419b99ca 100644 --- a/src/vs/workbench/contrib/remote/common/remote.contribution.ts +++ b/src/vs/workbench/contrib/remote/common/remote.contribution.ts @@ -36,7 +36,8 @@ export class LabelContribution implements IWorkbenchContribution { formatting: { label: '${path}', separator: remoteEnvironment.os === OperatingSystem.Windows ? '\\' : '/', - tildify: remoteEnvironment.os !== OperatingSystem.Windows + tildify: remoteEnvironment.os !== OperatingSystem.Windows, + normalizeDriveLetter: remoteEnvironment.os === OperatingSystem.Windows } }); } From ca181db1b357969b8efc4df3593adf633145bb36 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 13 Aug 2019 11:09:54 +0200 Subject: [PATCH 529/861] Update documentation in tasks API to say that Global tasks are not currently supported Related to #78817 --- src/vs/vscode.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 38ff2ab34d1..bdef68b2eca 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -5208,7 +5208,7 @@ declare module 'vscode' { */ export enum TaskScope { /** - * The task is a global task + * The task is a global task. Global tasks are currrently not supported. */ Global = 1, @@ -5237,7 +5237,7 @@ declare module 'vscode' { * 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 scope Specifies the task's scope. It is either a global or a workspace task or a task for a specific workspace folder. Global tasks are currently not supported. * @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. From c23b596e7284f70e1b58ab379c64327f236b6ab3 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 13 Aug 2019 10:40:44 +0200 Subject: [PATCH 530/861] :lipstick: --- src/vs/base/browser/ui/grid/grid.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/vs/base/browser/ui/grid/grid.ts b/src/vs/base/browser/ui/grid/grid.ts index a35f9b2cdf4..4586d752d0b 100644 --- a/src/vs/base/browser/ui/grid/grid.ts +++ b/src/vs/base/browser/ui/grid/grid.ts @@ -7,7 +7,7 @@ import 'vs/css!./gridview'; import { Orientation } from 'vs/base/browser/ui/sash/sash'; import { Disposable } from 'vs/base/common/lifecycle'; import { tail2 as tail, equals } from 'vs/base/common/arrays'; -import { orthogonal, IView as IGridViewView, GridView, Sizing as GridViewSizing, Box, IGridViewStyles, IViewSize, ILayoutController, LayoutController } from './gridview'; +import { orthogonal, IView as IGridViewView, GridView, Sizing as GridViewSizing, Box, IGridViewStyles, IViewSize, LayoutController, IGridViewOptions } from './gridview'; import { Event } from 'vs/base/common/event'; import { InvisibleSizing } from 'vs/base/browser/ui/splitview/splitview'; @@ -193,11 +193,8 @@ export namespace Sizing { export interface IGridStyles extends IGridViewStyles { } -export interface IGridOptions { - readonly styles?: IGridStyles; - readonly proportionalLayout?: boolean; +export interface IGridOptions extends IGridViewOptions { readonly firstViewVisibleCachedSize?: number; - readonly layoutController?: ILayoutController; } export class Grid extends Disposable { From 45fec0124c405e29cf39c29abb631056d7f66afa Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 13 Aug 2019 11:33:16 +0200 Subject: [PATCH 531/861] splitview: add orthogonal size grid: combine layout and orthogonalLayout fixes #78173 --- src/vs/base/browser/ui/grid/gridview.ts | 87 +++++++++++-------- src/vs/base/browser/ui/splitview/splitview.ts | 38 ++++---- .../browser/ui/splitview/splitview.test.ts | 33 +++++-- 3 files changed, 99 insertions(+), 59 deletions(-) diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts index 5cefe23c549..38d1131affe 100644 --- a/src/vs/base/browser/ui/grid/gridview.ts +++ b/src/vs/base/browser/ui/grid/gridview.ts @@ -76,6 +76,11 @@ export class LayoutController implements ILayoutController { constructor(public isLayoutEnabled: boolean) { } } +export class MultiplexLayoutController implements ILayoutController { + get isLayoutEnabled(): boolean { return this.layoutControllers.every(l => l.isLayoutEnabled); } + constructor(private layoutControllers: ILayoutController[]) { } +} + export interface IGridViewOptions { readonly styles?: IGridViewStyles; readonly proportionalLayout?: boolean; // default true @@ -170,6 +175,7 @@ class BranchNode implements ISplitView, IDisposable { constructor( readonly orientation: Orientation, + readonly layoutController: ILayoutController, styles: IGridViewStyles, readonly proportionalLayout: boolean, size: number = 0, @@ -181,7 +187,7 @@ class BranchNode implements ISplitView, IDisposable { this.element = $('.monaco-grid-branch-node'); this.splitview = new SplitView(this.element, { orientation, styles, proportionalLayout }); - this.splitview.layout(size); + this.splitview.layout(size, orthogonalSize); const onDidSashReset = Event.map(this.splitview.onDidSashReset, i => [i]); this.splitviewSashResetDisposable = onDidSashReset(this._onDidSashReset.fire, this._onDidSashReset); @@ -198,12 +204,19 @@ class BranchNode implements ISplitView, IDisposable { } } - layout(size: number): void { + layout(size: number, orthogonalSize: number | undefined): void { + if (!this.layoutController.isLayoutEnabled) { + return; + } + + if (typeof orthogonalSize !== 'number') { + throw new Error('Invalid state'); + } + + this._size = orthogonalSize; this._orthogonalSize = size; - for (const child of this.children) { - child.orthogonalLayout(size); - } + this.splitview.layout(orthogonalSize, size); } setVisible(visible: boolean): void { @@ -212,11 +225,6 @@ class BranchNode implements ISplitView, IDisposable { } } - orthogonalLayout(size: number): void { - this._size = size; - this.splitview.layout(size); - } - addChild(node: Node, size: number | Sizing, index: number): void { if (index < 0 || index > this.children.length) { throw new Error('Invalid index'); @@ -539,12 +547,18 @@ class LeafNode implements ISplitView, IDisposable { // noop } - layout(size: number): void { - this._size = size; - - if (this.layoutController.isLayoutEnabled) { - this.view.layout(this.width, this.height, orthogonal(this.orientation)); + layout(size: number, orthogonalSize: number | undefined): void { + if (!this.layoutController.isLayoutEnabled) { + return; } + + if (typeof orthogonalSize !== 'number') { + throw new Error('Invalid state'); + } + + this._size = size; + this._orthogonalSize = orthogonalSize; + this.view.layout(this.width, this.height, orthogonal(this.orientation)); } setVisible(visible: boolean): void { @@ -553,14 +567,6 @@ class LeafNode implements ISplitView, IDisposable { } } - orthogonalLayout(size: number): void { - this._orthogonalSize = size; - - if (this.layoutController.isLayoutEnabled) { - this.view.layout(this.width, this.height, orthogonal(this.orientation)); - } - } - dispose(): void { } } @@ -568,7 +574,7 @@ type Node = BranchNode | LeafNode; function flipNode(node: T, size: number, orthogonalSize: number): T { if (node instanceof BranchNode) { - const result = new BranchNode(orthogonal(node.orientation), node.styles, node.proportionalLayout, size, orthogonalSize); + const result = new BranchNode(orthogonal(node.orientation), node.layoutController, node.styles, node.proportionalLayout, size, orthogonalSize); let totalSize = 0; @@ -589,7 +595,7 @@ function flipNode(node: T, size: number, orthogonalSize: number) return result as T; } else { - return new LeafNode((node as LeafNode).view, orthogonal(node.orientation), (node as LeafNode).layoutController, orthogonalSize) as T; + return new LeafNode((node as LeafNode).view, orthogonal(node.orientation), node.layoutController, orthogonalSize) as T; } } @@ -634,8 +640,9 @@ export class GridView implements IDisposable { const { size, orthogonalSize } = this._root; this.root = flipNode(this._root, orthogonalSize, size); - this.root.layout(size); - this.root.orthogonalLayout(orthogonalSize); + this.root.layout(size, orthogonalSize); + // this.root.layout(size); + // this.root.orthogonalLayout(orthogonalSize); } get width(): number { return this.root.width; } @@ -649,14 +656,25 @@ export class GridView implements IDisposable { private _onDidChange = new Relay(); readonly onDidChange = this._onDidChange.event; + /** + * The first layout controller makes sure layout only propagates + * to the views after the very first call to gridview.layout() + */ + private firstLayoutController: LayoutController; private layoutController: LayoutController; constructor(options: IGridViewOptions = {}) { this.element = $('.monaco-grid-view'); this.styles = options.styles || defaultStyles; this.proportionalLayout = typeof options.proportionalLayout !== 'undefined' ? !!options.proportionalLayout : true; - this.root = new BranchNode(Orientation.VERTICAL, this.styles, this.proportionalLayout); - this.layoutController = options.layoutController || new LayoutController(true); + + this.firstLayoutController = new LayoutController(false); + this.layoutController = new MultiplexLayoutController([ + this.firstLayoutController, + ...(options.layoutController ? [options.layoutController] : []) + ]); + + this.root = new BranchNode(Orientation.VERTICAL, this.layoutController, this.styles, this.proportionalLayout); } style(styles: IGridViewStyles): void { @@ -665,9 +683,10 @@ export class GridView implements IDisposable { } layout(width: number, height: number): void { + this.firstLayoutController.isLayoutEnabled = true; + const [size, orthogonalSize] = this.root.orientation === Orientation.HORIZONTAL ? [height, width] : [width, height]; - this.root.layout(size); - this.root.orthogonalLayout(orthogonalSize); + this.root.layout(size, orthogonalSize); } addView(view: IView, size: number | Sizing, location: number[]): void { @@ -694,9 +713,8 @@ export class GridView implements IDisposable { grandParent.removeChild(parentIndex); - const newParent = new BranchNode(parent.orientation, this.styles, this.proportionalLayout, parent.size, parent.orthogonalSize); + const newParent = new BranchNode(parent.orientation, parent.layoutController, this.styles, this.proportionalLayout, parent.size, parent.orthogonalSize); grandParent.addChild(newParent, parent.size, parentIndex); - newParent.orthogonalLayout(parent.orthogonalSize); const newSibling = new LeafNode(parent.view, grandParent.orientation, this.layoutController, parent.size); newParent.addChild(newSibling, newSiblingSize, 0); @@ -827,9 +845,6 @@ export class GridView implements IDisposable { fromParent.addChild(toNode, fromSize, fromIndex); toParent.addChild(fromNode, toSize, toIndex); - - fromParent.layout(fromParent.orthogonalSize); - toParent.layout(toParent.orthogonalSize); } } diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index 02c583d1e06..b5102c9f9b3 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -24,12 +24,12 @@ const defaultStyles: ISplitViewStyles = { }; export interface ISplitViewOptions { - orientation?: Orientation; // default Orientation.VERTICAL - styles?: ISplitViewStyles; - orthogonalStartSash?: Sash; - orthogonalEndSash?: Sash; - inverseAltBehavior?: boolean; - proportionalLayout?: boolean; // default true + readonly orientation?: Orientation; // default Orientation.VERTICAL + readonly styles?: ISplitViewStyles; + readonly orthogonalStartSash?: Sash; + readonly orthogonalEndSash?: Sash; + readonly inverseAltBehavior?: boolean; + readonly proportionalLayout?: boolean; // default true } /** @@ -48,7 +48,7 @@ export interface IView { readonly onDidChange: Event; readonly priority?: LayoutPriority; readonly snap?: boolean; - layout(size: number, orientation: Orientation): void; + layout(size: number, orthogonalSize: number | undefined): void; setVisible?(visible: boolean): void; } @@ -125,13 +125,13 @@ abstract class ViewItem { dom.addClass(container, 'visible'); } - layout(): void { + layout(_orthogonalSize: number | undefined): void { this.container.scrollTop = 0; this.container.scrollLeft = 0; } - layoutView(orientation: Orientation): void { - this.view.layout(this.size, orientation); + layoutView(orthogonalSize: number | undefined): void { + this.view.layout(this.size, orthogonalSize); } dispose(): IView { @@ -142,19 +142,19 @@ abstract class ViewItem { class VerticalViewItem extends ViewItem { - layout(): void { - super.layout(); + layout(orthogonalSize: number | undefined): void { + super.layout(orthogonalSize); this.container.style.height = `${this.size}px`; - this.layoutView(Orientation.VERTICAL); + this.layoutView(orthogonalSize); } } class HorizontalViewItem extends ViewItem { - layout(): void { - super.layout(); + layout(orthogonalSize: number | undefined): void { + super.layout(orthogonalSize); this.container.style.width = `${this.size}px`; - this.layoutView(Orientation.HORIZONTAL); + this.layoutView(orthogonalSize); } } @@ -205,6 +205,7 @@ export class SplitView extends Disposable { private sashContainer: HTMLElement; private viewContainer: HTMLElement; private size = 0; + private orthogonalSize: number | undefined; private contentSize = 0; private proportions: undefined | number[] = undefined; private viewItems: ViewItem[] = []; @@ -475,9 +476,10 @@ export class SplitView extends Disposable { return viewItem.cachedVisibleSize; } - layout(size: number): void { + layout(size: number, orthogonalSize?: number): void { const previousSize = Math.max(this.size, this.contentSize); this.size = size; + this.orthogonalSize = orthogonalSize; if (!this.proportions) { const indexes = range(this.viewItems.length); @@ -820,7 +822,7 @@ export class SplitView extends Disposable { this.contentSize = this.viewItems.reduce((r, i) => r + i.size, 0); // Layout views - this.viewItems.forEach(item => item.layout()); + this.viewItems.forEach(item => item.layout(this.orthogonalSize)); // Layout sashes this.sashItems.forEach(item => item.sash.layout()); diff --git a/src/vs/base/test/browser/ui/splitview/splitview.test.ts b/src/vs/base/test/browser/ui/splitview/splitview.test.ts index 504e665f21a..c5e9cfce763 100644 --- a/src/vs/base/test/browser/ui/splitview/splitview.test.ts +++ b/src/vs/base/test/browser/ui/splitview/splitview.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import { Emitter } from 'vs/base/common/event'; -import { SplitView, IView, Orientation, Sizing, LayoutPriority } from 'vs/base/browser/ui/splitview/splitview'; +import { SplitView, IView, Sizing, LayoutPriority } from 'vs/base/browser/ui/splitview/splitview'; import { Sash, SashState } from 'vs/base/browser/ui/sash/sash'; class TestView implements IView { @@ -27,7 +27,9 @@ class TestView implements IView { private _size = 0; get size(): number { return this._size; } - private _onDidLayout = new Emitter<{ size: number; orientation: Orientation }>(); + private _orthogonalSize: number | undefined = 0; + get orthogonalSize(): number | undefined { return this._orthogonalSize; } + private _onDidLayout = new Emitter<{ size: number; orthogonalSize: number | undefined }>(); readonly onDidLayout = this._onDidLayout.event; private _onDidFocus = new Emitter(); @@ -41,9 +43,10 @@ class TestView implements IView { assert(_minimumSize <= _maximumSize, 'splitview view minimum size must be <= maximum size'); } - layout(size: number, orientation: Orientation): void { + layout(size: number, orthogonalSize: number | undefined): void { this._size = size; - this._onDidLayout.fire({ size, orientation }); + this._orthogonalSize = orthogonalSize; + this._onDidLayout.fire({ size, orthogonalSize }); } focus(): void { @@ -523,4 +526,24 @@ suite('Splitview', () => { view2.dispose(); view1.dispose(); }); -}); \ No newline at end of file + + test('orthogonal size propagates to 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, LayoutPriority.Low); + const splitview = new SplitView(container, { proportionalLayout: false }); + splitview.layout(200); + + splitview.addView(view1, Sizing.Distribute); + splitview.addView(view2, Sizing.Distribute); + splitview.addView(view3, Sizing.Distribute); + + splitview.layout(200, 100); + assert.deepEqual([view1.orthogonalSize, view2.orthogonalSize, view3.orthogonalSize], [100, 100, 100]); + + splitview.dispose(); + view3.dispose(); + view2.dispose(); + view1.dispose(); + }); +}); From d94bb19d81dcd30da4958d0354c92f329e333e66 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 13 Aug 2019 12:07:53 +0200 Subject: [PATCH 532/861] strictPropertyInitialization in tasks and custom tree view Part of #78168 --- .../api/browser/mainThreadTreeViews.ts | 2 +- .../browser/parts/views/customView.ts | 54 ++++++++++--------- src/vs/workbench/common/views.ts | 2 +- .../tasks/browser/abstractTaskService.ts | 18 +++---- .../tasks/browser/terminalTaskSystem.ts | 25 +++++---- .../contrib/tasks/common/problemCollectors.ts | 16 +++--- .../contrib/tasks/common/problemMatcher.ts | 10 ++-- .../contrib/tasks/common/taskConfiguration.ts | 2 +- .../tasks/common/taskDefinitionRegistry.ts | 2 +- .../workbench/contrib/tasks/common/tasks.ts | 11 ++-- 10 files changed, 77 insertions(+), 65 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTreeViews.ts b/src/vs/workbench/api/browser/mainThreadTreeViews.ts index 2a1e3f5bc5f..79968a69f71 100644 --- a/src/vs/workbench/api/browser/mainThreadTreeViews.ts +++ b/src/vs/workbench/api/browser/mainThreadTreeViews.ts @@ -124,7 +124,7 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie this._dataProviders.forEach((dataProvider, treeViewId) => { const treeView = this.getTreeView(treeViewId); if (treeView) { - treeView.dataProvider = null; + treeView.dataProvider = undefined; } }); this._dataProviders.clear(); diff --git a/src/vs/workbench/browser/parts/views/customView.ts b/src/vs/workbench/browser/parts/views/customView.ts index 1163a294920..6c714028d8f 100644 --- a/src/vs/workbench/browser/parts/views/customView.ts +++ b/src/vs/workbench/browser/parts/views/customView.ts @@ -161,12 +161,12 @@ export class CustomTreeView extends Disposable implements ITreeView { private _showCollapseAllAction = false; private focused: boolean = false; - private domNode: HTMLElement; - private treeContainer: HTMLElement; + private domNode!: HTMLElement; + private treeContainer!: HTMLElement; private _messageValue: string | undefined; - private messageElement: HTMLDivElement; - private tree: WorkbenchAsyncDataTree; - private treeLabels: ResourceLabels; + private messageElement!: HTMLDivElement; + private tree: WorkbenchAsyncDataTree | undefined; + private treeLabels: ResourceLabels | undefined; private root: ITreeItem; private elementsToRefresh: ITreeItem[] = []; private menus: TitleMenus; @@ -218,12 +218,12 @@ export class CustomTreeView extends Disposable implements ITreeView { this.create(); } - private _dataProvider: ITreeViewDataProvider | null; - get dataProvider(): ITreeViewDataProvider | null { + private _dataProvider: ITreeViewDataProvider | undefined; + get dataProvider(): ITreeViewDataProvider | undefined { return this._dataProvider; } - set dataProvider(dataProvider: ITreeViewDataProvider | null) { + set dataProvider(dataProvider: ITreeViewDataProvider | undefined) { if (dataProvider) { this._dataProvider = new class implements ITreeViewDataProvider { async getChildren(node: ITreeItem): Promise { @@ -238,7 +238,7 @@ export class CustomTreeView extends Disposable implements ITreeView { this.updateMessage(); this.refresh(); } else { - this._dataProvider = null; + this._dataProvider = undefined; this.updateMessage(); } } @@ -399,7 +399,7 @@ export class CustomTreeView extends Disposable implements ITreeView { if (!e.browserEvent) { return; } - const selection = this.tree.getSelection(); + const selection = this.tree!.getSelection(); if ((selection.length === 1) && selection[0].command) { this.commandService.executeCommand(selection[0].command.id, ...(selection[0].command.arguments || [])); } @@ -416,7 +416,7 @@ export class CustomTreeView extends Disposable implements ITreeView { event.preventDefault(); event.stopPropagation(); - this.tree.setFocus([node]); + this.tree!.setFocus([node]); const actions = treeMenus.getResourceContextActions(node); if (!actions.length) { return; @@ -436,13 +436,13 @@ export class CustomTreeView extends Disposable implements ITreeView { onHide: (wasCancelled?: boolean) => { if (wasCancelled) { - this.tree.domFocus(); + this.tree!.domFocus(); } }, getActionsContext: () => ({ $treeViewId: this.id, $treeItemHandle: node.handle }), - actionRunner: new MultipleSelectionActionRunner(() => this.tree.getSelection()) + actionRunner: new MultipleSelectionActionRunner(() => this.tree!.getSelection()) }); } @@ -479,8 +479,8 @@ export class CustomTreeView extends Disposable implements ITreeView { DOM.clearNode(this.messageElement); } - private _height: number; - private _width: number; + private _height: number = 0; + private _width: number = 0; layout(height: number, width: number) { if (height && width) { this._height = height; @@ -532,10 +532,11 @@ export class CustomTreeView extends Disposable implements ITreeView { } async expand(itemOrItems: ITreeItem | ITreeItem[]): Promise { - if (this.tree) { + const tree = this.tree; + if (tree) { itemOrItems = Array.isArray(itemOrItems) ? itemOrItems : [itemOrItems]; await Promise.all(itemOrItems.map(element => { - return this.tree.expand(element, false); + return tree.expand(element, false); })); } return Promise.resolve(undefined); @@ -575,18 +576,19 @@ export class CustomTreeView extends Disposable implements ITreeView { private refreshing: boolean = false; private async doRefresh(elements: ITreeItem[]): Promise { - if (this.tree) { + const tree = this.tree; + if (tree) { this.refreshing = true; const parents: Set = new Set(); elements.forEach(element => { if (element !== this.root) { - const parent = this.tree.getParentElement(element); + const parent = tree.getParentElement(element); parents.add(parent); } else { parents.add(element); } }); - await Promise.all(Array.from(parents.values()).map(element => this.tree.updateChildren(element, true))); + await Promise.all(Array.from(parents.values()).map(element => tree.updateChildren(element, true))); this.refreshing = false; this.updateContentAreas(); if (this.focused) { @@ -772,7 +774,7 @@ class TreeRenderer extends Disposable implements ITreeRenderer; + private _tree: WorkbenchAsyncDataTree | undefined; constructor(private themeService: IWorkbenchThemeService) { super(); @@ -790,11 +792,15 @@ class Aligner extends Disposable { return false; } - const parent: ITreeItem = this._tree.getParentElement(treeItem) || this._tree.getInput(); - if (this.hasIcon(parent)) { + if (this._tree) { + const parent: ITreeItem = this._tree.getParentElement(treeItem) || this._tree.getInput(); + if (this.hasIcon(parent)) { + return false; + } + return !!parent.children && parent.children.every(c => c.collapsibleState === TreeItemCollapsibleState.None || !this.hasIcon(c)); + } else { return false; } - return !!parent.children && parent.children.every(c => c.collapsibleState === TreeItemCollapsibleState.None || !this.hasIcon(c)); } private hasIcon(node: ITreeItem): boolean { diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index c9ec1a841f6..fe73a0c0294 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -300,7 +300,7 @@ export interface IViewsService { export interface ITreeView extends IDisposable { - dataProvider: ITreeViewDataProvider | null; + dataProvider: ITreeViewDataProvider | undefined; showCollapseAllAction: boolean; diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 5451b8eb6f4..17e62768740 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -179,10 +179,10 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer private static nextHandle: number = 0; - private _schemaVersion: JsonSchemaVersion; - private _executionEngine: ExecutionEngine; - private _workspaceFolders: IWorkspaceFolder[]; - private _ignoredWorkspaceFolders: IWorkspaceFolder[]; + private _schemaVersion: JsonSchemaVersion | undefined; + private _executionEngine: ExecutionEngine | undefined; + private _workspaceFolders: IWorkspaceFolder[] | undefined; + private _ignoredWorkspaceFolders: IWorkspaceFolder[] | undefined; private _showIgnoreMessage?: boolean; private _providers: Map; private _providerTypes: Map; @@ -192,7 +192,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer protected _taskSystem?: ITaskSystem; protected _taskSystemListener?: IDisposable; - private _recentlyUsedTasks: LinkedMap; + private _recentlyUsedTasks: LinkedMap | undefined; protected _taskRunningState: IContextKey; @@ -375,28 +375,28 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer if (!this._workspaceFolders) { this.updateSetup(); } - return this._workspaceFolders; + return this._workspaceFolders!; } private get ignoredWorkspaceFolders(): IWorkspaceFolder[] { if (!this._ignoredWorkspaceFolders) { this.updateSetup(); } - return this._ignoredWorkspaceFolders; + return this._ignoredWorkspaceFolders!; } protected get executionEngine(): ExecutionEngine { if (this._executionEngine === undefined) { this.updateSetup(); } - return this._executionEngine; + return this._executionEngine!; } private get schemaVersion(): JsonSchemaVersion { if (this._schemaVersion === undefined) { this.updateSetup(); } - return this._schemaVersion; + return this._schemaVersion!; } private get showIgnoreMessage(): boolean { diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index 9d52970cf2c..fb838d2e49e 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -155,9 +155,10 @@ export class TerminalTaskSystem implements ITaskSystem { private idleTaskTerminals: LinkedMap; private sameTaskTerminals: IStringDictionary; private taskSystemInfoResolver: TaskSystemInfoResolver; - private lastTask: VerifiedTask; - private currentTask: VerifiedTask; - private isRerun: boolean; + private lastTask: VerifiedTask | undefined; + // Should always be set in run + private currentTask!: VerifiedTask; + private isRerun: boolean = false; private readonly _onDidStateChange: Emitter; @@ -485,28 +486,32 @@ export class TerminalTaskSystem implements ITaskSystem { } private reexecuteCommand(task: CustomTask | ContributedTask, trigger: string): Promise { - const workspaceFolder = this.currentTask.workspaceFolder = this.lastTask.workspaceFolder; + const lastTask = this.lastTask; + if (!lastTask) { + return Promise.reject(new Error('No task previously run')); + } + const workspaceFolder = this.currentTask.workspaceFolder = lastTask.workspaceFolder; let variables = new Set(); this.collectTaskVariables(variables, task); // Check that the task hasn't changed to include new variables let hasAllVariables = true; variables.forEach(value => { - if (value.substring(2, value.length - 1) in this.lastTask.getVerifiedTask().resolvedVariables) { + if (value.substring(2, value.length - 1) in lastTask.getVerifiedTask().resolvedVariables) { hasAllVariables = false; } }); if (!hasAllVariables) { - return this.resolveVariablesFromSet(this.lastTask.getVerifiedTask().systemInfo, this.lastTask.getVerifiedTask().workspaceFolder, task, variables).then((resolvedVariables) => { + return this.resolveVariablesFromSet(lastTask.getVerifiedTask().systemInfo, lastTask.getVerifiedTask().workspaceFolder, task, variables).then((resolvedVariables) => { this.currentTask.resolvedVariables = resolvedVariables; - return this.executeInTerminal(task, trigger, new VariableResolver(this.lastTask.getVerifiedTask().workspaceFolder, this.lastTask.getVerifiedTask().systemInfo, resolvedVariables.variables, this.configurationResolverService), workspaceFolder!); + return this.executeInTerminal(task, trigger, new VariableResolver(lastTask.getVerifiedTask().workspaceFolder, lastTask.getVerifiedTask().systemInfo, resolvedVariables.variables, this.configurationResolverService), workspaceFolder!); }, reason => { return Promise.reject(reason); }); } else { - this.currentTask.resolvedVariables = this.lastTask.getVerifiedTask().resolvedVariables; - return this.executeInTerminal(task, trigger, new VariableResolver(this.lastTask.getVerifiedTask().workspaceFolder, this.lastTask.getVerifiedTask().systemInfo, this.lastTask.getVerifiedTask().resolvedVariables.variables, this.configurationResolverService), workspaceFolder!); + this.currentTask.resolvedVariables = lastTask.getVerifiedTask().resolvedVariables; + return this.executeInTerminal(task, trigger, new VariableResolver(lastTask.getVerifiedTask().workspaceFolder, lastTask.getVerifiedTask().systemInfo, lastTask.getVerifiedTask().resolvedVariables.variables, this.configurationResolverService), workspaceFolder!); } } @@ -923,7 +928,7 @@ export class TerminalTaskSystem implements ITaskSystem { args = resolvedResult.args; commandExecutable = CommandString.value(command); - this.currentTask.shellLaunchConfig = launchConfigs = this.isRerun ? this.lastTask.getVerifiedTask().shellLaunchConfig : await this.createShellLaunchConfig(task, workspaceFolder, resolver, platform, options, command, args, waitOnExit); + this.currentTask.shellLaunchConfig = launchConfigs = (this.isRerun && this.lastTask) ? this.lastTask.getVerifiedTask().shellLaunchConfig : await this.createShellLaunchConfig(task, workspaceFolder, resolver, platform, options, command, args, waitOnExit); if (launchConfigs === undefined) { return [undefined, undefined, new TaskError(Severity.Error, nls.localize('TerminalTaskSystem', 'Can\'t execute a shell command on an UNC drive using cmd.exe.'), TaskErrors.UnknownError)]; } diff --git a/src/vs/workbench/contrib/tasks/common/problemCollectors.ts b/src/vs/workbench/contrib/tasks/common/problemCollectors.ts index eac610b4d4a..9a4884346b0 100644 --- a/src/vs/workbench/contrib/tasks/common/problemCollectors.ts +++ b/src/vs/workbench/contrib/tasks/common/problemCollectors.ts @@ -44,7 +44,7 @@ export abstract class AbstractProblemCollector implements IDisposable { private bufferLength: number; private openModels: IStringDictionary; private readonly modelListeners = new DisposableStore(); - private tail: Promise; + private tail: Promise | undefined; // [owner] -> ApplyToKind private applyToByOwner: Map; @@ -344,8 +344,8 @@ export const enum ProblemHandlingStrategy { export class StartStopProblemCollector extends AbstractProblemCollector implements IProblemMatcher { private owners: string[]; - private currentOwner: string; - private currentResource: string; + private currentOwner: string | undefined; + private currentResource: string | undefined; constructor(problemMatchers: ProblemMatcher[], markerService: IMarkerService, modelService: IModelService, _strategy: ProblemHandlingStrategy = ProblemHandlingStrategy.Clean, fileService?: IFileService) { super(problemMatchers, markerService, modelService, fileService); @@ -397,8 +397,8 @@ export class WatchingProblemCollector extends AbstractProblemCollector implement private _activeBackgroundMatchers: Set; // Current State - private currentOwner: string | null; - private currentResource: string | null; + private currentOwner: string | undefined; + private currentResource: string | undefined; constructor(problemMatchers: ProblemMatcher[], markerService: IMarkerService, modelService: IModelService, fileService?: IFileService) { super(problemMatchers, markerService, modelService, fileService); @@ -503,8 +503,8 @@ export class WatchingProblemCollector extends AbstractProblemCollector implement private resetCurrentResource(): void { this.reportMarkersForCurrentResource(); - this.currentOwner = null; - this.currentResource = null; + this.currentOwner = undefined; + this.currentResource = undefined; } private reportMarkersForCurrentResource(): void { @@ -512,4 +512,4 @@ export class WatchingProblemCollector extends AbstractProblemCollector implement this.deliverMarkersPerOwnerAndResource(this.currentOwner, this.currentResource); } } -} \ No newline at end of file +} diff --git a/src/vs/workbench/contrib/tasks/common/problemMatcher.ts b/src/vs/workbench/contrib/tasks/common/problemMatcher.ts index 18b98f751f0..ec7c7bcbb96 100644 --- a/src/vs/workbench/contrib/tasks/common/problemMatcher.ts +++ b/src/vs/workbench/contrib/tasks/common/problemMatcher.ts @@ -264,7 +264,7 @@ abstract class AbstractLineMatcher implements ILineMatcher { public abstract get matchLength(): number; - protected fillProblemData(data: ProblemData | null, pattern: ProblemPattern, matches: RegExpExecArray): data is ProblemData { + protected fillProblemData(data: ProblemData | undefined, pattern: ProblemPattern, matches: RegExpExecArray): data is ProblemData { if (data) { this.fillProperty(data, 'file', pattern, matches, true); this.appendProperty(data, 'message', pattern, matches, true); @@ -449,7 +449,7 @@ class SingleLineMatcher extends AbstractLineMatcher { class MultiLineMatcher extends AbstractLineMatcher { private patterns: ProblemPattern[]; - private data: ProblemData | null; + private data: ProblemData | undefined; constructor(matcher: ProblemMatcher, fileService?: IFileService) { super(matcher, fileService); @@ -480,7 +480,7 @@ class MultiLineMatcher extends AbstractLineMatcher { } let loop = !!this.patterns[this.patterns.length - 1].loop; if (!loop) { - this.data = null; + this.data = undefined; } const markerMatch = data ? this.getMarkerMatch(data) : null; return { match: markerMatch ? markerMatch : null, continue: loop }; @@ -491,7 +491,7 @@ class MultiLineMatcher extends AbstractLineMatcher { Assert.ok(pattern.loop === true && this.data !== null); let matches = pattern.regexp.exec(line); if (!matches) { - this.data = null; + this.data = undefined; return null; } let data = Objects.deepClone(this.data); @@ -794,7 +794,7 @@ export namespace Config { fileLocation?: string | string[]; /** - * The name of a predefined problem pattern, the inline definintion + * The name of a predefined problem pattern, the inline definition * of a problem pattern or an array of problem patterns to match * problems spread over multiple lines. */ diff --git a/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts b/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts index 4e856c3b65c..d0e83e2e000 100644 --- a/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts +++ b/src/vs/workbench/contrib/tasks/common/taskConfiguration.ts @@ -681,7 +681,7 @@ export namespace RunOptions { } } -class ParseContext { +interface ParseContext { workspaceFolder: IWorkspaceFolder; problemReporter: IProblemReporter; namedProblemMatchers: IStringDictionary; diff --git a/src/vs/workbench/contrib/tasks/common/taskDefinitionRegistry.ts b/src/vs/workbench/contrib/tasks/common/taskDefinitionRegistry.ts index b52a0229486..6a696c1666a 100644 --- a/src/vs/workbench/contrib/tasks/common/taskDefinitionRegistry.ts +++ b/src/vs/workbench/contrib/tasks/common/taskDefinitionRegistry.ts @@ -89,7 +89,7 @@ class TaskDefinitionRegistryImpl implements ITaskDefinitionRegistry { private taskTypes: IStringDictionary; private readyPromise: Promise; - private _schema: IJSONSchema; + private _schema: IJSONSchema | undefined; constructor() { this.taskTypes = Object.create(null); diff --git a/src/vs/workbench/contrib/tasks/common/tasks.ts b/src/vs/workbench/contrib/tasks/common/tasks.ts index 46593df22be..d1d4cc32eb4 100644 --- a/src/vs/workbench/contrib/tasks/common/tasks.ts +++ b/src/vs/workbench/contrib/tasks/common/tasks.ts @@ -518,7 +518,7 @@ export abstract class CommonTask { /** * The cached label. */ - _label: string; + _label: string = ''; type?: string; @@ -614,7 +614,7 @@ export abstract class CommonTask { export class CustomTask extends CommonTask { - type: '$customized'; // CUSTOMIZED_TASK_TYPE + type!: '$customized'; // CUSTOMIZED_TASK_TYPE /** * Indicated the source of the task (e.g. tasks.json or extension) @@ -626,7 +626,7 @@ export class CustomTask extends CommonTask { /** * The command configuration */ - command: CommandConfiguration; + command: CommandConfiguration = {}; public constructor(id: string, source: WorkspaceTaskSource, label: string, type: string, command: CommandConfiguration | undefined, hasDefinedMatchers: boolean, runOptions: RunOptions, configurationProperties: ConfigurationProperties) { @@ -754,8 +754,9 @@ export class ContributedTask extends CommonTask { /** * Indicated the source of the task (e.g. tasks.json or extension) + * Set in the super constructor */ - _source: ExtensionTaskSource; + _source!: ExtensionTaskSource; defines: KeyedTaskIdentifier; @@ -824,7 +825,7 @@ export class InMemoryTask extends CommonTask { */ _source: InMemoryTaskSource; - type: 'inMemory'; + type!: 'inMemory'; public constructor(id: string, source: InMemoryTaskSource, label: string, type: string, runOptions: RunOptions, configurationProperties: ConfigurationProperties) { From 5d22d7f74c36ef606347f647def0bad73b4877bc Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 13 Aug 2019 11:36:40 +0200 Subject: [PATCH 533/861] create API instance per extension --- .../api/common/extHostExtensionService.ts | 4 +- .../api/worker/extHostExtensionService.ts | 91 ++++++++++++++----- 2 files changed, 69 insertions(+), 26 deletions(-) diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts index 3b59d2d692d..99553033cd2 100644 --- a/src/vs/workbench/api/common/extHostExtensionService.ts +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -384,7 +384,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio try { activationTimesBuilder.activateCallStart(); logService.trace(`ExtensionService#_callActivateOptional ${extensionId.value}`); - const scope = typeof global === 'object' ? global : self; //todo@joh not so nice + const scope = typeof global === 'object' ? global : self; // `global` is nodejs while `self` is for workers const activateResult: Promise = extensionModule.activate.apply(scope, [context]); activationTimesBuilder.activateCallStop(); @@ -525,7 +525,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio } private async _doHandleExtensionTests(): Promise { - const { extensionDevelopmentLocationURI: extensionDevelopmentLocationURI, extensionTestsLocationURI } = this._initData.environment; + const { extensionDevelopmentLocationURI, extensionTestsLocationURI } = this._initData.environment; if (!(extensionDevelopmentLocationURI && extensionTestsLocationURI && extensionTestsLocationURI.scheme === Schemas.file)) { return Promise.resolve(undefined); } diff --git a/src/vs/workbench/api/worker/extHostExtensionService.ts b/src/vs/workbench/api/worker/extHostExtensionService.ts index 30d15e39399..6f7f2b67feb 100644 --- a/src/vs/workbench/api/worker/extHostExtensionService.ts +++ b/src/vs/workbench/api/worker/extHostExtensionService.ts @@ -3,53 +3,96 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { createApiFactoryAndRegisterActors } from 'vs/workbench/api/common/extHost.api.impl'; +import { createApiFactoryAndRegisterActors, IExtensionApiFactory } from 'vs/workbench/api/common/extHost.api.impl'; import { ExtensionActivationTimesBuilder } from 'vs/workbench/api/common/extHostExtensionActivator'; import { AbstractExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; import { endsWith } from 'vs/base/common/strings'; +import { IExtensionDescription, ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration'; +import * as vscode from 'vscode'; +import { TernarySearchTree } from 'vs/base/common/map'; import { nullExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; +import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; + +class ApiInstances { + + private readonly _apiInstances = new Map(); + + constructor( + private readonly _apiFactory: IExtensionApiFactory, + private readonly _extensionPaths: TernarySearchTree, + private readonly _extensionRegistry: ExtensionDescriptionRegistry, + private readonly _configProvider: ExtHostConfigProvider, + ) { + // + } + + get(modulePath: string): typeof vscode { + const extension = this._extensionPaths.findSubstr(modulePath) || nullExtensionDescription; + const id = ExtensionIdentifier.toKey(extension.identifier); + + let apiInstance = this._apiInstances.get(id); + if (!apiInstance) { + apiInstance = this._apiFactory(extension, this._extensionRegistry, this._configProvider); + this._apiInstances.set(id, apiInstance); + } + return apiInstance; + } +} export class ExtHostExtensionService extends AbstractExtHostExtensionService { + private _apiInstances?: ApiInstances; + protected async _beforeAlmostReadyToRunExtensions(): Promise { // initialize API and register actors - const factory = this._instaService.invokeFunction(createApiFactoryAndRegisterActors); - - // globally define the vscode module and share that for all extensions - // todo@joh have an instance per extension, not a shared one.... - const sharedApiInstance = factory(nullExtensionDescription, this._registry, await this._extHostConfiguration.getConfigProvider()); - define('vscode', sharedApiInstance); + const apiFactory = this._instaService.invokeFunction(createApiFactoryAndRegisterActors); + const configProvider = await this._extHostConfiguration.getConfigProvider(); + const extensionPath = await this.getExtensionPathIndex(); + this._apiInstances = new ApiInstances(apiFactory, extensionPath, this._registry, configProvider); } protected _loadCommonJSModule(modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { - // fake commonjs world + + // make sure modulePath ends with `.js` + const suffix = '.js'; + modulePath = endsWith(modulePath, suffix) ? modulePath : modulePath + suffix; + + interface FakeCommonJSSelf { + module?: object; + exports?: object; + require?: (module: string) => any; + window?: object; + __dirname: never; + __filename: never; + } + + // FAKE commonjs world that only collects exports + const patchSelf: FakeCommonJSSelf = self; const module = { exports: {} }; - //@ts-ignore - self['module'] = module; - //@ts-ignore - self['exports'] = module.exports; - // that's improper but might help extensions that aren't author correctly - // @ts-ignore - self['window'] = self; + patchSelf.module = module; + patchSelf.exports = module.exports; + patchSelf.window = self; // <- that's improper but might help extensions that aren't authored correctly + + // FAKE require function that only works for the vscode-module + patchSelf.require = (module: string) => { + if (module !== 'vscode') { + throw new Error(`Cannot load module '${module}'`); + } + return this._apiInstances!.get(modulePath); + }; try { activationTimesBuilder.codeLoadingStart(); - // import the single (!) script, make sure it's a JS-file - const suffix = '.js'; - if (endsWith(modulePath, suffix)) { - importScripts(modulePath); - } else { - importScripts(modulePath + suffix); - } + importScripts(modulePath); } finally { activationTimesBuilder.codeLoadingStop(); } - // return what it exported return Promise.resolve(module.exports as T); } - public async $setRemoteEnvironment(env: { [key: string]: string | null }): Promise { + async $setRemoteEnvironment(env: { [key: string]: string | null }): Promise { throw new Error('Not supported'); } } From 65ab4f871fc92e8782170a3dd87ba539c74fa896 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 13 Aug 2019 12:33:16 +0200 Subject: [PATCH 534/861] #78992 --- src/vs/workbench/contrib/files/browser/fileActions.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/fileActions.ts b/src/vs/workbench/contrib/files/browser/fileActions.ts index 8a2c0fe652f..9d87a9c16b1 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.ts @@ -44,7 +44,7 @@ import { CLOSE_EDITORS_AND_GROUP_COMMAND_ID } from 'vs/workbench/browser/parts/e import { coalesce } from 'vs/base/common/arrays'; import { AsyncDataTree } from 'vs/base/browser/ui/tree/asyncDataTree'; import { ExplorerItem, NewExplorerItem } from 'vs/workbench/contrib/files/common/explorerModel'; -import { onUnexpectedError } from 'vs/base/common/errors'; +import { onUnexpectedError, getErrorMessage } from 'vs/base/common/errors'; export const NEW_FILE_COMMAND_ID = 'explorer.newFile'; export const NEW_FILE_LABEL = nls.localize('newFile', "New File"); @@ -1108,7 +1108,7 @@ export const pasteFileHandler = async (accessor: ServicesAccessor) => { return await fileService.copy(fileToPaste, targetFile); } } catch (e) { - onError(notificationService, new Error(nls.localize('fileDeleted', "File to paste was deleted or moved meanwhile"))); + onError(notificationService, new Error(nls.localize('fileDeleted', "File to paste was deleted or moved meanwhile. {0}", getErrorMessage(e)))); return undefined; } })); From 0c044b6d5d32ae0cc5bb3078e95a8545c5e80288 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 13 Aug 2019 12:50:33 +0200 Subject: [PATCH 535/861] :lipstick: --- src/vs/workbench/workbench.desktop.main.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index eade62cbe03..c2d6ea7a5bc 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -32,7 +32,6 @@ import 'vs/workbench/services/textMate/electron-browser/textMateService'; import 'vs/workbench/services/workspace/electron-browser/workspaceEditingService'; import 'vs/workbench/services/extensions/common/inactiveExtensionUrlHandler'; import 'vs/workbench/services/search/node/searchService'; -import 'vs/workbench/contrib/debug/electron-browser/extensionHostDebugService'; import 'vs/workbench/services/output/node/outputChannelModelService'; import 'vs/workbench/services/textfile/node/textFileService'; import 'vs/workbench/services/dialogs/electron-browser/dialogService'; @@ -48,7 +47,6 @@ import 'vs/workbench/services/configurationResolver/electron-browser/configurati import 'vs/workbench/services/extensionManagement/node/extensionManagementService'; import 'vs/workbench/services/accessibility/node/accessibilityService'; import 'vs/workbench/services/remote/node/tunnelService'; -import 'vs/workbench/contrib/stats/electron-browser/workspaceStatsService'; import 'vs/workbench/services/backup/node/backupFileService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; @@ -104,6 +102,7 @@ import 'vs/workbench/contrib/localizations/browser/localizations.contribution'; import 'vs/workbench/contrib/logs/electron-browser/logs.contribution'; // Stats +import 'vs/workbench/contrib/stats/electron-browser/workspaceStatsService'; import 'vs/workbench/contrib/stats/electron-browser/stats.contribution'; // Rapid Render Splash @@ -111,6 +110,7 @@ import 'vs/workbench/contrib/splash/electron-browser/partsSplash.contribution'; // Debug import 'vs/workbench/contrib/debug/node/debugHelperService'; +import 'vs/workbench/contrib/debug/electron-browser/extensionHostDebugService'; // Webview import 'vs/workbench/contrib/webview/electron-browser/webview.contribution'; From 053fe57597db6e87589a12b45358f982491e6640 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 13 Aug 2019 13:02:00 +0200 Subject: [PATCH 536/861] Watching problem matchers should clear problems on task exit Fixes #78485 --- .../workbench/contrib/tasks/common/problemCollectors.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/tasks/common/problemCollectors.ts b/src/vs/workbench/contrib/tasks/common/problemCollectors.ts index 9a4884346b0..422c2e47e1b 100644 --- a/src/vs/workbench/contrib/tasks/common/problemCollectors.ts +++ b/src/vs/workbench/contrib/tasks/common/problemCollectors.ts @@ -47,7 +47,7 @@ export abstract class AbstractProblemCollector implements IDisposable { private tail: Promise | undefined; // [owner] -> ApplyToKind - private applyToByOwner: Map; + protected applyToByOwner: Map; // [owner] -> [resource] -> URI private resourcesToClean: Map>; // [owner] -> [resource] -> [markerkey] -> markerData @@ -512,4 +512,11 @@ export class WatchingProblemCollector extends AbstractProblemCollector implement this.deliverMarkersPerOwnerAndResource(this.currentOwner, this.currentResource); } } + + public done(): void { + [...this.applyToByOwner.keys()].forEach(owner => { + this.recordResourcesToClean(owner); + }); + super.done(); + } } From aa3a41995a691b9dd18a203e38e719dc5e56edce Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 13 Aug 2019 13:59:37 +0200 Subject: [PATCH 537/861] web - remove .yarnrc file --- remote/web/.yarnrc | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 remote/web/.yarnrc diff --git a/remote/web/.yarnrc b/remote/web/.yarnrc deleted file mode 100644 index b28191e6bae..00000000000 --- a/remote/web/.yarnrc +++ /dev/null @@ -1,3 +0,0 @@ -disturl "http://nodejs.org/dist" -target "10.11.0" -runtime "node" From 9de099ea8c4c3ee1514777e83b204afe52d44e33 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 13 Aug 2019 15:35:12 +0200 Subject: [PATCH 538/861] web - support vscode.env.openExternal Leverage DOM.windowOpenNoOpener() for this purpose. --- src/vs/workbench/browser/web.simpleservices.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index e31a873b221..2dae61b2abf 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -24,7 +24,7 @@ import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common import { ITunnelService } from 'vs/platform/remote/common/tunnel'; // tslint:disable-next-line: import-patterns import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; -import { addDisposableListener, EventType } from 'vs/base/browser/dom'; +import { addDisposableListener, EventType, windowOpenNoOpener } from 'vs/base/browser/dom'; import { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/common/editorService'; import { pathsToEditors } from 'vs/workbench/common/editor'; import { IFileService } from 'vs/platform/files/common/files'; @@ -774,6 +774,8 @@ export class SimpleWindowsService implements IWindowsService { // This needs to be handled from browser process to prevent // foreground ordering issues on Windows openExternal(_url: string): Promise { + windowOpenNoOpener(_url); + return Promise.resolve(true); } From 7c2805ec2ca2548f83748ac687271361d5c15ef4 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 13 Aug 2019 15:42:06 +0200 Subject: [PATCH 539/861] add IllusionMH and gjsjohnmurray for bot commands --- .github/commands.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/commands.yml b/.github/commands.yml index c9279232529..21ebd49ec3c 100644 --- a/.github/commands.yml +++ b/.github/commands.yml @@ -4,7 +4,7 @@ { type: 'comment', name: 'question', - allowUsers: ['cleidigh', 'usernamehw'], + allowUsers: ['cleidigh', 'usernamehw', 'gjsjohnmurray', 'IllusionMH'], action: 'updateLabels', addLabel: '*question' }, @@ -60,7 +60,7 @@ { type: 'comment', name: 'duplicate', - allowUsers: ['cleidigh', 'usernamehw'], + allowUsers: ['cleidigh', 'usernamehw', 'gjsjohnmurray', 'IllusionMH'], action: 'updateLabels', addLabel: '*duplicate' }, @@ -74,7 +74,7 @@ { type: 'comment', name: 'confirm', - allowUsers: ['cleidigh', 'usernamehw'], + allowUsers: ['cleidigh', 'usernamehw', 'gjsjohnmurray', 'IllusionMH'], action: 'updateLabels', addLabel: 'confirmed', removeLabel: 'confirmation-pending' @@ -90,14 +90,14 @@ { type: 'comment', name: 'findDuplicates', - allowUsers: ['cleidigh', 'usernamehw'], + allowUsers: ['cleidigh', 'usernamehw', 'gjsjohnmurray', 'IllusionMH'], action: 'comment', comment: "Potential duplicates:\n${potentialDuplicates}" }, { type: 'comment', name: 'needsMoreInfo', - allowUsers: ['cleidigh', 'usernamehw'], + allowUsers: ['cleidigh', 'usernamehw', 'gjsjohnmurray', 'IllusionMH'], action: 'updateLabels', addLabel: 'needs more info', comment: "Thanks for creating this issue! We figured it's missing some basic information or in some other way doesn't follow our [issue reporting](https://aka.ms/vscodeissuereporting) guidelines. Please take the time to review these and update the issue.\n\nHappy Coding!" From a6d41c14243821d3e36bc8aab196744669795c18 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 13 Aug 2019 11:58:48 +0200 Subject: [PATCH 540/861] doc :lipstick: --- src/vs/base/browser/ui/grid/gridview.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts index 38d1131affe..9b326ffbc2b 100644 --- a/src/vs/base/browser/ui/grid/gridview.ts +++ b/src/vs/base/browser/ui/grid/gridview.ts @@ -213,6 +213,7 @@ class BranchNode implements ISplitView, IDisposable { throw new Error('Invalid state'); } + // branch nodes should flip the normal/orthogonal directions this._size = orthogonalSize; this._orthogonalSize = size; From fc524344ff5df0aff04da3e087c6ee5e06387c83 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 13 Aug 2019 15:22:28 +0200 Subject: [PATCH 541/861] grid test :lipstick: --- src/vs/base/test/browser/ui/grid/grid.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/base/test/browser/ui/grid/grid.test.ts b/src/vs/base/test/browser/ui/grid/grid.test.ts index 25468a06bb9..a201e8b84ef 100644 --- a/src/vs/base/test/browser/ui/grid/grid.test.ts +++ b/src/vs/base/test/browser/ui/grid/grid.test.ts @@ -511,7 +511,8 @@ suite('SerializableGrid', function () { container.appendChild(grid.element); grid.layout(800, 600); - assert.deepEqual(grid.serialize(), { + const actual = grid.serialize(); + assert.deepEqual(actual, { orientation: 0, width: 800, height: 600, From cd6edb7410bfbcb7f9d38ac2bd8464170728353b Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 13 Aug 2019 15:22:39 +0200 Subject: [PATCH 542/861] reduce layout calls related to #77856 --- src/vs/base/browser/ui/grid/gridview.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts index 9b326ffbc2b..fa61ade982e 100644 --- a/src/vs/base/browser/ui/grid/gridview.ts +++ b/src/vs/base/browser/ui/grid/gridview.ts @@ -356,6 +356,10 @@ class BranchNode implements ISplitView, IDisposable { throw new Error('Invalid index'); } + if (this.splitview.isViewVisible(index) === visible) { + return; + } + this.splitview.setViewVisible(index, visible); this._onDidChange.fire(undefined); } From a329c30c3187ced49188aaf7979f606b443ba278 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 13 Aug 2019 15:27:51 +0200 Subject: [PATCH 543/861] :lipstick: --- src/vs/base/browser/ui/grid/gridview.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts index fa61ade982e..934601cf17c 100644 --- a/src/vs/base/browser/ui/grid/gridview.ts +++ b/src/vs/base/browser/ui/grid/gridview.ts @@ -646,8 +646,6 @@ export class GridView implements IDisposable { const { size, orthogonalSize } = this._root; this.root = flipNode(this._root, orthogonalSize, size); this.root.layout(size, orthogonalSize); - // this.root.layout(size); - // this.root.orthogonalLayout(orthogonalSize); } get width(): number { return this.root.width; } From d841937ff9293d082b09fc811da9633c71ee62f0 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 13 Aug 2019 16:17:24 +0200 Subject: [PATCH 544/861] web - delete unused SimpleExtensionManagementService --- .../workbench/browser/web.simpleservices.ts | 60 +------------------ 1 file changed, 1 insertion(+), 59 deletions(-) diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 2dae61b2abf..95d2533c4c6 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -8,9 +8,8 @@ import * as browser from 'vs/base/browser/browser'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { Event } from 'vs/base/common/event'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IGalleryExtension, IExtensionIdentifier, IReportedExtension, IExtensionManagementService, ILocalExtension, IGalleryMetadata } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IExtensionTipsService, ExtensionRecommendationReason, IExtensionRecommendation } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; -import { ExtensionType, ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { IURLHandler, IURLService } from 'vs/platform/url/common/url'; import { ConsoleLogService, ILogService } from 'vs/platform/log/common/log'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; @@ -80,63 +79,6 @@ registerSingleton(IExtensionTipsService, SimpleExtensionTipsService, true); //#endregion -export class SimpleExtensionManagementService implements IExtensionManagementService { - - _serviceBrand: any; - - onInstallExtension = Event.None; - onDidInstallExtension = Event.None; - onUninstallExtension = Event.None; - onDidUninstallExtension = Event.None; - - zip(extension: ILocalExtension): Promise { - // @ts-ignore - return Promise.resolve(undefined); - } - - unzip(zipLocation: URI, type: ExtensionType): Promise { - // @ts-ignore - return Promise.resolve(undefined); - } - - install(vsix: URI): Promise { - // @ts-ignore - return Promise.resolve(undefined); - } - - installFromGallery(extension: IGalleryExtension): Promise { - // @ts-ignore - return Promise.resolve(undefined); - } - - uninstall(extension: ILocalExtension, force?: boolean): Promise { - return Promise.resolve(undefined); - } - - reinstallFromGallery(extension: ILocalExtension): Promise { - return Promise.resolve(undefined); - } - - getInstalled(type?: ExtensionType): Promise { - // @ts-ignore - return Promise.resolve([]); - } - - getExtensionsReport(): Promise { - // @ts-ignore - return Promise.resolve([]); - } - - updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata): Promise { - // @ts-ignore - return Promise.resolve(local); - } -} - -registerSingleton(IExtensionManagementService, SimpleExtensionManagementService); - -//#endregion - //#region Extension URL Handler export const IExtensionUrlHandler = createDecorator('inactiveExtensionUrlHandler'); From 6371cad57381ead9cb744393501ae749f1a8ac40 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Tue, 13 Aug 2019 16:46:00 +0200 Subject: [PATCH 545/861] Work around minifier bug (#79044) --- .../services/extensions/node/proxyResolver.ts | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/services/extensions/node/proxyResolver.ts b/src/vs/workbench/services/extensions/node/proxyResolver.ts index 64c2e0a526e..12a6e3ea66a 100644 --- a/src/vs/workbench/services/extensions/node/proxyResolver.ts +++ b/src/vs/workbench/services/extensions/node/proxyResolver.ts @@ -469,24 +469,26 @@ async function readCaCertificates() { } async function readWindowsCaCertificates() { - const winCA = await import('vscode-windows-ca-certs'); + // Not using await to work around minifier bug (https://github.com/microsoft/vscode/issues/79044). + return import('vscode-windows-ca-certs') + .then(winCA => { + let ders: any[] = []; + const store = winCA(); + try { + let der: any; + while (der = store.next()) { + ders.push(der); + } + } finally { + store.done(); + } - let ders: any[] = []; - const store = winCA(); - try { - let der: any; - while (der = store.next()) { - ders.push(der); - } - } finally { - store.done(); - } - - const certs = new Set(ders.map(derToPem)); - return { - certs: Array.from(certs), - append: true - }; + const certs = new Set(ders.map(derToPem)); + return { + certs: Array.from(certs), + append: true + }; + }); } async function readMacCaCertificates() { From 2da1710b0864bb53eee52752fdb42ce135b12585 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 13 Aug 2019 16:53:11 +0200 Subject: [PATCH 546/861] fixes #77841 --- src/vs/workbench/contrib/debug/browser/callStackView.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/callStackView.ts b/src/vs/workbench/contrib/debug/browser/callStackView.ts index 93a7a5ed2bd..a366a0555e3 100644 --- a/src/vs/workbench/contrib/debug/browser/callStackView.ts +++ b/src/vs/workbench/contrib/debug/browser/callStackView.ts @@ -607,11 +607,9 @@ class CallStackDataSource implements IAsyncDataSourcethreads[0]) : Promise.resolve(threads); } else if (isDebugSession(element)) { const childSessions = this.debugService.getModel().getSessions().filter(s => s.parentSession === element); - if (childSessions.length) { - return Promise.resolve(childSessions); - } + const threads: CallStackItem[] = element.getAllThreads(); - return Promise.resolve(element.getAllThreads()); + return Promise.resolve(threads.concat(childSessions)); } else { return this.getThreadChildren(element); } From 1364caff336a417eb5f3bf728b60cb7ae16437f5 Mon Sep 17 00:00:00 2001 From: gjsjohnmurray Date: Tue, 13 Aug 2019 16:00:32 +0100 Subject: [PATCH 547/861] Fix microsoft/vscode#79047 --- src/vs/workbench/contrib/files/common/explorerService.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vs/workbench/contrib/files/common/explorerService.ts b/src/vs/workbench/contrib/files/common/explorerService.ts index 9d0f177a77a..81967032028 100644 --- a/src/vs/workbench/contrib/files/common/explorerService.ts +++ b/src/vs/workbench/contrib/files/common/explorerService.ts @@ -159,6 +159,12 @@ export class ExplorerService implements IExplorerService { const options: IResolveFileOptions = { resolveTo: [resource], resolveMetadata: this.sortOrder === 'modified' }; const workspaceFolder = this.contextService.getWorkspaceFolder(resource); const rootUri = workspaceFolder ? workspaceFolder.uri : this.roots[0].resource; + + // Do not waste time looking in a different scheme + if (resource.scheme !== rootUri.scheme) { + return Promise.resolve(undefined); + } + const root = this.roots.filter(r => r.resource.toString() === rootUri.toString()).pop()!; try { From a321c9ea3cd2a71ba82a408be816cb3fbef940dd Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 13 Aug 2019 17:43:54 +0200 Subject: [PATCH 548/861] debt - remove unused services from ctor --- src/vs/workbench/contrib/output/browser/outputServices.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/vs/workbench/contrib/output/browser/outputServices.ts b/src/vs/workbench/contrib/output/browser/outputServices.ts index 13d736f2db0..6e7141a041b 100644 --- a/src/vs/workbench/contrib/output/browser/outputServices.ts +++ b/src/vs/workbench/contrib/output/browser/outputServices.ts @@ -14,14 +14,11 @@ import { EditorOptions } from 'vs/workbench/common/editor'; import { IOutputChannelDescriptor, IOutputChannel, IOutputService, Extensions, OUTPUT_PANEL_ID, IOutputChannelRegistry, OUTPUT_SCHEME, LOG_SCHEME, CONTEXT_ACTIVE_LOG_OUTPUT, LOG_MIME, OUTPUT_MIME } from 'vs/workbench/contrib/output/common/output'; import { OutputPanel } from 'vs/workbench/contrib/output/browser/outputPanel'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { OutputLinkProvider } from 'vs/workbench/contrib/output/common/outputLinkProvider'; import { ITextModelService, ITextModelContentProvider } from 'vs/editor/common/services/resolverService'; import { ITextModel } from 'vs/editor/common/model'; import { IPanel } from 'vs/workbench/common/panel'; import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IWindowService } from 'vs/platform/windows/common/windows'; import { ILogService } from 'vs/platform/log/common/log'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; @@ -77,10 +74,7 @@ export class OutputService extends Disposable implements IOutputService, ITextMo @IStorageService private readonly storageService: IStorageService, @IInstantiationService private readonly instantiationService: IInstantiationService, @IPanelService private readonly panelService: IPanelService, - @IWorkspaceContextService contextService: IWorkspaceContextService, @ITextModelService textModelResolverService: ITextModelService, - @IEnvironmentService environmentService: IEnvironmentService, - @IWindowService windowService: IWindowService, @ILogService private readonly logService: ILogService, @ILifecycleService private readonly lifecycleService: ILifecycleService, @IContextKeyService private readonly contextKeyService: IContextKeyService, From bbb1be82bfa933c1777290b376919bc85637723d Mon Sep 17 00:00:00 2001 From: kieferrm Date: Tue, 13 Aug 2019 15:48:26 +0000 Subject: [PATCH 549/861] allow attached-container --- src/vs/platform/telemetry/browser/workbenchCommonProperties.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/telemetry/browser/workbenchCommonProperties.ts b/src/vs/platform/telemetry/browser/workbenchCommonProperties.ts index 3e6c88bd451..582ace32809 100644 --- a/src/vs/platform/telemetry/browser/workbenchCommonProperties.ts +++ b/src/vs/platform/telemetry/browser/workbenchCommonProperties.ts @@ -76,7 +76,7 @@ function cleanRemoteAuthority(remoteAuthority?: string): string { let ret = 'other'; // Whitelisted remote authorities - ['ssh-remote', 'dev-container', 'wsl'].forEach((res: string) => { + ['ssh-remote', 'dev-container', 'attached-container', 'wsl'].forEach((res: string) => { if (remoteAuthority!.indexOf(`${res}+`) === 0) { ret = res; } From fe4729e2e33d3d6bed23c158c128a528a56322b2 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 13 Aug 2019 08:51:00 -0700 Subject: [PATCH 550/861] xterm@3.15.0-beta99 Diff: https://github.com/xtermjs/xterm.js/compare/f3b9dc0...95ff154 Changes: - Fix alt click following links Fixes #78828 --- package.json | 2 +- remote/package.json | 2 +- remote/yarn.lock | 8 ++++---- yarn.lock | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index a371ab6f684..495aaf1e2e4 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "vscode-ripgrep": "^1.5.6", "vscode-sqlite3": "4.0.8", "vscode-textmate": "^4.2.2", - "xterm": "3.15.0-beta98", + "xterm": "3.15.0-beta99", "xterm-addon-search": "0.2.0-beta3", "xterm-addon-web-links": "0.1.0-beta10", "yauzl": "^2.9.2", diff --git a/remote/package.json b/remote/package.json index d3ad3afaed7..ae754c1ae64 100644 --- a/remote/package.json +++ b/remote/package.json @@ -21,7 +21,7 @@ "vscode-proxy-agent": "0.4.0", "vscode-ripgrep": "^1.5.6", "vscode-textmate": "^4.2.2", - "xterm": "3.15.0-beta98", + "xterm": "3.15.0-beta99", "xterm-addon-search": "0.2.0-beta3", "xterm-addon-web-links": "0.1.0-beta10", "yauzl": "^2.9.2", diff --git a/remote/yarn.lock b/remote/yarn.lock index b271a9fd5cc..5d578d3130b 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -1227,10 +1227,10 @@ xterm-addon-web-links@0.1.0-beta10: resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23" integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg== -xterm@3.15.0-beta98: - version "3.15.0-beta98" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta98.tgz#37f37c35577422880e7ef673cc37f9d2a45dd40c" - integrity sha512-vZbg2LcRvoiJOgr1MyeLFM9mF4uib3BWUWDHyFc+vZ58CTuK0iczOvFXgk/ySo23ZLqwmHQSigLgmWvZ8J5G0Q== +xterm@3.15.0-beta99: + version "3.15.0-beta99" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta99.tgz#0010a7ea5d56cbb08a1e3a525b353c96a158e7a0" + integrity sha512-Vm0ZWToWwO4uk/28Kqvqt9L92h5EU2z4WR9I6xcQaPIBmkJPINIARU4LWQnvaOfgFhRbpwBMveTfh8/jM97lPg== yauzl@^2.9.2: version "2.10.0" diff --git a/yarn.lock b/yarn.lock index 62a825ad594..0a6b395f80d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9956,10 +9956,10 @@ xterm-addon-web-links@0.1.0-beta10: resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23" integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg== -xterm@3.15.0-beta98: - version "3.15.0-beta98" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta98.tgz#37f37c35577422880e7ef673cc37f9d2a45dd40c" - integrity sha512-vZbg2LcRvoiJOgr1MyeLFM9mF4uib3BWUWDHyFc+vZ58CTuK0iczOvFXgk/ySo23ZLqwmHQSigLgmWvZ8J5G0Q== +xterm@3.15.0-beta99: + version "3.15.0-beta99" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta99.tgz#0010a7ea5d56cbb08a1e3a525b353c96a158e7a0" + integrity sha512-Vm0ZWToWwO4uk/28Kqvqt9L92h5EU2z4WR9I6xcQaPIBmkJPINIARU4LWQnvaOfgFhRbpwBMveTfh8/jM97lPg== y18n@^3.2.1: version "3.2.1" From 9d34c8207a99242d2cda7050b3121732a21f8ea9 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 13 Aug 2019 08:55:03 -0700 Subject: [PATCH 551/861] Update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 495aaf1e2e4..2ad68c6cc7d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "a7dba33608e7866342d550c5cd6ed038bba999b4", + "distro": "c70929f01c8688bf05a58fc514f649309e9d45a5", "author": { "name": "Microsoft Corporation" }, From ff0d0e3d6655df94a11e038e3afb1c07095b8c34 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 13 Aug 2019 18:06:18 +0200 Subject: [PATCH 552/861] Use heuristic to avoid scrambled duplicate problems in small terminal Fixes #77475 --- src/vs/platform/markers/common/markers.ts | 9 ++++++++- .../workbench/contrib/tasks/common/problemCollectors.ts | 7 ++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/markers/common/markers.ts b/src/vs/platform/markers/common/markers.ts index 235c4b12f36..26d05bc8c2e 100644 --- a/src/vs/platform/markers/common/markers.ts +++ b/src/vs/platform/markers/common/markers.ts @@ -129,6 +129,10 @@ export interface MarkerStatistics { export namespace IMarkerData { const emptyString = ''; export function makeKey(markerData: IMarkerData): string { + return makeKeyOptionalMessage(markerData, true); + } + + export function makeKeyOptionalMessage(markerData: IMarkerData, useMessage: boolean): string { let result: string[] = [emptyString]; if (markerData.source) { result.push(markerData.source.replace('¦', '\¦')); @@ -145,7 +149,10 @@ export namespace IMarkerData { } else { result.push(emptyString); } - if (markerData.message) { + + // Modifed to not include the message as part of the marker key to work around + // https://github.com/microsoft/vscode/issues/77475 + if (markerData.message && useMessage) { result.push(markerData.message.replace('¦', '\¦')); } else { result.push(emptyString); diff --git a/src/vs/workbench/contrib/tasks/common/problemCollectors.ts b/src/vs/workbench/contrib/tasks/common/problemCollectors.ts index 422c2e47e1b..30333ecdc3d 100644 --- a/src/vs/workbench/contrib/tasks/common/problemCollectors.ts +++ b/src/vs/workbench/contrib/tasks/common/problemCollectors.ts @@ -278,9 +278,14 @@ export abstract class AbstractProblemCollector implements IDisposable { markersPerResource = new Map(); markersPerOwner.set(resourceAsString, markersPerResource); } - let key = IMarkerData.makeKey(marker); + let key = IMarkerData.makeKeyOptionalMessage(marker, false); + let existingMarker; if (!markersPerResource.has(key)) { markersPerResource.set(key, marker); + } else if (((existingMarker = markersPerResource.get(key)) !== undefined) && existingMarker.message.length < marker.message.length) { + // Most likely https://github.com/microsoft/vscode/issues/77475 + // Heuristic dictates that when the key is the same and message is smaller, we have hit this limitation. + markersPerResource.set(key, marker); } } From d0ed03f2e6ce71bfa5dcbeb6923ec3256b9d8ecc Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 13 Aug 2019 09:31:09 -0700 Subject: [PATCH 553/861] Move driver enabling behind flag --- src/vs/workbench/browser/web.main.ts | 6 ++++++ src/vs/workbench/workbench.web.api.ts | 5 +++++ src/vs/workbench/workbench.web.main.ts | 4 ---- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index 909f7578e4c..cf8d773184b 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -41,6 +41,7 @@ import { BrowserStorageService } from 'vs/platform/storage/browser/storageServic import { IStorageService } from 'vs/platform/storage/common/storage'; import { getThemeTypeSelector, DARK, HIGH_CONTRAST, LIGHT } from 'vs/platform/theme/common/themeService'; import { InMemoryUserDataProvider } from 'vs/workbench/services/userData/common/inMemoryUserDataProvider'; +import { registerWindowDriver } from 'vs/platform/driver/browser/driver'; class CodeRendererMain extends Disposable { @@ -83,6 +84,11 @@ class CodeRendererMain extends Disposable { })); this._register(workbench.onShutdown(() => this.dispose())); + // Driver + if (this.configuration.driver) { + registerWindowDriver(); + } + // Startup workbench.startup(); } diff --git a/src/vs/workbench/workbench.web.api.ts b/src/vs/workbench/workbench.web.api.ts index bc4b9d1d767..15156252d69 100644 --- a/src/vs/workbench/workbench.web.api.ts +++ b/src/vs/workbench/workbench.web.api.ts @@ -48,6 +48,11 @@ export interface IWorkbenchConstructionOptions { * A factory for web sockets. */ webSocketFactory?: IWebSocketFactory; + + /** + * Experimental: Whether to enable the smoke test driver. + */ + driver?: boolean; } /** diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 5f9a88accf0..1a41fc77ac4 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -54,7 +54,6 @@ import { ContextMenuService } from 'vs/platform/contextview/browser/contextMenuS import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; import { BackupFileService } from 'vs/workbench/services/backup/common/backupFileService'; import { ExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagementService'; -import { registerWindowDriver } from 'vs/platform/driver/browser/driver'; registerSingleton(IRequestService, RequestService, true); registerSingleton(IExtensionManagementService, ExtensionManagementService); @@ -91,6 +90,3 @@ import 'vs/workbench/contrib/terminal/browser/terminalInstanceService'; import 'vs/workbench/contrib/tasks/browser/taskService'; //#endregion - -// TODO: This should only be registered in a particular launch setup -registerWindowDriver(); From e89abca44186a74bc6df2bb29ea9b82839b6cdda Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 13 Aug 2019 09:31:55 -0700 Subject: [PATCH 554/861] Add driver option to IWorkbenchConstructionOptions --- src/vs/workbench/browser/web.main.ts | 5 +++++ src/vs/workbench/workbench.web.api.ts | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index 909f7578e4c..0dd0a93ef46 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -83,6 +83,11 @@ class CodeRendererMain extends Disposable { })); this._register(workbench.onShutdown(() => this.dispose())); + // Driver + if (this.configuration.driver) { + registerWindowDriver(); + } + // Startup workbench.startup(); } diff --git a/src/vs/workbench/workbench.web.api.ts b/src/vs/workbench/workbench.web.api.ts index bc4b9d1d767..15156252d69 100644 --- a/src/vs/workbench/workbench.web.api.ts +++ b/src/vs/workbench/workbench.web.api.ts @@ -48,6 +48,11 @@ export interface IWorkbenchConstructionOptions { * A factory for web sockets. */ webSocketFactory?: IWebSocketFactory; + + /** + * Experimental: Whether to enable the smoke test driver. + */ + driver?: boolean; } /** From 9ee03331e8631e1e569f6ac1250c9e8aaf4c4d8f Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 13 Aug 2019 09:38:08 -0700 Subject: [PATCH 555/861] Update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2ad68c6cc7d..cf5ff6a7afb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "c70929f01c8688bf05a58fc514f649309e9d45a5", + "distro": "6ce1c040c0d555b998dba62dd333f437a7b2d44f", "author": { "name": "Microsoft Corporation" }, From 96be6fd2120a74fcd60b89bce9a1b7fb031dec74 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 13 Aug 2019 09:46:21 -0700 Subject: [PATCH 556/861] Make monaco includes consistent --- src/tsconfig.monaco.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tsconfig.monaco.json b/src/tsconfig.monaco.json index 32983503724..aa0af48b342 100644 --- a/src/tsconfig.monaco.json +++ b/src/tsconfig.monaco.json @@ -14,7 +14,7 @@ }, "include": [ "typings/require.d.ts", - "./typings/require-monaco.d.ts", + "typings/require-monaco.d.ts", "typings/thenable.d.ts", "typings/es6-promise.d.ts", "typings/lib.es2018.promise.d.ts", From 8f1c14f737988c06c30dd83936da488e8a55711d Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 13 Aug 2019 09:48:58 -0700 Subject: [PATCH 557/861] Fix naming of puppeteer driver --- test/smoke/src/vscode/code.ts | 2 +- .../src/vscode/{puppeteer-driver.ts => puppeteerDriver.ts} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename test/smoke/src/vscode/{puppeteer-driver.ts => puppeteerDriver.ts} (100%) diff --git a/test/smoke/src/vscode/code.ts b/test/smoke/src/vscode/code.ts index f381ed002e9..364e44acf3c 100644 --- a/test/smoke/src/vscode/code.ts +++ b/test/smoke/src/vscode/code.ts @@ -10,7 +10,7 @@ import * as fs from 'fs'; import * as mkdirp from 'mkdirp'; import { tmpName } from 'tmp'; import { IDriver, connect as connectElectronDriver, IDisposable, IElement, Thenable } from './driver'; -import { connect as connectPuppeteerDriver, launch } from './puppeteer-driver'; +import { connect as connectPuppeteerDriver, launch } from './puppeteerDriver'; import { Logger } from '../logger'; import { ncp } from 'ncp'; import { URI } from 'vscode-uri'; diff --git a/test/smoke/src/vscode/puppeteer-driver.ts b/test/smoke/src/vscode/puppeteerDriver.ts similarity index 100% rename from test/smoke/src/vscode/puppeteer-driver.ts rename to test/smoke/src/vscode/puppeteerDriver.ts From 933dc05cf986f9c13d72e6c38f49c8bf008df1ed Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 13 Aug 2019 10:21:33 -0700 Subject: [PATCH 558/861] Fix compile --- src/vs/workbench/browser/web.main.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index 0dd0a93ef46..909f7578e4c 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -83,11 +83,6 @@ class CodeRendererMain extends Disposable { })); this._register(workbench.onShutdown(() => this.dispose())); - // Driver - if (this.configuration.driver) { - registerWindowDriver(); - } - // Startup workbench.startup(); } From ca2eb3be062bb5d6f15788667b523557b9f33dae Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 13 Aug 2019 10:33:48 -0700 Subject: [PATCH 559/861] Skip using vscode's encoding for port forwarded uris Fixes https://github.com/microsoft/vscode-remote-release/issues/1132 --- src/vs/workbench/contrib/webview/common/portMapping.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/webview/common/portMapping.ts b/src/vs/workbench/contrib/webview/common/portMapping.ts index 964c0ac6da0..e47390dcf05 100644 --- a/src/vs/workbench/contrib/webview/common/portMapping.ts +++ b/src/vs/workbench/contrib/webview/common/portMapping.ts @@ -47,16 +47,16 @@ export class WebviewPortMappingManager extends Disposable { if (this.extensionLocation && this.extensionLocation.scheme === REMOTE_HOST_SCHEME) { const tunnel = await this.getOrCreateTunnel(mapping.extensionHostPort); if (tunnel) { - return uri.with({ + return encodeURI(uri.with({ authority: `127.0.0.1:${tunnel.tunnelLocalPort}`, - }).toString(); + }).toString(true)); } } if (mapping.webviewPort !== mapping.extensionHostPort) { - return uri.with({ + return encodeURI(uri.with({ authority: `${requestLocalHostInfo.address}:${mapping.extensionHostPort}` - }).toString(); + }).toString(true)); } } } @@ -84,4 +84,4 @@ export class WebviewPortMappingManager extends Disposable { } return tunnel; } -} \ No newline at end of file +} From 16d5e2650f7f7d0e21b5a1c9a4602c354b3ec719 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 13 Aug 2019 19:49:21 +0200 Subject: [PATCH 560/861] grid tests :lipstick: --- src/vs/base/test/browser/ui/grid/grid.test.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/vs/base/test/browser/ui/grid/grid.test.ts b/src/vs/base/test/browser/ui/grid/grid.test.ts index a201e8b84ef..d8dbad25721 100644 --- a/src/vs/base/test/browser/ui/grid/grid.test.ts +++ b/src/vs/base/test/browser/ui/grid/grid.test.ts @@ -9,6 +9,7 @@ import { TestView, nodesToArrays } from './util'; import { deepClone } from 'vs/base/common/objects'; // Simple example: +// // +-----+---------------+ // | 4 | 2 | // +-----+---------+-----+ @@ -16,6 +17,16 @@ import { deepClone } from 'vs/base/common/objects'; // +---------------+ 3 | // | 5 | | // +---------------+-----+ +// +// V +// +-H +// | +-4 +// | +-2 +// +-H +// | +-V +// | +-1 +// | +-5 +// +-3 suite('Grid', function () { let container: HTMLElement; From 064e134c6c931603b0664f8ed758c47992ec1bf6 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 13 Aug 2019 11:19:14 -0700 Subject: [PATCH 561/861] Launch server from tests --- test/smoke/src/vscode/code.ts | 2 +- test/smoke/src/vscode/puppeteerDriver.ts | 29 ++++++++++++++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/test/smoke/src/vscode/code.ts b/test/smoke/src/vscode/code.ts index 364e44acf3c..8a7ffc3d7b1 100644 --- a/test/smoke/src/vscode/code.ts +++ b/test/smoke/src/vscode/code.ts @@ -173,7 +173,7 @@ export async function spawn(options: SpawnOptions): Promise { let connectDriver: typeof connectElectronDriver; if (options.web) { - launch(args); + await launch(args); connectDriver = connectPuppeteerDriver.bind(connectPuppeteerDriver, !!options.headless); } else { const spawnOptions: cp.SpawnOptions = { env }; diff --git a/test/smoke/src/vscode/puppeteerDriver.ts b/test/smoke/src/vscode/puppeteerDriver.ts index 0397c313436..85621a74cbf 100644 --- a/test/smoke/src/vscode/puppeteerDriver.ts +++ b/test/smoke/src/vscode/puppeteerDriver.ts @@ -4,6 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import * as puppeteer from 'puppeteer'; +import { ChildProcess, spawn } from 'child_process'; +import { join } from 'path'; +import { Readable } from 'stream'; const width = 1200; const height = 800; @@ -177,10 +180,23 @@ function timeout(ms: number): Promise { // function runInDriver(call: string, args: (string | boolean)[]): Promise {} let args; +let server: ChildProcess; +let endpoint: string | undefined; -export function launch(_args): void { +export async function launch(_args): Promise { args = _args; - // TODO: Move puppeteer launch here + console.log('launch args', args); + + // TODO: --web-user-data-dir (tmpdir) + server = spawn(join(args[0], '/resources/server/web.sh'), ['--driver', 'web']); + endpoint = await new Promise(r => { + server.stdout.on('data', d => { + const matches = d.toString('ascii').match(/Web UI available at (.+)/); + if (matches !== null) { + r(matches[1]); + } + }); + }); } export function connect(headless: boolean, outPath: string, handle: string): Promise<{ client: IDisposable, driver: IDriver }> { @@ -194,9 +210,14 @@ export function connect(headless: boolean, outPath: string, handle: string): Pro }); const page = (await browser.pages())[0]; await page.setViewport({ width, height }); - await page.goto(`http://127.0.0.1:9888?folder=${args[1]}`); + const endpointSplit = endpoint!.split('#'); + await page.goto(`${endpointSplit[0]}?folder=${args[1]}#${endpointSplit[1]}`); const result = { - client: { dispose: () => { } }, + client: { + dispose: () => { + server.kill(); + } + }, driver: buildDriver(browser, page) }; c(result); From f4deaa16c1e21e275b2a0925e60120d2774844f6 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 13 Aug 2019 11:19:55 -0700 Subject: [PATCH 562/861] Remove unused import --- test/smoke/src/vscode/puppeteerDriver.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/test/smoke/src/vscode/puppeteerDriver.ts b/test/smoke/src/vscode/puppeteerDriver.ts index 85621a74cbf..fe305d7394f 100644 --- a/test/smoke/src/vscode/puppeteerDriver.ts +++ b/test/smoke/src/vscode/puppeteerDriver.ts @@ -6,7 +6,6 @@ import * as puppeteer from 'puppeteer'; import { ChildProcess, spawn } from 'child_process'; import { join } from 'path'; -import { Readable } from 'stream'; const width = 1200; const height = 800; From 68f94dd8b4310301a213f618d077433ce58a0fbf Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 13 Aug 2019 11:28:29 -0700 Subject: [PATCH 563/861] Use temp user data dir --- test/smoke/src/vscode/puppeteerDriver.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/test/smoke/src/vscode/puppeteerDriver.ts b/test/smoke/src/vscode/puppeteerDriver.ts index fe305d7394f..99ea0443e99 100644 --- a/test/smoke/src/vscode/puppeteerDriver.ts +++ b/test/smoke/src/vscode/puppeteerDriver.ts @@ -6,6 +6,9 @@ import * as puppeteer from 'puppeteer'; import { ChildProcess, spawn } from 'child_process'; import { join } from 'path'; +import { tmpdir } from 'os'; +import { mkdir } from 'fs'; +import { promisify } from 'util'; const width = 1200; const height = 800; @@ -184,11 +187,18 @@ let endpoint: string | undefined; export async function launch(_args): Promise { args = _args; - console.log('launch args', args); - // TODO: --web-user-data-dir (tmpdir) - server = spawn(join(args[0], '/resources/server/web.sh'), ['--driver', 'web']); - endpoint = await new Promise(r => { + // TODO: Don't open up the system browser + const webUserDataDir = join(tmpdir(), `smoketest-${Math.random() * 10000000000}`); + await promisify(mkdir)(webUserDataDir); + server = spawn(join(args[0], 'resources/server/web.sh'), ['--driver', 'web', '--web-user-data-dir', webUserDataDir]); + server.stderr.on('data', e => console.log('Server error: ' + e)); + endpoint = await waitForEndpoint(); + await timeout(2000); +} + +function waitForEndpoint(): Promise { + return new Promise(r => { server.stdout.on('data', d => { const matches = d.toString('ascii').match(/Web UI available at (.+)/); if (matches !== null) { From 27f5a327c922d4e68004a84b3f6a9e114eb765de Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 13 Aug 2019 11:34:02 -0700 Subject: [PATCH 564/861] Kill process when process exits --- test/smoke/src/vscode/puppeteerDriver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/smoke/src/vscode/puppeteerDriver.ts b/test/smoke/src/vscode/puppeteerDriver.ts index 99ea0443e99..81b59e3ece6 100644 --- a/test/smoke/src/vscode/puppeteerDriver.ts +++ b/test/smoke/src/vscode/puppeteerDriver.ts @@ -193,8 +193,8 @@ export async function launch(_args): Promise { await promisify(mkdir)(webUserDataDir); server = spawn(join(args[0], 'resources/server/web.sh'), ['--driver', 'web', '--web-user-data-dir', webUserDataDir]); server.stderr.on('data', e => console.log('Server error: ' + e)); + process.on('exit', () => server.kill()); endpoint = await waitForEndpoint(); - await timeout(2000); } function waitForEndpoint(): Promise { From 3db202b4308b9f92e72dfc6f646f3a41ba4483a7 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 13 Aug 2019 11:35:44 -0700 Subject: [PATCH 565/861] Clean up teardown code --- test/smoke/src/vscode/puppeteerDriver.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/test/smoke/src/vscode/puppeteerDriver.ts b/test/smoke/src/vscode/puppeteerDriver.ts index 81b59e3ece6..ee6db8b0e5e 100644 --- a/test/smoke/src/vscode/puppeteerDriver.ts +++ b/test/smoke/src/vscode/puppeteerDriver.ts @@ -182,7 +182,7 @@ function timeout(ms: number): Promise { // function runInDriver(call: string, args: (string | boolean)[]): Promise {} let args; -let server: ChildProcess; +let server: ChildProcess | undefined; let endpoint: string | undefined; export async function launch(_args): Promise { @@ -193,13 +193,20 @@ export async function launch(_args): Promise { await promisify(mkdir)(webUserDataDir); server = spawn(join(args[0], 'resources/server/web.sh'), ['--driver', 'web', '--web-user-data-dir', webUserDataDir]); server.stderr.on('data', e => console.log('Server error: ' + e)); - process.on('exit', () => server.kill()); + process.on('exit', teardown); endpoint = await waitForEndpoint(); } +function teardown(): void { + if (server) { + server.kill(); + server = undefined; + } +} + function waitForEndpoint(): Promise { return new Promise(r => { - server.stdout.on('data', d => { + server!.stdout.on('data', d => { const matches = d.toString('ascii').match(/Web UI available at (.+)/); if (matches !== null) { r(matches[1]); @@ -222,11 +229,7 @@ export function connect(headless: boolean, outPath: string, handle: string): Pro const endpointSplit = endpoint!.split('#'); await page.goto(`${endpointSplit[0]}?folder=${args[1]}#${endpointSplit[1]}`); const result = { - client: { - dispose: () => { - server.kill(); - } - }, + client: { dispose: () => teardown }, driver: buildDriver(browser, page) }; c(result); From d5840463a32164129dcfa94c0ebbbaca0b74c437 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 13 Aug 2019 11:37:26 -0700 Subject: [PATCH 566/861] Improve logging name --- test/smoke/src/vscode/puppeteerDriver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/smoke/src/vscode/puppeteerDriver.ts b/test/smoke/src/vscode/puppeteerDriver.ts index ee6db8b0e5e..7bf04dc0296 100644 --- a/test/smoke/src/vscode/puppeteerDriver.ts +++ b/test/smoke/src/vscode/puppeteerDriver.ts @@ -192,7 +192,7 @@ export async function launch(_args): Promise { const webUserDataDir = join(tmpdir(), `smoketest-${Math.random() * 10000000000}`); await promisify(mkdir)(webUserDataDir); server = spawn(join(args[0], 'resources/server/web.sh'), ['--driver', 'web', '--web-user-data-dir', webUserDataDir]); - server.stderr.on('data', e => console.log('Server error: ' + e)); + server.stderr.on('data', e => console.log('Server stderr: ' + e)); process.on('exit', teardown); endpoint = await waitForEndpoint(); } From 687d759cb6ba1a94f9cc8f09c3db3d3d96b5bc27 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 13 Aug 2019 11:39:17 -0700 Subject: [PATCH 567/861] Try add smoke tests to build --- build/azure-pipelines/web/product-build-web.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/build/azure-pipelines/web/product-build-web.yml b/build/azure-pipelines/web/product-build-web.yml index fe5231dacc1..c36ee9da2d9 100644 --- a/build/azure-pipelines/web/product-build-web.yml +++ b/build/azure-pipelines/web/product-build-web.yml @@ -88,6 +88,14 @@ steps: yarn gulp vscode-web-min-ci displayName: Build +- script: | + set -e + cd test/smoke + yarn compile + cd - + yarn smoketest --web --headless + displayName: Smoke tests + # upload only the workbench.web.api.js source maps because # we just compiled these bits in the previous step and the # general task to upload source maps has already been run From 6059f324dd0a11e9e35cc9bb9e46542c5dbd5fe6 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 13 Aug 2019 11:45:57 -0700 Subject: [PATCH 568/861] Add continueeOnError to smoke tests --- build/azure-pipelines/web/product-build-web.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/build/azure-pipelines/web/product-build-web.yml b/build/azure-pipelines/web/product-build-web.yml index c36ee9da2d9..8dde071b485 100644 --- a/build/azure-pipelines/web/product-build-web.yml +++ b/build/azure-pipelines/web/product-build-web.yml @@ -94,6 +94,7 @@ steps: yarn compile cd - yarn smoketest --web --headless + continueOnError: true displayName: Smoke tests # upload only the workbench.web.api.js source maps because From 4af418a01f50f03b4a6756c045abaa6241e6e0df Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 13 Aug 2019 12:35:22 -0700 Subject: [PATCH 569/861] Use bat on Windows --- test/smoke/src/vscode/puppeteerDriver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/smoke/src/vscode/puppeteerDriver.ts b/test/smoke/src/vscode/puppeteerDriver.ts index 7bf04dc0296..5d7b163b71c 100644 --- a/test/smoke/src/vscode/puppeteerDriver.ts +++ b/test/smoke/src/vscode/puppeteerDriver.ts @@ -191,7 +191,7 @@ export async function launch(_args): Promise { // TODO: Don't open up the system browser const webUserDataDir = join(tmpdir(), `smoketest-${Math.random() * 10000000000}`); await promisify(mkdir)(webUserDataDir); - server = spawn(join(args[0], 'resources/server/web.sh'), ['--driver', 'web', '--web-user-data-dir', webUserDataDir]); + server = spawn(join(args[0], `resources/server/web.${process.platform === 'win32' ? 'bat' : 'sh'}`), ['--driver', 'web', '--web-user-data-dir', webUserDataDir]); server.stderr.on('data', e => console.log('Server stderr: ' + e)); process.on('exit', teardown); endpoint = await waitForEndpoint(); From bb256ef71eda218cc327363d05da014729dd79b0 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 13 Aug 2019 15:08:58 +0200 Subject: [PATCH 570/861] debt: use action bar from the panel view --- .../parts/views/media/panelviewlet.css | 4 ++ .../browser/parts/views/panelViewlet.ts | 4 ++ .../extensions/browser/extensionsViews.ts | 43 +++++++------------ .../extensions/browser/media/extensions.css | 5 --- .../browser/media/extensionsViewlet.css | 15 ++++--- 5 files changed, 33 insertions(+), 38 deletions(-) diff --git a/src/vs/workbench/browser/parts/views/media/panelviewlet.css b/src/vs/workbench/browser/parts/views/media/panelviewlet.css index e1ce2ee1b60..e022f97beb8 100644 --- a/src/vs/workbench/browser/parts/views/media/panelviewlet.css +++ b/src/vs/workbench/browser/parts/views/media/panelviewlet.css @@ -7,6 +7,10 @@ border-top: none !important; /* less clutter: do not show any border for first views in a panel */ } +.monaco-panel-view .panel > .panel-header > .actions.show { + display: initial; +} + .monaco-panel-view .panel > .panel-header h3.title { white-space: nowrap; text-overflow: ellipsis; diff --git a/src/vs/workbench/browser/parts/views/panelViewlet.ts b/src/vs/workbench/browser/parts/views/panelViewlet.ts index ef9dbe0d75f..4a5a2a0cbc3 100644 --- a/src/vs/workbench/browser/parts/views/panelViewlet.ts +++ b/src/vs/workbench/browser/parts/views/panelViewlet.ts @@ -41,6 +41,7 @@ export interface IViewletPanelOptions extends IPanelOptions { actionRunner?: IActionRunner; id: string; title: string; + showActionsAlways?: boolean; } export abstract class ViewletPanel extends Panel implements IView { @@ -67,6 +68,7 @@ export abstract class ViewletPanel extends Panel implements IView { protected actionRunner?: IActionRunner; protected toolbar: ToolBar; + private readonly showActionsAlways: boolean = false; private headerContainer: HTMLElement; private titleContainer: HTMLElement; @@ -82,6 +84,7 @@ export abstract class ViewletPanel extends Panel implements IView { this.id = options.id; this.title = options.title; this.actionRunner = options.actionRunner; + this.showActionsAlways = !!options.showActionsAlways; this.focusedViewContextKey = FocusedViewContext.bindTo(contextKeyService); } @@ -133,6 +136,7 @@ export abstract class ViewletPanel extends Panel implements IView { this.renderHeaderTitle(container, this.title); const actions = append(container, $('.actions')); + toggleClass(actions, 'show', this.showActionsAlways); this.toolbar = new ToolBar(actions, this.contextMenuService, { orientation: ActionsOrientation.HORIZONTAL, actionViewItemProvider: action => this.getActionViewItem(action), diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts index ae585737ab7..51c49a2202b 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts @@ -14,7 +14,7 @@ import { IExtensionManagementServer, IExtensionManagementServerService, IExtensi import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { append, $, toggleClass } from 'vs/base/browser/dom'; +import { append, $, toggleClass, addClass } from 'vs/base/browser/dom'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { Delegate, Renderer, IExtensionsViewState } from 'vs/workbench/contrib/extensions/browser/extensionsList'; import { IExtension, IExtensionsWorkbenchService, ExtensionState } from 'vs/workbench/contrib/extensions/common/extensions'; @@ -27,7 +27,7 @@ import { OpenGlobalSettingsAction } from 'vs/workbench/contrib/preferences/brows import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge'; -import { ActionBar, Separator } from 'vs/base/browser/ui/actionbar/actionbar'; +import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { InstallWorkspaceRecommendedExtensionsAction, ConfigureWorkspaceFolderRecommendedExtensionsAction, ManageExtensionAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { WorkbenchPagedList } from 'vs/platform/list/browser/listService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -103,16 +103,13 @@ export class ExtensionsListView extends ViewletPanel { @IProductService protected readonly productService: IProductService, @IContextKeyService contextKeyService: IContextKeyService, ) { - super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService, contextKeyService); + super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title, showActionsAlways: true }, keybindingService, contextMenuService, configurationService, contextKeyService); this.server = options.server; } protected renderHeader(container: HTMLElement): void { - this.renderHeaderTitle(container); - } - - renderHeaderTitle(container: HTMLElement): void { - super.renderHeaderTitle(container, this.title); + addClass(container, 'extension-view-header'); + super.renderHeader(container); this.badgeContainer = append(container, $('.count-badge-wrapper')); this.badge = new CountBadge(this.badgeContainer); @@ -953,25 +950,15 @@ export class WorkspaceRecommendedExtensionsView extends ExtensionsListView { this._register(this.contextService.onDidChangeWorkbenchState(() => this.update())); } - renderHeader(container: HTMLElement): void { - super.renderHeader(container); + getActions(): IAction[] { + if (!this.installAllAction) { + this.installAllAction = this._register(this.instantiationService.createInstance(InstallWorkspaceRecommendedExtensionsAction, InstallWorkspaceRecommendedExtensionsAction.ID, InstallWorkspaceRecommendedExtensionsAction.LABEL, [])); + this.installAllAction.class = 'octicon octicon-cloud-download'; + } - const listActionBar = $('.list-actionbar-container'); - container.insertBefore(listActionBar, this.badgeContainer); - - const actionbar = this._register(new ActionBar(listActionBar, { - animated: false - })); - actionbar.onDidRun(({ error }) => error && this.notificationService.error(error)); - - this.installAllAction = this._register(this.instantiationService.createInstance(InstallWorkspaceRecommendedExtensionsAction, InstallWorkspaceRecommendedExtensionsAction.ID, InstallWorkspaceRecommendedExtensionsAction.LABEL, [])); const configureWorkspaceFolderAction = this._register(this.instantiationService.createInstance(ConfigureWorkspaceFolderRecommendedExtensionsAction, ConfigureWorkspaceFolderRecommendedExtensionsAction.ID, ConfigureWorkspaceFolderRecommendedExtensionsAction.LABEL)); - - this.installAllAction.class = 'octicon octicon-cloud-download'; configureWorkspaceFolderAction.class = 'octicon octicon-pencil'; - - actionbar.push([this.installAllAction], { icon: true, label: false }); - actionbar.push([configureWorkspaceFolderAction], { icon: true, label: false }); + return [this.installAllAction, configureWorkspaceFolderAction]; } async show(query: string): Promise> { @@ -986,9 +973,11 @@ export class WorkspaceRecommendedExtensionsView extends ExtensionsListView { this.setRecommendationsToInstall(); } - private setRecommendationsToInstall(): Promise { - return this.getRecommendationsToInstall() - .then(recommendations => { this.installAllAction.recommendations = recommendations; }); + private async setRecommendationsToInstall(): Promise { + const recommendations = await this.getRecommendationsToInstall(); + if (this.installAllAction) { + this.installAllAction.recommendations = recommendations; + } } private getRecommendationsToInstall(): Promise { diff --git a/src/vs/workbench/contrib/extensions/browser/media/extensions.css b/src/vs/workbench/contrib/extensions/browser/media/extensions.css index 4a74b3ce38d..ad1858f6f05 100644 --- a/src/vs/workbench/contrib/extensions/browser/media/extensions.css +++ b/src/vs/workbench/contrib/extensions/browser/media/extensions.css @@ -6,8 +6,3 @@ .monaco-workbench .activitybar > .content .monaco-action-bar .action-label.extensions { -webkit-mask: url('extensions-activity-bar.svg') no-repeat 50% 50%; } - -.extensions .split-view-view .panel-header .count-badge-wrapper { - position: absolute; - right: 12px; -} \ No newline at end of file diff --git a/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css b/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css index ede6bff2a64..57be7e4e1d4 100644 --- a/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css +++ b/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css @@ -27,13 +27,16 @@ height: calc(100% - 38px); } -.extensions-viewlet > .extensions .list-actionbar-container .monaco-action-bar .action-item > .octicon { - font-size: 12px; - line-height: 1; - margin-right: 10px; +.extensions-viewlet > .extensions .extension-view-header .monaco-action-bar { + margin-right: 4px; } -.extensions-viewlet > .extensions .list-actionbar-container .monaco-action-bar .action-item.disabled { +.extensions-viewlet > .extensions .extension-view-header .monaco-action-bar .action-item > .action-label.icon.octicon { + vertical-align: middle; + line-height: 22px; +} + +.extensions-viewlet > .extensions .extension-view-header .monaco-action-bar .action-item.disabled { display: none; } @@ -44,7 +47,7 @@ } .extensions-viewlet > .extensions .panel-header { - padding-right: 28px; + padding-right: 6px; } .extensions-viewlet > .extensions .panel-header > .title { From c954a8ab52fd3ecc5379a6c97be0a5552be0780d Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 13 Aug 2019 23:08:25 +0200 Subject: [PATCH 571/861] Fix microsoft/vscode-remote-release/issues/1066 --- .../extensions/browser/extensionsActions.ts | 46 ++++++++++++++----- .../extensions/browser/extensionsViewlet.ts | 4 +- .../extensions/browser/extensionsViews.ts | 13 +++++- .../browser/remoteExtensionsInstaller.ts | 2 +- 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index b598b94ea4b..4b5d6194654 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -3022,7 +3022,10 @@ interface IExtensionPickItem extends IQuickPickItem { export class InstallLocalExtensionsInRemoteAction extends Action { + private extensions: IExtension[] | undefined = undefined; + constructor( + private readonly selectAndInstall: boolean, @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService, @IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService, @IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService, @@ -3034,7 +3037,12 @@ export class InstallLocalExtensionsInRemoteAction extends Action { ) { super('workbench.extensions.actions.installLocalExtensionsInRemote'); this.update(); - this._register(this.extensionsWorkbenchService.onChange(() => this.update())); + this.extensionsWorkbenchService.queryLocal().then(() => this.updateExtensions()); + this._register(this.extensionsWorkbenchService.onChange(() => { + if (this.extensions) { + this.updateExtensions(); + } + })); } get label(): string { @@ -3042,24 +3050,38 @@ export class InstallLocalExtensionsInRemoteAction extends Action { localize('install local extensions', "Install Local Extensions in {0}...", this.extensionManagementServerService.remoteExtensionManagementServer.label) : ''; } - private update(): void { - this.enabled = this.getLocalExtensionsToInstall().length > 0; + private updateExtensions(): void { + this.extensions = this.extensionsWorkbenchService.local; + this.update(); } - private getLocalExtensionsToInstall(): IExtension[] { - return this.extensionsWorkbenchService.local.filter(extension => { + private update(): void { + this.enabled = !!this.extensions && this.getExtensionsToInstall(this.extensions).length > 0; + } + + async run(): Promise { + if (this.selectAndInstall) { + return this.selectAndInstallLocalExtensions(); + } else { + const extensionsToInstall = await this.queryExtensionsToInstall(); + return this.installLocalExtensions(extensionsToInstall); + } + } + + private async queryExtensionsToInstall(): Promise { + const local = await this.extensionsWorkbenchService.queryLocal(); + return this.getExtensionsToInstall(local); + } + + private getExtensionsToInstall(local: IExtension[]): IExtension[] { + return local.filter(extension => { const action = this.instantiationService.createInstance(RemoteInstallAction); action.extension = extension; return action.enabled; }); } - async run(): Promise { - this.selectAndInstallLocalExtensions(); - return Promise.resolve(); - } - - private selectAndInstallLocalExtensions(): void { + private async selectAndInstallLocalExtensions(): Promise { const quickPick = this.quickInputService.createQuickPick(); quickPick.busy = true; const disposable = quickPick.onDidAccept(() => { @@ -3069,7 +3091,7 @@ export class InstallLocalExtensionsInRemoteAction extends Action { this.onDidAccept(quickPick.selectedItems); }); quickPick.show(); - const localExtensionsToInstall = this.getLocalExtensionsToInstall(); + const localExtensionsToInstall = await this.queryExtensionsToInstall(); quickPick.busy = false; if (localExtensionsToInstall.length) { quickPick.title = localize('install local extensions title', "Install Local Extensions in {0}", this.extensionManagementServerService.remoteExtensionManagementServer!.label); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts index 50e67a2a888..8396d202e4f 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts @@ -22,7 +22,7 @@ import { IExtensionsWorkbenchService, IExtensionsViewlet, VIEWLET_ID, AutoUpdate import { ShowEnabledExtensionsAction, ShowInstalledExtensionsAction, ShowRecommendedExtensionsAction, ShowPopularExtensionsAction, ShowDisabledExtensionsAction, ShowOutdatedExtensionsAction, ClearExtensionsInputAction, ChangeSortAction, UpdateAllAction, CheckForUpdatesAction, DisableAllAction, EnableAllAction, - EnableAutoUpdateAction, DisableAutoUpdateAction, ShowBuiltInExtensionsAction, InstallVSIXAction, InstallLocalExtensionsInRemoteAction + EnableAutoUpdateAction, DisableAutoUpdateAction, ShowBuiltInExtensionsAction, InstallVSIXAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IExtensionEnablementService, IExtensionManagementServerService, IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; @@ -348,7 +348,6 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio @IInstantiationService instantiationService: IInstantiationService, @IEditorGroupsService private readonly editorGroupService: IEditorGroupsService, @IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService, - @IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService, @INotificationService private readonly notificationService: INotificationService, @IViewletService private readonly viewletService: IViewletService, @IThemeService themeService: IThemeService, @@ -478,7 +477,6 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio this.instantiationService.createInstance(CheckForUpdatesAction, CheckForUpdatesAction.ID, CheckForUpdatesAction.LABEL), ...(this.configurationService.getValue(AutoUpdateConfigurationKey) ? [this.instantiationService.createInstance(DisableAutoUpdateAction, DisableAutoUpdateAction.ID, DisableAutoUpdateAction.LABEL)] : [this.instantiationService.createInstance(UpdateAllAction, UpdateAllAction.ID, UpdateAllAction.LABEL), this.instantiationService.createInstance(EnableAutoUpdateAction, EnableAutoUpdateAction.ID, EnableAutoUpdateAction.LABEL)]), this.instantiationService.createInstance(InstallVSIXAction, InstallVSIXAction.ID, InstallVSIXAction.LABEL), - ...(this.extensionManagementServerService.localExtensionManagementServer && this.extensionManagementServerService.remoteExtensionManagementServer ? [this.instantiationService.createInstance(InstallLocalExtensionsInRemoteAction)] : []), new Separator(), this.instantiationService.createInstance(DisableAllAction, DisableAllAction.ID, DisableAllAction.LABEL), this.instantiationService.createInstance(EnableAllAction, EnableAllAction.ID, EnableAllAction.LABEL) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts index 51c49a2202b..41731a7311c 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts @@ -28,7 +28,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; -import { InstallWorkspaceRecommendedExtensionsAction, ConfigureWorkspaceFolderRecommendedExtensionsAction, ManageExtensionAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; +import { InstallWorkspaceRecommendedExtensionsAction, ConfigureWorkspaceFolderRecommendedExtensionsAction, ManageExtensionAction, InstallLocalExtensionsInRemoteAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { WorkbenchPagedList } from 'vs/platform/list/browser/listService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; @@ -73,7 +73,7 @@ class ExtensionListViewWarning extends Error { } export class ExtensionsListView extends ViewletPanel { - private readonly server: IExtensionManagementServer | undefined; + protected readonly server: IExtensionManagementServer | undefined; private messageContainer: HTMLElement; private messageSeverityIcon: HTMLElement; private messageBox: HTMLElement; @@ -861,6 +861,15 @@ export class ServerExtensionsView extends ExtensionsListView { } return super.show(query.trim()); } + + getActions(): IAction[] { + if (this.extensionManagementServerService.localExtensionManagementServer === this.server) { + const installLocalExtensionsInRemoteAction = this._register(this.instantiationService.createInstance(InstallLocalExtensionsInRemoteAction, false)); + installLocalExtensionsInRemoteAction.class = 'octicon octicon-cloud-download'; + return [installLocalExtensionsInRemoteAction]; + } + return []; + } } export class EnabledExtensionsView extends ExtensionsListView { diff --git a/src/vs/workbench/contrib/extensions/browser/remoteExtensionsInstaller.ts b/src/vs/workbench/contrib/extensions/browser/remoteExtensionsInstaller.ts index 84c47be3064..b140853a820 100644 --- a/src/vs/workbench/contrib/extensions/browser/remoteExtensionsInstaller.ts +++ b/src/vs/workbench/contrib/extensions/browser/remoteExtensionsInstaller.ts @@ -22,7 +22,7 @@ export class RemoteExtensionsInstaller extends Disposable implements IWorkbenchC ) { super(); if (this.extensionManagementServerService.localExtensionManagementServer && this.extensionManagementServerService.remoteExtensionManagementServer) { - const installLocalExtensionsInRemoteAction = instantiationService.createInstance(InstallLocalExtensionsInRemoteAction); + const installLocalExtensionsInRemoteAction = instantiationService.createInstance(InstallLocalExtensionsInRemoteAction, true); CommandsRegistry.registerCommand('workbench.extensions.installLocalExtensions', () => installLocalExtensionsInRemoteAction.run()); let disposable = Disposable.None; const appendMenuItem = () => { From 5d49ab27dbca1aaeb78a91dd15543950aa1e0daf Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 13 Aug 2019 23:17:49 +0200 Subject: [PATCH 572/861] fix label --- .../contrib/extensions/browser/extensionsActions.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index 4b5d6194654..ec19e774ab1 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -3046,8 +3046,12 @@ export class InstallLocalExtensionsInRemoteAction extends Action { } get label(): string { - return this.extensionManagementServerService.remoteExtensionManagementServer ? - localize('install local extensions', "Install Local Extensions in {0}...", this.extensionManagementServerService.remoteExtensionManagementServer.label) : ''; + if (this.extensionManagementServerService.remoteExtensionManagementServer) { + return this.selectAndInstall ? + localize('select and install local extensions', "Install Local Extensions in {0}...", this.extensionManagementServerService.remoteExtensionManagementServer.label) + : localize('install local extensions', "Install Local Extensions in {0}", this.extensionManagementServerService.remoteExtensionManagementServer.label); + } + return ''; } private updateExtensions(): void { @@ -3057,6 +3061,7 @@ export class InstallLocalExtensionsInRemoteAction extends Action { private update(): void { this.enabled = !!this.extensions && this.getExtensionsToInstall(this.extensions).length > 0; + this.tooltip = this.label; } async run(): Promise { From 8da78b6b50f49fd5fd70516ee3b17655f6bd5c34 Mon Sep 17 00:00:00 2001 From: Utkarsh Gupta Date: Wed, 14 Aug 2019 02:52:46 +0530 Subject: [PATCH 573/861] fix: event's jsdoc typo --- src/vs/editor/browser/editorBrowser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/browser/editorBrowser.ts b/src/vs/editor/browser/editorBrowser.ts index 496e9cae7ab..705b6def023 100644 --- a/src/vs/editor/browser/editorBrowser.ts +++ b/src/vs/editor/browser/editorBrowser.ts @@ -399,7 +399,7 @@ export interface ICodeEditor extends editorCommon.IEditor { */ onWillType(listener: (text: string) => void): IDisposable; /** - * An event emitted before interpreting typed characters (on the keyboard). + * An event emitted after interpreting typed characters (on the keyboard). * @event * @internal */ From c08cfdf128f3727de2c0a82548d84eb47d97d4ba Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Tue, 13 Aug 2019 14:34:14 -0700 Subject: [PATCH 574/861] Move cleanRemoteAuthority function to common location --- .../browser/workbenchCommonProperties.ts | 16 +--------------- .../platform/telemetry/common/telemetryUtils.ts | 16 ++++++++++++++++ .../telemetry/node/workbenchCommonProperties.ts | 17 +---------------- 3 files changed, 18 insertions(+), 31 deletions(-) diff --git a/src/vs/platform/telemetry/browser/workbenchCommonProperties.ts b/src/vs/platform/telemetry/browser/workbenchCommonProperties.ts index 582ace32809..8f2d2413061 100644 --- a/src/vs/platform/telemetry/browser/workbenchCommonProperties.ts +++ b/src/vs/platform/telemetry/browser/workbenchCommonProperties.ts @@ -12,6 +12,7 @@ export const lastSessionDateStorageKey = 'telemetry.lastSessionDate'; import * as Platform from 'vs/base/common/platform'; import * as uuid from 'vs/base/common/uuid'; +import { cleanRemoteAuthority } from 'vs/platform/telemetry/common/telemetryUtils'; export async function resolveWorkbenchCommonProperties(storageService: IStorageService, commit: string | undefined, version: string | undefined, machineId: string, remoteAuthority?: string): Promise<{ [name: string]: string | undefined }> { const result: { [name: string]: string | undefined; } = Object.create(null); @@ -69,18 +70,3 @@ export async function resolveWorkbenchCommonProperties(storageService: IStorageS return result; } -function cleanRemoteAuthority(remoteAuthority?: string): string { - if (!remoteAuthority) { - return 'none'; - } - - let ret = 'other'; - // Whitelisted remote authorities - ['ssh-remote', 'dev-container', 'attached-container', 'wsl'].forEach((res: string) => { - if (remoteAuthority!.indexOf(`${res}+`) === 0) { - ret = res; - } - }); - - return ret; -} diff --git a/src/vs/platform/telemetry/common/telemetryUtils.ts b/src/vs/platform/telemetry/common/telemetryUtils.ts index f8990d64a32..d98abe9e156 100644 --- a/src/vs/platform/telemetry/common/telemetryUtils.ts +++ b/src/vs/platform/telemetry/common/telemetryUtils.ts @@ -288,6 +288,22 @@ export function validateTelemetryData(data?: any): { properties: Properties, mea }; } +export function cleanRemoteAuthority(remoteAuthority?: string): string { + if (!remoteAuthority) { + return 'none'; + } + + let ret = 'other'; + // Whitelisted remote authorities + ['ssh-remote', 'dev-container', 'attached-container', 'wsl'].forEach((res: string) => { + if (remoteAuthority!.indexOf(`${res}+`) === 0) { + ret = res; + } + }); + + return ret; +} + function flatten(obj: any, result: { [key: string]: any }, order: number = 0, prefix?: string): void { if (!obj) { return; diff --git a/src/vs/platform/telemetry/node/workbenchCommonProperties.ts b/src/vs/platform/telemetry/node/workbenchCommonProperties.ts index d1b83a14146..81d6a4d3d22 100644 --- a/src/vs/platform/telemetry/node/workbenchCommonProperties.ts +++ b/src/vs/platform/telemetry/node/workbenchCommonProperties.ts @@ -6,6 +6,7 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProperties'; import { instanceStorageKey, firstSessionDateStorageKey, lastSessionDateStorageKey } from 'vs/platform/telemetry/common/telemetry'; +import { cleanRemoteAuthority } from 'vs/platform/telemetry/common/telemetryUtils'; export async function resolveWorkbenchCommonProperties(storageService: IStorageService, commit: string | undefined, version: string | undefined, machineId: string, installSourcePath: string, remoteAuthority?: string): Promise<{ [name: string]: string | undefined }> { const result = await resolveCommonProperties(commit, version, machineId, installSourcePath); @@ -30,19 +31,3 @@ export async function resolveWorkbenchCommonProperties(storageService: IStorageS return result; } - -function cleanRemoteAuthority(remoteAuthority?: string): string { - if (!remoteAuthority) { - return 'none'; - } - - let ret = 'other'; - // Whitelisted remote authorities - ['ssh-remote', 'dev-container', 'wsl'].forEach((res: string) => { - if (remoteAuthority!.indexOf(`${res}+`) === 0) { - ret = res; - } - }); - - return ret; -} From 8e28611ac3caf211cdbeba58840ed33c60eb13f3 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 13 Aug 2019 23:55:45 +0200 Subject: [PATCH 575/861] #78168 strict init --- .../extensions/browser/extensionsViewer.ts | 13 ++-- .../extensions/browser/extensionsViews.ts | 76 +++++++++++-------- .../extensions/browser/extensionsWidgets.ts | 10 +-- .../browser/extensionsWorkbenchService.ts | 6 +- 4 files changed, 58 insertions(+), 47 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViewer.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViewer.ts index 8747ad8ca51..aeb50c75c64 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViewer.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViewer.ts @@ -156,7 +156,7 @@ export class UnknownExtensionRenderer implements IListRenderer { - return this.extensionsWorkdbenchService.open(this.extensionData.extension, sideByside); + if (this._extensionData) { + return this.extensionsWorkdbenchService.open(this._extensionData.extension, sideByside); + } + return Promise.resolve(); } } @@ -263,4 +262,4 @@ export class ExtensionData implements IExtensionData { } return null; } -} \ No newline at end of file +} diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts index 41731a7311c..ab7e8ee8fb1 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts @@ -74,14 +74,15 @@ class ExtensionListViewWarning extends Error { } export class ExtensionsListView extends ViewletPanel { protected readonly server: IExtensionManagementServer | undefined; - private messageContainer: HTMLElement; - private messageSeverityIcon: HTMLElement; - private messageBox: HTMLElement; - private extensionsList: HTMLElement; - private badge: CountBadge; - protected badgeContainer: HTMLElement; - private list: WorkbenchPagedList | null; - private queryRequest: { query: string, request: CancelablePromise> } | null; + private bodyTemplate: { + messageContainer: HTMLElement; + messageSeverityIcon: HTMLElement; + messageBox: HTMLElement; + extensionsList: HTMLElement; + } | undefined; + private badge: CountBadge | undefined; + private list: WorkbenchPagedList | null = null; + private queryRequest: { query: string, request: CancelablePromise> } | null = null; constructor( options: ExtensionsListViewOptions, @@ -111,20 +112,19 @@ export class ExtensionsListView extends ViewletPanel { addClass(container, 'extension-view-header'); super.renderHeader(container); - this.badgeContainer = append(container, $('.count-badge-wrapper')); - this.badge = new CountBadge(this.badgeContainer); + this.badge = new CountBadge(append(container, $('.count-badge-wrapper'))); this._register(attachBadgeStyler(this.badge, this.themeService)); } renderBody(container: HTMLElement): void { - this.extensionsList = append(container, $('.extensions-list')); - this.messageContainer = append(container, $('.message-container')); - this.messageSeverityIcon = append(this.messageContainer, $('')); - this.messageBox = append(this.messageContainer, $('.message')); + const extensionsList = append(container, $('.extensions-list')); + const messageContainer = append(container, $('.message-container')); + const messageSeverityIcon = append(messageContainer, $('')); + const messageBox = append(messageContainer, $('.message')); const delegate = new Delegate(); const extensionsViewState = new ExtensionsViewState(); const renderer = this.instantiationService.createInstance(Renderer, extensionsViewState); - this.list = this.instantiationService.createInstance(WorkbenchPagedList, this.extensionsList, delegate, [renderer], { + this.list = this.instantiationService.createInstance(WorkbenchPagedList, extensionsList, delegate, [renderer], { ariaLabel: localize('extensions', "Extensions"), multipleSelectionSupport: false, setRowLineHeight: false, @@ -144,10 +144,19 @@ export class ExtensionsListView extends ViewletPanel { .map(e => e.elements[0]) .filter(e => !!e) .on(this.pin, this)); + + this.bodyTemplate = { + extensionsList, + messageBox, + messageContainer, + messageSeverityIcon + }; } protected layoutBody(height: number, width: number): void { - this.extensionsList.style.height = height + 'px'; + if (this.bodyTemplate) { + this.bodyTemplate.extensionsList.style.height = height + 'px'; + } if (this.list) { this.list.layout(height, width); } @@ -479,7 +488,7 @@ export class ExtensionsListView extends ViewletPanel { } - private _searchExperiments: Promise; + private _searchExperiments: Promise | undefined; private getSearchExperiments(): Promise { if (!this._searchExperiments) { this._searchExperiments = this.experimentService.getExperimentsByType(ExperimentActionType.ExtensionSearchResults); @@ -690,24 +699,27 @@ export class ExtensionsListView extends ViewletPanel { this.list.scrollTop = 0; const count = this.count(); - toggleClass(this.extensionsList, 'hidden', count === 0); - toggleClass(this.messageContainer, 'hidden', count > 0); - this.badge.setCount(count); + if (this.bodyTemplate && this.badge) { - if (count === 0 && this.isBodyVisible()) { - if (error) { - if (error instanceof ExtensionListViewWarning) { - this.messageSeverityIcon.className = SeverityIcon.className(Severity.Warning); - this.messageBox.textContent = getErrorMessage(error); + toggleClass(this.bodyTemplate.extensionsList, 'hidden', count === 0); + toggleClass(this.bodyTemplate.messageContainer, 'hidden', count > 0); + this.badge.setCount(count); + + if (count === 0 && this.isBodyVisible()) { + if (error) { + if (error instanceof ExtensionListViewWarning) { + this.bodyTemplate.messageSeverityIcon.className = SeverityIcon.className(Severity.Warning); + this.bodyTemplate.messageBox.textContent = getErrorMessage(error); + } else { + this.bodyTemplate.messageSeverityIcon.className = SeverityIcon.className(Severity.Error); + this.bodyTemplate.messageBox.textContent = localize('error', "Error while loading extensions. {0}", getErrorMessage(error)); + } } else { - this.messageSeverityIcon.className = SeverityIcon.className(Severity.Error); - this.messageBox.textContent = localize('error', "Error while loading extensions. {0}", getErrorMessage(error)); + this.bodyTemplate.messageSeverityIcon.className = ''; + this.bodyTemplate.messageBox.textContent = localize('no extensions found', "No extensions found."); } - } else { - this.messageSeverityIcon.className = ''; - this.messageBox.textContent = localize('no extensions found', "No extensions found."); + alert(this.bodyTemplate.messageBox.textContent); } - alert(this.messageBox.textContent); } } } @@ -949,7 +961,7 @@ export class RecommendedExtensionsView extends ExtensionsListView { export class WorkspaceRecommendedExtensionsView extends ExtensionsListView { private readonly recommendedExtensionsQuery = '@recommended:workspace'; - private installAllAction: InstallWorkspaceRecommendedExtensionsAction; + private installAllAction: InstallWorkspaceRecommendedExtensionsAction | undefined; renderBody(container: HTMLElement): void { super.renderBody(container); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.ts index e27cc72e7d1..05741f72a62 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.ts @@ -18,9 +18,9 @@ import { Emitter, Event } from 'vs/base/common/event'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; export abstract class ExtensionWidget extends Disposable implements IExtensionContainer { - private _extension: IExtension; - get extension(): IExtension { return this._extension; } - set extension(extension: IExtension) { this._extension = extension; this.update(); } + private _extension: IExtension | null = null; + get extension(): IExtension | null { return this._extension; } + set extension(extension: IExtension | null) { this._extension = extension; this.update(); } update(): void { this.render(); } abstract render(): void; } @@ -183,7 +183,7 @@ export class RecommendationWidget extends ExtensionWidget { private element?: HTMLElement; private readonly disposables = this._register(new DisposableStore()); - private _tooltip: string; + private _tooltip: string = ''; get tooltip(): string { return this._tooltip; } set tooltip(tooltip: string) { if (this._tooltip !== tooltip) { @@ -314,4 +314,4 @@ class RemoteBadge extends Disposable { updateTitle(); } } -} \ No newline at end of file +} diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index 7ddf7c7fa70..b64689e02c6 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -484,7 +484,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension private readonly _onChange: Emitter = new Emitter(); get onChange(): Event { return this._onChange.event; } - private _extensionAllowedBadgeProviders: string[]; + private _extensionAllowedBadgeProviders: string[] | undefined; private installing: IExtension[] = []; constructor( @@ -1096,12 +1096,12 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension } - private _ignoredAutoUpdateExtensions: string[]; + private _ignoredAutoUpdateExtensions: string[] | undefined; private get ignoredAutoUpdateExtensions(): string[] { if (!this._ignoredAutoUpdateExtensions) { this._ignoredAutoUpdateExtensions = JSON.parse(this.storageService.get('extensions.ignoredAutoUpdateExtension', StorageScope.GLOBAL, '[]') || '[]'); } - return this._ignoredAutoUpdateExtensions; + return this._ignoredAutoUpdateExtensions!; } private set ignoredAutoUpdateExtensions(extensionIds: string[]) { From e80c80fd207657914539c3bed749b50352239ce7 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 14 Aug 2019 00:29:04 +0200 Subject: [PATCH 576/861] #78168 strict init --- .../extensions/browser/extensionsViewlet.ts | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts index 8396d202e4f..d9aef35dae5 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts @@ -319,7 +319,8 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensionsViewlet { - private onSearchChange: EventOf; + private readonly _onSearchChange: Emitter = this._register(new Emitter()); + private readonly onSearchChange: EventOf = this._onSearchChange.event; private nonEmptyWorkspaceContextKey: IContextKey; private defaultViewsContextKey: IContextKey; private searchMarketplaceExtensionsContextKey: IContextKey; @@ -333,12 +334,10 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio private defaultRecommendedExtensionsContextKey: IContextKey; private searchDelayer: Delayer; - private root: HTMLElement; - - private searchBox: SuggestEnabledInput; - private extensionsBox: HTMLElement; - private primaryActions: IAction[]; - private secondaryActions: IAction[] | null; + private root: HTMLElement | undefined; + private searchBox: SuggestEnabledInput | undefined; + private primaryActions: IAction[] | undefined; + private secondaryActions: IAction[] | null = null; private readonly searchViewletState: MementoObject; constructor( @@ -417,32 +416,35 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio this._register(attachSuggestEnabledInputBoxStyler(this.searchBox, this.themeService)); - const _searchChange = new Emitter(); - this.onSearchChange = _searchChange.event; this._register(this.searchBox.onInputDidChange(() => { this.triggerSearch(); - _searchChange.fire(this.searchBox.getValue()); + this._onSearchChange.fire(this.searchBox!.getValue()); }, this)); this._register(this.searchBox.onShouldFocusResults(() => this.focusListView(), this)); this._register(this.onDidChangeVisibility(visible => { if (visible) { - this.searchBox.focus(); + this.searchBox!.focus(); } })); - this.extensionsBox = append(this.root, $('.extensions')); - super.create(this.extensionsBox); + super.create(append(this.root, $('.extensions'))); } focus(): void { - this.searchBox.focus(); + if (this.searchBox) { + this.searchBox.focus(); + } } layout(dimension: Dimension): void { - toggleClass(this.root, 'narrow', dimension.width <= 300); - this.searchBox.layout({ height: 20, width: dimension.width - 34 }); + if (this.root) { + toggleClass(this.root, 'narrow', dimension.width <= 300); + } + if (this.searchBox) { + this.searchBox.layout({ height: 20, width: dimension.width - 34 }); + } super.layout(new Dimension(dimension.width, dimension.height - 38)); } @@ -453,7 +455,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio getActions(): IAction[] { if (!this.primaryActions) { this.primaryActions = [ - this.instantiationService.createInstance(ClearExtensionsInputAction, ClearExtensionsInputAction.ID, ClearExtensionsInputAction.LABEL, this.onSearchChange, this.searchBox.getValue()) + this.instantiationService.createInstance(ClearExtensionsInputAction, ClearExtensionsInputAction.ID, ClearExtensionsInputAction.LABEL, this.onSearchChange, this.searchBox ? this.searchBox.getValue() : '') ]; } return this.primaryActions; @@ -487,22 +489,24 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio } search(value: string): void { - const event = new Event('input', { bubbles: true }) as SearchInputEvent; - event.immediate = true; + if (this.searchBox) { + const event = new Event('input', { bubbles: true }) as SearchInputEvent; + event.immediate = true; - this.searchBox.setValue(value); + this.searchBox.setValue(value); + } } - private triggerSearch(immediate = false): void { - this.searchDelayer.trigger(() => this.doSearch(), immediate || !this.searchBox.getValue() ? 0 : 500).then(undefined, err => this.onError(err)); + private triggerSearch(): void { + this.searchDelayer.trigger(() => this.doSearch(), this.searchBox && this.searchBox.getValue() ? 500 : 0).then(undefined, err => this.onError(err)); } private normalizedQuery(): string { - return this.searchBox.getValue().replace(/@category/g, 'category').replace(/@tag:/g, 'tag:').replace(/@ext:/g, 'ext:'); + return this.searchBox ? this.searchBox.getValue().replace(/@category/g, 'category').replace(/@tag:/g, 'tag:').replace(/@ext:/g, 'ext:') : ''; } protected saveState(): void { - const value = this.searchBox.getValue(); + const value = this.searchBox ? this.searchBox.getValue() : ''; if (ExtensionsListView.isLocalExtensionsQuery(value)) { this.searchViewletState['query.value'] = value; } else { From 5a87b682d8cafe712d675f628c4c2742fc7b50f6 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 14 Aug 2019 01:09:36 +0200 Subject: [PATCH 577/861] #78168 strict init --- .../extensions/browser/extensionEditor.ts | 318 ++++++++++-------- 1 file changed, 174 insertions(+), 144 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index e7cc0836f23..2a19adea3df 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -133,29 +133,33 @@ interface IActiveElement { focus(): void; } +interface IExtensionEditorTemplate { + iconContainer: HTMLElement; + icon: HTMLImageElement; + name: HTMLElement; + identifier: HTMLElement; + preview: HTMLElement; + builtin: HTMLElement; + license: HTMLElement; + publisher: HTMLElement; + installCount: HTMLElement; + rating: HTMLElement; + repository: HTMLElement; + description: HTMLElement; + extensionActionBar: ActionBar; + navbar: NavBar; + content: HTMLElement; + subtextContainer: HTMLElement; + subtext: HTMLElement; + ignoreActionbar: ActionBar; + header: HTMLElement; +} + export class ExtensionEditor extends BaseEditor { static readonly ID: string = 'workbench.editor.extension'; - private iconContainer: HTMLElement; - private icon: HTMLImageElement; - private name: HTMLElement; - private identifier: HTMLElement; - private preview: HTMLElement; - private builtin: HTMLElement; - private license: HTMLElement; - private publisher: HTMLElement; - private installCount: HTMLElement; - private rating: HTMLElement; - private repository: HTMLElement; - private description: HTMLElement; - private extensionActionBar: ActionBar; - private navbar: NavBar; - private content: HTMLElement; - private subtextContainer: HTMLElement; - private subtext: HTMLElement; - private ignoreActionbar: ActionBar; - private header: HTMLElement; + private template: IExtensionEditorTemplate | undefined; private extensionReadme: Cache | null; private extensionChangelog: Cache | null; @@ -164,7 +168,7 @@ export class ExtensionEditor extends BaseEditor { private layoutParticipants: ILayoutParticipant[] = []; private readonly contentDisposables = this._register(new DisposableStore()); private readonly transientDisposables = this._register(new DisposableStore()); - private activeElement: IActiveElement | null; + private activeElement: IActiveElement | null = null; private editorLoadComplete: boolean = false; constructor( @@ -192,43 +196,43 @@ export class ExtensionEditor extends BaseEditor { const root = append(parent, $('.extension-editor')); root.tabIndex = 0; // this is required for the focus tracker on the editor root.style.outline = 'none'; - this.header = append(root, $('.header')); + const header = append(root, $('.header')); - this.iconContainer = append(this.header, $('.icon-container')); - this.icon = append(this.iconContainer, $('img.icon', { draggable: false })); + const iconContainer = append(header, $('.icon-container')); + const icon = append(iconContainer, $('img.icon', { draggable: false })); - const details = append(this.header, $('.details')); + const details = append(header, $('.details')); const title = append(details, $('.title')); - this.name = append(title, $('span.name.clickable', { title: localize('name', "Extension name") })); - this.identifier = append(title, $('span.identifier', { title: localize('extension id', "Extension identifier") })); + const name = append(title, $('span.name.clickable', { title: localize('name', "Extension name") })); + const identifier = append(title, $('span.identifier', { title: localize('extension id', "Extension identifier") })); - this.preview = append(title, $('span.preview', { title: localize('preview', "Preview") })); - this.preview.textContent = localize('preview', "Preview"); + const preview = append(title, $('span.preview', { title: localize('preview', "Preview") })); + preview.textContent = localize('preview', "Preview"); - this.builtin = append(title, $('span.builtin')); - this.builtin.textContent = localize('builtin', "Built-in"); + const builtin = append(title, $('span.builtin')); + builtin.textContent = localize('builtin', "Built-in"); const subtitle = append(details, $('.subtitle')); - this.publisher = append(subtitle, $('span.publisher.clickable', { title: localize('publisher', "Publisher name"), tabIndex: 0 })); + const publisher = append(subtitle, $('span.publisher.clickable', { title: localize('publisher', "Publisher name"), tabIndex: 0 })); - this.installCount = append(subtitle, $('span.install', { title: localize('install count', "Install count"), tabIndex: 0 })); + const installCount = append(subtitle, $('span.install', { title: localize('install count', "Install count"), tabIndex: 0 })); - this.rating = append(subtitle, $('span.rating.clickable', { title: localize('rating', "Rating"), tabIndex: 0 })); + const rating = append(subtitle, $('span.rating.clickable', { title: localize('rating', "Rating"), tabIndex: 0 })); - this.repository = append(subtitle, $('span.repository.clickable')); - this.repository.textContent = localize('repository', 'Repository'); - this.repository.style.display = 'none'; - this.repository.tabIndex = 0; + const repository = append(subtitle, $('span.repository.clickable')); + repository.textContent = localize('repository', 'Repository'); + repository.style.display = 'none'; + repository.tabIndex = 0; - this.license = append(subtitle, $('span.license.clickable')); - this.license.textContent = localize('license', 'License'); - this.license.style.display = 'none'; - this.license.tabIndex = 0; + const license = append(subtitle, $('span.license.clickable')); + license.textContent = localize('license', 'License'); + license.style.display = 'none'; + license.tabIndex = 0; - this.description = append(details, $('.description')); + const description = append(details, $('.description')); const extensionActions = append(details, $('.actions')); - this.extensionActionBar = new ActionBar(extensionActions, { + const extensionActionBar = this._register(new ActionBar(extensionActions, { animated: false, actionViewItemProvider: (action: Action) => { if (action instanceof ExtensionEditorDropDownAction) { @@ -236,29 +240,48 @@ export class ExtensionEditor extends BaseEditor { } return undefined; } - }); + })); - this.subtextContainer = append(details, $('.subtext-container')); - this.subtext = append(this.subtextContainer, $('.subtext')); - this.ignoreActionbar = new ActionBar(this.subtextContainer, { animated: false }); + const subtextContainer = append(details, $('.subtext-container')); + const subtext = append(subtextContainer, $('.subtext')); + const ignoreActionbar = this._register(new ActionBar(subtextContainer, { animated: false })); - this._register(this.extensionActionBar); - this._register(this.ignoreActionbar); - - this._register(Event.chain(this.extensionActionBar.onDidRun) + this._register(Event.chain(extensionActionBar.onDidRun) .map(({ error }) => error) .filter(error => !!error) .on(this.onError, this)); - this._register(Event.chain(this.ignoreActionbar.onDidRun) + this._register(Event.chain(ignoreActionbar.onDidRun) .map(({ error }) => error) .filter(error => !!error) .on(this.onError, this)); const body = append(root, $('.body')); - this.navbar = new NavBar(body); + const navbar = new NavBar(body); - this.content = append(body, $('.content')); + const content = append(body, $('.content')); + + this.template = { + builtin, + content, + description, + extensionActionBar, + header, + icon, + iconContainer, + identifier, + ignoreActionbar, + installCount, + license, + name, + navbar, + preview, + publisher, + rating, + repository, + subtext, + subtextContainer + }; } private onClick(element: HTMLElement, callback: () => void): IDisposable { @@ -276,6 +299,13 @@ export class ExtensionEditor extends BaseEditor { } async setInput(input: ExtensionsInput, options: EditorOptions, token: CancellationToken): Promise { + if (this.template) { + await this.updateTemplate(input, this.template); + } + return super.setInput(input, options, token); + } + + private async updateTemplate(input: ExtensionsInput, template: IExtensionEditorTemplate): Promise { const runningExtensions = await this.extensionService.getExtensions(); const colorThemes = await this.workbenchThemeService.getColorThemes(); const fileIconThemes = await this.workbenchThemeService.getFileIconThemes(); @@ -290,18 +320,18 @@ export class ExtensionEditor extends BaseEditor { this.extensionChangelog = new Cache(() => createCancelablePromise(token => extension.getChangelog(token))); this.extensionManifest = new Cache(() => createCancelablePromise(token => extension.getManifest(token))); - const remoteBadge = this.instantiationService.createInstance(RemoteBadgeWidget, this.iconContainer, true); - const onError = Event.once(domEvent(this.icon, 'error')); - onError(() => this.icon.src = extension.iconUrlFallback, null, this.transientDisposables); - this.icon.src = extension.iconUrl; + const remoteBadge = this.instantiationService.createInstance(RemoteBadgeWidget, template.iconContainer, true); + const onError = Event.once(domEvent(template.icon, 'error')); + onError(() => template.icon.src = extension.iconUrlFallback, null, this.transientDisposables); + template.icon.src = extension.iconUrl; - this.name.textContent = extension.displayName; - this.identifier.textContent = extension.identifier.id; - this.preview.style.display = extension.preview ? 'inherit' : 'none'; - this.builtin.style.display = extension.type === ExtensionType.System ? 'inherit' : 'none'; + template.name.textContent = extension.displayName; + template.identifier.textContent = extension.identifier.id; + template.preview.style.display = extension.preview ? 'inherit' : 'none'; + template.builtin.style.display = extension.type === ExtensionType.System ? 'inherit' : 'none'; - this.publisher.textContent = extension.publisherDisplayName; - this.description.textContent = extension.description; + template.publisher.textContent = extension.publisherDisplayName; + template.description.textContent = extension.description; const extRecommendations = this.extensionTipsService.getAllRecommendationsWithReason(); let recommendationsData = {}; @@ -319,40 +349,40 @@ export class ExtensionEditor extends BaseEditor { */ this.telemetryService.publicLog('extensionGallery:openExtension', assign(extension.telemetryData, recommendationsData)); - toggleClass(this.name, 'clickable', !!extension.url); - toggleClass(this.publisher, 'clickable', !!extension.url); - toggleClass(this.rating, 'clickable', !!extension.url); + toggleClass(template.name, 'clickable', !!extension.url); + toggleClass(template.publisher, 'clickable', !!extension.url); + toggleClass(template.rating, 'clickable', !!extension.url); if (extension.url) { - this.transientDisposables.add(this.onClick(this.name, () => window.open(extension.url))); - this.transientDisposables.add(this.onClick(this.rating, () => window.open(`${extension.url}#review-details`))); - this.transientDisposables.add(this.onClick(this.publisher, () => { + this.transientDisposables.add(this.onClick(template.name, () => window.open(extension.url))); + this.transientDisposables.add(this.onClick(template.rating, () => window.open(`${extension.url}#review-details`))); + this.transientDisposables.add(this.onClick(template.publisher, () => { this.viewletService.openViewlet(VIEWLET_ID, true) .then(viewlet => viewlet as IExtensionsViewlet) .then(viewlet => viewlet.search(`publisher:"${extension.publisherDisplayName}"`)); })); if (extension.licenseUrl) { - this.transientDisposables.add(this.onClick(this.license, () => window.open(extension.licenseUrl))); - this.license.style.display = 'initial'; + this.transientDisposables.add(this.onClick(template.license, () => window.open(extension.licenseUrl))); + template.license.style.display = 'initial'; } else { - this.license.style.display = 'none'; + template.license.style.display = 'none'; } } else { - this.license.style.display = 'none'; + template.license.style.display = 'none'; } if (extension.repository) { - this.transientDisposables.add(this.onClick(this.repository, () => window.open(extension.repository))); - this.repository.style.display = 'initial'; + this.transientDisposables.add(this.onClick(template.repository, () => window.open(extension.repository))); + template.repository.style.display = 'initial'; } else { - this.repository.style.display = 'none'; + template.repository.style.display = 'none'; } const widgets = [ remoteBadge, - this.instantiationService.createInstance(InstallCountWidget, this.installCount, false), - this.instantiationService.createInstance(RatingsWidget, this.rating, false) + this.instantiationService.createInstance(InstallCountWidget, template.installCount, false), + this.instantiationService.createInstance(RatingsWidget, template.rating, false) ]; const reloadAction = this.instantiationService.createInstance(ReloadAction); const combinedInstallAction = this.instantiationService.createInstance(CombinedInstallAction); @@ -375,20 +405,20 @@ export class ExtensionEditor extends BaseEditor { const extensionContainers: ExtensionContainers = this.instantiationService.createInstance(ExtensionContainers, [...actions, ...widgets]); extensionContainers.extension = extension; - this.extensionActionBar.clear(); - this.extensionActionBar.push(actions, { icon: true, label: true }); + template.extensionActionBar.clear(); + template.extensionActionBar.push(actions, { icon: true, label: true }); for (const disposable of [...actions, ...widgets, extensionContainers]) { this.transientDisposables.add(disposable); } - this.setSubText(extension, reloadAction); - this.content.innerHTML = ''; // Clear content before setting navbar actions. + this.setSubText(extension, reloadAction, template); + template.content.innerHTML = ''; // Clear content before setting navbar actions. - this.navbar.clear(); - this.navbar.onChange(this.onNavbarChange.bind(this, extension), this, this.transientDisposables); + template.navbar.clear(); + template.navbar.onChange(e => this.onNavbarChange(extension, e, template), this, this.transientDisposables); if (extension.hasReadme()) { - this.navbar.push(NavbarSection.Readme, localize('details', "Details"), localize('detailstooltip', "Extension details, rendered from the extension's 'README.md' file")); + template.navbar.push(NavbarSection.Readme, localize('details', "Details"), localize('detailstooltip', "Extension details, rendered from the extension's 'README.md' file")); } this.extensionManifest.get() .promise @@ -397,25 +427,23 @@ export class ExtensionEditor extends BaseEditor { combinedInstallAction.manifest = manifest; } if (extension.extensionPack.length) { - this.navbar.push(NavbarSection.ExtensionPack, localize('extensionPack', "Extension Pack"), localize('extensionsPack', "Set of extensions that can be installed together")); + template.navbar.push(NavbarSection.ExtensionPack, localize('extensionPack', "Extension Pack"), localize('extensionsPack', "Set of extensions that can be installed together")); } if (manifest && manifest.contributes) { - this.navbar.push(NavbarSection.Contributions, localize('contributions', "Contributions"), localize('contributionstooltip', "Lists contributions to VS Code by this extension")); + template.navbar.push(NavbarSection.Contributions, localize('contributions', "Contributions"), localize('contributionstooltip', "Lists contributions to VS Code by this extension")); } if (extension.hasChangelog()) { - this.navbar.push(NavbarSection.Changelog, localize('changelog', "Changelog"), localize('changelogtooltip', "Extension update history, rendered from the extension's 'CHANGELOG.md' file")); + template.navbar.push(NavbarSection.Changelog, localize('changelog', "Changelog"), localize('changelogtooltip', "Extension update history, rendered from the extension's 'CHANGELOG.md' file")); } if (extension.dependencies.length) { - this.navbar.push(NavbarSection.Dependencies, localize('dependencies', "Dependencies"), localize('dependenciestooltip', "Lists extensions this extension depends on")); + template.navbar.push(NavbarSection.Dependencies, localize('dependencies', "Dependencies"), localize('dependenciestooltip', "Lists extensions this extension depends on")); } this.editorLoadComplete = true; }); - - return super.setInput(input, options, token); } - private setSubText(extension: IExtension, reloadAction: ReloadAction): void { - hide(this.subtextContainer); + private setSubText(extension: IExtension, reloadAction: ReloadAction, template: IExtensionEditorTemplate): void { + hide(template.subtextContainer); const ignoreAction = this.instantiationService.createInstance(IgnoreExtensionRecommendationAction); const undoIgnoreAction = this.instantiationService.createInstance(UndoIgnoreExtensionRecommendationAction); @@ -424,23 +452,23 @@ export class ExtensionEditor extends BaseEditor { ignoreAction.enabled = false; undoIgnoreAction.enabled = false; - this.ignoreActionbar.clear(); - this.ignoreActionbar.push([ignoreAction, undoIgnoreAction], { icon: true, label: true }); + template.ignoreActionbar.clear(); + template.ignoreActionbar.push([ignoreAction, undoIgnoreAction], { icon: true, label: true }); this.transientDisposables.add(ignoreAction); this.transientDisposables.add(undoIgnoreAction); const extRecommendations = this.extensionTipsService.getAllRecommendationsWithReason(); if (extRecommendations[extension.identifier.id.toLowerCase()]) { ignoreAction.enabled = true; - this.subtext.textContent = extRecommendations[extension.identifier.id.toLowerCase()].reasonText; - show(this.subtextContainer); + template.subtext.textContent = extRecommendations[extension.identifier.id.toLowerCase()].reasonText; + show(template.subtextContainer); } else if (this.extensionTipsService.getAllIgnoredRecommendations().global.indexOf(extension.identifier.id.toLowerCase()) !== -1) { undoIgnoreAction.enabled = true; - this.subtext.textContent = localize('recommendationHasBeenIgnored', "You have chosen not to receive recommendations for this extension."); - show(this.subtextContainer); + template.subtext.textContent = localize('recommendationHasBeenIgnored', "You have chosen not to receive recommendations for this extension."); + show(template.subtextContainer); } else { - this.subtext.textContent = ''; + template.subtext.textContent = ''; } this.extensionTipsService.onRecommendationChange(change => { @@ -450,28 +478,28 @@ export class ExtensionEditor extends BaseEditor { const extRecommendations = this.extensionTipsService.getAllRecommendationsWithReason(); if (extRecommendations[extension.identifier.id.toLowerCase()]) { ignoreAction.enabled = true; - this.subtext.textContent = extRecommendations[extension.identifier.id.toLowerCase()].reasonText; + template.subtext.textContent = extRecommendations[extension.identifier.id.toLowerCase()].reasonText; } } else { undoIgnoreAction.enabled = true; ignoreAction.enabled = false; - this.subtext.textContent = localize('recommendationHasBeenIgnored', "You have chosen not to receive recommendations for this extension."); + template.subtext.textContent = localize('recommendationHasBeenIgnored', "You have chosen not to receive recommendations for this extension."); } } }); this.transientDisposables.add(reloadAction.onDidChange(e => { if (e.tooltip) { - this.subtext.textContent = reloadAction.tooltip; - show(this.subtextContainer); + template.subtext.textContent = reloadAction.tooltip; + show(template.subtextContainer); ignoreAction.enabled = false; undoIgnoreAction.enabled = false; } if (e.enabled === true) { - show(this.subtextContainer); + show(template.subtextContainer); } if (e.enabled === false) { - hide(this.subtextContainer); + hide(template.subtextContainer); } })); } @@ -495,7 +523,7 @@ export class ExtensionEditor extends BaseEditor { } } - private onNavbarChange(extension: IExtension, { id, focus }: { id: string, focus: boolean }): void { + private onNavbarChange(extension: IExtension, { id, focus }: { id: string | null, focus: boolean }, template: IExtensionEditorTemplate): void { if (this.editorLoadComplete) { /* __GDPR__ "extensionEditor:navbarChange" : { @@ -509,30 +537,32 @@ export class ExtensionEditor extends BaseEditor { } this.contentDisposables.clear(); - this.content.innerHTML = ''; + template.content.innerHTML = ''; this.activeElement = null; - this.open(id, extension) - .then(activeElement => { - this.activeElement = activeElement; - if (focus) { - this.focus(); - } - }); + if (id) { + this.open(id, extension, template) + .then(activeElement => { + this.activeElement = activeElement; + if (focus) { + this.focus(); + } + }); + } } - private open(id: string, extension: IExtension): Promise { + private open(id: string, extension: IExtension, template: IExtensionEditorTemplate): Promise { switch (id) { - case NavbarSection.Readme: return this.openReadme(); - case NavbarSection.Contributions: return this.openContributions(); - case NavbarSection.Changelog: return this.openChangelog(); - case NavbarSection.Dependencies: return this.openDependencies(extension); - case NavbarSection.ExtensionPack: return this.openExtensionPack(extension); + case NavbarSection.Readme: return this.openReadme(template); + case NavbarSection.Contributions: return this.openContributions(template); + case NavbarSection.Changelog: return this.openChangelog(template); + case NavbarSection.Dependencies: return this.openDependencies(extension, template); + case NavbarSection.ExtensionPack: return this.openExtensionPack(extension, template); } return Promise.resolve(null); } - private openMarkdown(cacheResult: CacheResult, noContentCopy: string): Promise { - return this.loadContents(() => cacheResult) + private openMarkdown(cacheResult: CacheResult, noContentCopy: string, template: IExtensionEditorTemplate): Promise { + return this.loadContents(() => cacheResult, template) .then(marked.parse) .then(content => this.renderBody(content)) .then(removeEmbeddedSVGs) @@ -544,7 +574,7 @@ export class ExtensionEditor extends BaseEditor { { svgWhiteList: this.extensionsWorkbenchService.allowedBadgeProviders, }); - webviewElement.mountTo(this.content); + webviewElement.mountTo(template.content); this.contentDisposables.add(webviewElement.onDidFocus(() => this.fireOnDidFocus())); const removeLayoutParticipant = arrays.insert(this.layoutParticipants, webviewElement); this.contentDisposables.add(toDisposable(removeLayoutParticipant)); @@ -563,7 +593,7 @@ export class ExtensionEditor extends BaseEditor { return webviewElement; }) .then(undefined, () => { - const p = append(this.content, $('p.nocontent')); + const p = append(template.content, $('p.nocontent')); p.textContent = noContentCopy; return p; }); @@ -757,17 +787,17 @@ export class ExtensionEditor extends BaseEditor { `; } - private openReadme(): Promise { - return this.openMarkdown(this.extensionReadme!.get(), localize('noReadme', "No README available.")); + private openReadme(template: IExtensionEditorTemplate): Promise { + return this.openMarkdown(this.extensionReadme!.get(), localize('noReadme', "No README available."), template); } - private openChangelog(): Promise { - return this.openMarkdown(this.extensionChangelog!.get(), localize('noChangelog', "No Changelog available.")); + private openChangelog(template: IExtensionEditorTemplate): Promise { + return this.openMarkdown(this.extensionChangelog!.get(), localize('noChangelog', "No Changelog available."), template); } - private openContributions(): Promise { + private openContributions(template: IExtensionEditorTemplate): Promise { const content = $('div', { class: 'subcontent', tabindex: '0' }); - return this.loadContents(() => this.extensionManifest!.get()) + return this.loadContents(() => this.extensionManifest!.get(), template) .then(manifest => { if (!manifest) { return content; @@ -798,28 +828,28 @@ export class ExtensionEditor extends BaseEditor { const isEmpty = !renders.some(x => x); if (isEmpty) { append(content, $('p.nocontent')).textContent = localize('noContributions', "No Contributions"); - append(this.content, content); + append(template.content, content); } else { - append(this.content, scrollableContent.getDomNode()); + append(template.content, scrollableContent.getDomNode()); this.contentDisposables.add(scrollableContent); } return content; }, () => { append(content, $('p.nocontent')).textContent = localize('noContributions', "No Contributions"); - append(this.content, content); + append(template.content, content); return content; }); } - private openDependencies(extension: IExtension): Promise { + private openDependencies(extension: IExtension, template: IExtensionEditorTemplate): Promise { if (arrays.isFalsyOrEmpty(extension.dependencies)) { - append(this.content, $('p.nocontent')).textContent = localize('noDependencies', "No Dependencies"); - return Promise.resolve(this.content); + append(template.content, $('p.nocontent')).textContent = localize('noDependencies', "No Dependencies"); + return Promise.resolve(template.content); } const content = $('div', { class: 'subcontent' }); const scrollableContent = new DomScrollableElement(content, {}); - append(this.content, scrollableContent.getDomNode()); + append(template.content, scrollableContent.getDomNode()); this.contentDisposables.add(scrollableContent); const dependenciesTree = this.instantiationService.createInstance(ExtensionsTree, new ExtensionData(extension, null, extension => extension.dependencies || [], this.extensionsWorkbenchService), content); @@ -836,10 +866,10 @@ export class ExtensionEditor extends BaseEditor { return Promise.resolve({ focus() { dependenciesTree.domFocus(); } }); } - private openExtensionPack(extension: IExtension): Promise { + private openExtensionPack(extension: IExtension, template: IExtensionEditorTemplate): Promise { const content = $('div', { class: 'subcontent' }); const scrollableContent = new DomScrollableElement(content, {}); - append(this.content, scrollableContent.getDomNode()); + append(template.content, scrollableContent.getDomNode()); this.contentDisposables.add(scrollableContent); const extensionsPackTree = this.instantiationService.createInstance(ExtensionsTree, new ExtensionData(extension, null, extension => extension.extensionPack || [], this.extensionsWorkbenchService), content); @@ -1259,11 +1289,11 @@ export class ExtensionEditor extends BaseEditor { return null; } - private loadContents(loadingTask: () => CacheResult): Promise { - addClass(this.content, 'loading'); + private loadContents(loadingTask: () => CacheResult, template: IExtensionEditorTemplate): Promise { + addClass(template.content, 'loading'); const result = loadingTask(); - const onDone = () => removeClass(this.content, 'loading'); + const onDone = () => removeClass(template.content, 'loading'); result.promise.then(onDone, onDone); this.contentDisposables.add(toDisposable(() => result.dispose())); From ec07311dab2556c9d66a4cb3eecdc21c524202e1 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Tue, 13 Aug 2019 16:23:31 -0700 Subject: [PATCH 578/861] fixes #77797 --- src/vs/workbench/browser/parts/sidebar/sidebarPart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts b/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts index 66650e527f7..9e17bf39cc4 100644 --- a/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts +++ b/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts @@ -63,7 +63,7 @@ export class SidebarPart extends CompositePart implements IViewletServi return; } - return width; + return Math.max(width, 300); } //#endregion From 82601dcaa4b7aaea6c71d7e375484454321dcceb Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 13 Aug 2019 11:54:50 -0700 Subject: [PATCH 579/861] Split formatted text renderer into own file --- src/vs/base/browser/formattedTextRenderer.ts | 199 +++++++++++++++++ src/vs/base/browser/htmlContentRenderer.ts | 201 +----------------- src/vs/base/browser/ui/inputbox/inputBox.ts | 3 +- .../browser/formattedTextRenderer.test.ts | 104 +++++++++ src/vs/base/test/browser/htmlContent.test.ts | 101 +-------- .../accessibilityHelp/accessibilityHelp.ts | 2 +- .../browser/accessibility/accessibility.ts | 2 +- 7 files changed, 314 insertions(+), 298 deletions(-) create mode 100644 src/vs/base/browser/formattedTextRenderer.ts create mode 100644 src/vs/base/test/browser/formattedTextRenderer.test.ts diff --git a/src/vs/base/browser/formattedTextRenderer.ts b/src/vs/base/browser/formattedTextRenderer.ts new file mode 100644 index 00000000000..6d33caf8acc --- /dev/null +++ b/src/vs/base/browser/formattedTextRenderer.ts @@ -0,0 +1,199 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as DOM from 'vs/base/browser/dom'; +import { createElement, IContentActionHandler, RenderOptions } from 'vs/base/browser/htmlContentRenderer'; + +export function renderText(text: string, options: RenderOptions = {}): HTMLElement { + const element = createElement(options); + element.textContent = text; + return element; +} + +export function renderFormattedText(formattedText: string, options: RenderOptions = {}): HTMLElement { + const element = createElement(options); + _renderFormattedText(element, parseFormattedText(formattedText), options.actionHandler); + return element; +} + +class StringStream { + private source: string; + private index: number; + + constructor(source: string) { + this.source = source; + this.index = 0; + } + + public eos(): boolean { + return this.index >= this.source.length; + } + + public next(): string { + const next = this.peek(); + this.advance(); + return next; + } + + public peek(): string { + return this.source[this.index]; + } + + public advance(): void { + this.index++; + } +} + +const enum FormatType { + Invalid, + Root, + Text, + Bold, + Italics, + Action, + ActionClose, + NewLine +} + +interface IFormatParseTree { + type: FormatType; + content?: string; + index?: number; + children?: IFormatParseTree[]; +} + +export function _renderFormattedText(element: Node, treeNode: IFormatParseTree, actionHandler?: IContentActionHandler) { + let child: Node | undefined; + + if (treeNode.type === FormatType.Text) { + child = document.createTextNode(treeNode.content || ''); + } else if (treeNode.type === FormatType.Bold) { + child = document.createElement('b'); + } else if (treeNode.type === FormatType.Italics) { + child = document.createElement('i'); + } else if (treeNode.type === FormatType.Action && actionHandler) { + const a = document.createElement('a'); + a.href = '#'; + actionHandler.disposeables.add(DOM.addStandardDisposableListener(a, 'click', (event) => { + actionHandler.callback(String(treeNode.index), event); + })); + + child = a; + } else if (treeNode.type === FormatType.NewLine) { + child = document.createElement('br'); + } else if (treeNode.type === FormatType.Root) { + child = element; + } + + if (child && element !== child) { + element.appendChild(child); + } + + if (child && Array.isArray(treeNode.children)) { + treeNode.children.forEach((nodeChild) => { + _renderFormattedText(child!, nodeChild, actionHandler); + }); + } +} + +export function parseFormattedText(content: string): IFormatParseTree { + + const root: IFormatParseTree = { + type: FormatType.Root, + children: [] + }; + + let actionViewItemIndex = 0; + let current = root; + const stack: IFormatParseTree[] = []; + const stream = new StringStream(content); + + while (!stream.eos()) { + let next = stream.next(); + + const isEscapedFormatType = (next === '\\' && formatTagType(stream.peek()) !== FormatType.Invalid); + if (isEscapedFormatType) { + next = stream.next(); // unread the backslash if it escapes a format tag type + } + + if (!isEscapedFormatType && isFormatTag(next) && next === stream.peek()) { + stream.advance(); + + if (current.type === FormatType.Text) { + current = stack.pop()!; + } + + const type = formatTagType(next); + if (current.type === type || (current.type === FormatType.Action && type === FormatType.ActionClose)) { + current = stack.pop()!; + } else { + const newCurrent: IFormatParseTree = { + type: type, + children: [] + }; + + if (type === FormatType.Action) { + newCurrent.index = actionViewItemIndex; + actionViewItemIndex++; + } + + current.children!.push(newCurrent); + stack.push(current); + current = newCurrent; + } + } else if (next === '\n') { + if (current.type === FormatType.Text) { + current = stack.pop()!; + } + + current.children!.push({ + type: FormatType.NewLine + }); + + } else { + if (current.type !== FormatType.Text) { + const textCurrent: IFormatParseTree = { + type: FormatType.Text, + content: next + }; + current.children!.push(textCurrent); + stack.push(current); + current = textCurrent; + + } else { + current.content += next; + } + } + } + + if (current.type === FormatType.Text) { + current = stack.pop()!; + } + + if (stack.length) { + // incorrectly formatted string literal + } + + return root; +} + +function isFormatTag(char: string): boolean { + return formatTagType(char) !== FormatType.Invalid; +} + +function formatTagType(char: string): FormatType { + switch (char) { + case '*': + return FormatType.Bold; + case '_': + return FormatType.Italics; + case '[': + return FormatType.Action; + case ']': + return FormatType.ActionClose; + default: + return FormatType.Invalid; + } +} diff --git a/src/vs/base/browser/htmlContentRenderer.ts b/src/vs/base/browser/htmlContentRenderer.ts index 4506912e178..80f956bf138 100644 --- a/src/vs/base/browser/htmlContentRenderer.ts +++ b/src/vs/base/browser/htmlContentRenderer.ts @@ -28,7 +28,7 @@ export interface RenderOptions { codeBlockRenderCallback?: () => void; } -function createElement(options: RenderOptions): HTMLElement { +export function createElement(options: RenderOptions): HTMLElement { const tagName = options.inline ? 'span' : 'div'; const element = document.createElement(tagName); if (options.className) { @@ -37,18 +37,6 @@ function createElement(options: RenderOptions): HTMLElement { return element; } -export function renderText(text: string, options: RenderOptions = {}): HTMLElement { - const element = createElement(options); - element.textContent = text; - return element; -} - -export function renderFormattedText(formattedText: string, options: RenderOptions = {}): HTMLElement { - const element = createElement(options); - _renderFormattedText(element, parseFormattedText(formattedText), options.actionHandler); - return element; -} - /** * Create html nodes for the given content element. */ @@ -205,190 +193,3 @@ export function renderMarkdown(markdown: IMarkdownString, options: RenderOptions return element; } - -// --- formatted string parsing - -class StringStream { - private source: string; - private index: number; - - constructor(source: string) { - this.source = source; - this.index = 0; - } - - public eos(): boolean { - return this.index >= this.source.length; - } - - public next(): string { - const next = this.peek(); - this.advance(); - return next; - } - - public peek(): string { - return this.source[this.index]; - } - - public advance(): void { - this.index++; - } -} - -const enum FormatType { - Invalid, - Root, - Text, - Bold, - Italics, - Action, - ActionClose, - NewLine -} - -interface IFormatParseTree { - type: FormatType; - content?: string; - index?: number; - children?: IFormatParseTree[]; -} - -function _renderFormattedText(element: Node, treeNode: IFormatParseTree, actionHandler?: IContentActionHandler) { - let child: Node | undefined; - - if (treeNode.type === FormatType.Text) { - child = document.createTextNode(treeNode.content || ''); - } - else if (treeNode.type === FormatType.Bold) { - child = document.createElement('b'); - } - else if (treeNode.type === FormatType.Italics) { - child = document.createElement('i'); - } - else if (treeNode.type === FormatType.Action && actionHandler) { - const a = document.createElement('a'); - a.href = '#'; - actionHandler.disposeables.add(DOM.addStandardDisposableListener(a, 'click', (event) => { - actionHandler.callback(String(treeNode.index), event); - })); - - child = a; - } - else if (treeNode.type === FormatType.NewLine) { - child = document.createElement('br'); - } - else if (treeNode.type === FormatType.Root) { - child = element; - } - - if (child && element !== child) { - element.appendChild(child); - } - - if (child && Array.isArray(treeNode.children)) { - treeNode.children.forEach((nodeChild) => { - _renderFormattedText(child!, nodeChild, actionHandler); - }); - } -} - -function parseFormattedText(content: string): IFormatParseTree { - - const root: IFormatParseTree = { - type: FormatType.Root, - children: [] - }; - - let actionViewItemIndex = 0; - let current = root; - const stack: IFormatParseTree[] = []; - const stream = new StringStream(content); - - while (!stream.eos()) { - let next = stream.next(); - - const isEscapedFormatType = (next === '\\' && formatTagType(stream.peek()) !== FormatType.Invalid); - if (isEscapedFormatType) { - next = stream.next(); // unread the backslash if it escapes a format tag type - } - - if (!isEscapedFormatType && isFormatTag(next) && next === stream.peek()) { - stream.advance(); - - if (current.type === FormatType.Text) { - current = stack.pop()!; - } - - const type = formatTagType(next); - if (current.type === type || (current.type === FormatType.Action && type === FormatType.ActionClose)) { - current = stack.pop()!; - } else { - const newCurrent: IFormatParseTree = { - type: type, - children: [] - }; - - if (type === FormatType.Action) { - newCurrent.index = actionViewItemIndex; - actionViewItemIndex++; - } - - current.children!.push(newCurrent); - stack.push(current); - current = newCurrent; - } - } else if (next === '\n') { - if (current.type === FormatType.Text) { - current = stack.pop()!; - } - - current.children!.push({ - type: FormatType.NewLine - }); - - } else { - if (current.type !== FormatType.Text) { - const textCurrent: IFormatParseTree = { - type: FormatType.Text, - content: next - }; - current.children!.push(textCurrent); - stack.push(current); - current = textCurrent; - - } else { - current.content += next; - } - } - } - - if (current.type === FormatType.Text) { - current = stack.pop()!; - } - - if (stack.length) { - // incorrectly formatted string literal - } - - return root; -} - -function isFormatTag(char: string): boolean { - return formatTagType(char) !== FormatType.Invalid; -} - -function formatTagType(char: string): FormatType { - switch (char) { - case '*': - return FormatType.Bold; - case '_': - return FormatType.Italics; - case '[': - return FormatType.Action; - case ']': - return FormatType.ActionClose; - default: - return FormatType.Invalid; - } -} diff --git a/src/vs/base/browser/ui/inputbox/inputBox.ts b/src/vs/base/browser/ui/inputbox/inputBox.ts index 59d0c9900b9..fb8658883c3 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.ts +++ b/src/vs/base/browser/ui/inputbox/inputBox.ts @@ -8,7 +8,8 @@ import 'vs/css!./inputBox'; import * as nls from 'vs/nls'; import * as Bal from 'vs/base/browser/browser'; import * as dom from 'vs/base/browser/dom'; -import { RenderOptions, renderFormattedText, renderText } from 'vs/base/browser/htmlContentRenderer'; +import { RenderOptions } from 'vs/base/browser/htmlContentRenderer'; +import { renderFormattedText, renderText } from 'vs/base/browser/formattedTextRenderer'; import * as aria from 'vs/base/browser/ui/aria/aria'; import { IAction } from 'vs/base/common/actions'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; diff --git a/src/vs/base/test/browser/formattedTextRenderer.test.ts b/src/vs/base/test/browser/formattedTextRenderer.test.ts new file mode 100644 index 00000000000..0be97478522 --- /dev/null +++ b/src/vs/base/test/browser/formattedTextRenderer.test.ts @@ -0,0 +1,104 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { renderText, renderFormattedText } from 'vs/base/browser/formattedTextRenderer'; +import { DisposableStore } from 'vs/base/common/lifecycle'; + +suite('FormattedTextRenderer', () => { + const store = new DisposableStore(); + + setup(() => { + store.clear(); + }); + + teardown(() => { + store.clear(); + }); + + test('render simple element', () => { + let result: HTMLElement = renderText('testing'); + + assert.strictEqual(result.nodeType, document.ELEMENT_NODE); + assert.strictEqual(result.textContent, 'testing'); + assert.strictEqual(result.tagName, 'DIV'); + }); + + test('render element with class', () => { + let result: HTMLElement = renderText('testing', { + className: 'testClass' + }); + assert.strictEqual(result.nodeType, document.ELEMENT_NODE); + assert.strictEqual(result.className, 'testClass'); + }); + + test('simple formatting', () => { + let result: HTMLElement = renderFormattedText('**bold**'); + assert.strictEqual(result.children.length, 1); + assert.strictEqual(result.firstChild!.textContent, 'bold'); + assert.strictEqual((result.firstChild).tagName, 'B'); + assert.strictEqual(result.innerHTML, 'bold'); + + result = renderFormattedText('__italics__'); + assert.strictEqual(result.innerHTML, 'italics'); + + result = renderFormattedText('this string has **bold** and __italics__'); + assert.strictEqual(result.innerHTML, 'this string has bold and italics'); + }); + + test('no formatting', () => { + let result: HTMLElement = renderFormattedText('this is just a string'); + assert.strictEqual(result.innerHTML, 'this is just a string'); + }); + + test('preserve newlines', () => { + let result: HTMLElement = renderFormattedText('line one\nline two'); + assert.strictEqual(result.innerHTML, 'line one
line two'); + }); + + test('action', () => { + let callbackCalled = false; + let result: HTMLElement = renderFormattedText('[[action]]', { + actionHandler: { + callback(content) { + assert.strictEqual(content, '0'); + callbackCalled = true; + }, + disposeables: store + } + }); + assert.strictEqual(result.innerHTML, 'action'); + + let event: MouseEvent = document.createEvent('MouseEvent'); + event.initEvent('click', true, true); + result.firstChild!.dispatchEvent(event); + assert.strictEqual(callbackCalled, true); + }); + + test('fancy action', () => { + let callbackCalled = false; + let result: HTMLElement = renderFormattedText('__**[[action]]**__', { + actionHandler: { + callback(content) { + assert.strictEqual(content, '0'); + callbackCalled = true; + }, + disposeables: store + } + }); + assert.strictEqual(result.innerHTML, 'action'); + + let event: MouseEvent = document.createEvent('MouseEvent'); + event.initEvent('click', true, true); + result.firstChild!.firstChild!.firstChild!.dispatchEvent(event); + assert.strictEqual(callbackCalled, true); + }); + + test('escaped formatting', () => { + let result: HTMLElement = renderFormattedText('\\*\\*bold\\*\\*'); + assert.strictEqual(result.children.length, 0); + assert.strictEqual(result.innerHTML, '**bold**'); + }); +}); diff --git a/src/vs/base/test/browser/htmlContent.test.ts b/src/vs/base/test/browser/htmlContent.test.ts index d5dec0729d9..c52e73056b9 100644 --- a/src/vs/base/test/browser/htmlContent.test.ts +++ b/src/vs/base/test/browser/htmlContent.test.ts @@ -2,105 +2,12 @@ * 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 * as marked from 'vs/base/common/marked/marked'; -import { renderMarkdown, renderText, renderFormattedText } from 'vs/base/browser/htmlContentRenderer'; -import { DisposableStore } from 'vs/base/common/lifecycle'; +import { renderMarkdown } from 'vs/base/browser/htmlContentRenderer'; suite('HtmlContent', () => { - const store = new DisposableStore(); - - setup(() => { - store.clear(); - }); - - teardown(() => { - store.clear(); - }); - - test('render simple element', () => { - let result: HTMLElement = renderText('testing'); - - assert.strictEqual(result.nodeType, document.ELEMENT_NODE); - assert.strictEqual(result.textContent, 'testing'); - assert.strictEqual(result.tagName, 'DIV'); - }); - - test('render element with class', () => { - let result: HTMLElement = renderText('testing', { - className: 'testClass' - }); - assert.strictEqual(result.nodeType, document.ELEMENT_NODE); - assert.strictEqual(result.className, 'testClass'); - }); - - test('simple formatting', () => { - let result: HTMLElement = renderFormattedText('**bold**'); - assert.strictEqual(result.children.length, 1); - assert.strictEqual(result.firstChild!.textContent, 'bold'); - assert.strictEqual((result.firstChild).tagName, 'B'); - assert.strictEqual(result.innerHTML, 'bold'); - - result = renderFormattedText('__italics__'); - assert.strictEqual(result.innerHTML, 'italics'); - - result = renderFormattedText('this string has **bold** and __italics__'); - assert.strictEqual(result.innerHTML, 'this string has bold and italics'); - }); - - test('no formatting', () => { - let result: HTMLElement = renderFormattedText('this is just a string'); - assert.strictEqual(result.innerHTML, 'this is just a string'); - }); - - test('preserve newlines', () => { - let result: HTMLElement = renderFormattedText('line one\nline two'); - assert.strictEqual(result.innerHTML, 'line one
line two'); - }); - - test('action', () => { - let callbackCalled = false; - let result: HTMLElement = renderFormattedText('[[action]]', { - actionHandler: { - callback(content) { - assert.strictEqual(content, '0'); - callbackCalled = true; - }, - disposeables: store - } - }); - assert.strictEqual(result.innerHTML, 'action'); - - let event: MouseEvent = document.createEvent('MouseEvent'); - event.initEvent('click', true, true); - result.firstChild!.dispatchEvent(event); - assert.strictEqual(callbackCalled, true); - }); - - test('fancy action', () => { - let callbackCalled = false; - let result: HTMLElement = renderFormattedText('__**[[action]]**__', { - actionHandler: { - callback(content) { - assert.strictEqual(content, '0'); - callbackCalled = true; - }, - disposeables: store - } - }); - assert.strictEqual(result.innerHTML, 'action'); - - let event: MouseEvent = document.createEvent('MouseEvent'); - event.initEvent('click', true, true); - result.firstChild!.firstChild!.firstChild!.dispatchEvent(event); - assert.strictEqual(callbackCalled, true); - }); - - test('escaped formatting', () => { - let result: HTMLElement = renderFormattedText('\\*\\*bold\\*\\*'); - assert.strictEqual(result.children.length, 0); - assert.strictEqual(result.innerHTML, '**bold**'); - }); test('image rendering conforms to default', () => { const markdown = { value: `![image](someimageurl 'caption')` }; const result: HTMLElement = renderMarkdown(markdown); @@ -111,6 +18,7 @@ suite('HtmlContent', () => { }).trim(); assert.strictEqual(result.innerHTML, imageFromMarked); }); + test('image rendering conforms to default without title', () => { const markdown = { value: `![image](someimageurl)` }; const result: HTMLElement = renderMarkdown(markdown); @@ -121,14 +29,17 @@ suite('HtmlContent', () => { }).trim(); assert.strictEqual(result.innerHTML, imageFromMarked); }); + test('image width from title params', () => { let result: HTMLElement = renderMarkdown({ value: `![image](someimageurl|width=100 'caption')` }); assert.strictEqual(result.innerHTML, `

image

`); }); + test('image height from title params', () => { let result: HTMLElement = renderMarkdown({ value: `![image](someimageurl|height=100 'caption')` }); assert.strictEqual(result.innerHTML, `

image

`); }); + test('image width and height from title params', () => { let result: HTMLElement = renderMarkdown({ value: `![image](someimageurl|height=200,width=100 'caption')` }); assert.strictEqual(result.innerHTML, `

image

`); diff --git a/src/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.ts b/src/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.ts index 22e860f8eb0..1981153c0c8 100644 --- a/src/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.ts +++ b/src/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.ts @@ -7,7 +7,7 @@ import 'vs/css!./accessibilityHelp'; import * as browser from 'vs/base/browser/browser'; import * as dom from 'vs/base/browser/dom'; import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode'; -import { renderFormattedText } from 'vs/base/browser/htmlContentRenderer'; +import { renderFormattedText } from 'vs/base/browser/formattedTextRenderer'; import { alert } from 'vs/base/browser/ui/aria/aria'; import { Widget } from 'vs/base/browser/ui/widget'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; diff --git a/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.ts b/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.ts index 9d6b5c95ba2..a45ab650031 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.ts @@ -7,7 +7,7 @@ import 'vs/css!./accessibility'; import * as nls from 'vs/nls'; import * as dom from 'vs/base/browser/dom'; import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode'; -import { renderFormattedText } from 'vs/base/browser/htmlContentRenderer'; +import { renderFormattedText } from 'vs/base/browser/formattedTextRenderer'; import { alert } from 'vs/base/browser/ui/aria/aria'; import { Widget } from 'vs/base/browser/ui/widget'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; From ae85999e600984b521468465b1501f2408962af2 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 13 Aug 2019 11:59:04 -0700 Subject: [PATCH 580/861] Split MarkdownRenderOptions from FormattedTextRenderOptions --- src/vs/base/browser/formattedTextRenderer.ts | 31 ++++++++++++++--- src/vs/base/browser/htmlContentRenderer.ts | 34 +++++-------------- src/vs/base/browser/ui/inputbox/inputBox.ts | 4 +-- .../contrib/markdown/markdownRenderer.ts | 4 +-- 4 files changed, 38 insertions(+), 35 deletions(-) diff --git a/src/vs/base/browser/formattedTextRenderer.ts b/src/vs/base/browser/formattedTextRenderer.ts index 6d33caf8acc..0e9b0c9571c 100644 --- a/src/vs/base/browser/formattedTextRenderer.ts +++ b/src/vs/base/browser/formattedTextRenderer.ts @@ -4,20 +4,41 @@ *--------------------------------------------------------------------------------------------*/ import * as DOM from 'vs/base/browser/dom'; -import { createElement, IContentActionHandler, RenderOptions } from 'vs/base/browser/htmlContentRenderer'; +import { IMouseEvent } from 'vs/base/browser/mouseEvent'; +import { DisposableStore } from 'vs/base/common/lifecycle'; -export function renderText(text: string, options: RenderOptions = {}): HTMLElement { +export interface IContentActionHandler { + callback: (content: string, event?: IMouseEvent) => void; + readonly disposeables: DisposableStore; +} + +export interface FormattedTextRenderOptions { + readonly className?: string; + readonly inline?: boolean; + readonly actionHandler?: IContentActionHandler; +} + +export function renderText(text: string, options: FormattedTextRenderOptions = {}): HTMLElement { const element = createElement(options); element.textContent = text; return element; } -export function renderFormattedText(formattedText: string, options: RenderOptions = {}): HTMLElement { +export function renderFormattedText(formattedText: string, options: FormattedTextRenderOptions = {}): HTMLElement { const element = createElement(options); _renderFormattedText(element, parseFormattedText(formattedText), options.actionHandler); return element; } +export function createElement(options: FormattedTextRenderOptions): HTMLElement { + const tagName = options.inline ? 'span' : 'div'; + const element = document.createElement(tagName); + if (options.className) { + element.className = options.className; + } + return element; +} + class StringStream { private source: string; private index: number; @@ -64,7 +85,7 @@ interface IFormatParseTree { children?: IFormatParseTree[]; } -export function _renderFormattedText(element: Node, treeNode: IFormatParseTree, actionHandler?: IContentActionHandler) { +function _renderFormattedText(element: Node, treeNode: IFormatParseTree, actionHandler?: IContentActionHandler) { let child: Node | undefined; if (treeNode.type === FormatType.Text) { @@ -98,7 +119,7 @@ export function _renderFormattedText(element: Node, treeNode: IFormatParseTree, } } -export function parseFormattedText(content: string): IFormatParseTree { +function parseFormattedText(content: string): IFormatParseTree { const root: IFormatParseTree = { type: FormatType.Root, diff --git a/src/vs/base/browser/htmlContentRenderer.ts b/src/vs/base/browser/htmlContentRenderer.ts index 80f956bf138..7fd9f63b75a 100644 --- a/src/vs/base/browser/htmlContentRenderer.ts +++ b/src/vs/base/browser/htmlContentRenderer.ts @@ -4,43 +4,25 @@ *--------------------------------------------------------------------------------------------*/ import * as DOM from 'vs/base/browser/dom'; -import { defaultGenerator } from 'vs/base/common/idGenerator'; -import { escape } from 'vs/base/common/strings'; -import { removeMarkdownEscapes, IMarkdownString, parseHrefAndDimensions } from 'vs/base/common/htmlContent'; -import * as marked from 'vs/base/common/marked/marked'; -import { IMouseEvent } from 'vs/base/browser/mouseEvent'; -import { DisposableStore } from 'vs/base/common/lifecycle'; +import { createElement, FormattedTextRenderOptions } from 'vs/base/browser/formattedTextRenderer'; import { onUnexpectedError } from 'vs/base/common/errors'; -import { URI } from 'vs/base/common/uri'; +import { IMarkdownString, parseHrefAndDimensions, removeMarkdownEscapes } from 'vs/base/common/htmlContent'; +import { defaultGenerator } from 'vs/base/common/idGenerator'; +import * as marked from 'vs/base/common/marked/marked'; import { parse } from 'vs/base/common/marshalling'; import { cloneAndChange } from 'vs/base/common/objects'; +import { escape } from 'vs/base/common/strings'; +import { URI } from 'vs/base/common/uri'; -export interface IContentActionHandler { - callback: (content: string, event?: IMouseEvent) => void; - readonly disposeables: DisposableStore; -} - -export interface RenderOptions { - className?: string; - inline?: boolean; - actionHandler?: IContentActionHandler; +export interface MarkdownRenderOptions extends FormattedTextRenderOptions { codeBlockRenderer?: (modeId: string, value: string) => Promise; codeBlockRenderCallback?: () => void; } -export function createElement(options: RenderOptions): HTMLElement { - const tagName = options.inline ? 'span' : 'div'; - const element = document.createElement(tagName); - if (options.className) { - element.className = options.className; - } - return element; -} - /** * Create html nodes for the given content element. */ -export function renderMarkdown(markdown: IMarkdownString, options: RenderOptions = {}): HTMLElement { +export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRenderOptions = {}): HTMLElement { const element = createElement(options); const _uriMassage = function (part: string): string { diff --git a/src/vs/base/browser/ui/inputbox/inputBox.ts b/src/vs/base/browser/ui/inputbox/inputBox.ts index fb8658883c3..454ce9c87af 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.ts +++ b/src/vs/base/browser/ui/inputbox/inputBox.ts @@ -8,7 +8,7 @@ import 'vs/css!./inputBox'; import * as nls from 'vs/nls'; import * as Bal from 'vs/base/browser/browser'; import * as dom from 'vs/base/browser/dom'; -import { RenderOptions } from 'vs/base/browser/htmlContentRenderer'; +import { MarkdownRenderOptions } from 'vs/base/browser/htmlContentRenderer'; import { renderFormattedText, renderText } from 'vs/base/browser/formattedTextRenderer'; import * as aria from 'vs/base/browser/ui/aria/aria'; import { IAction } from 'vs/base/common/actions'; @@ -439,7 +439,7 @@ export class InputBox extends Widget { div = dom.append(container, $('.monaco-inputbox-container')); layout(); - const renderOptions: RenderOptions = { + const renderOptions: MarkdownRenderOptions = { inline: true, className: 'monaco-inputbox-message' }; diff --git a/src/vs/editor/contrib/markdown/markdownRenderer.ts b/src/vs/editor/contrib/markdown/markdownRenderer.ts index 5825a919bf5..34a713d0b17 100644 --- a/src/vs/editor/contrib/markdown/markdownRenderer.ts +++ b/src/vs/editor/contrib/markdown/markdownRenderer.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IMarkdownString } from 'vs/base/common/htmlContent'; -import { renderMarkdown, RenderOptions } from 'vs/base/browser/htmlContentRenderer'; +import { renderMarkdown, MarkdownRenderOptions } from 'vs/base/browser/htmlContentRenderer'; import { IOpenerService, NullOpenerService } from 'vs/platform/opener/common/opener'; import { IModeService } from 'vs/editor/common/services/modeService'; import { URI } from 'vs/base/common/uri'; @@ -33,7 +33,7 @@ export class MarkdownRenderer extends Disposable { super(); } - private getOptions(disposeables: DisposableStore): RenderOptions { + private getOptions(disposeables: DisposableStore): MarkdownRenderOptions { return { codeBlockRenderer: (languageAlias, value) => { // In markdown, From 12792640f5976311352ef701579a77325b79aa03 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 13 Aug 2019 12:02:32 -0700 Subject: [PATCH 581/861] Rename htmlContentRenderer -> markdownRenderer --- .../browser/{htmlContentRenderer.ts => markdownRenderer.ts} | 0 src/vs/base/browser/ui/inputbox/inputBox.ts | 2 +- src/vs/base/browser/ui/selectBox/selectBoxCustom.ts | 2 +- .../browser/{htmlContent.test.ts => markdownRenderer.test.ts} | 4 ++-- src/vs/editor/contrib/markdown/markdownRenderer.ts | 2 +- .../workbench/contrib/comments/browser/commentsTreeViewer.ts | 2 +- src/vs/workbench/contrib/preferences/browser/settingsTree.ts | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) rename src/vs/base/browser/{htmlContentRenderer.ts => markdownRenderer.ts} (100%) rename src/vs/base/test/browser/{htmlContent.test.ts => markdownRenderer.test.ts} (95%) diff --git a/src/vs/base/browser/htmlContentRenderer.ts b/src/vs/base/browser/markdownRenderer.ts similarity index 100% rename from src/vs/base/browser/htmlContentRenderer.ts rename to src/vs/base/browser/markdownRenderer.ts diff --git a/src/vs/base/browser/ui/inputbox/inputBox.ts b/src/vs/base/browser/ui/inputbox/inputBox.ts index 454ce9c87af..7af2a58f46d 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.ts +++ b/src/vs/base/browser/ui/inputbox/inputBox.ts @@ -8,7 +8,7 @@ import 'vs/css!./inputBox'; import * as nls from 'vs/nls'; import * as Bal from 'vs/base/browser/browser'; import * as dom from 'vs/base/browser/dom'; -import { MarkdownRenderOptions } from 'vs/base/browser/htmlContentRenderer'; +import { MarkdownRenderOptions } from 'vs/base/browser/markdownRenderer'; import { renderFormattedText, renderText } from 'vs/base/browser/formattedTextRenderer'; import * as aria from 'vs/base/browser/ui/aria/aria'; import { IAction } from 'vs/base/common/actions'; diff --git a/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts b/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts index 134c64bbef4..d144eb63050 100644 --- a/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts +++ b/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts @@ -18,7 +18,7 @@ import { domEvent } from 'vs/base/browser/event'; import { ScrollbarVisibility } from 'vs/base/common/scrollable'; import { ISelectBoxDelegate, ISelectOptionItem, ISelectBoxOptions, ISelectBoxStyles, ISelectData } from 'vs/base/browser/ui/selectBox/selectBox'; import { isMacintosh } from 'vs/base/common/platform'; -import { renderMarkdown } from 'vs/base/browser/htmlContentRenderer'; +import { renderMarkdown } from 'vs/base/browser/markdownRenderer'; const $ = dom.$; diff --git a/src/vs/base/test/browser/htmlContent.test.ts b/src/vs/base/test/browser/markdownRenderer.test.ts similarity index 95% rename from src/vs/base/test/browser/htmlContent.test.ts rename to src/vs/base/test/browser/markdownRenderer.test.ts index c52e73056b9..525eb86e741 100644 --- a/src/vs/base/test/browser/htmlContent.test.ts +++ b/src/vs/base/test/browser/markdownRenderer.test.ts @@ -5,9 +5,9 @@ import * as assert from 'assert'; import * as marked from 'vs/base/common/marked/marked'; -import { renderMarkdown } from 'vs/base/browser/htmlContentRenderer'; +import { renderMarkdown } from 'vs/base/browser/markdownRenderer'; -suite('HtmlContent', () => { +suite('MarkdownRenderer', () => { test('image rendering conforms to default', () => { const markdown = { value: `![image](someimageurl 'caption')` }; const result: HTMLElement = renderMarkdown(markdown); diff --git a/src/vs/editor/contrib/markdown/markdownRenderer.ts b/src/vs/editor/contrib/markdown/markdownRenderer.ts index 34a713d0b17..81f0b2ccc87 100644 --- a/src/vs/editor/contrib/markdown/markdownRenderer.ts +++ b/src/vs/editor/contrib/markdown/markdownRenderer.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IMarkdownString } from 'vs/base/common/htmlContent'; -import { renderMarkdown, MarkdownRenderOptions } from 'vs/base/browser/htmlContentRenderer'; +import { renderMarkdown, MarkdownRenderOptions } from 'vs/base/browser/markdownRenderer'; import { IOpenerService, NullOpenerService } from 'vs/platform/opener/common/opener'; import { IModeService } from 'vs/editor/common/services/modeService'; import { URI } from 'vs/base/common/uri'; diff --git a/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts b/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts index 7ab435e96ca..5baf982dd93 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts @@ -5,7 +5,7 @@ import * as dom from 'vs/base/browser/dom'; import * as nls from 'vs/nls'; -import { renderMarkdown } from 'vs/base/browser/htmlContentRenderer'; +import { renderMarkdown } from 'vs/base/browser/markdownRenderer'; import { onUnexpectedError } from 'vs/base/common/errors'; import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts index 7106918e292..82465a22624 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as DOM from 'vs/base/browser/dom'; -import { renderMarkdown } from 'vs/base/browser/htmlContentRenderer'; +import { renderMarkdown } from 'vs/base/browser/markdownRenderer'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { IMouseEvent } from 'vs/base/browser/mouseEvent'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; From 0921202c2cb04a1b3755ab347ee0a5e509b1e4e3 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 14 Aug 2019 07:59:53 +0200 Subject: [PATCH 582/861] web - do not loose state on unload --- src/vs/platform/storage/browser/storageService.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/vs/platform/storage/browser/storageService.ts b/src/vs/platform/storage/browser/storageService.ts index 392ca58f2b8..a11505e32ac 100644 --- a/src/vs/platform/storage/browser/storageService.ts +++ b/src/vs/platform/storage/browser/storageService.ts @@ -144,8 +144,10 @@ export class BrowserStorageService extends Disposable implements IStorageService // Signal as event so that clients can still store data this._onWillSaveState.fire({ reason: WillSaveStateReason.SHUTDOWN }); - // Close DBs - this.globalStorage.close(); - this.workspaceStorage.close(); + // We explicitly do not close our DBs because writing data onBeforeUnload() + // can result in unexpected results. Namely, it seems that - even though this + // operation is async - sometimes it is being triggered on unload and + // succeeds. Often though, the DBs turn out to be empty because the write + // never had a chance to complete. } } From ba69d8dcccaebbfaa94906503728eb7c3e45b9c1 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 14 Aug 2019 08:33:50 +0200 Subject: [PATCH 583/861] open exter - move into opener service --- .../editor/browser/services/openerService.ts | 9 ++++- src/vs/platform/opener/common/opener.ts | 14 ++++++- .../workbench/api/browser/mainThreadWindow.ts | 7 ++-- .../files/browser/editors/binaryFileEditor.ts | 14 ++----- .../opener/electron-browser/openerService.ts | 40 +++++++++++++++++++ src/vs/workbench/workbench.common.main.ts | 3 -- src/vs/workbench/workbench.desktop.main.ts | 1 + src/vs/workbench/workbench.web.main.ts | 3 ++ 8 files changed, 70 insertions(+), 21 deletions(-) create mode 100644 src/vs/workbench/services/opener/electron-browser/openerService.ts diff --git a/src/vs/editor/browser/services/openerService.ts b/src/vs/editor/browser/services/openerService.ts index c175034f969..608d6e3b5d9 100644 --- a/src/vs/editor/browser/services/openerService.ts +++ b/src/vs/editor/browser/services/openerService.ts @@ -55,8 +55,7 @@ export class OpenerService implements IOpenerService { if (equalsIgnoreCase(scheme, Schemas.http) || equalsIgnoreCase(scheme, Schemas.https) || equalsIgnoreCase(scheme, Schemas.mailto)) { // open http or default mail application - dom.windowOpenNoOpener(encodeURI(resource.toString(true))); - return Promise.resolve(true); + return this.openExternal(resource); } else if (equalsIgnoreCase(scheme, Schemas.command)) { // run command or bail out if command isn't known @@ -100,4 +99,10 @@ export class OpenerService implements IOpenerService { ).then(() => true); } } + + openExternal(resource: URI): Promise { + dom.windowOpenNoOpener(encodeURI(resource.toString(true))); + + return Promise.resolve(true); + } } diff --git a/src/vs/platform/opener/common/opener.ts b/src/vs/platform/opener/common/opener.ts index 8c0f9fee5df..c8336fc712c 100644 --- a/src/vs/platform/opener/common/opener.ts +++ b/src/vs/platform/opener/common/opener.ts @@ -9,7 +9,6 @@ import { IDisposable } from 'vs/base/common/lifecycle'; export const IOpenerService = createDecorator('openerService'); - export interface IOpener { open(resource: URI, options?: { openToSide?: boolean }): Promise; } @@ -18,6 +17,9 @@ export interface IOpenerService { _serviceBrand: any; + /** + * Register a participant that can handle the open() call. + */ registerOpener(opener: IOpener): IDisposable; /** @@ -27,10 +29,18 @@ export interface IOpenerService { * @return A promise that resolves when the opening is done. */ open(resource: URI, options?: { openToSide?: boolean }): Promise; + + /** + * Opens a URL externally. + * + * @param url A resource to open externally. + */ + openExternal(resource: URI): Promise; } export const NullOpenerService: IOpenerService = Object.freeze({ _serviceBrand: undefined, registerOpener() { return { dispose() { } }; }, - open() { return Promise.resolve(false); } + open() { return Promise.resolve(false); }, + openExternal() { return Promise.resolve(false); } }); diff --git a/src/vs/workbench/api/browser/mainThreadWindow.ts b/src/vs/workbench/api/browser/mainThreadWindow.ts index 410bb4ec66d..acbb5c6f306 100644 --- a/src/vs/workbench/api/browser/mainThreadWindow.ts +++ b/src/vs/workbench/api/browser/mainThreadWindow.ts @@ -6,12 +6,13 @@ import { Event } from 'vs/base/common/event'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { URI, UriComponents } from 'vs/base/common/uri'; -import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows'; +import { IWindowService } from 'vs/platform/windows/common/windows'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { ExtHostContext, ExtHostWindowShape, IExtHostContext, MainContext, MainThreadWindowShape, IOpenUriOptions } from '../common/extHost.protocol'; import { ITunnelService, RemoteTunnel } from 'vs/platform/remote/common/tunnel'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { extractLocalHostUriMetaDataForPortMapping } from 'vs/workbench/contrib/webview/common/portMapping'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; @extHostNamedCustomer(MainContext.MainThreadWindow) export class MainThreadWindow implements MainThreadWindowShape { @@ -23,7 +24,7 @@ export class MainThreadWindow implements MainThreadWindowShape { constructor( extHostContext: IExtHostContext, @IWindowService private readonly windowService: IWindowService, - @IWindowsService private readonly windowsService: IWindowsService, + @IOpenerService private readonly openerService: IOpenerService, @ITunnelService private readonly tunnelService: ITunnelService, @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService ) { @@ -58,7 +59,7 @@ export class MainThreadWindow implements MainThreadWindowShape { } } - return this.windowsService.openExternal(encodeURI(uri.toString(true))); + return this.openerService.openExternal(uri); } private getOrCreateTunnel(remotePort: number): Promise | undefined { diff --git a/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts b/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts index 580a2990ac4..d6ce1130e86 100644 --- a/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts +++ b/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts @@ -7,16 +7,15 @@ import * as nls from 'vs/nls'; import { BaseBinaryResourceEditor } from 'vs/workbench/browser/parts/editor/binaryEditor'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { IWindowsService } from 'vs/platform/windows/common/windows'; import { EditorInput, EditorOptions } from 'vs/workbench/common/editor'; import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput'; -import { URI } from 'vs/base/common/uri'; import { BINARY_FILE_EDITOR_ID } from 'vs/workbench/contrib/files/common/files'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IFileService } from 'vs/platform/files/common/files'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; /** * An implementation of editor for binary files like images. @@ -28,7 +27,7 @@ export class BinaryFileEditor extends BaseBinaryResourceEditor { constructor( @ITelemetryService telemetryService: ITelemetryService, @IThemeService themeService: IThemeService, - @IWindowsService private readonly windowsService: IWindowsService, + @IOpenerService private readonly openerService: IOpenerService, @IEditorService private readonly editorService: IEditorService, @IStorageService storageService: IStorageService, @IFileService fileService: IFileService, @@ -39,7 +38,7 @@ export class BinaryFileEditor extends BaseBinaryResourceEditor { BinaryFileEditor.ID, { openInternal: (input, options) => this.openInternal(input, options), - openExternal: resource => this.openExternal(resource) + openExternal: resource => this.openerService.openExternal(resource) }, telemetryService, themeService, @@ -58,13 +57,6 @@ export class BinaryFileEditor extends BaseBinaryResourceEditor { } } - private async openExternal(resource: URI): Promise { - const didOpen = await this.windowsService.openExternal(resource.toString()); - if (!didOpen) { - return this.windowsService.showItemInFolder(resource); - } - } - getTitle(): string | null { return this.input ? this.input.getName() : nls.localize('binaryFileEditor', "Binary File Viewer"); } diff --git a/src/vs/workbench/services/opener/electron-browser/openerService.ts b/src/vs/workbench/services/opener/electron-browser/openerService.ts new file mode 100644 index 00000000000..3085bd78a14 --- /dev/null +++ b/src/vs/workbench/services/opener/electron-browser/openerService.ts @@ -0,0 +1,40 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import { OpenerService as BaseOpenerService } from 'vs/editor/browser/services/openerService'; +import { IWindowsService } from 'vs/platform/windows/common/windows'; +import { ICommandService } from 'vs/platform/commands/common/commands'; +import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; +import { Schemas } from 'vs/base/common/network'; +import { URI } from 'vs/base/common/uri'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; + +export class OpenerService extends BaseOpenerService { + + _serviceBrand!: ServiceIdentifier; + + constructor( + @ICodeEditorService codeEditorService: ICodeEditorService, + @ICommandService commandService: ICommandService, + @IWindowsService private readonly windowsService: IWindowsService + ) { + super(codeEditorService, commandService); + } + + async openExternal(resource: URI): Promise { + const success = this.windowsService.openExternal(encodeURI(resource.toString(true))); + if (!success && resource.scheme === Schemas.file) { + await this.windowsService.showItemInFolder(resource); + + return true; + } + + return success; + } +} + +registerSingleton(IOpenerService, OpenerService, true); diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index 3558c2ffef3..72765299a31 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -80,8 +80,6 @@ import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IListService, ListService } from 'vs/platform/list/browser/listService'; -import { OpenerService } from 'vs/editor/browser/services/openerService'; -import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService'; import { EditorWorkerServiceImpl } from 'vs/editor/common/services/editorWorkerServiceImpl'; import { MarkerDecorationsService } from 'vs/editor/common/services/markerDecorationsServiceImpl'; @@ -102,7 +100,6 @@ import { DownloadService } from 'vs/platform/download/common/downloadService'; registerSingleton(IExtensionGalleryService, ExtensionGalleryService, true); registerSingleton(IContextViewService, ContextViewService, true); registerSingleton(IListService, ListService, true); -registerSingleton(IOpenerService, OpenerService, true); registerSingleton(IEditorWorkerService, EditorWorkerServiceImpl); registerSingleton(IMarkerDecorationsService, MarkerDecorationsService); registerSingleton(IMarkerService, MarkerService, true); diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index c2d6ea7a5bc..4d2996a0ed6 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -48,6 +48,7 @@ import 'vs/workbench/services/extensionManagement/node/extensionManagementServic import 'vs/workbench/services/accessibility/node/accessibilityService'; import 'vs/workbench/services/remote/node/tunnelService'; import 'vs/workbench/services/backup/node/backupFileService'; +import 'vs/workbench/services/opener/electron-browser/openerService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 1a41fc77ac4..169b3c07ef6 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -54,6 +54,8 @@ import { ContextMenuService } from 'vs/platform/contextview/browser/contextMenuS import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; import { BackupFileService } from 'vs/workbench/services/backup/common/backupFileService'; import { ExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagementService'; +import { OpenerService } from 'vs/editor/browser/services/openerService'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; registerSingleton(IRequestService, RequestService, true); registerSingleton(IExtensionManagementService, ExtensionManagementService); @@ -63,6 +65,7 @@ registerSingleton(IClipboardService, BrowserClipboardService, true); registerSingleton(IAccessibilityService, BrowserAccessibilityService, true); registerSingleton(ILifecycleService, BrowserLifecycleService); registerSingleton(IContextMenuService, ContextMenuService); +registerSingleton(IOpenerService, OpenerService, true); //#endregion From 1a5ac941e78b860633c1b7c1d922419878379bc8 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 14 Aug 2019 10:15:40 +0200 Subject: [PATCH 584/861] add extension kind web --- src/vs/platform/extensions/common/extensions.ts | 4 ++-- .../services/extensions/browser/extensionService.ts | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/vs/platform/extensions/common/extensions.ts b/src/vs/platform/extensions/common/extensions.ts index 93a52746e6b..a043fdfcaa3 100644 --- a/src/vs/platform/extensions/common/extensions.ts +++ b/src/vs/platform/extensions/common/extensions.ts @@ -106,7 +106,7 @@ export interface IExtensionContributions { localizations?: ILocalization[]; } -export type ExtensionKind = 'ui' | 'workspace'; +export type ExtensionKind = 'ui' | 'workspace' | 'web'; export function isIExtensionIdentifier(thing: any): thing is IExtensionIdentifier { return thing @@ -221,4 +221,4 @@ export interface IExtensionDescription extends IExtensionManifest { export function isLanguagePackExtension(manifest: IExtensionManifest): boolean { return manifest.contributes && manifest.contributes.localizations ? manifest.contributes.localizations.length > 0 : false; -} \ No newline at end of file +} diff --git a/src/vs/workbench/services/extensions/browser/extensionService.ts b/src/vs/workbench/services/extensions/browser/extensionService.ts index a32024e35ac..7d624f12bf8 100644 --- a/src/vs/workbench/services/extensions/browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/browser/extensionService.ts @@ -65,11 +65,14 @@ export class ExtensionService extends AbstractExtensionService implements IExten const remoteAgentConnection = this._remoteAgentService.getConnection()!; - const webHostProcessWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, true, Promise.resolve([]), URI.parse('empty:value')); //todo@joh + const webExtensions = this.getExtensions().then(extensions => extensions.filter(ext => ext.extensionKind === 'web')); + const remoteExtensions = this.getExtensions().then(extensions => extensions.filter(ext => ext.extensionKind !== 'web')); + + const webHostProcessWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, true, webExtensions, URI.parse('empty:value')); //todo@joh const webHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, webHostProcessWorker, remoteAgentConnection.remoteAuthority, initialActivationEvents); result.push(webHostProcessManager); - const remoteExtHostProcessWorker = this._instantiationService.createInstance(RemoteExtensionHostClient, this.getExtensions(), this._createProvider(remoteAgentConnection.remoteAuthority), this._remoteAgentService.socketFactory); + const remoteExtHostProcessWorker = this._instantiationService.createInstance(RemoteExtensionHostClient, remoteExtensions, this._createProvider(remoteAgentConnection.remoteAuthority), this._remoteAgentService.socketFactory); const remoteExtHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, remoteExtHostProcessWorker, remoteAgentConnection.remoteAuthority, initialActivationEvents); result.push(remoteExtHostProcessManager); From 6883d5533b0dd150298d18953713f69e41678a74 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 14 Aug 2019 10:31:43 +0200 Subject: [PATCH 585/861] add action only in remote --- .../workbench/contrib/extensions/browser/extensionsViews.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts index ab7e8ee8fb1..733aa5fa5b1 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts @@ -859,7 +859,7 @@ export class ServerExtensionsView extends ExtensionsListView { @IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService, @IExtensionManagementServerService extensionManagementServerService: IExtensionManagementServerService, @IProductService productService: IProductService, - @IContextKeyService contextKeyService: IContextKeyService, + @IContextKeyService contextKeyService: IContextKeyService ) { options.server = server; super(options, notificationService, keybindingService, contextMenuService, instantiationService, themeService, extensionService, extensionsWorkbenchService, editorService, tipsService, telemetryService, configurationService, contextService, experimentService, workbenchThemeService, extensionManagementServerService, productService, contextKeyService); @@ -875,7 +875,7 @@ export class ServerExtensionsView extends ExtensionsListView { } getActions(): IAction[] { - if (this.extensionManagementServerService.localExtensionManagementServer === this.server) { + if (this.extensionManagementServerService.remoteExtensionManagementServer && this.extensionManagementServerService.localExtensionManagementServer === this.server) { const installLocalExtensionsInRemoteAction = this._register(this.instantiationService.createInstance(InstallLocalExtensionsInRemoteAction, false)); installLocalExtensionsInRemoteAction.class = 'octicon octicon-cloud-download'; return [installLocalExtensionsInRemoteAction]; From fa8c6e6b77a206f8d65bc53a83b100e253ae9658 Mon Sep 17 00:00:00 2001 From: gjsjohnmurray Date: Wed, 14 Aug 2019 10:42:59 +0100 Subject: [PATCH 586/861] Improve #79047 fix after feedback --- src/vs/workbench/contrib/files/common/explorerService.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/files/common/explorerService.ts b/src/vs/workbench/contrib/files/common/explorerService.ts index 81967032028..aff4390570c 100644 --- a/src/vs/workbench/contrib/files/common/explorerService.ts +++ b/src/vs/workbench/contrib/files/common/explorerService.ts @@ -158,12 +158,10 @@ export class ExplorerService implements IExplorerService { // Stat needs to be resolved first and then revealed const options: IResolveFileOptions = { resolveTo: [resource], resolveMetadata: this.sortOrder === 'modified' }; const workspaceFolder = this.contextService.getWorkspaceFolder(resource); - const rootUri = workspaceFolder ? workspaceFolder.uri : this.roots[0].resource; - - // Do not waste time looking in a different scheme - if (resource.scheme !== rootUri.scheme) { + if (workspaceFolder === null) { return Promise.resolve(undefined); } + const rootUri = workspaceFolder.uri; const root = this.roots.filter(r => r.resource.toString() === rootUri.toString()).pop()!; From b2b0c86dda9fe74c6e76d56fb61fe545859726b2 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 14 Aug 2019 11:58:58 +0200 Subject: [PATCH 587/861] use `vscode-remote`-endpoint when importing scripts --- src/vs/workbench/api/worker/extHostExtensionService.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/api/worker/extHostExtensionService.ts b/src/vs/workbench/api/worker/extHostExtensionService.ts index 6f7f2b67feb..be34dbe2d64 100644 --- a/src/vs/workbench/api/worker/extHostExtensionService.ts +++ b/src/vs/workbench/api/worker/extHostExtensionService.ts @@ -13,6 +13,8 @@ import * as vscode from 'vscode'; import { TernarySearchTree } from 'vs/base/common/map'; import { nullExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; +import { isWeb } from 'vs/base/common/platform'; +import { URI } from 'vs/base/common/uri'; class ApiInstances { @@ -83,8 +85,14 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { }; try { + // todo@joh this is a copy of `dom.ts#asDomUri` + // build url of the things we resolve + const url = isWeb + ? URI.parse(window.location.href).with({ path: '/vscode-remote', query: JSON.stringify(URI.file(modulePath)) }).toString(true) + : modulePath; + activationTimesBuilder.codeLoadingStart(); - importScripts(modulePath); + importScripts(url); } finally { activationTimesBuilder.codeLoadingStop(); } From 158f859217d08b50830dcf451375d83790a48333 Mon Sep 17 00:00:00 2001 From: skprabhanjan Date: Wed, 14 Aug 2019 17:50:50 +0530 Subject: [PATCH 588/861] Added preserveCase in search side bar --- .../search/browser/media/searchview.css | 14 +++++++++ .../contrib/search/browser/searchView.ts | 12 +++++++- .../contrib/search/browser/searchWidget.ts | 29 ++++++++++++++++++- .../contrib/search/common/searchModel.ts | 15 ++++++++-- .../services/search/common/replace.ts | 22 ++++++++++++-- 5 files changed, 85 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/search/browser/media/searchview.css b/src/vs/workbench/contrib/search/browser/media/searchview.css index 3181a10d8d1..f530bce968a 100644 --- a/src/vs/workbench/contrib/search/browser/media/searchview.css +++ b/src/vs/workbench/contrib/search/browser/media/searchview.css @@ -60,6 +60,20 @@ display: inline-flex; } +.search-view .search-widget .replace-input { + position: relative; + display: flex; + display: -webkit-flex; + vertical-align: middle; + width: auto !important; +} + +.search-view .search-widget .replace-input > .controls { + position: absolute; + top: 3px; + right: 2px; +} + .search-view .search-widget .replace-container.disabled { display: none; } diff --git a/src/vs/workbench/contrib/search/browser/searchView.ts b/src/vs/workbench/contrib/search/browser/searchView.ts index 2daad95ca68..e42ff0dd0e5 100644 --- a/src/vs/workbench/contrib/search/browser/searchView.ts +++ b/src/vs/workbench/contrib/search/browser/searchView.ts @@ -364,6 +364,7 @@ export class SearchView extends ViewletPanel { const searchHistory = history.search || this.viewletState['query.searchHistory'] || []; const replaceHistory = history.replace || this.viewletState['query.replaceHistory'] || []; const showReplace = typeof this.viewletState['view.showReplace'] === 'boolean' ? this.viewletState['view.showReplace'] : true; + const preserveCase = this.viewletState['query.preserveCase'] === true; this.searchWidget = this._register(this.instantiationService.createInstance(SearchWidget, container, { value: contentPattern, @@ -372,7 +373,8 @@ export class SearchView extends ViewletPanel { isCaseSensitive: isCaseSensitive, isWholeWords: isWholeWords, searchHistory: searchHistory, - replaceHistory: replaceHistory + replaceHistory: replaceHistory, + preserveCase: preserveCase })); if (showReplace) { @@ -390,6 +392,12 @@ export class SearchView extends ViewletPanel { this.viewModel.replaceActive = state; this.refreshTree(); })); + + this._register(this.searchWidget.onPreserveCaseChange((state) => { + this.viewModel.preserveCase = state; + this.refreshTree(); + })); + this._register(this.searchWidget.onReplaceValueChanged((value) => { this.viewModel.replaceString = this.searchWidget.getReplaceValue(); this.delayedRefresh.trigger(() => this.refreshTree()); @@ -1641,6 +1649,7 @@ export class SearchView extends ViewletPanel { const patternExcludes = this.inputPatternExcludes.getValue().trim(); const patternIncludes = this.inputPatternIncludes.getValue().trim(); const useExcludesAndIgnoreFiles = this.inputPatternExcludes.useExcludesAndIgnoreFiles(); + const preserveCase = this.viewModel.preserveCase; this.viewletState['query.contentPattern'] = contentPattern; this.viewletState['query.regex'] = isRegex; @@ -1649,6 +1658,7 @@ export class SearchView extends ViewletPanel { this.viewletState['query.folderExclusions'] = patternExcludes; this.viewletState['query.folderIncludes'] = patternIncludes; this.viewletState['query.useExcludesAndIgnoreFiles'] = useExcludesAndIgnoreFiles; + this.viewletState['query.preserveCase'] = preserveCase; const isReplaceShown = this.searchAndReplaceWidget.isReplaceShown(); this.viewletState['view.showReplace'] = isReplaceShown; diff --git a/src/vs/workbench/contrib/search/browser/searchWidget.ts b/src/vs/workbench/contrib/search/browser/searchWidget.ts index 6cfbb4d5542..26b29b280c1 100644 --- a/src/vs/workbench/contrib/search/browser/searchWidget.ts +++ b/src/vs/workbench/contrib/search/browser/searchWidget.ts @@ -33,6 +33,7 @@ import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; +import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox'; export interface ISearchWidgetOptions { value?: string; @@ -42,6 +43,7 @@ export interface ISearchWidgetOptions { isWholeWords?: boolean; searchHistory?: string[]; replaceHistory?: string[]; + preserveCase?: boolean; } class ReplaceAllAction extends Action { @@ -97,6 +99,7 @@ export class SearchWidget extends Widget { replaceInputFocusTracker: dom.IFocusTracker; private replaceInputBoxFocused: IContextKey; private _replaceHistoryDelayer: Delayer; + private _preserveCase: Checkbox; private ignoreGlobalFindBufferOnNextFocus = false; private previousGlobalFindBufferValue: string; @@ -113,6 +116,9 @@ export class SearchWidget extends Widget { private _onReplaceStateChange = this._register(new Emitter()); readonly onReplaceStateChange: Event = this._onReplaceStateChange.event; + private _onPreserveCaseChange = this._register(new Emitter()); + readonly onPreserveCaseChange: Event = this._onPreserveCaseChange.event; + private _onReplaceValueChanged = this._register(new Emitter()); readonly onReplaceValueChanged: Event = this._onReplaceValueChanged.event; @@ -333,13 +339,34 @@ export class SearchWidget extends Widget { private renderReplaceInput(parent: HTMLElement, options: ISearchWidgetOptions): void { this.replaceContainer = dom.append(parent, dom.$('.replace-container.disabled')); - const replaceBox = dom.append(this.replaceContainer, dom.$('.input-box')); + const replaceBox = dom.append(this.replaceContainer, dom.$('.replace-input')); + this.replaceInput = this._register(new ContextScopedHistoryInputBox(replaceBox, this.contextViewService, { ariaLabel: nls.localize('label.Replace', 'Replace: Type replace term and press Enter to preview or Escape to cancel'), placeholder: nls.localize('search.replace.placeHolder', "Replace"), history: options.replaceHistory || [], flexibleHeight: true }, this.contextKeyService)); + + this._preserveCase = this._register(new Checkbox({ + actionClassName: 'monaco-preserve-case', + title: nls.localize('label.preserveCaseCheckbox', "Preserve Case"), + isChecked: !!options.preserveCase, + })); + + this._register(this._preserveCase.onChange(viaKeyboard => { + if (!viaKeyboard) { + this.replaceInput.focus(); + this._onPreserveCaseChange.fire(this._preserveCase.checked); + } + })); + + let controls = document.createElement('div'); + controls.className = 'controls'; + controls.style.display = 'block'; + controls.appendChild(this._preserveCase.domNode); + replaceBox.appendChild(controls); + this._register(attachInputBoxStyler(this.replaceInput, this.themeService)); this.onkeydown(this.replaceInput.inputElement, (keyboardEvent) => this.onReplaceInputKeyDown(keyboardEvent)); this.replaceInput.value = options.replaceValue || ''; diff --git a/src/vs/workbench/contrib/search/common/searchModel.ts b/src/vs/workbench/contrib/search/common/searchModel.ts index 1c93ff5221c..1962709126f 100644 --- a/src/vs/workbench/contrib/search/common/searchModel.ts +++ b/src/vs/workbench/contrib/search/common/searchModel.ts @@ -103,17 +103,17 @@ export class Match { } const fullMatchText = this.fullMatchText(); - let replaceString = searchModel.replacePattern.getReplaceString(fullMatchText); + let replaceString = searchModel.replacePattern.getReplaceString(fullMatchText, searchModel.preserveCase); // If match string is not matching then regex pattern has a lookahead expression if (replaceString === null) { const fullMatchTextWithTrailingContent = this.fullMatchText(true); - replaceString = searchModel.replacePattern.getReplaceString(fullMatchTextWithTrailingContent); + replaceString = searchModel.replacePattern.getReplaceString(fullMatchTextWithTrailingContent, searchModel.preserveCase); // Search/find normalize line endings - check whether \r prevents regex from matching if (replaceString === null) { const fullMatchTextWithoutCR = fullMatchTextWithTrailingContent.replace(/\r\n/g, '\n'); - replaceString = searchModel.replacePattern.getReplaceString(fullMatchTextWithoutCR); + replaceString = searchModel.replacePattern.getReplaceString(fullMatchTextWithoutCR, searchModel.preserveCase); } } @@ -895,6 +895,7 @@ export class SearchModel extends Disposable { private _replaceActive: boolean = false; private _replaceString: string | null = null; private _replacePattern: ReplacePattern | null = null; + private _preserveCase: boolean = false; private readonly _onReplaceTermChanged: Emitter = this._register(new Emitter()); readonly onReplaceTermChanged: Event = this._onReplaceTermChanged.event; @@ -926,6 +927,14 @@ export class SearchModel extends Disposable { return this._replaceString || ''; } + set preserveCase(value: boolean) { + this._preserveCase = value; + } + + get preserveCase(): boolean { + return this._preserveCase; + } + set replaceString(replaceString: string) { this._replaceString = replaceString; if (this._searchQuery) { diff --git a/src/vs/workbench/services/search/common/replace.ts b/src/vs/workbench/services/search/common/replace.ts index a6caab8223e..3f58ea89fe0 100644 --- a/src/vs/workbench/services/search/common/replace.ts +++ b/src/vs/workbench/services/search/common/replace.ts @@ -54,7 +54,7 @@ export class ReplacePattern { * Returns the replace string for the first match in the given text. * If text has no matches then returns null. */ - getReplaceString(text: string): string | null { + getReplaceString(text: string, preserveCase?: boolean): string | null { this._regExp.lastIndex = 0; let match = this._regExp.exec(text); if (match) { @@ -65,12 +65,30 @@ export class ReplacePattern { let replaceString = text.replace(this._regExp, this.pattern); return replaceString.substr(match.index, match[0].length - (text.length - replaceString.length)); } - return this.pattern; + return this.buildReplaceString(match, preserveCase); } return null; } + public buildReplaceString(matches: string[] | null, preserveCase?: boolean): string { + + if (preserveCase && matches && (matches[0] !== '')) { + if (matches[0].toUpperCase() === matches[0]) { + return this._replacePattern.toUpperCase(); + } else if (matches[0].toLowerCase() === matches[0]) { + return this._replacePattern.toLowerCase(); + } else if (strings.containsUppercaseCharacter(matches[0][0])) { + return this._replacePattern[0].toUpperCase() + this._replacePattern.substr(1); + } else { + // we don't understand its pattern yet. + return this._replacePattern; + } + } else { + return this._replacePattern; + } + } + /** * \n => LF * \t => TAB From 9d4ba37d4ca38ef3bad829db03256bfe7b0a32fc Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 14 Aug 2019 15:15:57 +0200 Subject: [PATCH 589/861] test build schedule --- build/azure-pipelines/product-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index f38f4311826..f559126ecea 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -143,8 +143,8 @@ trigger: none pr: none schedules: -- cron: "0 5 * * Mon-Fri" - displayName: Mon-Fri at 7:00 +- cron: "20 13 * * Mon-Fri" + displayName: Mon-Fri at 15:20 branches: include: - master From 5875c55136372aab0dcb5848cc2ff1cffb295e3d Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 14 Aug 2019 15:21:29 +0200 Subject: [PATCH 590/861] Revert "test build schedule" This reverts commit 9d4ba37d4ca38ef3bad829db03256bfe7b0a32fc. --- build/azure-pipelines/product-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index f559126ecea..f38f4311826 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -143,8 +143,8 @@ trigger: none pr: none schedules: -- cron: "20 13 * * Mon-Fri" - displayName: Mon-Fri at 15:20 +- cron: "0 5 * * Mon-Fri" + displayName: Mon-Fri at 7:00 branches: include: - master From 361dbb9fafada498101aef1c4786d1184634489d Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 14 Aug 2019 12:37:36 +0200 Subject: [PATCH 591/861] better check for worker/web extension --- .../services/extensions/browser/extensionService.ts | 7 +++++-- .../workbench/services/extensions/common/extensionsUtil.ts | 5 +++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/services/extensions/browser/extensionService.ts b/src/vs/workbench/services/extensions/browser/extensionService.ts index 7d624f12bf8..80e9fe37c3f 100644 --- a/src/vs/workbench/services/extensions/browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/browser/extensionService.ts @@ -20,6 +20,8 @@ import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEn import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { WebWorkerExtensionHostStarter } from 'vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter'; import { URI } from 'vs/base/common/uri'; +import { isWebExtension } from 'vs/workbench/services/extensions/common/extensionsUtil'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; export class ExtensionService extends AbstractExtensionService implements IExtensionService { @@ -34,6 +36,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten @IFileService fileService: IFileService, @IProductService productService: IProductService, @IRemoteAgentService private readonly _remoteAgentService: IRemoteAgentService, + @IConfigurationService private readonly _configService: IConfigurationService, ) { super( instantiationService, @@ -65,8 +68,8 @@ export class ExtensionService extends AbstractExtensionService implements IExten const remoteAgentConnection = this._remoteAgentService.getConnection()!; - const webExtensions = this.getExtensions().then(extensions => extensions.filter(ext => ext.extensionKind === 'web')); - const remoteExtensions = this.getExtensions().then(extensions => extensions.filter(ext => ext.extensionKind !== 'web')); + const webExtensions = this.getExtensions().then(extensions => extensions.filter(ext => isWebExtension(ext, this._configService))); + const remoteExtensions = this.getExtensions().then(extensions => extensions.filter(ext => !isWebExtension(ext, this._configService))); const webHostProcessWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, true, webExtensions, URI.parse('empty:value')); //todo@joh const webHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, webHostProcessWorker, remoteAgentConnection.remoteAuthority, initialActivationEvents); diff --git a/src/vs/workbench/services/extensions/common/extensionsUtil.ts b/src/vs/workbench/services/extensions/common/extensionsUtil.ts index e03ddb10239..a1496708db6 100644 --- a/src/vs/workbench/services/extensions/common/extensionsUtil.ts +++ b/src/vs/workbench/services/extensions/common/extensionsUtil.ts @@ -10,6 +10,11 @@ import { getGalleryExtensionId, areSameExtensions } from 'vs/platform/extensionM import { isNonEmptyArray } from 'vs/base/common/arrays'; import { IProductService } from 'vs/platform/product/common/product'; +export function isWebExtension(manifest: IExtensionManifest, configurationService: IConfigurationService): boolean { + const extensionKind = getExtensionKind(manifest, configurationService); + return extensionKind === 'web'; +} + export function isUIExtension(manifest: IExtensionManifest, productService: IProductService, configurationService: IConfigurationService): boolean { const uiContributions = ExtensionsRegistry.getExtensionPoints().filter(e => e.defaultExtensionKind !== 'workspace').map(e => e.name); const extensionId = getGalleryExtensionId(manifest.publisher, manifest.name); From 8f3b7dec4a02dcc4a2d45d96669e01cdb8a21d6c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 14 Aug 2019 16:02:01 +0200 Subject: [PATCH 592/861] debt - IExtensionDescription#main should be relative like all other file references --- .../workbench/api/common/extHostExtensionService.ts | 8 ++++---- src/vs/workbench/api/node/extHostExtensionService.ts | 11 ++++++++--- .../workbench/api/worker/extHostExtensionService.ts | 12 ++++++------ .../services/extensions/node/extensionPoints.ts | 5 ----- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts index 99553033cd2..8c903a6027c 100644 --- a/src/vs/workbench/api/common/extHostExtensionService.ts +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -5,7 +5,7 @@ import * as nls from 'vs/nls'; import * as path from 'vs/base/common/path'; -import { originalFSPath } from 'vs/base/common/resources'; +import { originalFSPath, joinPath } from 'vs/base/common/resources'; import { Barrier } from 'vs/base/common/async'; import { dispose, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { TernarySearchTree } from 'vs/base/common/map'; @@ -332,14 +332,14 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio const activationTimesBuilder = new ExtensionActivationTimesBuilder(reason.startup); return Promise.all([ - this._loadCommonJSModule(extensionDescription.main, activationTimesBuilder), + this._loadCommonJSModule(joinPath(extensionDescription.extensionLocation, extensionDescription.main), activationTimesBuilder), this._loadExtensionContext(extensionDescription) ]).then(values => { return AbstractExtHostExtensionService._callActivate(this._logService, extensionDescription.identifier, values[0], values[1], activationTimesBuilder); }); } - protected abstract _loadCommonJSModule(modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise; + protected abstract _loadCommonJSModule(module: URI, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise; private _loadExtensionContext(extensionDescription: IExtensionDescription): Promise { @@ -536,7 +536,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio let testRunner: ITestRunner | INewTestRunner | undefined; let requireError: Error | undefined; try { - testRunner = await this._loadCommonJSModule(extensionTestsPath, new ExtensionActivationTimesBuilder(false)); + testRunner = await this._loadCommonJSModule(URI.file(extensionTestsPath), new ExtensionActivationTimesBuilder(false)); } catch (error) { requireError = error; } diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 8f1f5d6ee75..5b03a318564 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -11,6 +11,8 @@ import { connectProxyResolver } from 'vs/workbench/services/extensions/node/prox import { AbstractExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; import { ExtHostDownloadService } from 'vs/workbench/api/node/extHostDownloadService'; import { CLIServer } from 'vs/workbench/api/node/extHostCLIServer'; +import { URI } from 'vs/base/common/uri'; +import { Schemas } from 'vs/base/common/network'; export class ExtHostExtensionService extends AbstractExtHostExtensionService { @@ -55,12 +57,15 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { }; } - protected _loadCommonJSModule(modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { + protected _loadCommonJSModule(module: URI, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { + if (module.scheme !== Schemas.file) { + throw new Error(`Cannot load URI: '${module}', must be of file-scheme`); + } let r: T | null = null; activationTimesBuilder.codeLoadingStart(); - this._logService.info(`ExtensionService#loadCommonJSModule ${modulePath}`); + this._logService.info(`ExtensionService#loadCommonJSModule ${module.toString(true)}`); try { - r = require.__$__nodeRequire(modulePath); + r = require.__$__nodeRequire(module.fsPath); } catch (e) { return Promise.reject(e); } finally { diff --git a/src/vs/workbench/api/worker/extHostExtensionService.ts b/src/vs/workbench/api/worker/extHostExtensionService.ts index be34dbe2d64..19b44f7dc18 100644 --- a/src/vs/workbench/api/worker/extHostExtensionService.ts +++ b/src/vs/workbench/api/worker/extHostExtensionService.ts @@ -54,11 +54,11 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { this._apiInstances = new ApiInstances(apiFactory, extensionPath, this._registry, configProvider); } - protected _loadCommonJSModule(modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { + protected _loadCommonJSModule(module: URI, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { // make sure modulePath ends with `.js` const suffix = '.js'; - modulePath = endsWith(modulePath, suffix) ? modulePath : modulePath + suffix; + let modulePath = endsWith(module.fsPath, suffix) ? module.fsPath : module.fsPath + suffix; interface FakeCommonJSSelf { module?: object; @@ -71,9 +71,9 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { // FAKE commonjs world that only collects exports const patchSelf: FakeCommonJSSelf = self; - const module = { exports: {} }; - patchSelf.module = module; - patchSelf.exports = module.exports; + const exports = Object.create(null); + patchSelf.module = { exports }; + patchSelf.exports = exports; patchSelf.window = self; // <- that's improper but might help extensions that aren't authored correctly // FAKE require function that only works for the vscode-module @@ -97,7 +97,7 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { activationTimesBuilder.codeLoadingStop(); } - return Promise.resolve(module.exports as T); + return Promise.resolve(exports); } async $setRemoteEnvironment(env: { [key: string]: string | null }): Promise { diff --git a/src/vs/workbench/services/extensions/node/extensionPoints.ts b/src/vs/workbench/services/extensions/node/extensionPoints.ts index f20f824a2e2..8abe6aa7f52 100644 --- a/src/vs/workbench/services/extensions/node/extensionPoints.ts +++ b/src/vs/workbench/services/extensions/node/extensionPoints.ts @@ -309,11 +309,6 @@ class ExtensionManifestValidator extends ExtensionManifestHandler { extensionDescription.id = `${extensionDescription.publisher}.${extensionDescription.name}`; extensionDescription.identifier = new ExtensionIdentifier(extensionDescription.id); - // main := absolutePath(`main`) - if (extensionDescription.main) { - extensionDescription.main = path.join(this._absoluteFolderPath, extensionDescription.main); - } - extensionDescription.extensionLocation = URI.file(this._absoluteFolderPath); return extensionDescription; From 48b3d1c0619b33efb442c70af5d323af10660028 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 14 Aug 2019 16:29:28 +0200 Subject: [PATCH 593/861] move windowsIPC => common --- src/vs/code/electron-main/app.ts | 2 +- .../platform/windows/{node => common}/windowsIpc.ts | 0 .../windows/electron-browser/windowsService.ts | 11 ++++++----- 3 files changed, 7 insertions(+), 6 deletions(-) rename src/vs/platform/windows/{node => common}/windowsIpc.ts (100%) diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index d71ddf83ea1..15e9c438ddb 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -7,7 +7,7 @@ import { app, ipcMain as ipc, systemPreferences, shell, Event, contentTracing, p import { IProcessEnvironment, isWindows, isMacintosh } from 'vs/base/common/platform'; import { WindowsManager } from 'vs/code/electron-main/windows'; import { IWindowsService, OpenContext, ActiveWindowManager, IURIToOpen } from 'vs/platform/windows/common/windows'; -import { WindowsChannel } from 'vs/platform/windows/node/windowsIpc'; +import { WindowsChannel } from 'vs/platform/windows/common/windowsIpc'; import { WindowsService } from 'vs/platform/windows/electron-main/windowsService'; import { ILifecycleService, LifecycleMainPhase } from 'vs/platform/lifecycle/electron-main/lifecycleMain'; import { getShellEnvironment } from 'vs/code/node/shellEnv'; diff --git a/src/vs/platform/windows/node/windowsIpc.ts b/src/vs/platform/windows/common/windowsIpc.ts similarity index 100% rename from src/vs/platform/windows/node/windowsIpc.ts rename to src/vs/platform/windows/common/windowsIpc.ts diff --git a/src/vs/platform/windows/electron-browser/windowsService.ts b/src/vs/platform/windows/electron-browser/windowsService.ts index 228dfd98ba2..57bd96143af 100644 --- a/src/vs/platform/windows/electron-browser/windowsService.ts +++ b/src/vs/platform/windows/electron-browser/windowsService.ts @@ -13,17 +13,14 @@ import { URI } from 'vs/base/common/uri'; import { ParsedArgs } from 'vs/platform/environment/common/environment'; import { IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService'; import { IProcessEnvironment } from 'vs/base/common/platform'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; export class WindowsService implements IWindowsService { - _serviceBrand: any; + _serviceBrand!: ServiceIdentifier; private channel: IChannel; - constructor(@IMainProcessService mainProcessService: IMainProcessService) { - this.channel = mainProcessService.getChannel('windows'); - } - get onWindowOpen(): Event { return this.channel.listen('onWindowOpen'); } get onWindowFocus(): Event { return this.channel.listen('onWindowFocus'); } get onWindowBlur(): Event { return this.channel.listen('onWindowBlur'); } @@ -31,6 +28,10 @@ export class WindowsService implements IWindowsService { get onWindowUnmaximize(): Event { return this.channel.listen('onWindowUnmaximize'); } get onRecentlyOpenedChange(): Event { return this.channel.listen('onRecentlyOpenedChange'); } + constructor(@IMainProcessService mainProcessService: IMainProcessService) { + this.channel = mainProcessService.getChannel('windows'); + } + pickFileFolderAndOpen(options: INativeOpenDialogOptions): Promise { return this.channel.call('pickFileFolderAndOpen', options); } From ec62819ffa298f8b57e6db285e10404a3e6c89d4 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 14 Aug 2019 16:29:47 +0200 Subject: [PATCH 594/861] very basic support to load multiple files --- .../api/worker/extHostExtensionService.ts | 66 +++++++++++++------ 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/api/worker/extHostExtensionService.ts b/src/vs/workbench/api/worker/extHostExtensionService.ts index 19b44f7dc18..0b49644e7cc 100644 --- a/src/vs/workbench/api/worker/extHostExtensionService.ts +++ b/src/vs/workbench/api/worker/extHostExtensionService.ts @@ -6,15 +6,16 @@ import { createApiFactoryAndRegisterActors, IExtensionApiFactory } from 'vs/workbench/api/common/extHost.api.impl'; import { ExtensionActivationTimesBuilder } from 'vs/workbench/api/common/extHostExtensionActivator'; import { AbstractExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; -import { endsWith } from 'vs/base/common/strings'; +import { endsWith, startsWith } from 'vs/base/common/strings'; import { IExtensionDescription, ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration'; import * as vscode from 'vscode'; import { TernarySearchTree } from 'vs/base/common/map'; import { nullExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; -import { isWeb } from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; +import { Schemas } from 'vs/base/common/network'; +import { joinPath } from 'vs/base/common/resources'; class ApiInstances { @@ -56,9 +57,6 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { protected _loadCommonJSModule(module: URI, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { - // make sure modulePath ends with `.js` - const suffix = '.js'; - let modulePath = endsWith(module.fsPath, suffix) ? module.fsPath : module.fsPath + suffix; interface FakeCommonJSSelf { module?: object; @@ -71,28 +69,44 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { // FAKE commonjs world that only collects exports const patchSelf: FakeCommonJSSelf = self; - const exports = Object.create(null); - patchSelf.module = { exports }; - patchSelf.exports = exports; patchSelf.window = self; // <- that's improper but might help extensions that aren't authored correctly // FAKE require function that only works for the vscode-module - patchSelf.require = (module: string) => { - if (module !== 'vscode') { - throw new Error(`Cannot load module '${module}'`); + const moduleStack: URI[] = []; + patchSelf.require = (mod: string) => { + const parent = moduleStack[moduleStack.length - 1]; + if (mod === 'vscode') { + return this._apiInstances!.get(parent.fsPath); } - return this._apiInstances!.get(modulePath); + if (!startsWith(mod, '.')) { + throw new Error(`Cannot load module '${mod}'`); + } + + const exports = Object.create(null); + patchSelf.module = { exports }; + patchSelf.exports = exports; + + const next = joinPath(parent, '..', ensureSuffix(mod, '.js')); + moduleStack.push(next); + importScripts(asDomUri(next).toString(true)); + moduleStack.pop(); + + return exports; }; try { - // todo@joh this is a copy of `dom.ts#asDomUri` - // build url of the things we resolve - const url = isWeb - ? URI.parse(window.location.href).with({ path: '/vscode-remote', query: JSON.stringify(URI.file(modulePath)) }).toString(true) - : modulePath; - activationTimesBuilder.codeLoadingStart(); - importScripts(url); + + const exports = Object.create(null); + patchSelf.module = { exports }; + patchSelf.exports = exports; + + module = module.with({ path: ensureSuffix(module.path, '.js') }); + moduleStack.push(module); + + importScripts(asDomUri(module).toString(true)); + moduleStack.pop(); + } finally { activationTimesBuilder.codeLoadingStop(); } @@ -104,3 +118,17 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { throw new Error('Not supported'); } } + +// todo@joh this is a copy of `dom.ts#asDomUri` +function asDomUri(uri: URI): URI { + if (Schemas.vscodeRemote === uri.scheme) { + // rewrite vscode-remote-uris to uris of the window location + // so that they can be intercepted by the service worker + return URI.parse(window.location.href).with({ path: '/vscode-remote', query: JSON.stringify(uri) }); + } + return uri; +} + +function ensureSuffix(path: string, suffix: string): string { + return endsWith(path, suffix) ? path : path + suffix; +} From 73772a4ff1a5f4808eabd9cc0be74d91800c03b9 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 14 Aug 2019 16:21:20 +0200 Subject: [PATCH 595/861] #69108 Move IWorkspaceStatsService to common Introduce a simple service for web --- .../workbench/browser/web.simpleservices.ts | 20 +++++++++++++++- .../electron-browser/experimentService.ts | 2 +- .../contrib/stats/common/workspaceStats.ts | 23 +++++++++++++++++++ .../stats/electron-browser/workspaceStats.ts | 2 +- .../electron-browser/workspaceStatsService.ts | 18 +-------------- 5 files changed, 45 insertions(+), 20 deletions(-) create mode 100644 src/vs/workbench/contrib/stats/common/workspaceStats.ts diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 95d2533c4c6..527823182a3 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -22,7 +22,7 @@ import { ISerializableCommandAction } from 'vs/platform/actions/common/actions'; import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing'; import { ITunnelService } from 'vs/platform/remote/common/tunnel'; // tslint:disable-next-line: import-patterns -import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; +import { IWorkspaceContextService, WorkbenchState, IWorkspace } from 'vs/platform/workspace/common/workspace'; import { addDisposableListener, EventType, windowOpenNoOpener } from 'vs/base/browser/dom'; import { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/common/editorService'; import { pathsToEditors } from 'vs/workbench/common/editor'; @@ -39,6 +39,8 @@ import { IProductService } from 'vs/platform/product/common/product'; import Severity from 'vs/base/common/severity'; import { localize } from 'vs/nls'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; +// tslint:disable-next-line: import-patterns +import { IWorkspaceStatsService, Tags } from 'vs/workbench/contrib/stats/common/workspaceStats'; //#region Extension Tips @@ -847,6 +849,22 @@ registerSingleton(ITunnelService, SimpleTunnelService); //#region experiments +class WorkspaceStatsService implements IWorkspaceStatsService { + + _serviceBrand: any; + + getTags(): Promise { + return Promise.resolve({}); + } + + getTelemetryWorkspaceId(workspace: IWorkspace, state: WorkbenchState): string | undefined { + return undefined; + } + +} + +registerSingleton(IWorkspaceStatsService, WorkspaceStatsService); + class ExperimentService implements IExperimentService { _serviceBrand: any; diff --git a/src/vs/workbench/contrib/experiments/electron-browser/experimentService.ts b/src/vs/workbench/contrib/experiments/electron-browser/experimentService.ts index 79dd609cb60..0d880ac7fd7 100644 --- a/src/vs/workbench/contrib/experiments/electron-browser/experimentService.ts +++ b/src/vs/workbench/contrib/experiments/electron-browser/experimentService.ts @@ -20,7 +20,7 @@ import { distinct } from 'vs/base/common/arrays'; import { ExtensionType } from 'vs/platform/extensions/common/extensions'; import { ExperimentState, IExperimentAction, IExperimentService, IExperiment, ExperimentActionType, IExperimentActionPromptProperties } from 'vs/workbench/contrib/experiments/common/experimentService'; import { IProductService } from 'vs/platform/product/common/product'; -import { IWorkspaceStatsService } from 'vs/workbench/contrib/stats/electron-browser/workspaceStatsService'; +import { IWorkspaceStatsService } from 'vs/workbench/contrib/stats/common/workspaceStats'; interface IExperimentStorageState { enabled: boolean; diff --git a/src/vs/workbench/contrib/stats/common/workspaceStats.ts b/src/vs/workbench/contrib/stats/common/workspaceStats.ts new file mode 100644 index 00000000000..177911447fc --- /dev/null +++ b/src/vs/workbench/contrib/stats/common/workspaceStats.ts @@ -0,0 +1,23 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { WorkbenchState, IWorkspace } from 'vs/platform/workspace/common/workspace'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; + +export type Tags = { [index: string]: boolean | number | string | undefined }; + +export const IWorkspaceStatsService = createDecorator('workspaceStatsService'); + +export interface IWorkspaceStatsService { + _serviceBrand: any; + + getTags(): Promise; + + /** + * Returns an id for the workspace, different from the id returned by the context service. A hash based + * on the folder uri or workspace configuration, not time-based, and undefined for empty workspaces. + */ + getTelemetryWorkspaceId(workspace: IWorkspace, state: WorkbenchState): string | undefined; +} diff --git a/src/vs/workbench/contrib/stats/electron-browser/workspaceStats.ts b/src/vs/workbench/contrib/stats/electron-browser/workspaceStats.ts index 1eac917c60c..7577b5a9bda 100644 --- a/src/vs/workbench/contrib/stats/electron-browser/workspaceStats.ts +++ b/src/vs/workbench/contrib/stats/electron-browser/workspaceStats.ts @@ -14,7 +14,7 @@ import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { endsWith } from 'vs/base/common/strings'; import { ITextFileService, } from 'vs/workbench/services/textfile/common/textfiles'; import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; -import { IWorkspaceStatsService, Tags } from 'vs/workbench/contrib/stats/electron-browser/workspaceStatsService'; +import { IWorkspaceStatsService, Tags } from 'vs/workbench/contrib/stats/common/workspaceStats'; import { IWorkspaceInformation } from 'vs/platform/diagnostics/common/diagnosticsService'; const SshProtocolMatcher = /^([^@:]+@)?([^:]+):/; diff --git a/src/vs/workbench/contrib/stats/electron-browser/workspaceStatsService.ts b/src/vs/workbench/contrib/stats/electron-browser/workspaceStatsService.ts index b56c4a821ca..3cce4db8bfb 100644 --- a/src/vs/workbench/contrib/stats/electron-browser/workspaceStatsService.ts +++ b/src/vs/workbench/contrib/stats/electron-browser/workspaceStatsService.ts @@ -18,10 +18,8 @@ import { hasWorkspaceFileExtension } from 'vs/platform/workspaces/common/workspa import { localize } from 'vs/nls'; import Severity from 'vs/base/common/severity'; import { joinPath } from 'vs/base/common/resources'; -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; - -export type Tags = { [index: string]: boolean | number | string | undefined }; +import { IWorkspaceStatsService, Tags } from 'vs/workbench/contrib/stats/common/workspaceStats'; const DISABLE_WORKSPACE_PROMPT_KEY = 'workspaces.dontPromptToOpen'; @@ -93,20 +91,6 @@ const PyModulesToLookFor = [ 'botframework-connector' ]; -export const IWorkspaceStatsService = createDecorator('workspaceStatsService'); - -export interface IWorkspaceStatsService { - _serviceBrand: any; - getTags(): Promise; - - /** - * Returns an id for the workspace, different from the id returned by the context service. A hash based - * on the folder uri or workspace configuration, not time-based, and undefined for empty workspaces. - */ - getTelemetryWorkspaceId(workspace: IWorkspace, state: WorkbenchState): string | undefined; -} - - export class WorkspaceStatsService implements IWorkspaceStatsService { _serviceBrand: any; private _tags: Tags; From 6f55bec945612318aa86d7e1deee5f6dc95fb8b8 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 14 Aug 2019 16:38:14 +0200 Subject: [PATCH 596/861] Fix #69108 --- .../workbench/browser/web.simpleservices.ts | 31 +- .../experimentalPrompt.ts | 0 .../experiments.contribution.ts | 5 +- .../experiments/common/experimentService.ts | 404 ++++++++++++++++- .../electron-browser/experimentService.ts | 407 ------------------ .../experimentService.test.ts | 3 +- .../experimentalPrompts.test.ts | 2 +- .../electron-browser/extensionsViews.test.ts | 3 +- src/vs/workbench/workbench.common.main.ts | 3 + src/vs/workbench/workbench.desktop.main.ts | 3 - 10 files changed, 411 insertions(+), 450 deletions(-) rename src/vs/workbench/contrib/experiments/{electron-browser => browser}/experimentalPrompt.ts (100%) rename src/vs/workbench/contrib/experiments/{electron-browser => browser}/experiments.contribution.ts (79%) delete mode 100644 src/vs/workbench/contrib/experiments/electron-browser/experimentService.ts diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 527823182a3..f9bfd69e4c9 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -31,8 +31,6 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { ParsedArgs } from 'vs/platform/environment/common/environment'; import { IProcessEnvironment } from 'vs/base/common/platform'; import { toStoreData, restoreRecentlyOpened } from 'vs/platform/history/common/historyStorage'; -// tslint:disable-next-line: import-patterns -import { IExperimentService, IExperiment, ExperimentActionType, ExperimentState } from 'vs/workbench/contrib/experiments/common/experimentService'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IProductService } from 'vs/platform/product/common/product'; @@ -847,7 +845,7 @@ registerSingleton(ITunnelService, SimpleTunnelService); //#endregion -//#region experiments +//#region workspace stats class WorkspaceStatsService implements IWorkspaceStatsService { @@ -865,31 +863,4 @@ class WorkspaceStatsService implements IWorkspaceStatsService { registerSingleton(IWorkspaceStatsService, WorkspaceStatsService); -class ExperimentService implements IExperimentService { - _serviceBrand: any; - - async getExperimentById(id: string): Promise { - return { - enabled: false, - id: '', - state: ExperimentState.NoRun - }; - } - - async getExperimentsByType(type: ExperimentActionType): Promise { - return []; - } - - async getCuratedExtensionsList(curatedExtensionsKey: string): Promise { - return []; - } - - markAsCompleted(experimentId: string): void { } - - onExperimentEnabled: Event = Event.None; - -} - -registerSingleton(IExperimentService, ExperimentService); - //#endregion diff --git a/src/vs/workbench/contrib/experiments/electron-browser/experimentalPrompt.ts b/src/vs/workbench/contrib/experiments/browser/experimentalPrompt.ts similarity index 100% rename from src/vs/workbench/contrib/experiments/electron-browser/experimentalPrompt.ts rename to src/vs/workbench/contrib/experiments/browser/experimentalPrompt.ts diff --git a/src/vs/workbench/contrib/experiments/electron-browser/experiments.contribution.ts b/src/vs/workbench/contrib/experiments/browser/experiments.contribution.ts similarity index 79% rename from src/vs/workbench/contrib/experiments/electron-browser/experiments.contribution.ts rename to src/vs/workbench/contrib/experiments/browser/experiments.contribution.ts index ca28e9b6f67..67b6159734f 100644 --- a/src/vs/workbench/contrib/experiments/electron-browser/experiments.contribution.ts +++ b/src/vs/workbench/contrib/experiments/browser/experiments.contribution.ts @@ -4,12 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IExperimentService } from 'vs/workbench/contrib/experiments/common/experimentService'; -import { ExperimentService } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; +import { IExperimentService, ExperimentService } from 'vs/workbench/contrib/experiments/common/experimentService'; import { Registry } from 'vs/platform/registry/common/platform'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; -import { ExperimentalPrompts } from 'vs/workbench/contrib/experiments/electron-browser/experimentalPrompt'; +import { ExperimentalPrompts } from 'vs/workbench/contrib/experiments/browser/experimentalPrompt'; registerSingleton(IExperimentService, ExperimentService, true); diff --git a/src/vs/workbench/contrib/experiments/common/experimentService.ts b/src/vs/workbench/contrib/experiments/common/experimentService.ts index 437afe18bd6..5707377ce4b 100644 --- a/src/vs/workbench/contrib/experiments/common/experimentService.ts +++ b/src/vs/workbench/contrib/experiments/common/experimentService.ts @@ -4,7 +4,23 @@ *--------------------------------------------------------------------------------------------*/ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { Event } from 'vs/base/common/event'; +import { Emitter, Event } from 'vs/base/common/event'; +import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { ITelemetryService, lastSessionDateStorageKey } from 'vs/platform/telemetry/common/telemetry'; +import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { language } from 'vs/base/common/platform'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { match } from 'vs/base/common/glob'; +import { IRequestService, asJson } from 'vs/platform/request/common/request'; +import { ITextFileService, StateChange } from 'vs/workbench/services/textfile/common/textfiles'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { distinct } from 'vs/base/common/arrays'; +import { ExtensionType } from 'vs/platform/extensions/common/extensions'; +import { IProductService } from 'vs/platform/product/common/product'; +import { IWorkspaceStatsService } from 'vs/workbench/contrib/stats/common/workspaceStats'; export const enum ExperimentState { Evaluating, @@ -56,4 +72,388 @@ export interface IExperimentService { onExperimentEnabled: Event; } -export const IExperimentService = createDecorator('experimentService'); \ No newline at end of file +export const IExperimentService = createDecorator('experimentService'); + +interface IExperimentStorageState { + enabled: boolean; + state: ExperimentState; + editCount?: number; + lastEditedDate?: string; +} + +interface IRawExperiment { + id: string; + enabled?: boolean; + condition?: { + insidersOnly?: boolean; + newUser?: boolean; + displayLanguage?: string; + installedExtensions?: { + excludes?: string[]; + includes?: string[]; + }, + fileEdits?: { + filePathPattern?: string; + workspaceIncludes?: string[]; + workspaceExcludes?: string[]; + minEditCount: number; + }, + experimentsPreviouslyRun?: { + excludes?: string[]; + includes?: string[]; + } + userProbability?: number; + }; + action?: IExperimentAction; +} + +export class ExperimentService extends Disposable implements IExperimentService { + _serviceBrand: any; + private _experiments: IExperiment[] = []; + private _loadExperimentsPromise: Promise; + private _curatedMapping = Object.create(null); + + private readonly _onExperimentEnabled = this._register(new Emitter()); + onExperimentEnabled: Event = this._onExperimentEnabled.event; + + constructor( + @IStorageService private readonly storageService: IStorageService, + @IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService, + @ITextFileService private readonly textFileService: ITextFileService, + @IEnvironmentService private readonly environmentService: IEnvironmentService, + @ITelemetryService private readonly telemetryService: ITelemetryService, + @ILifecycleService private readonly lifecycleService: ILifecycleService, + @IRequestService private readonly requestService: IRequestService, + @IConfigurationService private readonly configurationService: IConfigurationService, + @IProductService private readonly productService: IProductService, + @IWorkspaceStatsService private readonly workspaceStatsService: IWorkspaceStatsService + ) { + super(); + + this._loadExperimentsPromise = Promise.resolve(this.lifecycleService.when(LifecyclePhase.Eventually)).then(() => this.loadExperiments()); + } + + public getExperimentById(id: string): Promise { + return this._loadExperimentsPromise.then(() => { + return this._experiments.filter(x => x.id === id)[0]; + }); + } + + public getExperimentsByType(type: ExperimentActionType): Promise { + return this._loadExperimentsPromise.then(() => { + if (type === ExperimentActionType.Custom) { + return this._experiments.filter(x => x.enabled && (!x.action || x.action.type === type)); + } + return this._experiments.filter(x => x.enabled && x.action && x.action.type === type); + }); + } + + public getCuratedExtensionsList(curatedExtensionsKey: string): Promise { + return this._loadExperimentsPromise.then(() => { + for (const experiment of this._experiments) { + if (experiment.enabled + && experiment.state === ExperimentState.Run + && this._curatedMapping[experiment.id] + && this._curatedMapping[experiment.id].curatedExtensionsKey === curatedExtensionsKey) { + return this._curatedMapping[experiment.id].curatedExtensionsList; + } + } + return []; + }); + } + + public markAsCompleted(experimentId: string): void { + const storageKey = 'experiments.' + experimentId; + const experimentState: IExperimentStorageState = safeParse(this.storageService.get(storageKey, StorageScope.GLOBAL), {}); + experimentState.state = ExperimentState.Complete; + this.storageService.store(storageKey, JSON.stringify(experimentState), StorageScope.GLOBAL); + } + + protected getExperiments(): Promise { + if (!this.productService.experimentsUrl || this.configurationService.getValue('workbench.enableExperiments') === false) { + return Promise.resolve([]); + } + return this.requestService.request({ type: 'GET', url: this.productService.experimentsUrl }, CancellationToken.None).then(context => { + if (context.res.statusCode !== 200) { + return Promise.resolve(null); + } + return asJson(context).then((result: any) => { + return result && Array.isArray(result['experiments']) ? result['experiments'] : []; + }); + }, () => Promise.resolve(null)); + } + + private loadExperiments(): Promise { + return this.getExperiments().then(rawExperiments => { + // Offline mode + if (!rawExperiments) { + const allExperimentIdsFromStorage = safeParse(this.storageService.get('allExperiments', StorageScope.GLOBAL), []); + if (Array.isArray(allExperimentIdsFromStorage)) { + allExperimentIdsFromStorage.forEach(experimentId => { + const storageKey = 'experiments.' + experimentId; + const experimentState: IExperimentStorageState = safeParse(this.storageService.get(storageKey, StorageScope.GLOBAL), null); + if (experimentState) { + this._experiments.push({ + id: experimentId, + enabled: experimentState.enabled, + state: experimentState.state + }); + } + }); + } + return Promise.resolve(null); + } + + // Clear disbaled/deleted experiments from storage + const allExperimentIdsFromStorage = safeParse(this.storageService.get('allExperiments', StorageScope.GLOBAL), []); + const enabledExperiments = rawExperiments.filter(experiment => !!experiment.enabled).map(experiment => experiment.id.toLowerCase()); + if (Array.isArray(allExperimentIdsFromStorage)) { + allExperimentIdsFromStorage.forEach(experiment => { + if (enabledExperiments.indexOf(experiment) === -1) { + this.storageService.remove(`experiments.${experiment}`, StorageScope.GLOBAL); + } + }); + } + if (enabledExperiments.length) { + this.storageService.store('allExperiments', JSON.stringify(enabledExperiments), StorageScope.GLOBAL); + } else { + this.storageService.remove('allExperiments', StorageScope.GLOBAL); + } + + const promises = rawExperiments.map(experiment => { + const processedExperiment: IExperiment = { + id: experiment.id, + enabled: !!experiment.enabled, + state: !!experiment.enabled ? ExperimentState.Evaluating : ExperimentState.NoRun + }; + + if (experiment.action) { + processedExperiment.action = { + type: ExperimentActionType[experiment.action.type] || ExperimentActionType.Custom, + properties: experiment.action.properties + }; + if (processedExperiment.action.type === ExperimentActionType.Prompt) { + ((processedExperiment.action.properties).commands || []).forEach(x => { + if (x.curatedExtensionsKey && Array.isArray(x.curatedExtensionsList)) { + this._curatedMapping[experiment.id] = x; + } + }); + } + if (!processedExperiment.action.properties) { + processedExperiment.action.properties = {}; + } + } + this._experiments.push(processedExperiment); + + if (!processedExperiment.enabled) { + return Promise.resolve(null); + } + + const storageKey = 'experiments.' + experiment.id; + const experimentState: IExperimentStorageState = safeParse(this.storageService.get(storageKey, StorageScope.GLOBAL), {}); + if (!experimentState.hasOwnProperty('enabled')) { + experimentState.enabled = processedExperiment.enabled; + } + if (!experimentState.hasOwnProperty('state')) { + experimentState.state = processedExperiment.enabled ? ExperimentState.Evaluating : ExperimentState.NoRun; + } else { + processedExperiment.state = experimentState.state; + } + + return this.shouldRunExperiment(experiment, processedExperiment).then((state: ExperimentState) => { + experimentState.state = processedExperiment.state = state; + this.storageService.store(storageKey, JSON.stringify(experimentState), StorageScope.GLOBAL); + + if (state === ExperimentState.Run) { + this.fireRunExperiment(processedExperiment); + } + return Promise.resolve(null); + }); + + }); + return Promise.all(promises).then(() => { + type ExperimentsClassification = { + experiments: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; + }; + this.telemetryService.publicLog2<{ experiments: IExperiment[] }, ExperimentsClassification>('experiments', { experiments: this._experiments }); + }); + }); + } + + private fireRunExperiment(experiment: IExperiment) { + this._onExperimentEnabled.fire(experiment); + const runExperimentIdsFromStorage: string[] = safeParse(this.storageService.get('currentOrPreviouslyRunExperiments', StorageScope.GLOBAL), []); + if (runExperimentIdsFromStorage.indexOf(experiment.id) === -1) { + runExperimentIdsFromStorage.push(experiment.id); + } + + // Ensure we dont store duplicates + const distinctExperiments = distinct(runExperimentIdsFromStorage); + if (runExperimentIdsFromStorage.length !== distinctExperiments.length) { + this.storageService.store('currentOrPreviouslyRunExperiments', JSON.stringify(distinctExperiments), StorageScope.GLOBAL); + } + } + + private checkExperimentDependencies(experiment: IRawExperiment): boolean { + const experimentsPreviouslyRun = experiment.condition ? experiment.condition.experimentsPreviouslyRun : undefined; + if (experimentsPreviouslyRun) { + const runExperimentIdsFromStorage: string[] = safeParse(this.storageService.get('currentOrPreviouslyRunExperiments', StorageScope.GLOBAL), []); + let includeCheck = true; + let excludeCheck = true; + const includes = experimentsPreviouslyRun.includes; + if (Array.isArray(includes)) { + includeCheck = runExperimentIdsFromStorage.some(x => includes.indexOf(x) > -1); + } + const excludes = experimentsPreviouslyRun.excludes; + if (includeCheck && Array.isArray(excludes)) { + excludeCheck = !runExperimentIdsFromStorage.some(x => excludes.indexOf(x) > -1); + } + if (!includeCheck || !excludeCheck) { + return false; + } + } + return true; + } + + private shouldRunExperiment(experiment: IRawExperiment, processedExperiment: IExperiment): Promise { + if (processedExperiment.state !== ExperimentState.Evaluating) { + return Promise.resolve(processedExperiment.state); + } + + if (!experiment.enabled) { + return Promise.resolve(ExperimentState.NoRun); + } + + const condition = experiment.condition; + if (!condition) { + return Promise.resolve(ExperimentState.Run); + } + + if (!this.checkExperimentDependencies(experiment)) { + return Promise.resolve(ExperimentState.NoRun); + } + + if (this.environmentService.appQuality === 'stable' && condition.insidersOnly === true) { + return Promise.resolve(ExperimentState.NoRun); + } + + const isNewUser = !this.storageService.get(lastSessionDateStorageKey, StorageScope.GLOBAL); + if ((condition.newUser === true && !isNewUser) + || (condition.newUser === false && isNewUser)) { + return Promise.resolve(ExperimentState.NoRun); + } + + if (typeof condition.displayLanguage === 'string') { + let localeToCheck = condition.displayLanguage.toLowerCase(); + let displayLanguage = language!.toLowerCase(); + + if (localeToCheck !== displayLanguage) { + const a = displayLanguage.indexOf('-'); + const b = localeToCheck.indexOf('-'); + if (a > -1) { + displayLanguage = displayLanguage.substr(0, a); + } + if (b > -1) { + localeToCheck = localeToCheck.substr(0, b); + } + if (displayLanguage !== localeToCheck) { + return Promise.resolve(ExperimentState.NoRun); + } + } + } + + if (!condition.userProbability) { + condition.userProbability = 1; + } + + let extensionsCheckPromise = Promise.resolve(true); + const installedExtensions = condition.installedExtensions; + if (installedExtensions) { + extensionsCheckPromise = this.extensionManagementService.getInstalled(ExtensionType.User).then(locals => { + let includesCheck = true; + let excludesCheck = true; + const localExtensions = locals.map(local => `${local.manifest.publisher.toLowerCase()}.${local.manifest.name.toLowerCase()}`); + if (Array.isArray(installedExtensions.includes) && installedExtensions.includes.length) { + const extensionIncludes = installedExtensions.includes.map(e => e.toLowerCase()); + includesCheck = localExtensions.some(e => extensionIncludes.indexOf(e) > -1); + } + if (Array.isArray(installedExtensions.excludes) && installedExtensions.excludes.length) { + const extensionExcludes = installedExtensions.excludes.map(e => e.toLowerCase()); + excludesCheck = !localExtensions.some(e => extensionExcludes.indexOf(e) > -1); + } + return includesCheck && excludesCheck; + }); + } + + const storageKey = 'experiments.' + experiment.id; + const experimentState: IExperimentStorageState = safeParse(this.storageService.get(storageKey, StorageScope.GLOBAL), {}); + + return extensionsCheckPromise.then(success => { + const fileEdits = condition.fileEdits; + if (!success || !fileEdits || typeof fileEdits.minEditCount !== 'number') { + const runExperiment = success && typeof condition.userProbability === 'number' && Math.random() < condition.userProbability; + return runExperiment ? ExperimentState.Run : ExperimentState.NoRun; + } + + experimentState.editCount = experimentState.editCount || 0; + if (experimentState.editCount >= fileEdits.minEditCount) { + return ExperimentState.Run; + } + + const onSaveHandler = this.textFileService.models.onModelsSaved(e => { + const date = new Date().toDateString(); + const latestExperimentState: IExperimentStorageState = safeParse(this.storageService.get(storageKey, StorageScope.GLOBAL), {}); + if (latestExperimentState.state !== ExperimentState.Evaluating) { + onSaveHandler.dispose(); + return; + } + e.forEach(async event => { + if (event.kind !== StateChange.SAVED + || latestExperimentState.state !== ExperimentState.Evaluating + || date === latestExperimentState.lastEditedDate + || (typeof latestExperimentState.editCount === 'number' && latestExperimentState.editCount >= fileEdits.minEditCount) + ) { + return; + } + let filePathCheck = true; + let workspaceCheck = true; + + if (typeof fileEdits.filePathPattern === 'string') { + filePathCheck = match(fileEdits.filePathPattern, event.resource.fsPath); + } + if (Array.isArray(fileEdits.workspaceIncludes) && fileEdits.workspaceIncludes.length) { + const tags = await this.workspaceStatsService.getTags(); + workspaceCheck = !!tags && fileEdits.workspaceIncludes.some(x => !!tags[x]); + } + if (workspaceCheck && Array.isArray(fileEdits.workspaceExcludes) && fileEdits.workspaceExcludes.length) { + const tags = await this.workspaceStatsService.getTags(); + workspaceCheck = !!tags && !fileEdits.workspaceExcludes.some(x => !!tags[x]); + } + if (filePathCheck && workspaceCheck) { + latestExperimentState.editCount = (latestExperimentState.editCount || 0) + 1; + latestExperimentState.lastEditedDate = date; + this.storageService.store(storageKey, JSON.stringify(latestExperimentState), StorageScope.GLOBAL); + } + }); + if (typeof latestExperimentState.editCount === 'number' && latestExperimentState.editCount >= fileEdits.minEditCount) { + processedExperiment.state = latestExperimentState.state = (typeof condition.userProbability === 'number' && Math.random() < condition.userProbability && this.checkExperimentDependencies(experiment)) ? ExperimentState.Run : ExperimentState.NoRun; + this.storageService.store(storageKey, JSON.stringify(latestExperimentState), StorageScope.GLOBAL); + if (latestExperimentState.state === ExperimentState.Run && experiment.action && ExperimentActionType[experiment.action.type] === ExperimentActionType.Prompt) { + this.fireRunExperiment(processedExperiment); + } + } + }); + this._register(onSaveHandler); + return ExperimentState.Evaluating; + }); + } +} + + +function safeParse(text: string | undefined, defaultObject: any) { + try { + return text ? JSON.parse(text) || defaultObject : defaultObject; + } catch (e) { + return defaultObject; + } +} diff --git a/src/vs/workbench/contrib/experiments/electron-browser/experimentService.ts b/src/vs/workbench/contrib/experiments/electron-browser/experimentService.ts deleted file mode 100644 index 0d880ac7fd7..00000000000 --- a/src/vs/workbench/contrib/experiments/electron-browser/experimentService.ts +++ /dev/null @@ -1,407 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { ITelemetryService, lastSessionDateStorageKey } from 'vs/platform/telemetry/common/telemetry'; -import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { language } from 'vs/base/common/platform'; -import { Disposable } from 'vs/base/common/lifecycle'; -import { match } from 'vs/base/common/glob'; -import { IRequestService, asJson } from 'vs/platform/request/common/request'; -import { Emitter, Event } from 'vs/base/common/event'; -import { ITextFileService, StateChange } from 'vs/workbench/services/textfile/common/textfiles'; -import { CancellationToken } from 'vs/base/common/cancellation'; -import { distinct } from 'vs/base/common/arrays'; -import { ExtensionType } from 'vs/platform/extensions/common/extensions'; -import { ExperimentState, IExperimentAction, IExperimentService, IExperiment, ExperimentActionType, IExperimentActionPromptProperties } from 'vs/workbench/contrib/experiments/common/experimentService'; -import { IProductService } from 'vs/platform/product/common/product'; -import { IWorkspaceStatsService } from 'vs/workbench/contrib/stats/common/workspaceStats'; - -interface IExperimentStorageState { - enabled: boolean; - state: ExperimentState; - editCount?: number; - lastEditedDate?: string; -} - -interface IRawExperiment { - id: string; - enabled?: boolean; - condition?: { - insidersOnly?: boolean; - newUser?: boolean; - displayLanguage?: string; - installedExtensions?: { - excludes?: string[]; - includes?: string[]; - }, - fileEdits?: { - filePathPattern?: string; - workspaceIncludes?: string[]; - workspaceExcludes?: string[]; - minEditCount: number; - }, - experimentsPreviouslyRun?: { - excludes?: string[]; - includes?: string[]; - } - userProbability?: number; - }; - action?: IExperimentAction; -} - -export class ExperimentService extends Disposable implements IExperimentService { - _serviceBrand: any; - private _experiments: IExperiment[] = []; - private _loadExperimentsPromise: Promise; - private _curatedMapping = Object.create(null); - - private readonly _onExperimentEnabled = this._register(new Emitter()); - onExperimentEnabled: Event = this._onExperimentEnabled.event; - - constructor( - @IStorageService private readonly storageService: IStorageService, - @IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService, - @ITextFileService private readonly textFileService: ITextFileService, - @IEnvironmentService private readonly environmentService: IEnvironmentService, - @ITelemetryService private readonly telemetryService: ITelemetryService, - @ILifecycleService private readonly lifecycleService: ILifecycleService, - @IRequestService private readonly requestService: IRequestService, - @IConfigurationService private readonly configurationService: IConfigurationService, - @IProductService private readonly productService: IProductService, - @IWorkspaceStatsService private readonly workspaceStatsService: IWorkspaceStatsService - ) { - super(); - - this._loadExperimentsPromise = Promise.resolve(this.lifecycleService.when(LifecyclePhase.Eventually)).then(() => this.loadExperiments()); - } - - public getExperimentById(id: string): Promise { - return this._loadExperimentsPromise.then(() => { - return this._experiments.filter(x => x.id === id)[0]; - }); - } - - public getExperimentsByType(type: ExperimentActionType): Promise { - return this._loadExperimentsPromise.then(() => { - if (type === ExperimentActionType.Custom) { - return this._experiments.filter(x => x.enabled && (!x.action || x.action.type === type)); - } - return this._experiments.filter(x => x.enabled && x.action && x.action.type === type); - }); - } - - public getCuratedExtensionsList(curatedExtensionsKey: string): Promise { - return this._loadExperimentsPromise.then(() => { - for (const experiment of this._experiments) { - if (experiment.enabled - && experiment.state === ExperimentState.Run - && this._curatedMapping[experiment.id] - && this._curatedMapping[experiment.id].curatedExtensionsKey === curatedExtensionsKey) { - return this._curatedMapping[experiment.id].curatedExtensionsList; - } - } - return []; - }); - } - - public markAsCompleted(experimentId: string): void { - const storageKey = 'experiments.' + experimentId; - const experimentState: IExperimentStorageState = safeParse(this.storageService.get(storageKey, StorageScope.GLOBAL), {}); - experimentState.state = ExperimentState.Complete; - this.storageService.store(storageKey, JSON.stringify(experimentState), StorageScope.GLOBAL); - } - - protected getExperiments(): Promise { - if (!this.productService.experimentsUrl || this.configurationService.getValue('workbench.enableExperiments') === false) { - return Promise.resolve([]); - } - return this.requestService.request({ type: 'GET', url: this.productService.experimentsUrl }, CancellationToken.None).then(context => { - if (context.res.statusCode !== 200) { - return Promise.resolve(null); - } - return asJson(context).then((result: any) => { - return result && Array.isArray(result['experiments']) ? result['experiments'] : []; - }); - }, () => Promise.resolve(null)); - } - - private loadExperiments(): Promise { - return this.getExperiments().then(rawExperiments => { - // Offline mode - if (!rawExperiments) { - const allExperimentIdsFromStorage = safeParse(this.storageService.get('allExperiments', StorageScope.GLOBAL), []); - if (Array.isArray(allExperimentIdsFromStorage)) { - allExperimentIdsFromStorage.forEach(experimentId => { - const storageKey = 'experiments.' + experimentId; - const experimentState: IExperimentStorageState = safeParse(this.storageService.get(storageKey, StorageScope.GLOBAL), null); - if (experimentState) { - this._experiments.push({ - id: experimentId, - enabled: experimentState.enabled, - state: experimentState.state - }); - } - }); - } - return Promise.resolve(null); - } - - // Clear disbaled/deleted experiments from storage - const allExperimentIdsFromStorage = safeParse(this.storageService.get('allExperiments', StorageScope.GLOBAL), []); - const enabledExperiments = rawExperiments.filter(experiment => !!experiment.enabled).map(experiment => experiment.id.toLowerCase()); - if (Array.isArray(allExperimentIdsFromStorage)) { - allExperimentIdsFromStorage.forEach(experiment => { - if (enabledExperiments.indexOf(experiment) === -1) { - this.storageService.remove(`experiments.${experiment}`, StorageScope.GLOBAL); - } - }); - } - if (enabledExperiments.length) { - this.storageService.store('allExperiments', JSON.stringify(enabledExperiments), StorageScope.GLOBAL); - } else { - this.storageService.remove('allExperiments', StorageScope.GLOBAL); - } - - const promises = rawExperiments.map(experiment => { - const processedExperiment: IExperiment = { - id: experiment.id, - enabled: !!experiment.enabled, - state: !!experiment.enabled ? ExperimentState.Evaluating : ExperimentState.NoRun - }; - - if (experiment.action) { - processedExperiment.action = { - type: ExperimentActionType[experiment.action.type] || ExperimentActionType.Custom, - properties: experiment.action.properties - }; - if (processedExperiment.action.type === ExperimentActionType.Prompt) { - ((processedExperiment.action.properties).commands || []).forEach(x => { - if (x.curatedExtensionsKey && Array.isArray(x.curatedExtensionsList)) { - this._curatedMapping[experiment.id] = x; - } - }); - } - if (!processedExperiment.action.properties) { - processedExperiment.action.properties = {}; - } - } - this._experiments.push(processedExperiment); - - if (!processedExperiment.enabled) { - return Promise.resolve(null); - } - - const storageKey = 'experiments.' + experiment.id; - const experimentState: IExperimentStorageState = safeParse(this.storageService.get(storageKey, StorageScope.GLOBAL), {}); - if (!experimentState.hasOwnProperty('enabled')) { - experimentState.enabled = processedExperiment.enabled; - } - if (!experimentState.hasOwnProperty('state')) { - experimentState.state = processedExperiment.enabled ? ExperimentState.Evaluating : ExperimentState.NoRun; - } else { - processedExperiment.state = experimentState.state; - } - - return this.shouldRunExperiment(experiment, processedExperiment).then((state: ExperimentState) => { - experimentState.state = processedExperiment.state = state; - this.storageService.store(storageKey, JSON.stringify(experimentState), StorageScope.GLOBAL); - - if (state === ExperimentState.Run) { - this.fireRunExperiment(processedExperiment); - } - return Promise.resolve(null); - }); - - }); - return Promise.all(promises).then(() => { - type ExperimentsClassification = { - experiments: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; - }; - this.telemetryService.publicLog2<{ experiments: IExperiment[] }, ExperimentsClassification>('experiments', { experiments: this._experiments }); - }); - }); - } - - private fireRunExperiment(experiment: IExperiment) { - this._onExperimentEnabled.fire(experiment); - const runExperimentIdsFromStorage: string[] = safeParse(this.storageService.get('currentOrPreviouslyRunExperiments', StorageScope.GLOBAL), []); - if (runExperimentIdsFromStorage.indexOf(experiment.id) === -1) { - runExperimentIdsFromStorage.push(experiment.id); - } - - // Ensure we dont store duplicates - const distinctExperiments = distinct(runExperimentIdsFromStorage); - if (runExperimentIdsFromStorage.length !== distinctExperiments.length) { - this.storageService.store('currentOrPreviouslyRunExperiments', JSON.stringify(distinctExperiments), StorageScope.GLOBAL); - } - } - - private checkExperimentDependencies(experiment: IRawExperiment): boolean { - const experimentsPreviouslyRun = experiment.condition ? experiment.condition.experimentsPreviouslyRun : undefined; - if (experimentsPreviouslyRun) { - const runExperimentIdsFromStorage: string[] = safeParse(this.storageService.get('currentOrPreviouslyRunExperiments', StorageScope.GLOBAL), []); - let includeCheck = true; - let excludeCheck = true; - const includes = experimentsPreviouslyRun.includes; - if (Array.isArray(includes)) { - includeCheck = runExperimentIdsFromStorage.some(x => includes.indexOf(x) > -1); - } - const excludes = experimentsPreviouslyRun.excludes; - if (includeCheck && Array.isArray(excludes)) { - excludeCheck = !runExperimentIdsFromStorage.some(x => excludes.indexOf(x) > -1); - } - if (!includeCheck || !excludeCheck) { - return false; - } - } - return true; - } - - private shouldRunExperiment(experiment: IRawExperiment, processedExperiment: IExperiment): Promise { - if (processedExperiment.state !== ExperimentState.Evaluating) { - return Promise.resolve(processedExperiment.state); - } - - if (!experiment.enabled) { - return Promise.resolve(ExperimentState.NoRun); - } - - const condition = experiment.condition; - if (!condition) { - return Promise.resolve(ExperimentState.Run); - } - - if (!this.checkExperimentDependencies(experiment)) { - return Promise.resolve(ExperimentState.NoRun); - } - - if (this.environmentService.appQuality === 'stable' && condition.insidersOnly === true) { - return Promise.resolve(ExperimentState.NoRun); - } - - const isNewUser = !this.storageService.get(lastSessionDateStorageKey, StorageScope.GLOBAL); - if ((condition.newUser === true && !isNewUser) - || (condition.newUser === false && isNewUser)) { - return Promise.resolve(ExperimentState.NoRun); - } - - if (typeof condition.displayLanguage === 'string') { - let localeToCheck = condition.displayLanguage.toLowerCase(); - let displayLanguage = language!.toLowerCase(); - - if (localeToCheck !== displayLanguage) { - const a = displayLanguage.indexOf('-'); - const b = localeToCheck.indexOf('-'); - if (a > -1) { - displayLanguage = displayLanguage.substr(0, a); - } - if (b > -1) { - localeToCheck = localeToCheck.substr(0, b); - } - if (displayLanguage !== localeToCheck) { - return Promise.resolve(ExperimentState.NoRun); - } - } - } - - if (!condition.userProbability) { - condition.userProbability = 1; - } - - let extensionsCheckPromise = Promise.resolve(true); - const installedExtensions = condition.installedExtensions; - if (installedExtensions) { - extensionsCheckPromise = this.extensionManagementService.getInstalled(ExtensionType.User).then(locals => { - let includesCheck = true; - let excludesCheck = true; - const localExtensions = locals.map(local => `${local.manifest.publisher.toLowerCase()}.${local.manifest.name.toLowerCase()}`); - if (Array.isArray(installedExtensions.includes) && installedExtensions.includes.length) { - const extensionIncludes = installedExtensions.includes.map(e => e.toLowerCase()); - includesCheck = localExtensions.some(e => extensionIncludes.indexOf(e) > -1); - } - if (Array.isArray(installedExtensions.excludes) && installedExtensions.excludes.length) { - const extensionExcludes = installedExtensions.excludes.map(e => e.toLowerCase()); - excludesCheck = !localExtensions.some(e => extensionExcludes.indexOf(e) > -1); - } - return includesCheck && excludesCheck; - }); - } - - const storageKey = 'experiments.' + experiment.id; - const experimentState: IExperimentStorageState = safeParse(this.storageService.get(storageKey, StorageScope.GLOBAL), {}); - - return extensionsCheckPromise.then(success => { - const fileEdits = condition.fileEdits; - if (!success || !fileEdits || typeof fileEdits.minEditCount !== 'number') { - const runExperiment = success && typeof condition.userProbability === 'number' && Math.random() < condition.userProbability; - return runExperiment ? ExperimentState.Run : ExperimentState.NoRun; - } - - experimentState.editCount = experimentState.editCount || 0; - if (experimentState.editCount >= fileEdits.minEditCount) { - return ExperimentState.Run; - } - - const onSaveHandler = this.textFileService.models.onModelsSaved(e => { - const date = new Date().toDateString(); - const latestExperimentState: IExperimentStorageState = safeParse(this.storageService.get(storageKey, StorageScope.GLOBAL), {}); - if (latestExperimentState.state !== ExperimentState.Evaluating) { - onSaveHandler.dispose(); - return; - } - e.forEach(async event => { - if (event.kind !== StateChange.SAVED - || latestExperimentState.state !== ExperimentState.Evaluating - || date === latestExperimentState.lastEditedDate - || (typeof latestExperimentState.editCount === 'number' && latestExperimentState.editCount >= fileEdits.minEditCount) - ) { - return; - } - let filePathCheck = true; - let workspaceCheck = true; - - if (typeof fileEdits.filePathPattern === 'string') { - filePathCheck = match(fileEdits.filePathPattern, event.resource.fsPath); - } - if (Array.isArray(fileEdits.workspaceIncludes) && fileEdits.workspaceIncludes.length) { - const tags = await this.workspaceStatsService.getTags(); - workspaceCheck = !!tags && fileEdits.workspaceIncludes.some(x => !!tags[x]); - } - if (workspaceCheck && Array.isArray(fileEdits.workspaceExcludes) && fileEdits.workspaceExcludes.length) { - const tags = await this.workspaceStatsService.getTags(); - workspaceCheck = !!tags && !fileEdits.workspaceExcludes.some(x => !!tags[x]); - } - if (filePathCheck && workspaceCheck) { - latestExperimentState.editCount = (latestExperimentState.editCount || 0) + 1; - latestExperimentState.lastEditedDate = date; - this.storageService.store(storageKey, JSON.stringify(latestExperimentState), StorageScope.GLOBAL); - } - }); - if (typeof latestExperimentState.editCount === 'number' && latestExperimentState.editCount >= fileEdits.minEditCount) { - processedExperiment.state = latestExperimentState.state = (typeof condition.userProbability === 'number' && Math.random() < condition.userProbability && this.checkExperimentDependencies(experiment)) ? ExperimentState.Run : ExperimentState.NoRun; - this.storageService.store(storageKey, JSON.stringify(latestExperimentState), StorageScope.GLOBAL); - if (latestExperimentState.state === ExperimentState.Run && experiment.action && ExperimentActionType[experiment.action.type] === ExperimentActionType.Prompt) { - this.fireRunExperiment(processedExperiment); - } - } - }); - this._register(onSaveHandler); - return ExperimentState.Evaluating; - }); - } -} - - -function safeParse(text: string | undefined, defaultObject: any) { - try { - return text ? JSON.parse(text) || defaultObject : defaultObject; - } catch (e) { - return defaultObject; - } -} diff --git a/src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts b/src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts index f44b4d3904e..70851b908c9 100644 --- a/src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts +++ b/src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts @@ -4,8 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { ExperimentActionType, ExperimentState, IExperiment } from 'vs/workbench/contrib/experiments/common/experimentService'; -import { ExperimentService } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; +import { ExperimentActionType, ExperimentState, IExperiment, ExperimentService } from 'vs/workbench/contrib/experiments/common/experimentService'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { TestLifecycleService } from 'vs/workbench/test/workbenchTestServices'; diff --git a/src/vs/workbench/contrib/experiments/test/electron-browser/experimentalPrompts.test.ts b/src/vs/workbench/contrib/experiments/test/electron-browser/experimentalPrompts.test.ts index 781fc5ab7c0..ff693a1f4e3 100644 --- a/src/vs/workbench/contrib/experiments/test/electron-browser/experimentalPrompts.test.ts +++ b/src/vs/workbench/contrib/experiments/test/electron-browser/experimentalPrompts.test.ts @@ -12,7 +12,7 @@ import { TestNotificationService } from 'vs/platform/notification/test/common/te import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; -import { ExperimentalPrompts } from 'vs/workbench/contrib/experiments/electron-browser/experimentalPrompt'; +import { ExperimentalPrompts } from 'vs/workbench/contrib/experiments/browser/experimentalPrompt'; import { ExperimentActionType, ExperimentState, IExperiment, IExperimentActionPromptProperties, IExperimentService, LocalizedPromptText } from 'vs/workbench/contrib/experiments/common/experimentService'; import { TestExperimentService } from 'vs/workbench/contrib/experiments/test/electron-browser/experimentService.test'; import { TestLifecycleService } from 'vs/workbench/test/workbenchTestServices'; diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts index cf2b6c79522..a618098b66c 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts @@ -35,8 +35,7 @@ import { URLService } from 'vs/platform/url/common/urlService'; import { URI } from 'vs/base/common/uri'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { SinonStub } from 'sinon'; -import { IExperimentService, ExperimentState, ExperimentActionType } from 'vs/workbench/contrib/experiments/common/experimentService'; -import { ExperimentService } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; +import { IExperimentService, ExperimentState, ExperimentActionType, ExperimentService } from 'vs/workbench/contrib/experiments/common/experimentService'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl'; import { ExtensionIdentifier, ExtensionType, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index 72765299a31..7c12967c4ae 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -227,4 +227,7 @@ import 'vs/workbench/contrib/callHierarchy/browser/callHierarchy.contribution'; // Outline import 'vs/workbench/contrib/outline/browser/outline.contribution'; +// Experiments +import 'vs/workbench/contrib/experiments/browser/experiments.contribution'; + //#endregion diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index 4d2996a0ed6..d426224accf 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -154,9 +154,6 @@ import 'vs/workbench/contrib/themes/test/electron-browser/themes.test.contributi import 'vs/workbench/contrib/welcome/gettingStarted/electron-browser/gettingStarted.contribution'; import 'vs/workbench/contrib/welcome/page/browser/welcomePage.contribution'; -// Experiments -import 'vs/workbench/contrib/experiments/electron-browser/experiments.contribution'; - // Issues import 'vs/workbench/contrib/issue/electron-browser/issue.contribution'; From 994e1315c09a6d92e57adf8cb9d386f5b30b4b3f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 14 Aug 2019 16:49:22 +0200 Subject: [PATCH 597/861] tests -remove unused services --- .../textfile/test/textFileService.io.test.ts | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/services/textfile/test/textFileService.io.test.ts b/src/vs/workbench/services/textfile/test/textFileService.io.test.ts index 6bbdf0e42e1..eab223e0d4a 100644 --- a/src/vs/workbench/services/textfile/test/textFileService.io.test.ts +++ b/src/vs/workbench/services/textfile/test/textFileService.io.test.ts @@ -4,16 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import { URI } from 'vs/base/common/uri'; -import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; -import { workbenchInstantiationService, TestLifecycleService, TestTextFileService, TestWindowsService, TestContextService, TestFileService } from 'vs/workbench/test/workbenchTestServices'; -import { IWindowsService } from 'vs/platform/windows/common/windows'; +import { workbenchInstantiationService, TestTextFileService } from 'vs/workbench/test/workbenchTestServices'; import { ITextFileService, snapshotToString, TextFileOperationResult, TextFileOperationError } from 'vs/workbench/services/textfile/common/textfiles'; import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; import { IFileService } from 'vs/platform/files/common/files'; import { TextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textFileEditorModelManager'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { IModelService } from 'vs/editor/common/services/modelService'; -import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl'; import { Schemas } from 'vs/base/common/network'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; import { rimraf, RimRafMode, copy, readFile, exists } from 'vs/base/node/pfs'; @@ -36,13 +31,8 @@ import { detectEncodingByBOM } from 'vs/base/test/node/encoding/encoding.test'; class ServiceAccessor { constructor( - @ILifecycleService public lifecycleService: TestLifecycleService, @ITextFileService public textFileService: TestTextFileService, - @IUntitledEditorService public untitledEditorService: IUntitledEditorService, - @IWindowsService public windowsService: TestWindowsService, - @IWorkspaceContextService public contextService: TestContextService, - @IModelService public modelService: ModelServiceImpl, - @IFileService public fileService: TestFileService + @IUntitledEditorService public untitledEditorService: IUntitledEditorService ) { } } From 9c2cc80fcdab2c949294771daa05f61652ca009e Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 14 Aug 2019 16:56:16 +0200 Subject: [PATCH 598/861] Move getHashedRemotesFromUri to IWorkspaceStatsService --- src/vs/workbench/browser/web.simpleservices.ts | 4 ++++ .../electron-browser/extensionTipsService.ts | 7 +++---- .../contrib/stats/common/workspaceStats.ts | 3 +++ .../stats/electron-browser/workspaceStats.ts | 16 +--------------- .../electron-browser/workspaceStatsService.ts | 15 +++++++++++++++ 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index f9bfd69e4c9..46a3f6a59aa 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -859,6 +859,10 @@ class WorkspaceStatsService implements IWorkspaceStatsService { return undefined; } + getHashedRemotesFromUri(workspaceUri: URI, stripEndingDotGit?: boolean): Promise { + return Promise.resolve([]); + } + } registerSingleton(IWorkspaceStatsService, WorkspaceStatsService); diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts index b424211b797..33e5fbc2bfe 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts @@ -29,7 +29,6 @@ import { flatten, distinct, shuffle, coalesce } from 'vs/base/common/arrays'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { guessMimeTypes, MIME_UNKNOWN } from 'vs/base/common/mime'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; -import { getHashedRemotesFromUri } from 'vs/workbench/contrib/stats/electron-browser/workspaceStats'; import { IRequestService, asJson } from 'vs/platform/request/common/request'; import { isNumber } from 'vs/base/common/types'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; @@ -42,9 +41,9 @@ import { IExperimentService, ExperimentActionType, ExperimentState } from 'vs/wo import { CancellationToken } from 'vs/base/common/cancellation'; import { ExtensionType } from 'vs/platform/extensions/common/extensions'; import { extname } from 'vs/base/common/resources'; -import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IExeBasedExtensionTip } from 'vs/platform/product/common/product'; import { timeout } from 'vs/base/common/async'; +import { IWorkspaceStatsService } from 'vs/workbench/contrib/stats/common/workspaceStats'; const milliSecondsInADay = 1000 * 60 * 60 * 24; const choiceNever = localize('neverShowAgain', "Don't Show Again"); @@ -109,7 +108,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe @IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService, @IExtensionsWorkbenchService private readonly extensionWorkbenchService: IExtensionsWorkbenchService, @IExperimentService private readonly experimentService: IExperimentService, - @ITextFileService private readonly textFileService: ITextFileService + @IWorkspaceStatsService private readonly workspaceStatsService: IWorkspaceStatsService ) { super(); @@ -1078,7 +1077,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe const storageKey = 'extensionsAssistant/dynamicWorkspaceRecommendations'; const workspaceUri = this.contextService.getWorkspace().folders[0].uri; - return Promise.all([getHashedRemotesFromUri(workspaceUri, this.fileService, this.textFileService, false), getHashedRemotesFromUri(workspaceUri, this.fileService, this.textFileService, true)]).then(([hashedRemotes1, hashedRemotes2]) => { + return Promise.all([this.workspaceStatsService.getHashedRemotesFromUri(workspaceUri, false), this.workspaceStatsService.getHashedRemotesFromUri(workspaceUri, true)]).then(([hashedRemotes1, hashedRemotes2]) => { const hashedRemotes = (hashedRemotes1 || []).concat(hashedRemotes2 || []); if (!hashedRemotes.length) { return undefined; diff --git a/src/vs/workbench/contrib/stats/common/workspaceStats.ts b/src/vs/workbench/contrib/stats/common/workspaceStats.ts index 177911447fc..7bd69fc83cd 100644 --- a/src/vs/workbench/contrib/stats/common/workspaceStats.ts +++ b/src/vs/workbench/contrib/stats/common/workspaceStats.ts @@ -5,6 +5,7 @@ import { WorkbenchState, IWorkspace } from 'vs/platform/workspace/common/workspace'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { URI } from 'vs/base/common/uri'; export type Tags = { [index: string]: boolean | number | string | undefined }; @@ -20,4 +21,6 @@ export interface IWorkspaceStatsService { * on the folder uri or workspace configuration, not time-based, and undefined for empty workspaces. */ getTelemetryWorkspaceId(workspace: IWorkspace, state: WorkbenchState): string | undefined; + + getHashedRemotesFromUri(workspaceUri: URI, stripEndingDotGit?: boolean): Promise; } diff --git a/src/vs/workbench/contrib/stats/electron-browser/workspaceStats.ts b/src/vs/workbench/contrib/stats/electron-browser/workspaceStats.ts index 7577b5a9bda..d6d6c795e0c 100644 --- a/src/vs/workbench/contrib/stats/electron-browser/workspaceStats.ts +++ b/src/vs/workbench/contrib/stats/electron-browser/workspaceStats.ts @@ -136,20 +136,6 @@ export function getHashedRemotesFromConfig(text: string, stripEndingDotGit: bool }); } -export function getHashedRemotesFromUri(workspaceUri: URI, fileService: IFileService, textFileService: ITextFileService, stripEndingDotGit: boolean = false): Promise { - const path = workspaceUri.path; - const uri = workspaceUri.with({ path: `${path !== '/' ? path : ''}/.git/config` }); - return fileService.exists(uri).then(exists => { - if (!exists) { - return []; - } - return textFileService.read(uri, { acceptTextOnly: true }).then( - content => getHashedRemotesFromConfig(content.value, stripEndingDotGit), - err => [] // ignore missing or binary file - ); - }); -} - export class WorkspaceStats implements IWorkbenchContribution { constructor( @@ -230,7 +216,7 @@ export class WorkspaceStats implements IWorkbenchContribution { private reportRemotes(workspaceUris: URI[]): void { Promise.all(workspaceUris.map(workspaceUri => { - return getHashedRemotesFromUri(workspaceUri, this.fileService, this.textFileService, true); + return this.workspaceStatsService.getHashedRemotesFromUri(workspaceUri, true); })).then(hashedRemotes => { /* __GDPR__ "workspace.hashedRemotes" : { diff --git a/src/vs/workbench/contrib/stats/electron-browser/workspaceStatsService.ts b/src/vs/workbench/contrib/stats/electron-browser/workspaceStatsService.ts index 3cce4db8bfb..9c1c1d57180 100644 --- a/src/vs/workbench/contrib/stats/electron-browser/workspaceStatsService.ts +++ b/src/vs/workbench/contrib/stats/electron-browser/workspaceStatsService.ts @@ -20,6 +20,7 @@ import Severity from 'vs/base/common/severity'; import { joinPath } from 'vs/base/common/resources'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IWorkspaceStatsService, Tags } from 'vs/workbench/contrib/stats/common/workspaceStats'; +import { getHashedRemotesFromConfig } from 'vs/workbench/contrib/stats/electron-browser/workspaceStats'; const DISABLE_WORKSPACE_PROMPT_KEY = 'workspaces.dontPromptToOpen'; @@ -136,6 +137,20 @@ export class WorkspaceStatsService implements IWorkspaceStatsService { return workspaceId; } + getHashedRemotesFromUri(workspaceUri: URI, stripEndingDotGit: boolean = false): Promise { + const path = workspaceUri.path; + const uri = workspaceUri.with({ path: `${path !== '/' ? path : ''}/.git/config` }); + return this.fileService.exists(uri).then(exists => { + if (!exists) { + return []; + } + return this.textFileService.read(uri, { acceptTextOnly: true }).then( + content => getHashedRemotesFromConfig(content.value, stripEndingDotGit), + err => [] // ignore missing or binary file + ); + }); + } + /* __GDPR__FRAGMENT__ "WorkspaceTags" : { "workbench.filesToOpenOrCreate" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, From c3fcaef0c03a88e17cb2ce46d650b3425fd5efa9 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 14 Aug 2019 17:44:09 +0200 Subject: [PATCH 599/861] add and use `getWorkerBootstrapUrl`, don't use default worker factory anymore --- src/vs/base/worker/defaultWorkerFactory.ts | 33 +++++++++-------- .../browser/webWorkerExtensionHostStarter.ts | 36 +++++++++++-------- .../extensions/worker/extensionHostWorker.ts | 20 ++++------- .../worker/extensionHostWorkerMain.ts | 21 +++++++++++ 4 files changed, 68 insertions(+), 42 deletions(-) create mode 100644 src/vs/workbench/services/extensions/worker/extensionHostWorkerMain.ts diff --git a/src/vs/base/worker/defaultWorkerFactory.ts b/src/vs/base/worker/defaultWorkerFactory.ts index c2a7ddc54e6..bce60b6b855 100644 --- a/src/vs/base/worker/defaultWorkerFactory.ts +++ b/src/vs/base/worker/defaultWorkerFactory.ts @@ -19,26 +19,31 @@ function getWorker(workerId: string, label: string): Worker | Promise { // ESM-comment-begin if (typeof require === 'function') { // check if the JS lives on a different origin - const workerMain = require.toUrl('./' + workerId); - if (/^(http:)|(https:)|(file:)/.test(workerMain)) { - const currentUrl = String(window.location); - const currentOrigin = currentUrl.substr(0, currentUrl.length - window.location.hash.length - window.location.search.length - window.location.pathname.length); - if (workerMain.substring(0, currentOrigin.length) !== currentOrigin) { - // this is the cross-origin case - // i.e. the webpage is running at a different origin than where the scripts are loaded from - const workerBaseUrl = workerMain.substr(0, workerMain.length - 'vs/base/worker/workerMain.js'.length); - const js = `/*${label}*/self.MonacoEnvironment={baseUrl: '${workerBaseUrl}'};importScripts('${workerMain}');/*${label}*/`; - const url = `data:text/javascript;charset=utf-8,${encodeURIComponent(js)}`; - return new Worker(url); - } - } - return new Worker(workerMain + '#' + label); + const workerUrl = getWorkerBootstrapUrl(workerMain, label); + return new Worker(workerUrl, { name: label }); } // ESM-comment-end throw new Error(`You must define a function MonacoEnvironment.getWorkerUrl or MonacoEnvironment.getWorker`); } +export function getWorkerBootstrapUrl(scriptPath: string, label: string): string { + if (/^(http:)|(https:)|(file:)/.test(scriptPath)) { + const currentUrl = String(window.location); + const currentOrigin = currentUrl.substr(0, currentUrl.length - window.location.hash.length - window.location.search.length - window.location.pathname.length); + if (scriptPath.substring(0, currentOrigin.length) !== currentOrigin) { + // this is the cross-origin case + // i.e. the webpage is running at a different origin than where the scripts are loaded from + const myPath = 'vs/base/worker/defaultWorkerFactory.js'; + const workerBaseUrl = require.toUrl(myPath).slice(0, -myPath.length); + const js = `/*${label}*/self.MonacoEnvironment={baseUrl: '${workerBaseUrl}'};importScripts('${scriptPath}');/*${label}*/`; + const url = `data:text/javascript;charset=utf-8,${encodeURIComponent(js)}`; + return url; + } + } + return scriptPath + '#' + label; +} + function isPromiseLike(obj: any): obj is PromiseLike { if (typeof obj.then === 'function') { return true; diff --git a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts index 1f04364fa5d..5794b259061 100644 --- a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts +++ b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts @@ -3,9 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { DefaultWorkerFactory } from 'vs/base/worker/defaultWorkerFactory'; +import { getWorkerBootstrapUrl } from 'vs/base/worker/defaultWorkerFactory'; import { Emitter, Event } from 'vs/base/common/event'; -import { DisposableStore } from 'vs/base/common/lifecycle'; +import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; import { VSBuffer } from 'vs/base/common/buffer'; import { createMessageOfType, MessageType, isMessageOfType } from 'vs/workbench/services/extensions/common/extensionHostProtocol'; @@ -49,23 +49,29 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { if (!this._protocol) { const emitter = new Emitter(); - const worker = new DefaultWorkerFactory('WorkerExtensionHost').create( - 'vs/workbench/services/extensions/worker/extensionHostWorker', data => { - if (data instanceof ArrayBuffer) { - emitter.fire(VSBuffer.wrap(new Uint8Array(data, 0, data.byteLength))); - } else { - console.warn('UNKNOWN data received', data); - this._onDidExit.fire([77, 'UNKNOWN data received']); - } - }, err => { - this._onDidExit.fire([81, err]); - console.error(err); + + const url = getWorkerBootstrapUrl(require.toUrl('../worker/extensionHostWorkerMain.js'), 'WorkerExtensionHost'); + const worker = new Worker(url); + + worker.onmessage = (event) => { + const { data } = event; + if (!(data instanceof ArrayBuffer)) { + console.warn('UNKNOWN data received', data); + this._onDidExit.fire([77, 'UNKNOWN data received']); + return; } - ); + + emitter.fire(VSBuffer.wrap(new Uint8Array(data, 0, data.byteLength))); + }; + + worker.onerror = (event) => { + console.error(event.error); + this._onDidExit.fire([81, event.error]); + }; // keep for cleanup this._toDispose.add(emitter); - this._toDispose.add(worker); + this._toDispose.add(toDisposable(() => worker.terminate())); const protocol: IMessagePassingProtocol = { onMessage: emitter.event, diff --git a/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts b/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts index 3ed289be397..34e3f35a624 100644 --- a/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts +++ b/src/vs/workbench/services/extensions/worker/extensionHostWorker.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IRequestHandler } from 'vs/base/common/worker/simpleWorker'; import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; import { VSBuffer } from 'vs/base/common/buffer'; import { Emitter } from 'vs/base/common/event'; @@ -38,21 +37,18 @@ const hostUtil = new class implements IHostUtils { //todo@joh do not allow extensions to call postMessage and other globals... -class ExtensionWorker implements IRequestHandler { - - // worker-contract - readonly _requestHandlerBrand: any; - readonly onmessage: (data: any) => any; +class ExtensionWorker { // protocol readonly protocol: IMessagePassingProtocol; - constructor(postMessage: (message: any, transfer?: Transferable[]) => any) { + constructor() { let emitter = new Emitter(); let terminating = false; - this.onmessage = data => { + onmessage = event => { + const { data } = event; if (!(data instanceof ArrayBuffer)) { console.warn('UNKNOWN data received', data); return; @@ -98,8 +94,8 @@ function connectToRenderer(protocol: IMessagePassingProtocol): Promise any): IRequestHandler { - const res = new ExtensionWorker(postMessage); +(function create(): void { + const res = new ExtensionWorker(); connectToRenderer(res.protocol).then(data => { @@ -112,6 +108,4 @@ export function create(postMessage: (message: any, transfer?: Transferable[]) => onTerminate = () => extHostMain.terminate(); }); - - return res; -} +})(); diff --git a/src/vs/workbench/services/extensions/worker/extensionHostWorkerMain.ts b/src/vs/workbench/services/extensions/worker/extensionHostWorkerMain.ts new file mode 100644 index 00000000000..79455414c06 --- /dev/null +++ b/src/vs/workbench/services/extensions/worker/extensionHostWorkerMain.ts @@ -0,0 +1,21 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +(function () { + + let MonacoEnvironment = (self).MonacoEnvironment; + let monacoBaseUrl = MonacoEnvironment && MonacoEnvironment.baseUrl ? MonacoEnvironment.baseUrl : '../../../../../'; + + if (typeof (self).define !== 'function' || !(self).define.amd) { + importScripts(monacoBaseUrl + 'vs/loader.js'); + } + + require.config({ + baseUrl: monacoBaseUrl, + catchError: true + }); + + require(['vs/workbench/services/extensions/worker/extensionHostWorker'], () => { }, err => console.error(err)); +})(); From 16051c7a41ee3923a01f30604805e925eae717fc Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 14 Aug 2019 17:55:16 +0200 Subject: [PATCH 600/861] - use strings for view zone ids - make it unlikely that a new view instance would accept a view zone id from a previous view instance - remove that the find widget removes a view zone id from another view (fixes #71745) --- src/vs/base/common/strings.ts | 15 ++++++ .../editor/browser/controller/mouseHandler.ts | 2 +- .../editor/browser/controller/mouseTarget.ts | 2 +- src/vs/editor/browser/editorBrowser.ts | 6 +-- src/vs/editor/browser/view/viewImpl.ts | 8 +-- .../browser/viewParts/viewZones/viewZones.ts | 34 ++++++------ .../editor/browser/widget/diffEditorWidget.ts | 2 +- src/vs/editor/common/model/textModel.ts | 17 +----- .../editor/common/viewLayout/linesLayout.ts | 6 +-- src/vs/editor/common/viewLayout/viewLayout.ts | 6 +-- .../common/viewLayout/whitespaceComputer.ts | 53 +++++++++---------- src/vs/editor/common/viewModel/viewModel.ts | 8 +-- .../editor/contrib/codelens/codelensWidget.ts | 2 +- src/vs/editor/contrib/find/findWidget.ts | 12 +---- .../editor/contrib/zoneWidget/zoneWidget.ts | 2 +- src/vs/monaco.d.ts | 6 +-- .../api/browser/mainThreadCodeInsets.ts | 2 +- .../preferences/browser/preferencesWidgets.ts | 4 +- 18 files changed, 88 insertions(+), 99 deletions(-) diff --git a/src/vs/base/common/strings.ts b/src/vs/base/common/strings.ts index d4397d3279d..71185d07046 100644 --- a/src/vs/base/common/strings.ts +++ b/src/vs/base/common/strings.ts @@ -729,3 +729,18 @@ export function getNLines(str: string, n = 1): string { str.substr(0, idx) : str; } + +/** + * Produces 'a'-'z', followed by 'A'-'Z'... followed by 'a'-'z', etc. + */ +export function singleLetterHash(n: number): string { + const LETTERS_CNT = (CharCode.Z - CharCode.A + 1); + + n = n % (2 * LETTERS_CNT); + + if (n < LETTERS_CNT) { + return String.fromCharCode(CharCode.a + n); + } + + return String.fromCharCode(CharCode.A + n - LETTERS_CNT); +} diff --git a/src/vs/editor/browser/controller/mouseHandler.ts b/src/vs/editor/browser/controller/mouseHandler.ts index 06d4b2f5307..418e8ebee98 100644 --- a/src/vs/editor/browser/controller/mouseHandler.ts +++ b/src/vs/editor/browser/controller/mouseHandler.ts @@ -49,7 +49,7 @@ export interface IPointerHandlerHelper { */ getLastViewCursorsRenderData(): IViewCursorRenderData[]; - shouldSuppressMouseDownOnViewZone(viewZoneId: number): boolean; + shouldSuppressMouseDownOnViewZone(viewZoneId: string): boolean; shouldSuppressMouseDownOnWidget(widgetId: string): boolean; /** diff --git a/src/vs/editor/browser/controller/mouseTarget.ts b/src/vs/editor/browser/controller/mouseTarget.ts index 1f4c6ff52c7..f510e0f6f82 100644 --- a/src/vs/editor/browser/controller/mouseTarget.ts +++ b/src/vs/editor/browser/controller/mouseTarget.ts @@ -19,7 +19,7 @@ import { IViewModel } from 'vs/editor/common/viewModel/viewModel'; import { CursorColumns } from 'vs/editor/common/controller/cursorCommon'; export interface IViewZoneData { - viewZoneId: number; + viewZoneId: string; positionBefore: Position | null; positionAfter: Position | null; position: Position; diff --git a/src/vs/editor/browser/editorBrowser.ts b/src/vs/editor/browser/editorBrowser.ts index 705b6def023..91e6ea3864b 100644 --- a/src/vs/editor/browser/editorBrowser.ts +++ b/src/vs/editor/browser/editorBrowser.ts @@ -83,17 +83,17 @@ export interface IViewZoneChangeAccessor { * @param zone Zone to create * @return A unique identifier to the view zone. */ - addZone(zone: IViewZone): number; + addZone(zone: IViewZone): string; /** * Remove a zone * @param id A unique identifier to the view zone, as returned by the `addZone` call. */ - removeZone(id: number): void; + removeZone(id: string): void; /** * Change a zone's position. * The editor will rescan the `afterLineNumber` and `afterColumn` properties of a view zone. */ - layoutZone(id: number): void; + layoutZone(id: string): void; } /** diff --git a/src/vs/editor/browser/view/viewImpl.ts b/src/vs/editor/browser/view/viewImpl.ts index a476c33912a..45c711cecef 100644 --- a/src/vs/editor/browser/view/viewImpl.ts +++ b/src/vs/editor/browser/view/viewImpl.ts @@ -248,7 +248,7 @@ export class View extends ViewEventHandler { getLastViewCursorsRenderData: () => { return this.viewCursors.getLastRenderData() || []; }, - shouldSuppressMouseDownOnViewZone: (viewZoneId: number) => { + shouldSuppressMouseDownOnViewZone: (viewZoneId: string) => { return this.viewZones.shouldSuppressMouseDownOnViewZone(viewZoneId); }, shouldSuppressMouseDownOnWidget: (widgetId: string) => { @@ -473,17 +473,17 @@ export class View extends ViewEventHandler { this._renderOnce(() => { const changeAccessor: editorBrowser.IViewZoneChangeAccessor = { - addZone: (zone: editorBrowser.IViewZone): number => { + addZone: (zone: editorBrowser.IViewZone): string => { zonesHaveChanged = true; return this.viewZones.addZone(zone); }, - removeZone: (id: number): void => { + removeZone: (id: string): void => { if (!id) { return; } zonesHaveChanged = this.viewZones.removeZone(id) || zonesHaveChanged; }, - layoutZone: (id: number): void => { + layoutZone: (id: string): void => { if (!id) { return; } diff --git a/src/vs/editor/browser/viewParts/viewZones/viewZones.ts b/src/vs/editor/browser/viewParts/viewZones/viewZones.ts index a51fbe5bf02..6c01df4e0b6 100644 --- a/src/vs/editor/browser/viewParts/viewZones/viewZones.ts +++ b/src/vs/editor/browser/viewParts/viewZones/viewZones.ts @@ -14,7 +14,7 @@ import * as viewEvents from 'vs/editor/common/view/viewEvents'; import { IViewWhitespaceViewportData } from 'vs/editor/common/viewModel/viewModel'; export interface IMyViewZone { - whitespaceId: number; + whitespaceId: string; delegate: IViewZone; isVisible: boolean; domNode: FastDomNode; @@ -74,7 +74,7 @@ export class ViewZones extends ViewPart { const id = keys[i]; const zone = this._zones[id]; const props = this._computeWhitespaceProps(zone.delegate); - if (this._context.viewLayout.changeWhitespace(parseInt(id, 10), props.afterViewLineNumber, props.heightInPx)) { + if (this._context.viewLayout.changeWhitespace(id, props.afterViewLineNumber, props.heightInPx)) { this._safeCallOnComputedHeight(zone.delegate, props.heightInPx); hadAChange = true; } @@ -183,7 +183,7 @@ export class ViewZones extends ViewPart { }; } - public addZone(zone: IViewZone): number { + public addZone(zone: IViewZone): string { const props = this._computeWhitespaceProps(zone); const whitespaceId = this._context.viewLayout.addWhitespace(props.afterViewLineNumber, this._getZoneOrdinal(zone), props.heightInPx, props.minWidthInPx); @@ -200,18 +200,18 @@ export class ViewZones extends ViewPart { myZone.domNode.setPosition('absolute'); myZone.domNode.domNode.style.width = '100%'; myZone.domNode.setDisplay('none'); - myZone.domNode.setAttribute('monaco-view-zone', myZone.whitespaceId.toString()); + myZone.domNode.setAttribute('monaco-view-zone', myZone.whitespaceId); this.domNode.appendChild(myZone.domNode); if (myZone.marginDomNode) { myZone.marginDomNode.setPosition('absolute'); myZone.marginDomNode.domNode.style.width = '100%'; myZone.marginDomNode.setDisplay('none'); - myZone.marginDomNode.setAttribute('monaco-view-zone', myZone.whitespaceId.toString()); + myZone.marginDomNode.setAttribute('monaco-view-zone', myZone.whitespaceId); this.marginDomNode.appendChild(myZone.marginDomNode); } - this._zones[myZone.whitespaceId.toString()] = myZone; + this._zones[myZone.whitespaceId] = myZone; this.setShouldRender(); @@ -219,10 +219,10 @@ export class ViewZones extends ViewPart { return myZone.whitespaceId; } - public removeZone(id: number): boolean { - if (this._zones.hasOwnProperty(id.toString())) { - const zone = this._zones[id.toString()]; - delete this._zones[id.toString()]; + public removeZone(id: string): boolean { + if (this._zones.hasOwnProperty(id)) { + const zone = this._zones[id]; + delete this._zones[id]; this._context.viewLayout.removeWhitespace(zone.whitespaceId); zone.domNode.removeAttribute('monaco-visible-view-zone'); @@ -242,10 +242,10 @@ export class ViewZones extends ViewPart { return false; } - public layoutZone(id: number): boolean { + public layoutZone(id: string): boolean { let changed = false; - if (this._zones.hasOwnProperty(id.toString())) { - const zone = this._zones[id.toString()]; + if (this._zones.hasOwnProperty(id)) { + const zone = this._zones[id]; const props = this._computeWhitespaceProps(zone.delegate); // const newOrdinal = this._getZoneOrdinal(zone.delegate); changed = this._context.viewLayout.changeWhitespace(zone.whitespaceId, props.afterViewLineNumber, props.heightInPx) || changed; @@ -259,9 +259,9 @@ export class ViewZones extends ViewPart { return changed; } - public shouldSuppressMouseDownOnViewZone(id: number): boolean { - if (this._zones.hasOwnProperty(id.toString())) { - const zone = this._zones[id.toString()]; + public shouldSuppressMouseDownOnViewZone(id: string): boolean { + if (this._zones.hasOwnProperty(id)) { + const zone = this._zones[id]; return Boolean(zone.delegate.suppressMouseDown); } return false; @@ -314,7 +314,7 @@ export class ViewZones extends ViewPart { let hasVisibleZone = false; for (let i = 0, len = visibleWhitespaces.length; i < len; i++) { - visibleZones[visibleWhitespaces[i].id.toString()] = visibleWhitespaces[i]; + visibleZones[visibleWhitespaces[i].id] = visibleWhitespaces[i]; hasVisibleZone = true; } diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index 260f479df55..ee32431b77a 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -69,7 +69,7 @@ interface IDiffEditorWidgetStyle { } class VisualEditorState { - private _zones: number[]; + private _zones: string[]; private _zonesMap: { [zoneId: string]: boolean; }; private _decorations: string[]; diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index 874d7428cf3..0469471f8c4 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -110,21 +110,6 @@ export function createTextBuffer(value: string | model.ITextBufferFactory, defau let MODEL_ID = 0; -/** - * Produces 'a'-'z', followed by 'A'-'Z'... followed by 'a'-'z', etc. - */ -function singleLetter(result: number): string { - const LETTERS_CNT = (CharCode.Z - CharCode.A + 1); - - result = result % (2 * LETTERS_CNT); - - if (result < LETTERS_CNT) { - return String.fromCharCode(CharCode.a + result); - } - - return String.fromCharCode(CharCode.A + result - LETTERS_CNT); -} - const LIMIT_FIND_COUNT = 999; export const LONG_LINE_BOUNDARY = 10000; @@ -343,7 +328,7 @@ export class TextModel extends Disposable implements model.ITextModel { } }); - this._instanceId = singleLetter(MODEL_ID); + this._instanceId = strings.singleLetterHash(MODEL_ID); this._lastDecorationId = 0; this._decorations = Object.create(null); this._decorationsTree = new DecorationsTrees(); diff --git a/src/vs/editor/common/viewLayout/linesLayout.ts b/src/vs/editor/common/viewLayout/linesLayout.ts index 2967fb3b003..d6673ac8b8f 100644 --- a/src/vs/editor/common/viewLayout/linesLayout.ts +++ b/src/vs/editor/common/viewLayout/linesLayout.ts @@ -63,14 +63,14 @@ export class LinesLayout { * @param heightInPx The height of the whitespace, in pixels. * @return An id that can be used later to mutate or delete the whitespace */ - public insertWhitespace(afterLineNumber: number, ordinal: number, heightInPx: number, minWidth: number): number { + public insertWhitespace(afterLineNumber: number, ordinal: number, heightInPx: number, minWidth: number): string { return this._whitespaces.insertWhitespace(afterLineNumber, ordinal, heightInPx, minWidth); } /** * Change properties associated with a certain whitespace. */ - public changeWhitespace(id: number, newAfterLineNumber: number, newHeight: number): boolean { + public changeWhitespace(id: string, newAfterLineNumber: number, newHeight: number): boolean { return this._whitespaces.changeWhitespace(id, newAfterLineNumber, newHeight); } @@ -80,7 +80,7 @@ export class LinesLayout { * @param id The whitespace to remove * @return Returns true if the whitespace is found and it is removed. */ - public removeWhitespace(id: number): boolean { + public removeWhitespace(id: string): boolean { return this._whitespaces.removeWhitespace(id); } diff --git a/src/vs/editor/common/viewLayout/viewLayout.ts b/src/vs/editor/common/viewLayout/viewLayout.ts index f753f65d393..ad24479b4b2 100644 --- a/src/vs/editor/common/viewLayout/viewLayout.ts +++ b/src/vs/editor/common/viewLayout/viewLayout.ts @@ -173,13 +173,13 @@ export class ViewLayout extends Disposable implements IViewLayout { // ---- IVerticalLayoutProvider - public addWhitespace(afterLineNumber: number, ordinal: number, height: number, minWidth: number): number { + public addWhitespace(afterLineNumber: number, ordinal: number, height: number, minWidth: number): string { return this._linesLayout.insertWhitespace(afterLineNumber, ordinal, height, minWidth); } - public changeWhitespace(id: number, newAfterLineNumber: number, newHeight: number): boolean { + public changeWhitespace(id: string, newAfterLineNumber: number, newHeight: number): boolean { return this._linesLayout.changeWhitespace(id, newAfterLineNumber, newHeight); } - public removeWhitespace(id: number): boolean { + public removeWhitespace(id: string): boolean { return this._linesLayout.removeWhitespace(id); } public getVerticalOffsetForLineNumber(lineNumber: number): number { diff --git a/src/vs/editor/common/viewLayout/whitespaceComputer.ts b/src/vs/editor/common/viewLayout/whitespaceComputer.ts index 537c36ac807..8e5dd347e83 100644 --- a/src/vs/editor/common/viewLayout/whitespaceComputer.ts +++ b/src/vs/editor/common/viewLayout/whitespaceComputer.ts @@ -3,8 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import * as strings from 'vs/base/common/strings'; + export interface IEditorWhitespace { - readonly id: number; + readonly id: string; readonly afterLineNumber: number; readonly heightInLines: number; } @@ -15,6 +17,10 @@ export interface IEditorWhitespace { */ export class WhitespaceComputer { + private static INSTANCE_COUNT = 0; + + private readonly _instanceId: string; + /** * heights[i] is the height in pixels for whitespace at index i */ @@ -48,7 +54,7 @@ export class WhitespaceComputer { /** * ids[i] is the whitespace id of whitespace at index i */ - private readonly _ids: number[]; + private readonly _ids: string[]; /** * index at which a whitespace is positioned (inside heights, afterLineNumbers, prefixSum members) @@ -65,6 +71,7 @@ export class WhitespaceComputer { private _minWidth: number; constructor() { + this._instanceId = strings.singleLetterHash(++WhitespaceComputer.INSTANCE_COUNT); this._heights = []; this._minWidths = []; this._ids = []; @@ -113,21 +120,20 @@ export class WhitespaceComputer { * @param heightInPx The height of the whitespace, in pixels. * @return An id that can be used later to mutate or delete the whitespace */ - public insertWhitespace(afterLineNumber: number, ordinal: number, heightInPx: number, minWidth: number): number { + public insertWhitespace(afterLineNumber: number, ordinal: number, heightInPx: number, minWidth: number): string { afterLineNumber = afterLineNumber | 0; ordinal = ordinal | 0; heightInPx = heightInPx | 0; minWidth = minWidth | 0; - let id = (++this._lastWhitespaceId); + let id = this._instanceId + (++this._lastWhitespaceId); let insertionIndex = WhitespaceComputer.findInsertionIndex(this._afterLineNumbers, afterLineNumber, this._ordinals, ordinal); this._insertWhitespaceAtIndex(id, insertionIndex, afterLineNumber, ordinal, heightInPx, minWidth); this._minWidth = -1; /* marker for not being computed */ return id; } - private _insertWhitespaceAtIndex(id: number, insertIndex: number, afterLineNumber: number, ordinal: number, heightInPx: number, minWidth: number): void { - id = id | 0; + private _insertWhitespaceAtIndex(id: string, insertIndex: number, afterLineNumber: number, ordinal: number, heightInPx: number, minWidth: number): void { insertIndex = insertIndex | 0; afterLineNumber = afterLineNumber | 0; ordinal = ordinal | 0; @@ -150,15 +156,14 @@ export class WhitespaceComputer { } } - this._whitespaceId2Index[id.toString()] = insertIndex; + this._whitespaceId2Index[id] = insertIndex; this._prefixSumValidIndex = Math.min(this._prefixSumValidIndex, insertIndex - 1); } /** * Change properties associated with a certain whitespace. */ - public changeWhitespace(id: number, newAfterLineNumber: number, newHeight: number): boolean { - id = id | 0; + public changeWhitespace(id: string, newAfterLineNumber: number, newHeight: number): boolean { newAfterLineNumber = newAfterLineNumber | 0; newHeight = newHeight | 0; @@ -175,13 +180,11 @@ export class WhitespaceComputer { * @param newHeightInPx The new height of the whitespace, in pixels * @return Returns true if the whitespace is found and if the new height is different than the old height */ - public changeWhitespaceHeight(id: number, newHeightInPx: number): boolean { - id = id | 0; + public changeWhitespaceHeight(id: string, newHeightInPx: number): boolean { newHeightInPx = newHeightInPx | 0; - let sid = id.toString(); - if (this._whitespaceId2Index.hasOwnProperty(sid)) { - let index = this._whitespaceId2Index[sid]; + if (this._whitespaceId2Index.hasOwnProperty(id)) { + let index = this._whitespaceId2Index[id]; if (this._heights[index] !== newHeightInPx) { this._heights[index] = newHeightInPx; this._prefixSumValidIndex = Math.min(this._prefixSumValidIndex, index - 1); @@ -198,13 +201,11 @@ export class WhitespaceComputer { * @param newAfterLineNumber The new line number the whitespace will follow * @return Returns true if the whitespace is found and if the new line number is different than the old line number */ - public changeWhitespaceAfterLineNumber(id: number, newAfterLineNumber: number): boolean { - id = id | 0; + public changeWhitespaceAfterLineNumber(id: string, newAfterLineNumber: number): boolean { newAfterLineNumber = newAfterLineNumber | 0; - let sid = id.toString(); - if (this._whitespaceId2Index.hasOwnProperty(sid)) { - let index = this._whitespaceId2Index[sid]; + if (this._whitespaceId2Index.hasOwnProperty(id)) { + let index = this._whitespaceId2Index[id]; if (this._afterLineNumbers[index] !== newAfterLineNumber) { // `afterLineNumber` changed for this whitespace @@ -236,14 +237,10 @@ export class WhitespaceComputer { * @param id The whitespace to remove * @return Returns true if the whitespace is found and it is removed. */ - public removeWhitespace(id: number): boolean { - id = id | 0; - - let sid = id.toString(); - - if (this._whitespaceId2Index.hasOwnProperty(sid)) { - let index = this._whitespaceId2Index[sid]; - delete this._whitespaceId2Index[sid]; + public removeWhitespace(id: string): boolean { + if (this._whitespaceId2Index.hasOwnProperty(id)) { + let index = this._whitespaceId2Index[id]; + delete this._whitespaceId2Index[id]; this._removeWhitespaceAtIndex(index); this._minWidth = -1; /* marker for not being computed */ return true; @@ -459,7 +456,7 @@ export class WhitespaceComputer { * @param index The index of the whitespace. * @return `id` of whitespace at `index`. */ - public getIdForWhitespaceIndex(index: number): number { + public getIdForWhitespaceIndex(index: number): string { index = index | 0; return this._ids[index]; diff --git a/src/vs/editor/common/viewModel/viewModel.ts b/src/vs/editor/common/viewModel/viewModel.ts index fe832ef3707..0f16d0a84a2 100644 --- a/src/vs/editor/common/viewModel/viewModel.ts +++ b/src/vs/editor/common/viewModel/viewModel.ts @@ -17,7 +17,7 @@ import { IEditorWhitespace } from 'vs/editor/common/viewLayout/whitespaceCompute import { ITheme } from 'vs/platform/theme/common/themeService'; export interface IViewWhitespaceViewportData { - readonly id: number; + readonly id: string; readonly afterLineNumber: number; readonly verticalOffset: number; readonly height: number; @@ -74,15 +74,15 @@ export interface IViewLayout { * Reserve rendering space. * @return an identifier that can be later used to remove or change the whitespace. */ - addWhitespace(afterLineNumber: number, ordinal: number, height: number, minWidth: number): number; + addWhitespace(afterLineNumber: number, ordinal: number, height: number, minWidth: number): string; /** * Change the properties of a whitespace. */ - changeWhitespace(id: number, newAfterLineNumber: number, newHeight: number): boolean; + changeWhitespace(id: string, newAfterLineNumber: number, newHeight: number): boolean; /** * Remove rendering space */ - removeWhitespace(id: number): boolean; + removeWhitespace(id: string): boolean; /** * Get the layout information for whitespaces currently in the viewport */ diff --git a/src/vs/editor/contrib/codelens/codelensWidget.ts b/src/vs/editor/contrib/codelens/codelensWidget.ts index cb41dc9f459..5ae20b27edb 100644 --- a/src/vs/editor/contrib/codelens/codelensWidget.ts +++ b/src/vs/editor/contrib/codelens/codelensWidget.ts @@ -193,7 +193,7 @@ export class CodeLensWidget { private readonly _editor: editorBrowser.ICodeEditor; private readonly _viewZone!: CodeLensViewZone; - private readonly _viewZoneId!: number; + private readonly _viewZoneId!: string; private readonly _contentWidget!: CodeLensContentWidget; private _decorationIds: string[]; private _data: CodeLensItem[]; diff --git a/src/vs/editor/contrib/find/findWidget.ts b/src/vs/editor/contrib/find/findWidget.ts index 529d582ee47..a25d3b5b464 100644 --- a/src/vs/editor/contrib/find/findWidget.ts +++ b/src/vs/editor/contrib/find/findWidget.ts @@ -116,7 +116,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas private readonly _replaceFocusTracker: dom.IFocusTracker; private readonly _replaceInputFocused: IContextKey; private _viewZone?: FindWidgetViewZone; - private _viewZoneId?: number; + private _viewZoneId?: string; private _resizeSash!: Sash; private _resized!: boolean; @@ -224,15 +224,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas if (!this._isVisible) { return; } - if (this._viewZoneId === undefined) { - return; - } - this._codeEditor.changeViewZones((accessor) => { - if (this._viewZoneId) { - accessor.removeZone(this._viewZoneId); - } - this._viewZoneId = undefined; - }); + this._viewZoneId = undefined; })); diff --git a/src/vs/editor/contrib/zoneWidget/zoneWidget.ts b/src/vs/editor/contrib/zoneWidget/zoneWidget.ts index 2e7073d55a6..3e0fe0a7d66 100644 --- a/src/vs/editor/contrib/zoneWidget/zoneWidget.ts +++ b/src/vs/editor/contrib/zoneWidget/zoneWidget.ts @@ -51,7 +51,7 @@ const WIDGET_ID = 'vs.editor.contrib.zoneWidget'; export class ViewZoneDelegate implements IViewZone { public domNode: HTMLElement; - public id: number = 0; // A valid zone id should be greater than 0 + public id: string = ''; // A valid zone id should be greater than 0 public afterLineNumber: number; public afterColumn: number; public heightInLines: number; diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index a797b72a6f2..b44b3ae08ad 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -3605,17 +3605,17 @@ declare namespace monaco.editor { * @param zone Zone to create * @return A unique identifier to the view zone. */ - addZone(zone: IViewZone): number; + addZone(zone: IViewZone): string; /** * Remove a zone * @param id A unique identifier to the view zone, as returned by the `addZone` call. */ - removeZone(id: number): void; + removeZone(id: string): void; /** * Change a zone's position. * The editor will rescan the `afterLineNumber` and `afterColumn` properties of a view zone. */ - layoutZone(id: number): void; + layoutZone(id: string): void; } /** diff --git a/src/vs/workbench/api/browser/mainThreadCodeInsets.ts b/src/vs/workbench/api/browser/mainThreadCodeInsets.ts index 1e23e14ce69..2e9ea44a233 100644 --- a/src/vs/workbench/api/browser/mainThreadCodeInsets.ts +++ b/src/vs/workbench/api/browser/mainThreadCodeInsets.ts @@ -21,7 +21,7 @@ class EditorWebviewZone implements IViewZone { readonly afterColumn: number; readonly heightInLines: number; - private _id?: number; + private _id?: string; // suppressMouseDown?: boolean | undefined; // heightInPx?: number | undefined; // minWidthInPx?: number | undefined; diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts b/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts index 7eeb9c15120..66678cbfffb 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts @@ -36,7 +36,7 @@ import { ISettingsGroup } from 'vs/workbench/services/preferences/common/prefere export class SettingsHeaderWidget extends Widget implements IViewZone { - private id: number; + private id: string; private _domNode: HTMLElement; protected titleContainer: HTMLElement; @@ -121,7 +121,7 @@ export class DefaultSettingsHeaderWidget extends SettingsHeaderWidget { export class SettingsGroupTitleWidget extends Widget implements IViewZone { - private id: number; + private id: string; private _afterLineNumber: number; private _domNode: HTMLElement; From a42484093f22c7ddb93c2a48d2df33cb7dc0791e Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 14 Aug 2019 18:02:24 +0200 Subject: [PATCH 601/861] add `extensionHostWorker` entry point, fixes https://github.com/microsoft/vscode-internalbacklog/issues/738 --- build/gulpfile.vscode.web.js | 3 ++- src/buildfile.js | 10 +++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/build/gulpfile.vscode.web.js b/build/gulpfile.vscode.web.js index 11da75e482d..81e08f8e0a6 100644 --- a/build/gulpfile.vscode.web.js +++ b/build/gulpfile.vscode.web.js @@ -53,6 +53,7 @@ const buildfile = require('../src/buildfile'); const vscodeWebEntryPoints = [ buildfile.workbenchWeb, buildfile.serviceWorker, + buildfile.workerExtensionHost, buildfile.keyboardMaps, buildfile.base ]; @@ -148,4 +149,4 @@ const dashed = (str) => (str ? `-${str}` : ``); vscodeWebTaskCI )); gulp.task(vscodeWebTask); -}); \ No newline at end of file +}); diff --git a/src/buildfile.js b/src/buildfile.js index f9946efc703..43fcfa807c3 100644 --- a/src/buildfile.js +++ b/src/buildfile.js @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -function entrypoint (name) { +function entrypoint(name) { return [{ name: name, include: [], exclude: ['vs/css', 'vs/nls'] }]; } @@ -23,6 +23,14 @@ exports.serviceWorker = [{ dest: 'vs/workbench/contrib/resources/browser/resourceServiceWorkerMain.js' }]; +exports.workerExtensionHost = [{ + name: 'vs/workbench/services/extensions/worker/extensionHostWorker', + // include: [], + prepend: ['vs/loader.js'], + append: ['vs/workbench/services/extensions/worker/extensionHostWorkerMain'], + dest: 'vs/workbench/services/extensions/worker/extensionHostWorkerMain.js' +}]; + exports.workbench = require('./vs/workbench/buildfile').collectModules(['vs/workbench/workbench.desktop.main']); exports.workbenchWeb = entrypoint('vs/workbench/workbench.web.api'); From e677c03899d62a5814637548b904c5ac75de4a6c Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Wed, 14 Aug 2019 16:25:31 +0200 Subject: [PATCH 602/861] Update uglify-es (#79044) --- package.json | 4 ++-- yarn.lock | 25 ++++++++++--------------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index cf5ff6a7afb..eaa647b8917 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "gulp-shell": "^0.6.5", "gulp-tsb": "2.0.7", "gulp-tslint": "^8.1.3", - "gulp-uglify": "^3.0.0", + "gulp-uglify": "^3.0.2", "gulp-untar": "^0.0.7", "gulp-vinyl-zip": "^2.1.2", "http-server": "^0.11.1", @@ -133,7 +133,7 @@ "tslint": "^5.16.0", "typescript": "3.5.2", "typescript-formatter": "7.1.0", - "uglify-es": "^3.0.18", + "uglify-es": "^3.3.9", "underscore": "^1.8.2", "vinyl": "^2.0.0", "vinyl-fs": "^3.0.0", diff --git a/yarn.lock b/yarn.lock index 0a6b395f80d..8fabb92cfc0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4047,15 +4047,18 @@ gulp-tslint@^8.1.3: plugin-error "1.0.1" through "~2.3.8" -gulp-uglify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/gulp-uglify/-/gulp-uglify-3.0.0.tgz#0df0331d72a0d302e3e37e109485dddf33c6d1ca" - integrity sha1-DfAzHXKg0wLj434QlIXd3zPG0co= +gulp-uglify@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/gulp-uglify/-/gulp-uglify-3.0.2.tgz#5f5b2e8337f879ca9dec971feb1b82a5a87850b0" + integrity sha512-gk1dhB74AkV2kzqPMQBLA3jPoIAPd/nlNzP2XMDSG8XZrqnlCiDGAqC+rZOumzFvB5zOphlFh6yr3lgcAb/OOg== dependencies: + array-each "^1.0.1" + extend-shallow "^3.0.2" gulplog "^1.0.0" has-gulplog "^0.1.0" - lodash "^4.13.1" + isobject "^3.0.1" make-error-cause "^1.1.1" + safe-buffer "^5.1.2" through2 "^2.0.0" uglify-js "^3.0.5" vinyl-sourcemaps-apply "^0.2.0" @@ -5455,7 +5458,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@^4.13.1, lodash@^4.15.0, lodash@^4.3.0: +lodash@^4.15.0, lodash@^4.3.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" integrity sha1-eCA6TRwyiuHYbcpkYONptX9AVa4= @@ -9133,15 +9136,7 @@ uc.micro@^1.0.1, uc.micro@^1.0.3: resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.3.tgz#7ed50d5e0f9a9fb0a573379259f2a77458d50192" integrity sha1-ftUNXg+an7ClczeSWfKndFjVAZI= -uglify-es@^3.0.18: - version "3.1.9" - resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.1.9.tgz#6c82df628ac9eb7af9c61fd70c744a084abe6161" - integrity sha512-wVSiJKHDgDDFmxTVVvnbAH6IpamAFHYDI+5JvwPdaqIMnk8kRTX2JKwq1Fx7gb2+Jj5Dus8kzvIpKkWOMNU51w== - dependencies: - commander "~2.11.0" - source-map "~0.6.1" - -uglify-es@^3.3.4: +uglify-es@^3.3.4, uglify-es@^3.3.9: version "3.3.9" resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" integrity sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ== From 38cdba85df5dd29eb07a218f57bd7e609ee4d2cf Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Wed, 14 Aug 2019 16:26:21 +0200 Subject: [PATCH 603/861] Revert "Work around minifier bug (#79044)" This reverts commit 6371cad57381ead9cb744393501ae749f1a8ac40. --- .../services/extensions/node/proxyResolver.ts | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/services/extensions/node/proxyResolver.ts b/src/vs/workbench/services/extensions/node/proxyResolver.ts index 12a6e3ea66a..64c2e0a526e 100644 --- a/src/vs/workbench/services/extensions/node/proxyResolver.ts +++ b/src/vs/workbench/services/extensions/node/proxyResolver.ts @@ -469,26 +469,24 @@ async function readCaCertificates() { } async function readWindowsCaCertificates() { - // Not using await to work around minifier bug (https://github.com/microsoft/vscode/issues/79044). - return import('vscode-windows-ca-certs') - .then(winCA => { - let ders: any[] = []; - const store = winCA(); - try { - let der: any; - while (der = store.next()) { - ders.push(der); - } - } finally { - store.done(); - } + const winCA = await import('vscode-windows-ca-certs'); - const certs = new Set(ders.map(derToPem)); - return { - certs: Array.from(certs), - append: true - }; - }); + let ders: any[] = []; + const store = winCA(); + try { + let der: any; + while (der = store.next()) { + ders.push(der); + } + } finally { + store.done(); + } + + const certs = new Set(ders.map(derToPem)); + return { + certs: Array.from(certs), + append: true + }; } async function readMacCaCertificates() { From e0a685e5854fb9b77e439611cef0af327eac6936 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 14 Aug 2019 18:21:47 +0200 Subject: [PATCH 604/861] expose product configuration in product service --- .../common/extensionGalleryService.ts | 16 ++++---- .../product/browser/productService.ts | 39 ++++--------------- src/vs/platform/product/common/product.ts | 33 +--------------- .../platform/product/node/productService.ts | 33 ++++------------ .../api/browser/mainThreadWebview.ts | 2 +- .../workbench/browser/web.simpleservices.ts | 8 ++-- .../contrib/debug/browser/debugSession.ts | 2 +- .../experiments/common/experimentService.ts | 4 +- .../extensions/browser/extensionsActions.ts | 4 +- .../browser/extensionsWorkbenchService.ts | 8 ++-- .../contrib/feedback/browser/feedback.ts | 4 +- .../feedback/browser/feedbackStatusbarItem.ts | 2 +- .../preferences/browser/preferencesSearch.ts | 6 +-- .../browser/terminalProcessManager.ts | 2 +- .../browser/webWorkerExtensionHostStarter.ts | 8 ++-- .../common/abstractExtensionService.ts | 6 +-- .../extensions/common/extensionsUtil.ts | 2 +- .../common/remoteExtensionHostClient.ts | 10 ++--- .../remoteExtensionManagementIpc.ts | 4 +- .../remote/browser/remoteAgentServiceImpl.ts | 2 +- .../telemetry/browser/telemetryService.ts | 6 +-- .../electron-browser/telemetryService.ts | 6 +-- 22 files changed, 67 insertions(+), 140 deletions(-) diff --git a/src/vs/platform/extensionManagement/common/extensionGalleryService.ts b/src/vs/platform/extensionManagement/common/extensionGalleryService.ts index e291d436115..42fbff47fe2 100644 --- a/src/vs/platform/extensionManagement/common/extensionGalleryService.ts +++ b/src/vs/platform/extensionManagement/common/extensionGalleryService.ts @@ -342,10 +342,10 @@ export class ExtensionGalleryService implements IExtensionGalleryService { @IProductService private readonly productService: IProductService, @optional(IStorageService) private readonly storageService: IStorageService, ) { - const config = productService.extensionsGallery; + const config = productService.productConfiguration.extensionsGallery; this.extensionsGalleryUrl = config && config.serviceUrl; this.extensionsControlUrl = config && config.controlUrl; - this.commonHeadersPromise = resolveMarketplaceHeaders(productService.version, this.environmentService, this.fileService, this.storageService); + this.commonHeadersPromise = resolveMarketplaceHeaders(productService.productConfiguration.version, this.environmentService, this.fileService, this.storageService); } private api(path = ''): string { @@ -358,7 +358,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { getCompatibleExtension(arg1: IExtensionIdentifier | IGalleryExtension, version?: string): Promise { const extension: IGalleryExtension | null = isIExtensionIdentifier(arg1) ? null : arg1; - if (extension && extension.properties.engine && isEngineValid(extension.properties.engine, this.productService.version)) { + if (extension && extension.properties.engine && isEngineValid(extension.properties.engine, this.productService.productConfiguration.version)) { return Promise.resolve(extension); } const { id, uuid } = extension ? extension.identifier : arg1; @@ -384,7 +384,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { const versionAsset = rawExtension.versions.filter(v => v.version === version)[0]; if (versionAsset) { const extension = toExtension(rawExtension, versionAsset, 0, query); - if (extension.properties.engine && isEngineValid(extension.properties.engine, this.productService.version)) { + if (extension.properties.engine && isEngineValid(extension.properties.engine, this.productService.productConfiguration.version)) { return extension; } } @@ -619,7 +619,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { return this.queryGallery(query, CancellationToken.None).then(({ galleryExtensions }) => { if (galleryExtensions.length) { if (compatible) { - return Promise.all(galleryExtensions[0].versions.map(v => this.getEngine(v).then(engine => isEngineValid(engine, this.productService.version) ? v : null))) + return Promise.all(galleryExtensions[0].versions.map(v => this.getEngine(v).then(engine => isEngineValid(engine, this.productService.productConfiguration.version) ? v : null))) .then(versions => versions .filter(v => !!v) .map(v => ({ version: v!.version, date: v!.lastUpdated }))); @@ -705,7 +705,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { if (!engine) { return null; } - if (isEngineValid(engine, this.productService.version)) { + if (isEngineValid(engine, this.productService.productConfiguration.version)) { return Promise.resolve(version); } } @@ -737,7 +737,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { const version = versions[0]; return this.getEngine(version) .then(engine => { - if (!isEngineValid(engine, this.productService.version)) { + if (!isEngineValid(engine, this.productService.productConfiguration.version)) { return this.getLastValidExtensionVersionRecursively(extension, versions.slice(1)); } @@ -817,4 +817,4 @@ export async function resolveMarketplaceHeaders(version: string, environmentServ return headers; -} \ No newline at end of file +} diff --git a/src/vs/platform/product/browser/productService.ts b/src/vs/platform/product/browser/productService.ts index 70bc0b31bcc..fae6e1d5fa7 100644 --- a/src/vs/platform/product/browser/productService.ts +++ b/src/vs/platform/product/browser/productService.ts @@ -10,40 +10,17 @@ export class ProductService implements IProductService { _serviceBrand!: ServiceIdentifier; - private readonly productConfiguration: IProductConfiguration | null; + readonly productConfiguration: IProductConfiguration; constructor() { const element = document.getElementById('vscode-remote-product-configuration'); - this.productConfiguration = element ? JSON.parse(element.getAttribute('data-settings')!) : null; + this.productConfiguration = { + ...element ? JSON.parse(element.getAttribute('data-settings')!) : { + version: '1.38.0-unknown', + nameLong: 'Unknown', + extensionAllowedProposedApi: [], + }, ...{ urlProtocol: '', enableTelemetry: false } + }; } - get version(): string { return this.productConfiguration && this.productConfiguration.version ? this.productConfiguration.version : '1.38.0-unknown'; } - - get commit(): string | undefined { return this.productConfiguration ? this.productConfiguration.commit : undefined; } - - get nameLong(): string { return this.productConfiguration ? this.productConfiguration.nameLong : 'Unknown'; } - - get urlProtocol(): string { return ''; } - - get extensionAllowedProposedApi(): readonly string[] { return this.productConfiguration ? this.productConfiguration.extensionAllowedProposedApi : []; } - - get uiExtensions(): readonly string[] | undefined { return this.productConfiguration ? this.productConfiguration.uiExtensions : undefined; } - - get enableTelemetry(): boolean { return false; } - - get sendASmile(): { reportIssueUrl: string, requestFeatureUrl: string } | undefined { return this.productConfiguration ? this.productConfiguration.sendASmile : undefined; } - - get extensionsGallery() { return this.productConfiguration ? this.productConfiguration.extensionsGallery : undefined; } - - get settingsSearchBuildId(): number | undefined { return this.productConfiguration ? this.productConfiguration.settingsSearchBuildId : undefined; } - - get settingsSearchUrl(): string | undefined { return this.productConfiguration ? this.productConfiguration.settingsSearchUrl : undefined; } - - get experimentsUrl(): string | undefined { return this.productConfiguration ? this.productConfiguration.experimentsUrl : undefined; } - - get extensionKeywords(): { [extension: string]: readonly string[]; } | undefined { return this.productConfiguration ? this.productConfiguration.extensionKeywords : undefined; } - - get extensionAllowedBadgeProviders(): readonly string[] | undefined { return this.productConfiguration ? this.productConfiguration.extensionAllowedBadgeProviders : undefined; } - - get aiConfig() { return this.productConfiguration ? this.productConfiguration.aiConfig : undefined; } } diff --git a/src/vs/platform/product/common/product.ts b/src/vs/platform/product/common/product.ts index 05048ee0908..11b6fed267a 100644 --- a/src/vs/platform/product/common/product.ts +++ b/src/vs/platform/product/common/product.ts @@ -11,38 +11,7 @@ export interface IProductService { _serviceBrand: ServiceIdentifier; - readonly version: string; - readonly commit?: string; - readonly date?: string; - - readonly nameLong: string; - readonly urlProtocol: string; - readonly extensionAllowedProposedApi: readonly string[]; - readonly uiExtensions?: readonly string[]; - - readonly enableTelemetry: boolean; - readonly extensionsGallery?: { - readonly serviceUrl: string; - readonly itemUrl: string; - readonly controlUrl: string; - readonly recommendationsUrl: string; - }; - - readonly sendASmile?: { - readonly reportIssueUrl: string; - readonly requestFeatureUrl: string; - }; - - readonly settingsSearchBuildId?: number; - readonly settingsSearchUrl?: string; - - readonly experimentsUrl?: string; - readonly extensionKeywords?: { [extension: string]: readonly string[]; }; - readonly extensionAllowedBadgeProviders?: readonly string[]; - - readonly aiConfig?: { - readonly asimovKey: string; - }; + readonly productConfiguration: IProductConfiguration; } export interface IProductConfiguration { diff --git a/src/vs/platform/product/node/productService.ts b/src/vs/platform/product/node/productService.ts index ba9c84a551d..f3986577355 100644 --- a/src/vs/platform/product/node/productService.ts +++ b/src/vs/platform/product/node/productService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IProductService } from 'vs/platform/product/common/product'; +import { IProductService, IProductConfiguration } from 'vs/platform/product/common/product'; import product from 'vs/platform/product/node/product'; import pkg from 'vs/platform/product/node/package'; import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; @@ -12,31 +12,12 @@ export class ProductService implements IProductService { _serviceBrand!: ServiceIdentifier; - get version(): string { return pkg.version; } + readonly productConfiguration: IProductConfiguration; - get commit(): string | undefined { return product.commit; } + constructor() { + this.productConfiguration = { + ...product, ...{ version: pkg.version } + }; + } - get nameLong(): string { return product.nameLong; } - - get urlProtocol(): string { return product.urlProtocol; } - - get extensionAllowedProposedApi(): readonly string[] { return product.extensionAllowedProposedApi; } - - get uiExtensions(): readonly string[] | undefined { return product.uiExtensions; } - - get enableTelemetry(): boolean { return product.enableTelemetry; } - - get sendASmile(): { reportIssueUrl: string, requestFeatureUrl: string } { return product.sendASmile; } - - get extensionsGallery() { return product.extensionsGallery; } - - get settingsSearchBuildId(): number | undefined { return product.settingsSearchBuildId; } - - get settingsSearchUrl(): string | undefined { return product.settingsSearchUrl; } - - get experimentsUrl(): string | undefined { return product.experimentsUrl; } - - get extensionKeywords(): { [extension: string]: readonly string[]; } | undefined { return product.extensionKeywords; } - - get extensionAllowedBadgeProviders(): readonly string[] | undefined { return product.extensionAllowedBadgeProviders; } } diff --git a/src/vs/workbench/api/browser/mainThreadWebview.ts b/src/vs/workbench/api/browser/mainThreadWebview.ts index 90bdeb5ea74..f2c3141d063 100644 --- a/src/vs/workbench/api/browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/browser/mainThreadWebview.ts @@ -327,7 +327,7 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews if (MainThreadWebviews.standardSupportedLinkSchemes.has(link.scheme)) { return true; } - if (this._productService.urlProtocol === link.scheme) { + if (this._productService.productConfiguration.urlProtocol === link.scheme) { return true; } return !!webview.webview.contentOptions.enableCommandUris && link.scheme === 'command'; diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 46a3f6a59aa..33737a02966 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -741,13 +741,13 @@ export class SimpleWindowsService implements IWindowsService { async openAboutDialog(): Promise { const detail = localize('aboutDetail', "Version: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}", - this.productService.version || 'Unknown', - this.productService.commit || 'Unknown', - this.productService.date || 'Unknown', + this.productService.productConfiguration.version || 'Unknown', + this.productService.productConfiguration.commit || 'Unknown', + this.productService.productConfiguration.date || 'Unknown', navigator.userAgent ); - const result = await this.dialogService.show(Severity.Info, this.productService.nameLong, [localize('copy', "Copy"), localize('ok', "OK")], { detail }); + const result = await this.dialogService.show(Severity.Info, this.productService.productConfiguration.nameLong, [localize('copy', "Copy"), localize('ok', "OK")], { detail }); if (result === 0) { this.clipboardService.writeText(detail); diff --git a/src/vs/workbench/contrib/debug/browser/debugSession.ts b/src/vs/workbench/contrib/debug/browser/debugSession.ts index d4548944019..6fdc99451a6 100644 --- a/src/vs/workbench/contrib/debug/browser/debugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/debugSession.ts @@ -175,7 +175,7 @@ export class DebugSession implements IDebugSession { return this.raw!.initialize({ clientID: 'vscode', - clientName: this.productService.nameLong, + clientName: this.productService.productConfiguration.nameLong, adapterID: this.configuration.type, pathFormat: 'path', linesStartAt1: true, diff --git a/src/vs/workbench/contrib/experiments/common/experimentService.ts b/src/vs/workbench/contrib/experiments/common/experimentService.ts index 5707377ce4b..bef55ac4b26 100644 --- a/src/vs/workbench/contrib/experiments/common/experimentService.ts +++ b/src/vs/workbench/contrib/experiments/common/experimentService.ts @@ -170,10 +170,10 @@ export class ExperimentService extends Disposable implements IExperimentService } protected getExperiments(): Promise { - if (!this.productService.experimentsUrl || this.configurationService.getValue('workbench.enableExperiments') === false) { + if (!this.productService.productConfiguration.experimentsUrl || this.configurationService.getValue('workbench.enableExperiments') === false) { return Promise.resolve([]); } - return this.requestService.request({ type: 'GET', url: this.productService.experimentsUrl }, CancellationToken.None).then(context => { + return this.requestService.request({ type: 'GET', url: this.productService.productConfiguration.experimentsUrl }, CancellationToken.None).then(context => { if (context.res.statusCode !== 200) { return Promise.resolve(null); } diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index ec19e774ab1..05bef903d9e 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -76,10 +76,10 @@ export function toExtensionDescription(local: ILocalExtension): IExtensionDescri const promptDownloadManually = (extension: IGalleryExtension | undefined, message: string, error: Error, instantiationService: IInstantiationService, notificationService: INotificationService, openerService: IOpenerService, productService: IProductService) => { - if (!extension || error.name === INSTALL_ERROR_INCOMPATIBLE || error.name === INSTALL_ERROR_MALICIOUS || !productService.extensionsGallery) { + if (!extension || error.name === INSTALL_ERROR_INCOMPATIBLE || error.name === INSTALL_ERROR_MALICIOUS || !productService.productConfiguration.extensionsGallery) { return Promise.reject(error); } else { - const downloadUrl = `${productService.extensionsGallery.serviceUrl}/publishers/${extension.publisher}/vsextensions/${extension.name}/${extension.version}/vspackage`; + const downloadUrl = `${productService.productConfiguration.extensionsGallery.serviceUrl}/publishers/${extension.publisher}/vsextensions/${extension.name}/${extension.version}/vspackage`; notificationService.prompt(Severity.Error, message, [{ label: localize('download', "Download Manually"), run: () => openerService.open(URI.parse(downloadUrl)).then(() => { diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index b64689e02c6..99ec538b442 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -114,11 +114,11 @@ class Extension implements IExtension { } get url(): string | undefined { - if (!this.productService.extensionsGallery || !this.gallery) { + if (!this.productService.productConfiguration.extensionsGallery || !this.gallery) { return undefined; } - return `${this.productService.extensionsGallery.itemUrl}?itemName=${this.publisher}.${this.name}`; + return `${this.productService.productConfiguration.extensionsGallery.itemUrl}?itemName=${this.publisher}.${this.name}`; } get iconUrl(): string { @@ -615,7 +615,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension text = text.replace(extensionRegex, (m, ext) => { // Get curated keywords - const lookup = this.productService.extensionKeywords || {}; + const lookup = this.productService.productConfiguration.extensionKeywords || {}; const keywords = lookup[ext] || []; // Get mode name @@ -1022,7 +1022,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension get allowedBadgeProviders(): string[] { if (!this._extensionAllowedBadgeProviders) { - this._extensionAllowedBadgeProviders = (this.productService.extensionAllowedBadgeProviders || []).map(s => s.toLowerCase()); + this._extensionAllowedBadgeProviders = (this.productService.productConfiguration.extensionAllowedBadgeProviders || []).map(s => s.toLowerCase()); } return this._extensionAllowedBadgeProviders; } diff --git a/src/vs/workbench/contrib/feedback/browser/feedback.ts b/src/vs/workbench/contrib/feedback/browser/feedback.ts index 618dc7edaa9..130c7fd3a04 100644 --- a/src/vs/workbench/contrib/feedback/browser/feedback.ts +++ b/src/vs/workbench/contrib/feedback/browser/feedback.ts @@ -73,8 +73,8 @@ export class FeedbackDropdown extends Dropdown { this.feedbackDelegate = options.feedbackService; this.maxFeedbackCharacters = this.feedbackDelegate.getCharacterLimit(this.sentiment); - if (productService.sendASmile) { - this.requestFeatureLink = productService.sendASmile.requestFeatureUrl; + if (productService.productConfiguration.sendASmile) { + this.requestFeatureLink = productService.productConfiguration.sendASmile.requestFeatureUrl; } this.integrityService.isPure().then(result => { diff --git a/src/vs/workbench/contrib/feedback/browser/feedbackStatusbarItem.ts b/src/vs/workbench/contrib/feedback/browser/feedbackStatusbarItem.ts index c609aa4132f..458dc93b0b6 100644 --- a/src/vs/workbench/contrib/feedback/browser/feedbackStatusbarItem.ts +++ b/src/vs/workbench/contrib/feedback/browser/feedbackStatusbarItem.ts @@ -58,7 +58,7 @@ export class FeedbackStatusbarConribution extends Disposable implements IWorkben ) { super(); - if (productService.sendASmile) { + if (productService.productConfiguration.sendASmile) { this.entry = this._register(statusbarService.addEntry(this.getStatusEntry(), 'status.feedback', localize('status.feedback', "Tweet Feedback"), StatusbarAlignment.RIGHT, -100 /* towards the end of the right hand side */)); CommandsRegistry.registerCommand('_feedback.open', () => this.toggleFeedback()); diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts b/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts index 2887abfc0f3..ef36014032d 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts @@ -73,7 +73,7 @@ export class PreferencesSearchService extends Disposable implements IPreferences }; } else { return { - urlBase: this.productService.settingsSearchUrl + urlBase: this.productService.productConfiguration.settingsSearchUrl }; } } @@ -364,7 +364,7 @@ class RemoteSearchProvider implements ISearchProvider { const extensions = await this.installedExtensions; const filters = this.options.newExtensionsOnly ? [`diminish eq 'latest'`] : - this.getVersionFilters(extensions, this.productService.settingsSearchBuildId); + this.getVersionFilters(extensions, this.productService.productConfiguration.settingsSearchBuildId); const filterStr = filters .slice(filterPage * RemoteSearchProvider.MAX_REQUEST_FILTERS, (filterPage + 1) * RemoteSearchProvider.MAX_REQUEST_FILTERS) @@ -563,4 +563,4 @@ export class SettingMatches { endColumn: setting.valueRange.startColumn + match.end + 1 }; } -} \ No newline at end of file +} diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index b3ff7db5e88..b1ecf1026f3 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -226,7 +226,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce const isWorkspaceShellAllowed = this._configHelper.checkWorkspaceShellPermissions(); this._configHelper.showRecommendations(shellLaunchConfig); const baseEnv = this._configHelper.config.inheritEnv ? process.env as platform.IProcessEnvironment : await this._terminalInstanceService.getMainProcessParentEnv(); - const env = terminalEnvironment.createTerminalEnvironment(shellLaunchConfig, lastActiveWorkspace, envFromConfigValue, this._configurationResolverService, isWorkspaceShellAllowed, this._productService.version, this._configHelper.config.setLocaleVariables, baseEnv); + const env = terminalEnvironment.createTerminalEnvironment(shellLaunchConfig, lastActiveWorkspace, envFromConfigValue, this._configurationResolverService, isWorkspaceShellAllowed, this._productService.productConfiguration.version, this._configHelper.config.setLocaleVariables, baseEnv); const useConpty = this._configHelper.config.windowsEnableConpty && !isScreenReaderModeEnabled; return this._terminalInstanceService.createTerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, useConpty); diff --git a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts index 5794b259061..7848fdee127 100644 --- a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts +++ b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts @@ -117,15 +117,15 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { const [telemetryInfo, extensionDescriptions] = await Promise.all([this._telemetryService.getTelemetryInfo(), this._extensions]); const workspace = this._contextService.getWorkspace(); return { - commit: this._productService.commit, - version: this._productService.version, + commit: this._productService.productConfiguration.commit, + version: this._productService.productConfiguration.version, parentPid: -1, environment: { isExtensionDevelopmentDebug: false, appRoot: this._environmentService.appRoot ? URI.file(this._environmentService.appRoot) : undefined, appSettingsHome: this._environmentService.appSettingsHome ? this._environmentService.appSettingsHome : undefined, - appName: this._productService.nameLong, - appUriScheme: this._productService.urlProtocol, + appName: this._productService.productConfiguration.nameLong, + appUriScheme: this._productService.productConfiguration.urlProtocol, appLanguage: platform.language, extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI, extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI, diff --git a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts index 6445a03a6e6..51f991375a6 100644 --- a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts +++ b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts @@ -462,12 +462,12 @@ class ProposedApiController { } this.enableProposedApiForAll = !environmentService.isBuilt || - (!!environmentService.extensionDevelopmentLocationURI && productService.nameLong !== 'Visual Studio Code') || + (!!environmentService.extensionDevelopmentLocationURI && productService.productConfiguration.nameLong !== 'Visual Studio Code') || (this.enableProposedApiFor.length === 0 && 'enable-proposed-api' in environmentService.args); this.productAllowProposedApi = new Set(); - if (isNonEmptyArray(productService.extensionAllowedProposedApi)) { - productService.extensionAllowedProposedApi.forEach((id) => this.productAllowProposedApi.add(ExtensionIdentifier.toKey(id))); + if (isNonEmptyArray(productService.productConfiguration.extensionAllowedProposedApi)) { + productService.productConfiguration.extensionAllowedProposedApi.forEach((id) => this.productAllowProposedApi.add(ExtensionIdentifier.toKey(id))); } } diff --git a/src/vs/workbench/services/extensions/common/extensionsUtil.ts b/src/vs/workbench/services/extensions/common/extensionsUtil.ts index a1496708db6..2f7d4e01039 100644 --- a/src/vs/workbench/services/extensions/common/extensionsUtil.ts +++ b/src/vs/workbench/services/extensions/common/extensionsUtil.ts @@ -24,7 +24,7 @@ export function isUIExtension(manifest: IExtensionManifest, productService: IPro case 'workspace': return false; default: { // Tagged as UI extension in product - if (isNonEmptyArray(productService.uiExtensions) && productService.uiExtensions.some(id => areSameExtensions({ id }, { id: extensionId }))) { + if (isNonEmptyArray(productService.productConfiguration.uiExtensions) && productService.productConfiguration.uiExtensions.some(id => areSameExtensions({ id }, { id: extensionId }))) { return true; } // Not an UI extension if it has main diff --git a/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts b/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts index 47aaf4a22bb..ca657398990 100644 --- a/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts +++ b/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts @@ -71,7 +71,7 @@ export class RemoteExtensionHostClient extends Disposable implements IExtensionH public start(): Promise { const options: IConnectionOptions = { - commit: this._productService.commit, + commit: this._productService.productConfiguration.commit, socketFactory: this._socketFactory, addressProvider: { getAddress: async () => { @@ -181,15 +181,15 @@ export class RemoteExtensionHostClient extends Disposable implements IExtensionH const hostExtensions = allExtensions.filter(extension => extension.main && extension.api === 'none').map(extension => extension.identifier); const workspace = this._contextService.getWorkspace(); const r: IInitData = { - commit: this._productService.commit, - version: this._productService.version, + commit: this._productService.productConfiguration.commit, + version: this._productService.productConfiguration.version, parentPid: remoteExtensionHostData.pid, environment: { isExtensionDevelopmentDebug, appRoot: remoteExtensionHostData.appRoot, appSettingsHome: remoteExtensionHostData.appSettingsHome, - appName: this._productService.nameLong, - appUriScheme: this._productService.urlProtocol, + appName: this._productService.productConfiguration.nameLong, + appUriScheme: this._productService.productConfiguration.urlProtocol, appLanguage: platform.language, extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI, extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI, diff --git a/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts b/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts index 84ec145c4c8..75787071f85 100644 --- a/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts +++ b/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts @@ -69,7 +69,7 @@ export class RemoteExtensionManagementChannelClient extends ExtensionManagementC const installed = await this.getInstalled(ExtensionType.User); const compatible = await this.galleryService.getCompatibleExtension(extension); if (!compatible) { - return Promise.reject(new Error(localize('incompatible', "Unable to install extension '{0}' as it is not compatible with VS Code '{1}'.", extension.identifier.id, this.productService.version))); + return Promise.reject(new Error(localize('incompatible', "Unable to install extension '{0}' as it is not compatible with VS Code '{1}'.", extension.identifier.id, this.productService.productConfiguration.version))); } const manifest = await this.galleryService.getManifest(compatible, CancellationToken.None); if (manifest) { @@ -140,4 +140,4 @@ export class RemoteExtensionManagementChannelClient extends ExtensionManagementC } return this.getDependenciesAndPackedExtensionsRecursively(toGet, result, uiExtension, token); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/services/remote/browser/remoteAgentServiceImpl.ts b/src/vs/workbench/services/remote/browser/remoteAgentServiceImpl.ts index fd979ca094c..db4d2038ca3 100644 --- a/src/vs/workbench/services/remote/browser/remoteAgentServiceImpl.ts +++ b/src/vs/workbench/services/remote/browser/remoteAgentServiceImpl.ts @@ -28,7 +28,7 @@ export class RemoteAgentService extends AbstractRemoteAgentService implements IR super(environmentService); this.socketFactory = new BrowserSocketFactory(webSocketFactory); - this._connection = this._register(new RemoteAgentConnection(environmentService.configuration.remoteAuthority!, productService.commit, this.socketFactory, remoteAuthorityResolverService, signService)); + this._connection = this._register(new RemoteAgentConnection(environmentService.configuration.remoteAuthority!, productService.productConfiguration.commit, this.socketFactory, remoteAuthorityResolverService, signService)); } getConnection(): IRemoteAgentConnection | null { diff --git a/src/vs/workbench/services/telemetry/browser/telemetryService.ts b/src/vs/workbench/services/telemetry/browser/telemetryService.ts index eac9dcfb1d0..2632d935d80 100644 --- a/src/vs/workbench/services/telemetry/browser/telemetryService.ts +++ b/src/vs/workbench/services/telemetry/browser/telemetryService.ts @@ -79,11 +79,11 @@ export class TelemetryService extends Disposable implements ITelemetryService { ) { super(); - const aiKey = productService.aiConfig && productService.aiConfig.asimovKey; - if (!environmentService.isExtensionDevelopment && !environmentService.args['disable-telemetry'] && !!productService.enableTelemetry && !!aiKey) { + const aiKey = productService.productConfiguration.aiConfig && productService.productConfiguration.aiConfig.asimovKey; + if (!environmentService.isExtensionDevelopment && !environmentService.args['disable-telemetry'] && !!productService.productConfiguration.enableTelemetry && !!aiKey) { const config: ITelemetryServiceConfig = { appender: combinedAppender(new WebTelemetryAppender(aiKey, logService), new LogAppender(logService)), - commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.configuration.machineId, environmentService.configuration.remoteAuthority), + commonProperties: resolveWorkbenchCommonProperties(storageService, productService.productConfiguration.commit, productService.productConfiguration.version, environmentService.configuration.machineId, environmentService.configuration.remoteAuthority), piiPaths: [environmentService.appRoot] }; diff --git a/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts b/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts index 6eaaf220ce5..002b6ae4ce3 100644 --- a/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts +++ b/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts @@ -34,11 +34,11 @@ export class TelemetryService extends Disposable implements ITelemetryService { ) { super(); - if (!environmentService.isExtensionDevelopment && !environmentService.args['disable-telemetry'] && !!productService.enableTelemetry) { + if (!environmentService.isExtensionDevelopment && !environmentService.args['disable-telemetry'] && !!productService.productConfiguration.enableTelemetry) { const channel = sharedProcessService.getChannel('telemetryAppender'); const config: ITelemetryServiceConfig = { appender: combinedAppender(new TelemetryAppenderClient(channel), new LogAppender(logService)), - commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.configuration.machineId, environmentService.installSourcePath, environmentService.configuration.remoteAuthority), + commonProperties: resolveWorkbenchCommonProperties(storageService, productService.productConfiguration.commit, productService.productConfiguration.version, environmentService.configuration.machineId, environmentService.installSourcePath, environmentService.configuration.remoteAuthority), piiPaths: environmentService.extensionsPath ? [environmentService.appRoot, environmentService.extensionsPath] : [environmentService.appRoot] }; @@ -69,4 +69,4 @@ export class TelemetryService extends Disposable implements ITelemetryService { } } -registerSingleton(ITelemetryService, TelemetryService); \ No newline at end of file +registerSingleton(ITelemetryService, TelemetryService); From 2180dd6973bfb5892b6e4723bb65f00169b214b3 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 14 Aug 2019 18:27:09 +0200 Subject: [PATCH 605/861] use product service --- .../electron-browser/extensionTipsService.ts | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts index 33e5fbc2bfe..5610f403056 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts @@ -14,7 +14,6 @@ import { IExtensionTipsService, ExtensionRecommendationReason, IExtensionsConfig import { IModelService } from 'vs/editor/common/services/modelService'; import { ITextModel } from 'vs/editor/common/model'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; -import product from 'vs/platform/product/node/product'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ShowRecommendedExtensionsAction, InstallWorkspaceRecommendedExtensionsAction, InstallRecommendedExtensionAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import Severity from 'vs/base/common/severity'; @@ -23,7 +22,6 @@ import { IFileService } from 'vs/platform/files/common/files'; import { IExtensionsConfiguration, ConfigurationKey, ShowRecommendationsOnlyOnDemandKey, IExtensionsViewlet, IExtensionsWorkbenchService, EXTENSIONS_CONFIG } from 'vs/workbench/contrib/extensions/common/extensions'; import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import * as pfs from 'vs/base/node/pfs'; import * as os from 'os'; import { flatten, distinct, shuffle, coalesce } from 'vs/base/common/arrays'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @@ -41,7 +39,7 @@ import { IExperimentService, ExperimentActionType, ExperimentState } from 'vs/wo import { CancellationToken } from 'vs/base/common/cancellation'; import { ExtensionType } from 'vs/platform/extensions/common/extensions'; import { extname } from 'vs/base/common/resources'; -import { IExeBasedExtensionTip } from 'vs/platform/product/common/product'; +import { IExeBasedExtensionTip, IProductService } from 'vs/platform/product/common/product'; import { timeout } from 'vs/base/common/async'; import { IWorkspaceStatsService } from 'vs/workbench/contrib/stats/common/workspaceStats'; @@ -108,7 +106,8 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe @IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService, @IExtensionsWorkbenchService private readonly extensionWorkbenchService: IExtensionsWorkbenchService, @IExperimentService private readonly experimentService: IExperimentService, - @IWorkspaceStatsService private readonly workspaceStatsService: IWorkspaceStatsService + @IWorkspaceStatsService private readonly workspaceStatsService: IWorkspaceStatsService, + @IProductService private readonly productService: IProductService ) { super(); @@ -116,8 +115,8 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe return; } - if (product.extensionsGallery && product.extensionsGallery.recommendationsUrl) { - this._extensionsRecommendationsUrl = product.extensionsGallery.recommendationsUrl; + if (this.productService.productConfiguration.extensionsGallery && this.productService.productConfiguration.extensionsGallery.recommendationsUrl) { + this._extensionsRecommendationsUrl = this.productService.productConfiguration.extensionsGallery.recommendationsUrl; } this.sessionSeed = +new Date(); @@ -243,7 +242,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe } getKeymapRecommendations(): IExtensionRecommendation[] { - return (product.keymapExtensionTips || []) + return (this.productService.productConfiguration.keymapExtensionTips || []) .filter(extensionId => this.isExtensionAllowedToBeRecommended(extensionId)) .map(extensionId => ({ extensionId, sources: ['application'] })); } @@ -600,10 +599,10 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe return Object.keys(this._fileBasedRecommendations) .sort((a, b) => { if (this._fileBasedRecommendations[a].recommendedTime === this._fileBasedRecommendations[b].recommendedTime) { - if (!product.extensionImportantTips || caseInsensitiveGet(product.extensionImportantTips, a)) { + if (!this.productService.productConfiguration.extensionImportantTips || caseInsensitiveGet(this.productService.productConfiguration.extensionImportantTips, a)) { return -1; } - if (caseInsensitiveGet(product.extensionImportantTips, b)) { + if (caseInsensitiveGet(this.productService.productConfiguration.extensionImportantTips, b)) { return 1; } } @@ -614,11 +613,11 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe } /** - * Parse all file based recommendations from product.extensionTips - * Retire existing recommendations if they are older than a week or are not part of product.extensionTips anymore + * Parse all file based recommendations from this.productService.productConfiguration.extensionTips + * Retire existing recommendations if they are older than a week or are not part of this.productService.productConfiguration.extensionTips anymore */ private fetchFileBasedRecommendations() { - const extensionTips = product.extensionTips; + const extensionTips = this.productService.productConfiguration.extensionTips; if (!extensionTips) { return; } @@ -635,7 +634,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe } }); - forEach(product.extensionImportantTips, entry => { + forEach(this.productService.productConfiguration.extensionImportantTips, entry => { let { key: id, value } = entry; const { pattern } = value; let ids = this._availableRecommendations[pattern]; @@ -697,7 +696,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe let { key: pattern, value: ids } = entry; if (match(pattern, model.uri.toString())) { for (let id of ids) { - if (caseInsensitiveGet(product.extensionImportantTips, id)) { + if (caseInsensitiveGet(this.productService.productConfiguration.extensionImportantTips, id)) { recommendationsToSuggest.push(id); } const filedBasedRecommendation = this._fileBasedRecommendations[id.toLowerCase()] || { recommendedTime: now, sources: [] }; @@ -751,7 +750,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe } const id = recommendationsToSuggest[0]; - const entry = caseInsensitiveGet(product.extensionImportantTips, id); + const entry = caseInsensitiveGet(this.productService.productConfiguration.extensionImportantTips, id); if (!entry) { return false; } @@ -981,14 +980,14 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe } /** - * If user has any of the tools listed in product.exeBasedExtensionTips, fetch corresponding recommendations + * If user has any of the tools listed in this.productService.productConfiguration.exeBasedExtensionTips, fetch corresponding recommendations */ private fetchExecutableRecommendations(important: boolean): Promise { const homeDir = os.homedir(); let foundExecutables: Set = new Set(); let findExecutable = (exeName: string, tip: IExeBasedExtensionTip, path: string) => { - return pfs.fileExists(path).then(exists => { + return this.fileService.exists(URI.file(path)).then(exists => { if (exists && !foundExecutables.has(exeName)) { foundExecutables.add(exeName); (tip['recommendations'] || []).forEach(extensionId => { @@ -1005,7 +1004,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe let promises: Promise[] = []; // Loop through recommended extensions - forEach(product.exeBasedExtensionTips, entry => { + forEach(this.productService.productConfiguration.exeBasedExtensionTips, entry => { if (typeof entry.value !== 'object' || !Array.isArray(entry.value['recommendations'])) { return; } From 24121a38ef023bb378582ee045f7630b0bee0d7b Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 14 Aug 2019 09:44:44 -0700 Subject: [PATCH 606/861] Simplify terminal commands --- .../terminal/browser/terminal.contribution.ts | 5 ++-- .../terminal/browser/terminalActions.ts | 29 ++++--------------- .../contrib/terminal/common/terminal.ts | 2 +- .../terminal/common/terminalCommands.ts | 3 +- .../terminal/common/terminalService.ts | 10 +++++-- 5 files changed, 17 insertions(+), 32 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts index dbd0aa41286..2a343f63b05 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts @@ -20,7 +20,7 @@ import * as panel from 'vs/workbench/browser/panel'; import { getQuickNavigateHandler } from 'vs/workbench/browser/parts/quickopen/quickopen'; import { Extensions as QuickOpenExtensions, IQuickOpenRegistry, QuickOpenHandlerDescriptor } from 'vs/workbench/browser/quickopen'; import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions'; -import { AllowWorkspaceShellTerminalCommand, ClearSelectionTerminalAction, ClearTerminalAction, CopyTerminalSelectionAction, CreateNewInActiveWorkspaceTerminalAction, CreateNewTerminalAction, DeleteToLineStartTerminalAction, DeleteWordLeftTerminalAction, DeleteWordRightTerminalAction, DisallowWorkspaceShellTerminalCommand, FindNext, FindPrevious, FocusActiveTerminalAction, FocusNextPaneTerminalAction, FocusNextTerminalAction, FocusPreviousPaneTerminalAction, FocusPreviousTerminalAction, FocusTerminalFindWidgetAction, HideTerminalFindWidgetAction, KillTerminalAction, MoveToLineEndTerminalAction, MoveToLineStartTerminalAction, QuickOpenActionTermContributor, QuickOpenTermAction, RenameTerminalAction, ResizePaneDownTerminalAction, ResizePaneLeftTerminalAction, ResizePaneRightTerminalAction, ResizePaneUpTerminalAction, RunActiveFileInTerminalAction, RunSelectedTextInTerminalAction, ScrollDownPageTerminalAction, ScrollDownTerminalAction, ScrollToBottomTerminalAction, ScrollToNextCommandAction, ScrollToPreviousCommandAction, ScrollToTopTerminalAction, ScrollUpPageTerminalAction, ScrollUpTerminalAction, SelectAllTerminalAction, SelectDefaultShellWindowsTerminalAction, SelectToNextCommandAction, SelectToNextLineAction, SelectToPreviousCommandAction, SelectToPreviousLineAction, SendSequenceTerminalCommand, SplitInActiveWorkspaceTerminalAction, SplitTerminalAction, TerminalPasteAction, TERMINAL_PICKER_PREFIX, ToggleCaseSensitiveCommand, ToggleEscapeSequenceLoggingAction, ToggleRegexCommand, ToggleTerminalAction, ToggleWholeWordCommand, NavigationModeFocusPreviousTerminalAction, NavigationModeFocusNextTerminalAction, NavigationModeExitTerminalAction } from 'vs/workbench/contrib/terminal/browser/terminalActions'; +import { ClearSelectionTerminalAction, ClearTerminalAction, CopyTerminalSelectionAction, CreateNewInActiveWorkspaceTerminalAction, CreateNewTerminalAction, DeleteToLineStartTerminalAction, DeleteWordLeftTerminalAction, DeleteWordRightTerminalAction, FindNext, FindPrevious, FocusActiveTerminalAction, FocusNextPaneTerminalAction, FocusNextTerminalAction, FocusPreviousPaneTerminalAction, FocusPreviousTerminalAction, FocusTerminalFindWidgetAction, HideTerminalFindWidgetAction, KillTerminalAction, MoveToLineEndTerminalAction, MoveToLineStartTerminalAction, QuickOpenActionTermContributor, QuickOpenTermAction, RenameTerminalAction, ResizePaneDownTerminalAction, ResizePaneLeftTerminalAction, ResizePaneRightTerminalAction, ResizePaneUpTerminalAction, RunActiveFileInTerminalAction, RunSelectedTextInTerminalAction, ScrollDownPageTerminalAction, ScrollDownTerminalAction, ScrollToBottomTerminalAction, ScrollToNextCommandAction, ScrollToPreviousCommandAction, ScrollToTopTerminalAction, ScrollUpPageTerminalAction, ScrollUpTerminalAction, SelectAllTerminalAction, SelectDefaultShellWindowsTerminalAction, SelectToNextCommandAction, SelectToNextLineAction, SelectToPreviousCommandAction, SelectToPreviousLineAction, SendSequenceTerminalCommand, SplitInActiveWorkspaceTerminalAction, SplitTerminalAction, TerminalPasteAction, TERMINAL_PICKER_PREFIX, ToggleCaseSensitiveCommand, ToggleEscapeSequenceLoggingAction, ToggleRegexCommand, ToggleTerminalAction, ToggleWholeWordCommand, NavigationModeFocusPreviousTerminalAction, NavigationModeFocusNextTerminalAction, NavigationModeExitTerminalAction, ManageWorkspaceShellPermissionsTerminalCommand } from 'vs/workbench/contrib/terminal/browser/terminalActions'; import { TerminalPanel } from 'vs/workbench/contrib/terminal/browser/terminalPanel'; import { TerminalPickerHandler } from 'vs/workbench/contrib/terminal/browser/terminalQuickOpen'; import { KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_NOT_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, TERMINAL_PANEL_ID, DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, TerminalCursorStyle, ITerminalService, TERMINAL_ACTION_CATEGORY, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS } from 'vs/workbench/contrib/terminal/common/terminal'; @@ -387,8 +387,7 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ClearTerminalAct mac: { primary: KeyMod.CtrlCmd | KeyCode.KEY_K } }, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KeybindingWeight.WorkbenchContrib + 1), 'Terminal: Clear', category); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectDefaultShellWindowsTerminalAction, SelectDefaultShellWindowsTerminalAction.ID, SelectDefaultShellWindowsTerminalAction.LABEL), 'Terminal: Select Default Shell', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(AllowWorkspaceShellTerminalCommand, AllowWorkspaceShellTerminalCommand.ID, AllowWorkspaceShellTerminalCommand.LABEL), 'Terminal: Allow Workspace Shell Configuration', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(DisallowWorkspaceShellTerminalCommand, DisallowWorkspaceShellTerminalCommand.ID, DisallowWorkspaceShellTerminalCommand.LABEL), 'Terminal: Disallow Workspace Shell Configuration', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ManageWorkspaceShellPermissionsTerminalCommand, ManageWorkspaceShellPermissionsTerminalCommand.ID, ManageWorkspaceShellPermissionsTerminalCommand.LABEL), 'Terminal: Manage Workspace Shell Permissions', category); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(RenameTerminalAction, RenameTerminalAction.ID, RenameTerminalAction.LABEL), 'Terminal: Rename', category); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusTerminalFindWidgetAction, FocusTerminalFindWidgetAction.ID, FocusTerminalFindWidgetAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_F diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 41ceb3e71b1..4d07f85dc15 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -993,10 +993,10 @@ export class ClearSelectionTerminalAction extends Action { } } -export class AllowWorkspaceShellTerminalCommand extends Action { +export class ManageWorkspaceShellPermissionsTerminalCommand extends Action { - public static readonly ID = TERMINAL_COMMAND_ID.WORKSPACE_SHELL_ALLOW; - public static readonly LABEL = nls.localize('workbench.action.terminal.allowWorkspaceShell', "Allow Workspace Shell Configuration"); + public static readonly ID = TERMINAL_COMMAND_ID.MANAGE_WORKSPACE_SHELL_PERMISSIONS; + public static readonly LABEL = nls.localize('workbench.action.terminal.manageWorkspaceShellPermissions', "Manage Workspace Shell Permissions"); constructor( id: string, label: string, @@ -1005,27 +1005,8 @@ export class AllowWorkspaceShellTerminalCommand extends Action { super(id, label); } - public run(event?: any): Promise { - this.terminalService.setWorkspaceShellAllowed(true); - return Promise.resolve(undefined); - } -} - -export class DisallowWorkspaceShellTerminalCommand extends Action { - - public static readonly ID = TERMINAL_COMMAND_ID.WORKSPACE_SHELL_DISALLOW; - public static readonly LABEL = nls.localize('workbench.action.terminal.disallowWorkspaceShell', "Disallow Workspace Shell Configuration"); - - constructor( - id: string, label: string, - @ITerminalService private readonly terminalService: ITerminalService - ) { - super(id, label); - } - - public run(event?: any): Promise { - this.terminalService.setWorkspaceShellAllowed(false); - return Promise.resolve(undefined); + public async run(event?: any): Promise { + await this.terminalService.manageWorkspaceShellPermissions(); } } diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index bb99965b26c..4383fb9c82b 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -279,7 +279,7 @@ export interface ITerminalService { selectDefaultWindowsShell(): Promise; setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void; - setWorkspaceShellAllowed(isAllowed: boolean): void; + manageWorkspaceShellPermissions(): void; /** * Takes a path and returns the properly escaped path to send to the terminal. diff --git a/src/vs/workbench/contrib/terminal/common/terminalCommands.ts b/src/vs/workbench/contrib/terminal/common/terminalCommands.ts index 60da258805d..ddd108304ae 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalCommands.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalCommands.ts @@ -48,8 +48,7 @@ export const enum TERMINAL_COMMAND_ID { SCROLL_TO_TOP = 'workbench.action.terminal.scrollToTop', CLEAR = 'workbench.action.terminal.clear', CLEAR_SELECTION = 'workbench.action.terminal.clearSelection', - WORKSPACE_SHELL_ALLOW = 'workbench.action.terminal.allowWorkspaceShell', - WORKSPACE_SHELL_DISALLOW = 'workbench.action.terminal.disallowWorkspaceShell', + MANAGE_WORKSPACE_SHELL_PERMISSIONS = 'workbench.action.terminal.manageWorkspaceShellPermissions', RENAME = 'workbench.action.terminal.rename', FIND_WIDGET_FOCUS = 'workbench.action.terminal.focusFindWidget', FIND_WIDGET_HIDE = 'workbench.action.terminal.hideFindWidget', diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index 1b04048fdcc..398470899aa 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -479,8 +479,14 @@ export abstract class TerminalService implements ITerminalService { return terminalIndex; } - public setWorkspaceShellAllowed(isAllowed: boolean): void { - this.configHelper.setWorkspaceShellAllowed(isAllowed); + public async manageWorkspaceShellPermissions(): Promise { + const allowItem: IQuickPickItem = { label: nls.localize('workbench.action.terminal.allowWorkspaceShell', "Allow Workspace Shell Configuration") }; + const disallowItem: IQuickPickItem = { label: nls.localize('workbench.action.terminal.disallowWorkspaceShell', "Disallow Workspace Shell Configuration") }; + const value = await this._quickInputService.pick([allowItem, disallowItem], { canPickMany: false }); + if (!value) { + return; + } + this.configHelper.setWorkspaceShellAllowed(value === allowItem); } protected _showTerminalCloseConfirmation(): Promise { From 6cd382dc51232190d6a87c19cf1790fd27313dcd Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 14 Aug 2019 09:50:37 -0700 Subject: [PATCH 607/861] Improve typings, use async --- .../contrib/terminal/common/terminalService.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index 398470899aa..d2dc8ec3c59 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -489,18 +489,18 @@ export abstract class TerminalService implements ITerminalService { this.configHelper.setWorkspaceShellAllowed(value === allowItem); } - protected _showTerminalCloseConfirmation(): Promise { - let message; + protected async _showTerminalCloseConfirmation(): Promise { + let message: string; if (this.terminalInstances.length === 1) { message = nls.localize('terminalService.terminalCloseConfirmationSingular', "There is an active terminal session, do you want to kill it?"); } else { message = nls.localize('terminalService.terminalCloseConfirmationPlural', "There are {0} active terminal sessions, do you want to kill them?", this.terminalInstances.length); } - - return this._dialogService.confirm({ + const res = await this._dialogService.confirm({ message, type: 'warning', - }).then(res => !res.confirmed); + }); + return !res.confirmed; } protected _showNotEnoughSpaceToast(): void { From 70ddd34a9c0c94b6de2def5e216ca176e140daa6 Mon Sep 17 00:00:00 2001 From: mayaswrath Date: Wed, 14 Aug 2019 13:08:49 -0400 Subject: [PATCH 608/861] uses getSelections and simplifed the return --- .../debug/browser/debugEditorActions.ts | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts b/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts index 53d6608548e..645e55984a5 100644 --- a/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts +++ b/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts @@ -35,24 +35,22 @@ class ToggleBreakpointAction extends EditorAction { } public run(accessor: ServicesAccessor, editor: ICodeEditor): Promise { - if (editor.hasModel()) { + if (editor.hasModel() && editor.getSelections()) { const debugService = accessor.get(IDebugService); const modelUri = editor.getModel().uri; - const lineNumbers = new Set(editor._getCursors().getAll() - .filter(cs => cs.modelState.position) - .map(cs => cs.modelState.position.lineNumber)); - - const promises = Array>(); - lineNumbers.forEach(lineNumber => { - const bps = debugService.getModel().getBreakpoints({ lineNumber: lineNumber, uri: modelUri }); - + const canSet = debugService.getConfigurationManager().canSetBreakpointsIn(editor.getModel()); + // Does not account for multi line selections, Set to remove multiple cursor on the same line + const lineNumbers = [...new Set(editor.getSelections().map(s => s.getPosition().lineNumber))]; + return Promise.all(lineNumbers.map(line => { + const bps = debugService.getModel().getBreakpoints({ lineNumber: line, uri: modelUri }); if (bps.length) { - bps.map(bp => debugService.removeBreakpoints(bp.getId())).forEach(p => promises.push(p)); - } else if (debugService.getConfigurationManager().canSetBreakpointsIn(editor.getModel())) { - promises.push(debugService.addBreakpoints(modelUri, [{ lineNumber: lineNumber }], 'debugEditorActions.toggleBreakpointAction')); + return Promise.all(bps.map(bp => debugService.removeBreakpoints(bp.getId()))); + } else if (canSet) { + return (debugService.addBreakpoints(modelUri, [{ lineNumber: line }], 'debugEditorActions.toggleBreakpointAction')); + } else { //Line where a breakpoint cant be set + return Promise.resolve([]); } - }); - return Promise.all(promises); + })); } return Promise.resolve(); } From f4273c1972c9a45a13947694a65465a5846f7877 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 14 Aug 2019 10:20:10 -0700 Subject: [PATCH 609/861] Update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index eaa647b8917..628e97a2c1a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "6ce1c040c0d555b998dba62dd333f437a7b2d44f", + "distro": "afe23e028d98eeca8e26c62804b876ad9cce27b9", "author": { "name": "Microsoft Corporation" }, From 9689b2b047a5565a905bb802dde6bc419e25fc1d Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Wed, 14 Aug 2019 10:52:11 -0700 Subject: [PATCH 610/861] migrate keys from legacy layout #79020 --- src/vs/workbench/browser/layout.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 7f82e7e7562..5fe9f43d192 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -1177,10 +1177,12 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi } private createGridDescriptor(): ISerializedGrid { - const width = this.storageService.getNumber(Storage.GRID_WIDTH, StorageScope.GLOBAL, 600); - const height = this.storageService.getNumber(Storage.GRID_HEIGHT, StorageScope.GLOBAL, 400); - const sideBarSize = this.storageService.getNumber(Storage.SIDEBAR_SIZE, StorageScope.GLOBAL, 300); - const panelSize = this.storageService.getNumber(Storage.PANEL_SIZE, StorageScope.GLOBAL, 300); + const workbenchDimensions = getClientArea(this.parent); + const width = this.storageService.getNumber(Storage.GRID_WIDTH, StorageScope.GLOBAL, workbenchDimensions.width); + const height = this.storageService.getNumber(Storage.GRID_HEIGHT, StorageScope.GLOBAL, workbenchDimensions.height); + // At some point, we will not fall back to old keys from legacy layout, but for now, let's migrate the keys + const sideBarSize = this.storageService.getNumber(Storage.SIDEBAR_SIZE, StorageScope.GLOBAL, this.storageService.getNumber('workbench.sidebar.width', StorageScope.GLOBAL, Math.min(workbenchDimensions.width / 4, 300))!); + const panelSize = this.storageService.getNumber(Storage.PANEL_SIZE, StorageScope.GLOBAL, this.storageService.getNumber(this.state.panel.position === Position.BOTTOM ? 'workbench.panel.height' : 'workbench.panel.width', StorageScope.GLOBAL, workbenchDimensions.height / 3)); const titleBarHeight = this.titleBarPartView.minimumHeight; const statusBarHeight = this.statusBarPartView.minimumHeight; From c75f9bb75644483adb0282169e45bea5c9be76ed Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 14 Aug 2019 20:00:14 +0200 Subject: [PATCH 611/861] fix tests --- src/vs/platform/product/common/product.ts | 4 +- .../extensionsTipsService.test.ts | 38 +++++++++++-------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/vs/platform/product/common/product.ts b/src/vs/platform/product/common/product.ts index 11b6fed267a..ec42094d94c 100644 --- a/src/vs/platform/product/common/product.ts +++ b/src/vs/platform/product/common/product.ts @@ -43,8 +43,8 @@ export interface IProductConfiguration { readonly controlUrl: string; readonly recommendationsUrl: string; }; - extensionTips: { [id: string]: string; }; - extensionImportantTips: { [id: string]: { name: string; pattern: string; isExtensionPack?: boolean }; }; + readonly extensionTips: { [id: string]: string; }; + readonly extensionImportantTips: { [id: string]: { name: string; pattern: string; isExtensionPack?: boolean }; }; readonly exeBasedExtensionTips: { [id: string]: IExeBasedExtensionTip; }; readonly extensionKeywords: { [extension: string]: readonly string[]; }; readonly extensionAllowedBadgeProviders: readonly string[]; diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts index cd6d14c858d..b66c6143f24 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts @@ -52,6 +52,7 @@ import { NullLogService } from 'vs/platform/log/common/log'; import { Schemas } from 'vs/base/common/network'; import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider'; import { IFileService } from 'vs/platform/files/common/files'; +import { IProductService } from 'vs/platform/product/common/product'; const mockExtensionGallery: IGalleryExtension[] = [ aGalleryExtension('MockExtension1', { @@ -201,27 +202,32 @@ suite('ExtensionsTipsService Test', () => { instantiationService.stub(IExtensionEnablementService, new TestExtensionEnablementService(instantiationService)); instantiationService.stub(ITelemetryService, NullTelemetryService); instantiationService.stub(IURLService, URLService); + instantiationService.stub(IProductService, >{ + productConfiguration: { + ...product, ...{ + extensionTips: { + 'ms-vscode.csharp': '{**/*.cs,**/project.json,**/global.json,**/*.csproj,**/*.sln,**/appsettings.json}', + 'msjsdiag.debugger-for-chrome': '{**/*.ts,**/*.tsx**/*.js,**/*.jsx,**/*.es6,**/.babelrc}', + 'lukehoban.Go': '**/*.go' + }, + extensionImportantTips: { + 'ms-python.python': { + 'name': 'Python', + 'pattern': '{**/*.py}' + }, + 'ms-vscode.PowerShell': { + 'name': 'PowerShell', + 'pattern': '{**/*.ps,**/*.ps1}' + } + } + } + } + }); experimentService = instantiationService.createInstance(TestExperimentService); instantiationService.stub(IExperimentService, experimentService); onModelAddedEvent = new Emitter(); - - product.extensionTips = { - 'ms-vscode.csharp': '{**/*.cs,**/project.json,**/global.json,**/*.csproj,**/*.sln,**/appsettings.json}', - 'msjsdiag.debugger-for-chrome': '{**/*.ts,**/*.tsx**/*.js,**/*.jsx,**/*.es6,**/.babelrc}', - 'lukehoban.Go': '**/*.go' - }; - product.extensionImportantTips = { - 'ms-python.python': { - 'name': 'Python', - 'pattern': '{**/*.py}' - }, - 'ms-vscode.PowerShell': { - 'name': 'PowerShell', - 'pattern': '{**/*.ps,**/*.ps1}' - } - }; }); suiteTeardown(() => { From 37d8f1fd26a459f162efbe84e69ef10fa22f8a97 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 14 Aug 2019 11:37:16 -0700 Subject: [PATCH 612/861] Register driver --- src/vs/workbench/browser/web.main.ts | 5 +++++ test/smoke/src/vscode/puppeteerDriver.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index 1a47bd47cf8..d3bb53ad195 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -84,6 +84,11 @@ class CodeRendererMain extends Disposable { })); this._register(workbench.onShutdown(() => this.dispose())); + // Driver + if (this.configuration.driver) { + registerWindowDriver().then(d => this._register(d)); + } + // Startup workbench.startup(); } diff --git a/test/smoke/src/vscode/puppeteerDriver.ts b/test/smoke/src/vscode/puppeteerDriver.ts index 5d7b163b71c..70fa8ca0cc9 100644 --- a/test/smoke/src/vscode/puppeteerDriver.ts +++ b/test/smoke/src/vscode/puppeteerDriver.ts @@ -191,7 +191,7 @@ export async function launch(_args): Promise { // TODO: Don't open up the system browser const webUserDataDir = join(tmpdir(), `smoketest-${Math.random() * 10000000000}`); await promisify(mkdir)(webUserDataDir); - server = spawn(join(args[0], `resources/server/web.${process.platform === 'win32' ? 'bat' : 'sh'}`), ['--driver', 'web', '--web-user-data-dir', webUserDataDir]); + server = spawn(join(args[0], `resources/server/web.${process.platform === 'win32' ? 'bat' : 'sh'}`), ['--no-browser', '--driver', 'web', '--web-user-data-dir', webUserDataDir]); server.stderr.on('data', e => console.log('Server stderr: ' + e)); process.on('exit', teardown); endpoint = await waitForEndpoint(); From 1f8d0fced333afacf2250812942c4bc95d4521d4 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 14 Aug 2019 11:38:48 -0700 Subject: [PATCH 613/861] Teardown on sigint --- test/smoke/src/vscode/puppeteerDriver.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/smoke/src/vscode/puppeteerDriver.ts b/test/smoke/src/vscode/puppeteerDriver.ts index 70fa8ca0cc9..a5fd775cb2a 100644 --- a/test/smoke/src/vscode/puppeteerDriver.ts +++ b/test/smoke/src/vscode/puppeteerDriver.ts @@ -194,6 +194,7 @@ export async function launch(_args): Promise { server = spawn(join(args[0], `resources/server/web.${process.platform === 'win32' ? 'bat' : 'sh'}`), ['--no-browser', '--driver', 'web', '--web-user-data-dir', webUserDataDir]); server.stderr.on('data', e => console.log('Server stderr: ' + e)); process.on('exit', teardown); + process.on('SIGINT', teardown); endpoint = await waitForEndpoint(); } From e4863753b9fd6866c98eaeceb184ebd1bb880632 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 14 Aug 2019 11:36:57 -0700 Subject: [PATCH 614/861] Update markdown grammar --- .../syntaxes/markdown.tmLanguage.json | 37 +++++++++++++++---- .../test/colorize-results/test-33886_md.json | 20 +++++----- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json index f63c46a878d..6fb25ae6ce2 100644 --- a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json +++ b/extensions/markdown-basics/syntaxes/markdown.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/vscode-markdown-tm-grammar/commit/a595d8ba2ae9ce8864435d33db2afa0fe68b1487", + "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/05ccfa3db6edbd357390431f9e316adb38ba41d8", "name": "Markdown", "scopeName": "text.html.markdown", "patterns": [ @@ -716,7 +716,7 @@ { "begin": "(^|\\G)(\\s*)(.*)", "while": "(^|\\G)(?!\\s*([`~]{3,})\\s*$)", - "contentName": "meta.embedded.block.cpp source.cpp", + "contentName": "meta.embedded.block.cpp", "patterns": [ { "include": "source.cpp" @@ -1987,8 +1987,29 @@ "name": "comment.block.html" }, { - "begin": "(^|\\G)\\s*(?=<(script|style|pre)(\\s|$|>)(?!.*?))", - "end": "(?=.*)", + "begin": "(?i)(^|\\G)\\s*(?=<(script|style|pre)(\\s|$|>)(?!.*?))", + "end": "(?i)(.*)(())", + "endCaptures": { + "1": { + "patterns": [ + { + "include": "text.html.basic" + } + ] + }, + "2": { + "name": "meta.tag.structure.$4.end.html" + }, + "3": { + "name": "punctuation.definition.tag.begin.html" + }, + "4": { + "name": "entity.name.tag.html" + }, + "5": { + "name": "punctuation.definition.tag.end.html" + } + }, "patterns": [ { "begin": "(\\s*|$)", @@ -1997,12 +2018,12 @@ "include": "text.html.basic" } ], - "while": "^(?!.*)" + "while": "(?i)^(?!.*)" } ] }, { - "begin": "(^|\\G)\\s*(?=))", + "begin": "(?i)(^|\\G)\\s*(?=))", "patterns": [ { "include": "text.html.basic" @@ -2275,7 +2296,7 @@ }, "bracket": { "comment": "Markdown will convert this for us. We match it so that the HTML grammar will not mark it up as invalid.", - "match": "<(?![a-z/?\\$!])", + "match": "<(?![a-zA-Z/?\\$!])", "name": "meta.other.valid-bracket.markdown" }, "escape": { @@ -2566,4 +2587,4 @@ "name": "markup.inline.raw.string.markdown" } } -} +} \ No newline at end of file diff --git a/extensions/markdown-basics/test/colorize-results/test-33886_md.json b/extensions/markdown-basics/test/colorize-results/test-33886_md.json index 179172a5738..25799e89a36 100644 --- a/extensions/markdown-basics/test/colorize-results/test-33886_md.json +++ b/extensions/markdown-basics/test/colorize-results/test-33886_md.json @@ -111,7 +111,7 @@ }, { "c": "", - "t": "text.html.markdown meta.paragraph.markdown meta.tag.inline.code.end.html punctuation.definition.tag.end.html", + "t": "text.html.markdown meta.tag.inline.code.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -144,7 +144,7 @@ }, { "c": "", - "t": "text.html.markdown meta.paragraph.markdown meta.tag.structure.pre.end.html punctuation.definition.tag.end.html", + "t": "text.html.markdown meta.tag.structure.pre.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", @@ -254,7 +254,7 @@ }, { "c": "a", - "t": "text.html.markdown meta.paragraph.markdown", + "t": "text.html.markdown", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -265,7 +265,7 @@ }, { "c": "", - "t": "text.html.markdown meta.paragraph.markdown meta.tag.structure.pre.end.html punctuation.definition.tag.end.html", + "t": "text.html.markdown meta.tag.structure.pre.end.html punctuation.definition.tag.end.html", "r": { "dark_plus": "punctuation.definition.tag: #808080", "light_plus": "punctuation.definition.tag: #800000", From c4733f91c86a0aaeb2f5c122fc13512f6ea911fb Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 14 Aug 2019 14:49:23 -0700 Subject: [PATCH 615/861] Still show fix all actions for fix-all actions that can fix multiple errors with multple different diagnostics --- .../src/features/quickFix.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/src/features/quickFix.ts b/extensions/typescript-language-features/src/features/quickFix.ts index 6ce9f199704..7bc5d43f0eb 100644 --- a/extensions/typescript-language-features/src/features/quickFix.ts +++ b/extensions/typescript-language-features/src/features/quickFix.ts @@ -286,7 +286,12 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider { } // Make sure there are multiple diagnostics of the same type in the file - if (!this.diagnosticsManager.getDiagnostics(document.uri).some(x => x.code === diagnostic.code && x !== diagnostic)) { + if (!this.diagnosticsManager.getDiagnostics(document.uri).some(x => { + if (x === diagnostic) { + return false; + } + return x.code === diagnostic.code || fixAllErrorCodes.get(x.code as number) === diagnostic.code; + })) { return results; } @@ -304,6 +309,15 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider { } } +// Some fix all actions can actually fix multiple differnt diagnostics. Make sure we still show the fix all action +// in such cases +const fixAllErrorCodes = new Map([ + // Missing async + [2339, 2339], + [2345, 2339], +]); + + const preferredFixes = new Set([ 'annotateWithTypeFromJSDoc', 'constructorForDerivedNeedSuperCall', From 57c13dc0c4bc822ebb8916598ab2c5c77d0d2ab4 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 14 Aug 2019 14:50:45 -0700 Subject: [PATCH 616/861] Base web user data dir off normal one --- test/smoke/src/main.ts | 3 +-- test/smoke/src/vscode/puppeteerDriver.ts | 8 +++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/test/smoke/src/main.ts b/test/smoke/src/main.ts index bb75ee6066b..8427b540809 100644 --- a/test/smoke/src/main.ts +++ b/test/smoke/src/main.ts @@ -142,8 +142,7 @@ if (typeof stablePath === 'string' && !fs.existsSync(stablePath)) { fail(`Can't find Stable Code at ${stablePath}.`); } -// TODO: Server should be launched from smoke tests -const userDataDir = opts.web ? path.join(process.env.HOME!, '.vscode-remote/data') : path.join(testDataPath, 'd'); +const userDataDir = path.join(testDataPath, 'd'); let quality: Quality; if (process.env.VSCODE_DEV === '1') { diff --git a/test/smoke/src/vscode/puppeteerDriver.ts b/test/smoke/src/vscode/puppeteerDriver.ts index a5fd775cb2a..8aaa6782062 100644 --- a/test/smoke/src/vscode/puppeteerDriver.ts +++ b/test/smoke/src/vscode/puppeteerDriver.ts @@ -181,15 +181,13 @@ function timeout(ms: number): Promise { // function runInDriver(call: string, args: (string | boolean)[]): Promise {} -let args; +let args: string[] | undefined; let server: ChildProcess | undefined; let endpoint: string | undefined; -export async function launch(_args): Promise { +export async function launch(_args: string[]): Promise { args = _args; - - // TODO: Don't open up the system browser - const webUserDataDir = join(tmpdir(), `smoketest-${Math.random() * 10000000000}`); + const webUserDataDir = args.filter(e => e.includes('--user-data-dir='))[0].replace('--user-data-dir=', ''); await promisify(mkdir)(webUserDataDir); server = spawn(join(args[0], `resources/server/web.${process.platform === 'win32' ? 'bat' : 'sh'}`), ['--no-browser', '--driver', 'web', '--web-user-data-dir', webUserDataDir]); server.stderr.on('data', e => console.log('Server stderr: ' + e)); From d726f427e0eea0631f3900555d5308aadb287f42 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 14 Aug 2019 15:02:05 -0700 Subject: [PATCH 617/861] Update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 628e97a2c1a..2074de1024a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "afe23e028d98eeca8e26c62804b876ad9cce27b9", + "distro": "8ee1612ab2b050f366c2c4c1500fc243b407581f", "author": { "name": "Microsoft Corporation" }, From 414a35dcf793b11617a18d1db56034ace73bde8e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 14 Aug 2019 15:04:35 -0700 Subject: [PATCH 618/861] Use new browser none arg --- test/smoke/src/vscode/puppeteerDriver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/smoke/src/vscode/puppeteerDriver.ts b/test/smoke/src/vscode/puppeteerDriver.ts index 8aaa6782062..ba2c8359de1 100644 --- a/test/smoke/src/vscode/puppeteerDriver.ts +++ b/test/smoke/src/vscode/puppeteerDriver.ts @@ -189,7 +189,7 @@ export async function launch(_args: string[]): Promise { args = _args; const webUserDataDir = args.filter(e => e.includes('--user-data-dir='))[0].replace('--user-data-dir=', ''); await promisify(mkdir)(webUserDataDir); - server = spawn(join(args[0], `resources/server/web.${process.platform === 'win32' ? 'bat' : 'sh'}`), ['--no-browser', '--driver', 'web', '--web-user-data-dir', webUserDataDir]); + server = spawn(join(args[0], `resources/server/web.${process.platform === 'win32' ? 'bat' : 'sh'}`), ['--browser', 'none', '--driver', 'web', '--web-user-data-dir', webUserDataDir]); server.stderr.on('data', e => console.log('Server stderr: ' + e)); process.on('exit', teardown); process.on('SIGINT', teardown); From 2c4edeb617e41c0222fdd6729794113537eaf331 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 14 Aug 2019 14:54:09 -0700 Subject: [PATCH 619/861] Make sure we compare fully normalized error codes when checking for fix all actions --- .../typescript-language-features/src/features/quickFix.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/src/features/quickFix.ts b/extensions/typescript-language-features/src/features/quickFix.ts index 7bc5d43f0eb..2585142e097 100644 --- a/extensions/typescript-language-features/src/features/quickFix.ts +++ b/extensions/typescript-language-features/src/features/quickFix.ts @@ -290,7 +290,8 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider { if (x === diagnostic) { return false; } - return x.code === diagnostic.code || fixAllErrorCodes.get(x.code as number) === diagnostic.code; + return x.code === diagnostic.code + || (fixAllErrorCodes.has(x.code as number) && fixAllErrorCodes.get(x.code as number) === fixAllErrorCodes.get(diagnostic.code as number)); })) { return results; } From 46d0bd810069e5785b6fd045b03570562fc29492 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 14 Aug 2019 17:05:01 -0700 Subject: [PATCH 620/861] Don't include closing ] in folded range Fixes #79142 --- .../typescript-language-features/src/features/folding.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/typescript-language-features/src/features/folding.ts b/extensions/typescript-language-features/src/features/folding.ts index a00a2db5f00..0867c86fdc7 100644 --- a/extensions/typescript-language-features/src/features/folding.ts +++ b/extensions/typescript-language-features/src/features/folding.ts @@ -55,7 +55,7 @@ class TypeScriptFoldingProvider implements vscode.FoldingRangeProvider { const start = range.start.line; // workaround for #47240 - const end = (range.end.character > 0 && document.getText(new vscode.Range(range.end.translate(0, -1), range.end)) === '}') + const end = (range.end.character > 0 && new Set(['}', ']']).has(document.getText(new vscode.Range(range.end.translate(0, -1), range.end)))) ? Math.max(range.end.line - 1, range.start.line) : range.end.line; @@ -81,4 +81,4 @@ export function register( return vscode.languages.registerFoldingRangeProvider(selector, new TypeScriptFoldingProvider(client)); }); -} \ No newline at end of file +} From e0dd508b0eb811a6fe821152f4d310051c1a2060 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 14 Aug 2019 17:19:17 -0700 Subject: [PATCH 621/861] Register Remote Explorer when there are contributions. --- .../api/browser/viewsExtensionPoint.ts | 41 +- src/vs/workbench/browser/parts/views/views.ts | 14 +- src/vs/workbench/common/views.ts | 14 +- .../browser/help-documentation-dark.svg | 11 + .../remote/browser/help-documentation-hc.svg | 11 + .../browser/help-documentation-light.svg | 11 + .../remote/browser/help-feedback-dark.svg | 4 + .../remote/browser/help-feedback-hc.svg | 4 + .../remote/browser/help-feedback-light.svg | 4 + .../browser/help-getting-started-dark.svg | 4 + .../browser/help-getting-started-hc.svg | 4 + .../browser/help-getting-started-light.svg | 4 + .../remote/browser/help-report-issue-dark.svg | 4 + .../remote/browser/help-report-issue-hc.svg | 4 + .../browser/help-report-issue-light.svg | 4 + .../browser/help-review-issues-dark.svg | 4 + .../remote/browser/help-review-issues-hc.svg | 4 + .../browser/help-review-issues-light.svg | 4 + .../remote/browser/remote-activity-bar.svg | 13 + .../contrib/remote/browser/remote.ts | 419 ++++++++++++++++++ .../contrib/remote/browser/remoteViewlet.css | 92 ++++ .../remote/common/remote.contribution.ts | 28 ++ src/vs/workbench/workbench.common.main.ts | 1 + 23 files changed, 696 insertions(+), 7 deletions(-) create mode 100644 src/vs/workbench/contrib/remote/browser/help-documentation-dark.svg create mode 100644 src/vs/workbench/contrib/remote/browser/help-documentation-hc.svg create mode 100644 src/vs/workbench/contrib/remote/browser/help-documentation-light.svg create mode 100644 src/vs/workbench/contrib/remote/browser/help-feedback-dark.svg create mode 100644 src/vs/workbench/contrib/remote/browser/help-feedback-hc.svg create mode 100644 src/vs/workbench/contrib/remote/browser/help-feedback-light.svg create mode 100644 src/vs/workbench/contrib/remote/browser/help-getting-started-dark.svg create mode 100644 src/vs/workbench/contrib/remote/browser/help-getting-started-hc.svg create mode 100644 src/vs/workbench/contrib/remote/browser/help-getting-started-light.svg create mode 100644 src/vs/workbench/contrib/remote/browser/help-report-issue-dark.svg create mode 100644 src/vs/workbench/contrib/remote/browser/help-report-issue-hc.svg create mode 100644 src/vs/workbench/contrib/remote/browser/help-report-issue-light.svg create mode 100644 src/vs/workbench/contrib/remote/browser/help-review-issues-dark.svg create mode 100644 src/vs/workbench/contrib/remote/browser/help-review-issues-hc.svg create mode 100644 src/vs/workbench/contrib/remote/browser/help-review-issues-light.svg create mode 100644 src/vs/workbench/contrib/remote/browser/remote-activity-bar.svg create mode 100644 src/vs/workbench/contrib/remote/browser/remote.ts create mode 100644 src/vs/workbench/contrib/remote/browser/remoteViewlet.css diff --git a/src/vs/workbench/api/browser/viewsExtensionPoint.ts b/src/vs/workbench/api/browser/viewsExtensionPoint.ts index 149f1f4cebe..95a9aff3298 100644 --- a/src/vs/workbench/api/browser/viewsExtensionPoint.ts +++ b/src/vs/workbench/api/browser/viewsExtensionPoint.ts @@ -19,6 +19,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { VIEWLET_ID as EXPLORER } from 'vs/workbench/contrib/files/common/files'; import { VIEWLET_ID as SCM } from 'vs/workbench/contrib/scm/common/scm'; import { VIEWLET_ID as DEBUG } from 'vs/workbench/contrib/debug/common/debug'; +import { VIEWLET_ID as REMOTE } from 'vs/workbench/contrib/remote/common/remote.contribution'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { URI } from 'vs/base/common/uri'; import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor, ShowViewletAction } from 'vs/workbench/browser/viewlet'; @@ -79,6 +80,7 @@ interface IUserFriendlyViewDescriptor { id: string; name: string; when?: string; + group?: string; } const viewDescriptor: IJSONSchema = { @@ -99,6 +101,27 @@ const viewDescriptor: IJSONSchema = { } }; +const nestableViewDescriptor: IJSONSchema = { + type: 'object', + properties: { + id: { + description: localize('vscode.extension.contributes.view.id', 'Identifier of the view. Use this to register a data provider through `vscode.window.registerTreeDataProviderForView` API. Also to trigger activating your extension by registering `onView:${id}` event to `activationEvents`.'), + type: 'string' + }, + name: { + description: localize('vscode.extension.contributes.view.name', 'The human-readable name of the view. Will be shown'), + type: 'string' + }, + when: { + description: localize('vscode.extension.contributes.view.when', 'Condition which must be true to show this view'), + type: 'string' + }, + group: { + description: localize('vscode.extension.contributes.view.group', 'Nested group in the viewlet'), + type: 'string' + } + } +}; const viewsContribution: IJSONSchema = { description: localize('vscode.extension.contributes.views', "Contributes views to the editor"), type: 'object', @@ -126,6 +149,12 @@ const viewsContribution: IJSONSchema = { type: 'array', items: viewDescriptor, default: [] + }, + 'remote': { + description: localize('views.remote', "Contributes views to Remote container in the Activity bar"), + type: 'array', + items: nestableViewDescriptor, + default: [] } }, additionalProperties: { @@ -376,6 +405,12 @@ class ViewsExtensionHandler implements IWorkbenchContribution { return null; } + const order = ExtensionIdentifier.equals(extension.description.identifier, container.extensionId) + ? index + 1 + : container.orderDelegate + ? container.orderDelegate.getOrder(item.group) + : undefined; + const viewDescriptor = { id: item.id, name: item.name, @@ -384,9 +419,10 @@ class ViewsExtensionHandler implements IWorkbenchContribution { canToggleVisibility: true, collapsed: this.showCollapsed(container), treeView: this.instantiationService.createInstance(CustomTreeView, item.id, item.name, container), - order: ExtensionIdentifier.equals(extension.description.identifier, container.extensionId) ? index + 1 : undefined, + order: order, extensionId: extension.description.identifier, - originalContainerId: entry.key + originalContainerId: entry.key, + group: item.group }; viewIds.push(viewDescriptor.id); @@ -440,6 +476,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution { case 'explorer': return this.viewContainersRegistry.get(EXPLORER); case 'debug': return this.viewContainersRegistry.get(DEBUG); case 'scm': return this.viewContainersRegistry.get(SCM); + case 'remote': return this.viewContainersRegistry.get(REMOTE); default: return this.viewContainersRegistry.get(`workbench.view.extension.${value}`); } } diff --git a/src/vs/workbench/browser/parts/views/views.ts b/src/vs/workbench/browser/parts/views/views.ts index 2983c109250..23accec76fa 100644 --- a/src/vs/workbench/browser/parts/views/views.ts +++ b/src/vs/workbench/browser/parts/views/views.ts @@ -382,7 +382,19 @@ export class ContributableViewsModel extends Disposable { return 0; } - return (this.getViewOrder(a) - this.getViewOrder(b)) || (a.id < b.id ? -1 : 1); + return (this.getViewOrder(a) - this.getViewOrder(b)) || this.getGroupOrderResult(a, b) || (a.id < b.id ? -1 : 1); + } + + private getGroupOrderResult(a: IViewDescriptor, b: IViewDescriptor) { + if (!a.group || !b.group) { + return 0; + } + + if (a.group === b.group) { + return 0; + } + + return a.group < b.group ? -1 : 1; } private getViewOrder(viewDescriptor: IViewDescriptor): number { diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index c9ec1a841f6..92596fd9428 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -51,7 +51,7 @@ export interface IViewContainersRegistry { * * @returns the registered ViewContainer. */ - registerViewContainer(id: string, hideIfEmpty?: boolean, extensionId?: ExtensionIdentifier): ViewContainer; + registerViewContainer(id: string, hideIfEmpty?: boolean, extensionId?: ExtensionIdentifier, viewOrderDelegate?: ViewOrderDelegate): ViewContainer; /** * Deregisters the given view container @@ -67,8 +67,12 @@ export interface IViewContainersRegistry { get(id: string): ViewContainer | undefined; } +interface ViewOrderDelegate { + getOrder(group?: string): number | undefined; +} + export class ViewContainer { - protected constructor(readonly id: string, readonly hideIfEmpty: boolean, readonly extensionId?: ExtensionIdentifier) { } + protected constructor(readonly id: string, readonly hideIfEmpty: boolean, readonly extensionId?: ExtensionIdentifier, readonly orderDelegate?: ViewOrderDelegate) { } } class ViewContainersRegistryImpl extends Disposable implements IViewContainersRegistry { @@ -85,7 +89,7 @@ class ViewContainersRegistryImpl extends Disposable implements IViewContainersRe return values(this.viewContainers); } - registerViewContainer(id: string, hideIfEmpty?: boolean, extensionId?: ExtensionIdentifier): ViewContainer { + registerViewContainer(id: string, hideIfEmpty?: boolean, extensionId?: ExtensionIdentifier, viewOrderDelegate?: ViewOrderDelegate): ViewContainer { const existing = this.viewContainers.get(id); if (existing) { return existing; @@ -93,7 +97,7 @@ class ViewContainersRegistryImpl extends Disposable implements IViewContainersRe const viewContainer = new class extends ViewContainer { constructor() { - super(id, !!hideIfEmpty, extensionId); + super(id, !!hideIfEmpty, extensionId, viewOrderDelegate); } }; this.viewContainers.set(id, viewContainer); @@ -126,6 +130,8 @@ export interface IViewDescriptor { readonly when?: ContextKeyExpr; + readonly group?: string; + readonly order?: number; readonly weight?: number; diff --git a/src/vs/workbench/contrib/remote/browser/help-documentation-dark.svg b/src/vs/workbench/contrib/remote/browser/help-documentation-dark.svg new file mode 100644 index 00000000000..2673902c684 --- /dev/null +++ b/src/vs/workbench/contrib/remote/browser/help-documentation-dark.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/src/vs/workbench/contrib/remote/browser/help-documentation-hc.svg b/src/vs/workbench/contrib/remote/browser/help-documentation-hc.svg new file mode 100644 index 00000000000..e8dc8205bab --- /dev/null +++ b/src/vs/workbench/contrib/remote/browser/help-documentation-hc.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/src/vs/workbench/contrib/remote/browser/help-documentation-light.svg b/src/vs/workbench/contrib/remote/browser/help-documentation-light.svg new file mode 100644 index 00000000000..4a3009baeee --- /dev/null +++ b/src/vs/workbench/contrib/remote/browser/help-documentation-light.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/src/vs/workbench/contrib/remote/browser/help-feedback-dark.svg b/src/vs/workbench/contrib/remote/browser/help-feedback-dark.svg new file mode 100644 index 00000000000..5d99408934e --- /dev/null +++ b/src/vs/workbench/contrib/remote/browser/help-feedback-dark.svg @@ -0,0 +1,4 @@ + + + diff --git a/src/vs/workbench/contrib/remote/browser/help-feedback-hc.svg b/src/vs/workbench/contrib/remote/browser/help-feedback-hc.svg new file mode 100644 index 00000000000..941430e9dd6 --- /dev/null +++ b/src/vs/workbench/contrib/remote/browser/help-feedback-hc.svg @@ -0,0 +1,4 @@ + + + diff --git a/src/vs/workbench/contrib/remote/browser/help-feedback-light.svg b/src/vs/workbench/contrib/remote/browser/help-feedback-light.svg new file mode 100644 index 00000000000..72437202b72 --- /dev/null +++ b/src/vs/workbench/contrib/remote/browser/help-feedback-light.svg @@ -0,0 +1,4 @@ + + + diff --git a/src/vs/workbench/contrib/remote/browser/help-getting-started-dark.svg b/src/vs/workbench/contrib/remote/browser/help-getting-started-dark.svg new file mode 100644 index 00000000000..0ea65d83198 --- /dev/null +++ b/src/vs/workbench/contrib/remote/browser/help-getting-started-dark.svg @@ -0,0 +1,4 @@ + + + diff --git a/src/vs/workbench/contrib/remote/browser/help-getting-started-hc.svg b/src/vs/workbench/contrib/remote/browser/help-getting-started-hc.svg new file mode 100644 index 00000000000..5bb05d3d8c5 --- /dev/null +++ b/src/vs/workbench/contrib/remote/browser/help-getting-started-hc.svg @@ -0,0 +1,4 @@ + + + diff --git a/src/vs/workbench/contrib/remote/browser/help-getting-started-light.svg b/src/vs/workbench/contrib/remote/browser/help-getting-started-light.svg new file mode 100644 index 00000000000..46cde7f7cc0 --- /dev/null +++ b/src/vs/workbench/contrib/remote/browser/help-getting-started-light.svg @@ -0,0 +1,4 @@ + + + diff --git a/src/vs/workbench/contrib/remote/browser/help-report-issue-dark.svg b/src/vs/workbench/contrib/remote/browser/help-report-issue-dark.svg new file mode 100644 index 00000000000..0117ceb7ded --- /dev/null +++ b/src/vs/workbench/contrib/remote/browser/help-report-issue-dark.svg @@ -0,0 +1,4 @@ + + + diff --git a/src/vs/workbench/contrib/remote/browser/help-report-issue-hc.svg b/src/vs/workbench/contrib/remote/browser/help-report-issue-hc.svg new file mode 100644 index 00000000000..b0c521b7dc6 --- /dev/null +++ b/src/vs/workbench/contrib/remote/browser/help-report-issue-hc.svg @@ -0,0 +1,4 @@ + + + diff --git a/src/vs/workbench/contrib/remote/browser/help-report-issue-light.svg b/src/vs/workbench/contrib/remote/browser/help-report-issue-light.svg new file mode 100644 index 00000000000..5da9322b6a9 --- /dev/null +++ b/src/vs/workbench/contrib/remote/browser/help-report-issue-light.svg @@ -0,0 +1,4 @@ + + + diff --git a/src/vs/workbench/contrib/remote/browser/help-review-issues-dark.svg b/src/vs/workbench/contrib/remote/browser/help-review-issues-dark.svg new file mode 100644 index 00000000000..21eec9cbcb8 --- /dev/null +++ b/src/vs/workbench/contrib/remote/browser/help-review-issues-dark.svg @@ -0,0 +1,4 @@ + + + diff --git a/src/vs/workbench/contrib/remote/browser/help-review-issues-hc.svg b/src/vs/workbench/contrib/remote/browser/help-review-issues-hc.svg new file mode 100644 index 00000000000..94013ea52ae --- /dev/null +++ b/src/vs/workbench/contrib/remote/browser/help-review-issues-hc.svg @@ -0,0 +1,4 @@ + + + diff --git a/src/vs/workbench/contrib/remote/browser/help-review-issues-light.svg b/src/vs/workbench/contrib/remote/browser/help-review-issues-light.svg new file mode 100644 index 00000000000..826d0eefbf4 --- /dev/null +++ b/src/vs/workbench/contrib/remote/browser/help-review-issues-light.svg @@ -0,0 +1,4 @@ + + + diff --git a/src/vs/workbench/contrib/remote/browser/remote-activity-bar.svg b/src/vs/workbench/contrib/remote/browser/remote-activity-bar.svg new file mode 100644 index 00000000000..029e6b051c2 --- /dev/null +++ b/src/vs/workbench/contrib/remote/browser/remote-activity-bar.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/src/vs/workbench/contrib/remote/browser/remote.ts b/src/vs/workbench/contrib/remote/browser/remote.ts new file mode 100644 index 00000000000..ea530271414 --- /dev/null +++ b/src/vs/workbench/contrib/remote/browser/remote.ts @@ -0,0 +1,419 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import 'vs/css!./remoteViewlet'; +import * as nls from 'vs/nls'; +import * as dom from 'vs/base/browser/dom'; +import { URI } from 'vs/base/common/uri'; +import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { IStorageService } from 'vs/platform/storage/common/storage'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; +import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; +import { ViewContainerViewlet } from 'vs/workbench/browser/parts/views/viewsViewlet'; +import { VIEWLET_ID, VIEW_CONTAINER } from 'vs/workbench/contrib/remote/common/remote.contribution'; +import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet'; +import { IAddedViewDescriptorRef } from 'vs/workbench/browser/parts/views/views'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IViewDescriptor, IViewsRegistry, Extensions } from 'vs/workbench/common/views'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { ExtensionsRegistry, IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry'; +import { WorkbenchAsyncDataTree, TreeResourceNavigator2 } from 'vs/platform/list/browser/listService'; +import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list'; +import { ITreeRenderer, ITreeNode, IAsyncDataSource } from 'vs/base/browser/ui/tree/tree'; +import { Event } from 'vs/base/common/event'; +import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { ICommandService } from 'vs/platform/commands/common/commands'; +import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor } from 'vs/workbench/browser/viewlet'; + +interface HelpInformation { + extensionDescription: IExtensionDescription; + getStarted?: string; + documentation?: string; + feedback?: string; + issues?: string; +} + +const remoteHelpExtPoint = ExtensionsRegistry.registerExtensionPoint({ + extensionPoint: 'remoteHelp', + jsonSchema: { + description: nls.localize('RemoteHelpInformationExtPoint', 'Contributes help information for Remote'), + type: 'object', + properties: { + 'getStarted': { + description: nls.localize('RemoteHelpInformationExtPoint.getStarted', "The url to your project's Getting Started page"), + type: 'string' + }, + 'documentation': { + description: nls.localize('RemoteHelpInformationExtPoint.documentation', "The url to your project's documentation page"), + type: 'string' + }, + 'feedback': { + description: nls.localize('RemoteHelpInformationExtPoint.feedback', "The url to your project's feedback reporter"), + type: 'string' + }, + 'issues': { + description: nls.localize('RemoteHelpInformationExtPoint.issues', "The url to your project's issues list"), + type: 'string' + } + } + } +}); + +interface IViewModel { + helpInformations: HelpInformation[]; +} + +class HelpTreeVirtualDelegate implements IListVirtualDelegate { + getHeight(element: IHelpItem): number { + return 22; + } + + getTemplateId(element: IHelpItem): string { + return 'HelpItemTemplate'; + } +} + +interface IHelpItemTemplateData { + parent: HTMLElement; + icon: HTMLElement; +} + +class HelpTreeRenderer implements ITreeRenderer { + templateId: string = 'HelpItemTemplate'; + + renderTemplate(container: HTMLElement): IHelpItemTemplateData { + dom.addClass(container, 'remote-help-tree-node-item'); + + const icon = dom.append(container, dom.$('.remote-help-tree-node-item-icon')); + + const data = Object.create(null); + data.parent = container; + data.icon = icon; + + return data; + } + + renderElement(element: ITreeNode, index: number, templateData: IHelpItemTemplateData, height: number | undefined): void { + const container = templateData.parent; + dom.append(container, templateData.icon); + dom.addClass(templateData.icon, element.element.key); + const labelContainer = dom.append(container, dom.$('.help-item-label')); + labelContainer.innerText = element.element.label; + } + + disposeTemplate(templateData: IHelpItemTemplateData): void { + + } +} + +class HelpDataSource implements IAsyncDataSource { + hasChildren(element: any) { + return element instanceof HelpModel; + } + + getChildren(element: any) { + if (element instanceof HelpModel) { + return element.items; + } + + return []; + } +} + +interface IHelpItem { + key: string; + label: string; + handleClick(): Promise; +} + +class HelpItem implements IHelpItem { + constructor( + public key: string, + public label: string, + public values: { extensionDescription: IExtensionDescription; url: string }[], + private openerService: IOpenerService, + private quickInputService: IQuickInputService + ) { + } + + async handleClick() { + if (this.values.length > 1) { + let actions = this.values.map(value => { + return { + label: value.extensionDescription.displayName || value.extensionDescription.identifier.value, + description: value.url + }; + }); + + const action = await this.quickInputService.pick(actions, { placeHolder: nls.localize('pickRemoteExtension', "Select url to open") }); + + if (action) { + await this.openerService.open(URI.parse(action.label)); + } + } else { + await this.openerService.open(URI.parse(this.values[0].url)); + } + } +} + +class IssueReporterItem implements IHelpItem { + constructor( + public key: string, + public label: string, + public extensionDescriptions: IExtensionDescription[], + private quickInputService: IQuickInputService, + private commandService: ICommandService + ) { + } + + async handleClick() { + if (this.extensionDescriptions.length > 1) { + let actions = this.extensionDescriptions.map(extension => { + return { + label: extension.displayName || extension.identifier.value, + identifier: extension.identifier + }; + }); + + const action = await this.quickInputService.pick(actions, { placeHolder: nls.localize('pickRemoteExtensionToReportIssue', "Select an extension to report issue") }); + + if (action) { + await this.commandService.executeCommand('workbench.action.openIssueReporter', [action.identifier.value]); + } + } else { + await this.commandService.executeCommand('workbench.action.openIssueReporter', [this.extensionDescriptions[0].identifier.value]); + } + } +} + +class HelpModel { + items: IHelpItem[]; + + constructor( + viewModel: IViewModel, + openerService: IOpenerService, + quickInputService: IQuickInputService, + commandService: ICommandService + ) { + let helpItems: IHelpItem[] = []; + const getStarted = viewModel.helpInformations.filter(info => info.getStarted); + + if (getStarted.length) { + helpItems.push(new HelpItem( + 'getStarted', + nls.localize('remote.help.getStarted', "Get Started"), + getStarted.map((info: HelpInformation) => ({ + extensionDescription: info.extensionDescription, + url: info.getStarted! + })), + openerService, + quickInputService + )); + } + + const documentation = viewModel.helpInformations.filter(info => info.documentation); + + if (documentation.length) { + helpItems.push(new HelpItem( + 'documentation', + nls.localize('remote.help.documentation', "Read Documentation"), + documentation.map((info: HelpInformation) => ({ + extensionDescription: info.extensionDescription, + url: info.documentation! + })), + openerService, + quickInputService + )); + } + + const feedback = viewModel.helpInformations.filter(info => info.feedback); + + if (feedback.length) { + helpItems.push(new HelpItem( + 'feedback', + nls.localize('remote.help.feedback', "Provide Feedback"), + feedback.map((info: HelpInformation) => ({ + extensionDescription: info.extensionDescription, + url: info.feedback! + })), + openerService, + quickInputService + )); + } + + const issues = viewModel.helpInformations.filter(info => info.issues); + + if (issues.length) { + helpItems.push(new HelpItem( + 'issues', + nls.localize('remote.help.issues', "Review Issues"), + issues.map((info: HelpInformation) => ({ + extensionDescription: info.extensionDescription, + url: info.issues! + })), + openerService, + quickInputService + )); + } + + if (helpItems.length) { + helpItems.push(new IssueReporterItem( + 'issueReporter', + nls.localize('remote.help.report', "Report Issue"), + viewModel.helpInformations.map(info => info.extensionDescription), + quickInputService, + commandService + )); + } + + if (helpItems.length) { + this.items = helpItems; + } + } +} + +class HelpPanel extends ViewletPanel { + static readonly ID = '~remote.helpPanel'; + static readonly TITLE = nls.localize('remote.help', "Help and feedback"); + private tree!: WorkbenchAsyncDataTree; + + constructor( + protected viewModel: IViewModel, + options: IViewletPanelOptions, + @IKeybindingService protected keybindingService: IKeybindingService, + @IContextMenuService protected contextMenuService: IContextMenuService, + @IContextKeyService protected contextKeyService: IContextKeyService, + @IConfigurationService protected configurationService: IConfigurationService, + @IInstantiationService protected readonly instantiationService: IInstantiationService, + @IOpenerService protected openerService: IOpenerService, + @IQuickInputService protected quickInputService: IQuickInputService, + @ICommandService protected commandService: ICommandService + + + ) { + super(options, keybindingService, contextMenuService, configurationService, contextKeyService); + } + + protected renderBody(container: HTMLElement): void { + dom.addClass(container, 'remote-help'); + const treeContainer = document.createElement('div'); + dom.addClass(treeContainer, 'remote-help-content'); + container.appendChild(treeContainer); + + this.tree = this.instantiationService.createInstance(WorkbenchAsyncDataTree, + treeContainer, + new HelpTreeVirtualDelegate(), + [new HelpTreeRenderer()], + new HelpDataSource(), + { + keyboardSupport: true, + } + ); + + const model = new HelpModel(this.viewModel, this.openerService, this.quickInputService, this.commandService); + + this.tree.setInput(model); + + const helpItemNavigator = this._register(new TreeResourceNavigator2(this.tree, { openOnFocus: false, openOnSelection: false })); + + this._register(Event.debounce(helpItemNavigator.onDidOpenResource, (last, event) => event, 75, true)(e => { + e.element.handleClick(); + })); + } + + protected layoutBody(height: number, width: number): void { + this.tree.layout(height, width); + } +} + +class HelpPanelDescriptor implements IViewDescriptor { + readonly id = HelpPanel.ID; + readonly name = HelpPanel.TITLE; + readonly ctorDescriptor: { ctor: any, arguments?: any[] }; + readonly canToggleVisibility = true; + readonly hideByDefault = false; + readonly workspace = true; + + constructor(viewModel: IViewModel) { + this.ctorDescriptor = { ctor: HelpPanel, arguments: [viewModel] }; + } +} + + +export class RemoteViewlet extends ViewContainerViewlet implements IViewModel { + private helpPanelDescriptor = new HelpPanelDescriptor(this); + + helpInformations: HelpInformation[] = []; + + constructor( + @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, + @ITelemetryService telemetryService: ITelemetryService, + @IWorkspaceContextService contextService: IWorkspaceContextService, + @IStorageService storageService: IStorageService, + @IConfigurationService configurationService: IConfigurationService, + @IInstantiationService instantiationService: IInstantiationService, + @IThemeService themeService: IThemeService, + @IContextMenuService contextMenuService: IContextMenuService, + @IExtensionService extensionService: IExtensionService + ) { + super(VIEWLET_ID, `${VIEWLET_ID}.state`, true, configurationService, layoutService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService); + + remoteHelpExtPoint.setHandler((extensions) => { + let helpInformation: HelpInformation[] = []; + for (let extension of extensions) { + this._handleRemoteInfoExtensionPoint(extension, helpInformation); + } + + this.helpInformations = helpInformation; + + const viewsRegistry = Registry.as(Extensions.ViewsRegistry); + if (this.helpInformations.length) { + viewsRegistry.registerViews([this.helpPanelDescriptor], VIEW_CONTAINER); + } else { + viewsRegistry.deregisterViews([this.helpPanelDescriptor], VIEW_CONTAINER); + } + }); + } + + private _handleRemoteInfoExtensionPoint(extension: IExtensionPointUser, helpInformation: HelpInformation[]) { + if (!extension.value.documentation && !extension.value.feedback && !extension.value.getStarted && !extension.value.issues) { + return; + } + + helpInformation.push({ + extensionDescription: extension.description, + getStarted: extension.value.getStarted, + documentation: extension.value.documentation, + feedback: extension.value.feedback, + issues: extension.value.issues + }); + } + + onDidAddViews(added: IAddedViewDescriptorRef[]): ViewletPanel[] { + // too late, already added to the view model + return super.onDidAddViews(added); + } + + getTitle(): string { + const title = nls.localize('remote.explorer', "Remote Explorer"); + return title; + } +} + +Registry.as(ViewletExtensions.Viewlets).registerViewlet(new ViewletDescriptor( + RemoteViewlet, + VIEWLET_ID, + nls.localize('remote.explorer', "Remote Explorer"), + 'remote', + 4 +)); diff --git a/src/vs/workbench/contrib/remote/browser/remoteViewlet.css b/src/vs/workbench/contrib/remote/browser/remoteViewlet.css new file mode 100644 index 00000000000..86bd4b76dc9 --- /dev/null +++ b/src/vs/workbench/contrib/remote/browser/remoteViewlet.css @@ -0,0 +1,92 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +.monaco-workbench .activitybar>.content .monaco-action-bar .action-label.remote { + -webkit-mask: url('remote-activity-bar.svg') no-repeat 50% 50%; +} + +.remote-help-content .monaco-list .monaco-list-row .remote-help-tree-node-item { + display: flex; + height: 22px; + line-height: 22px; + flex: 1; + text-overflow: ellipsis; + overflow: hidden; + flex-wrap: nowrap; +} + +.remote-help-content .monaco-list .monaco-list-row .remote-help-tree-node-item>.remote-help-tree-node-item-icon { + background-size: 16px; + background-position: left center; + background-repeat: no-repeat; + padding-right: 6px; + width: 16px; + height: 22px; + -webkit-font-smoothing: antialiased; +} + +.remote-help-content .monaco-list .monaco-list-row .monaco-tl-twistie { + width: 0px !important; +} + +.vs .monaco-list .monaco-list-row .remote-help-tree-node-item>.remote-help-tree-node-item-icon.getStarted { + background-image: url('help-getting-started-light.svg') +} + +.vs .monaco-list .monaco-list-row .remote-help-tree-node-item>.remote-help-tree-node-item-icon.documentation { + background-image: url('help-documentation-light.svg') +} + +.vs .monaco-list .monaco-list-row .remote-help-tree-node-item>.remote-help-tree-node-item-icon.feedback { + background-image: url('help-feedback-light.svg') +} + +.vs .monaco-list .monaco-list-row .remote-help-tree-node-item>.remote-help-tree-node-item-icon.issues { + background-image: url('help-review-issues-light.svg') +} + +.vs .monaco-list .monaco-list-row .remote-help-tree-node-item>.remote-help-tree-node-item-icon.issueReporter { + background-image: url('help-report-issue-light.svg') +} + +.vs-dark .monaco-list .monaco-list-row .remote-help-tree-node-item>.remote-help-tree-node-item-icon.getStarted { + background-image: url('help-getting-started-dark.svg') +} + +.vs-dark .monaco-list .monaco-list-row .remote-help-tree-node-item>.remote-help-tree-node-item-icon.documentation { + background-image: url('help-documentation-dark.svg') +} + +.vs-dark .monaco-list .monaco-list-row .remote-help-tree-node-item>.remote-help-tree-node-item-icon.feedback { + background-image: url('help-feedback-dark.svg') +} + +.vs-dark .monaco-list .monaco-list-row .remote-help-tree-node-item>.remote-help-tree-node-item-icon.issues { + background-image: url('help-review-issues-dark.svg') +} + +.vs-dark .monaco-list .monaco-list-row .remote-help-tree-node-item>.remote-help-tree-node-item-icon.issueReporter { + background-image: url('help-report-issue-dark.svg') +} + +.hc-black .monaco-list .monaco-list-row .remote-help-tree-node-item>.remote-help-tree-node-item-icon.getStarted { + background-image: url('help-getting-started-hc.svg') +} + +.hc-black .monaco-list .monaco-list-row .remote-help-tree-node-item>.remote-help-tree-node-item-icon.documentation { + background-image: url('help-documentation-hc.svg') +} + +.hc-black .monaco-list .monaco-list-row .remote-help-tree-node-item>.remote-help-tree-node-item-icon.feedback { + background-image: url('help-feedback-hc.svg') +} + +.hc-black .monaco-list .monaco-list-row .remote-help-tree-node-item>.remote-help-tree-node-item-icon.issues { + background-image: url('help-review-issues-hc.svg') +} + +.hc-black .monaco-list .monaco-list-row .remote-help-tree-node-item>.remote-help-tree-node-item-icon.issueReporter { + background-image: url('help-report-issue-hc.svg') +} diff --git a/src/vs/workbench/contrib/remote/common/remote.contribution.ts b/src/vs/workbench/contrib/remote/common/remote.contribution.ts index 9235c739fb0..832193a8c22 100644 --- a/src/vs/workbench/contrib/remote/common/remote.contribution.ts +++ b/src/vs/workbench/contrib/remote/common/remote.contribution.ts @@ -17,6 +17,34 @@ import { IOutputChannelRegistry, Extensions as OutputExt, } from 'vs/workbench/c import { localize } from 'vs/nls'; import { joinPath } from 'vs/base/common/resources'; import { Disposable } from 'vs/base/common/lifecycle'; +import { ViewContainer, IViewContainersRegistry, Extensions as ViewContainerExtensions } from 'vs/workbench/common/views'; + +export const VIEWLET_ID = 'workbench.view.remote'; +export const VIEW_CONTAINER: ViewContainer = Registry.as(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer( + VIEWLET_ID, + true, + undefined, + { + getOrder: (group?: string) => { + if (!group) { + return; + } + + let matches = /^targets@(\d+)$/.exec(group); + if (matches) { + return -1000; + } + + matches = /^details@(\d+)$/.exec(group); + + if (matches) { + return -500; + } + + return; + } + } +); export class LabelContribution implements IWorkbenchContribution { constructor( diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index 3558c2ffef3..e54be8a3da6 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -194,6 +194,7 @@ import 'vs/workbench/contrib/tasks/browser/task.contribution'; // Remote import 'vs/workbench/contrib/remote/common/remote.contribution'; +import 'vs/workbench/contrib/remote/browser/remote'; // Emmet import 'vs/workbench/contrib/emmet/browser/emmet.contribution'; From 9649fa56d9eaa6f682c691bf03a47634097099ec Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 14 Aug 2019 17:48:37 -0700 Subject: [PATCH 622/861] Use undefined instead of null in IEditorOpeningEvent and IOpenEditorOverride --- .../workbench/browser/parts/editor/editor.ts | 2 +- .../browser/debugConfigurationManager.ts | 3 +- .../contrib/files/browser/fileActions.ts | 2 +- .../preferences/browser/preferencesActions.ts | 2 +- .../preferences/browser/settingsEditor2.ts | 4 +-- .../contrib/search/browser/searchView.ts | 2 +- .../services/editor/common/editorService.ts | 4 +-- .../preferences/browser/preferencesService.ts | 35 ++++++++++--------- .../preferences/common/preferences.ts | 10 +++--- 9 files changed, 33 insertions(+), 31 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editor.ts b/src/vs/workbench/browser/parts/editor/editor.ts index 5a56c61b3f0..634812bfa84 100644 --- a/src/vs/workbench/browser/parts/editor/editor.ts +++ b/src/vs/workbench/browser/parts/editor/editor.ts @@ -74,7 +74,7 @@ export interface IEditorOpeningEvent extends IEditorIdentifier { * Allows to prevent the opening of an editor by providing a callback * that will be executed instead. By returning another editor promise * it is possible to override the opening with another editor. It is ok - * to return a promise that resolves to NULL to prevent the opening + * to return a promise that resolves to `undefined` to prevent the opening * alltogether. */ prevent(callback: () => undefined | Promise): void; diff --git a/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts b/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts index 637086088b3..6682ac405d7 100644 --- a/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts +++ b/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts @@ -35,6 +35,7 @@ import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/c import { onUnexpectedError } from 'vs/base/common/errors'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { CancellationToken } from 'vs/base/common/cancellation'; +import { withUndefinedAsNull } from 'vs/base/common/types'; const jsonRegistry = Registry.as(JSONExtensions.JSONContribution); jsonRegistry.registerSchema(launchSchemaId, launchSchema); @@ -647,6 +648,6 @@ class UserLaunch extends AbstractLaunch implements ILaunch { } openConfigFile(sideBySide: boolean, preserveFocus: boolean, type?: string): Promise<{ editor: IEditor | null, created: boolean }> { - return this.preferencesService.openGlobalSettings(false, { preserveFocus }).then(editor => ({ editor, created: false })); + return this.preferencesService.openGlobalSettings(false, { preserveFocus }).then(editor => ({ editor: withUndefinedAsNull(editor), created: false })); } } diff --git a/src/vs/workbench/contrib/files/browser/fileActions.ts b/src/vs/workbench/contrib/files/browser/fileActions.ts index 9d87a9c16b1..e204c90c0bc 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.ts @@ -471,7 +471,7 @@ export class GlobalCompareResourcesAction extends Action { override: this.editorService.openEditor({ leftResource: activeResource, rightResource: resource - }).then(() => null) + }).then(() => undefined) }; } diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesActions.ts b/src/vs/workbench/contrib/preferences/browser/preferencesActions.ts index 34d9362a283..b93c9b2fd62 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesActions.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesActions.ts @@ -225,7 +225,7 @@ export class OpenFolderSettingsAction extends Action { return this.preferencesService.openFolderSettings(workspaceFolder.uri); } - return null; + return undefined; }); } diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts index 986cef51818..1382fd0df38 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts @@ -458,12 +458,12 @@ export class SettingsEditor2 extends BaseEditor { } } - switchToSettingsFile(): Promise { + switchToSettingsFile(): Promise { const query = parseQuery(this.searchWidget.getValue()); return this.openSettingsFile(query.query); } - private openSettingsFile(query?: string): Promise { + private openSettingsFile(query?: string): Promise { const currentSettingsTarget = this.settingsTargetsWidget.settingsTarget; const options: ISettingsEditorOptions = { query }; diff --git a/src/vs/workbench/contrib/search/browser/searchView.ts b/src/vs/workbench/contrib/search/browser/searchView.ts index 2daad95ca68..1683a0325d1 100644 --- a/src/vs/workbench/contrib/search/browser/searchView.ts +++ b/src/vs/workbench/contrib/search/browser/searchView.ts @@ -1455,7 +1455,7 @@ export class SearchView extends ViewletPanel { this.openSettings('.exclude'); } - private openSettings(query: string): Promise { + private openSettings(query: string): Promise { const options: ISettingsEditorOptions = { query }; return this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? this.preferencesService.openWorkspaceSettings(undefined, options) : diff --git a/src/vs/workbench/services/editor/common/editorService.ts b/src/vs/workbench/services/editor/common/editorService.ts index ab79c65ff48..be82e683eca 100644 --- a/src/vs/workbench/services/editor/common/editorService.ts +++ b/src/vs/workbench/services/editor/common/editorService.ts @@ -36,7 +36,7 @@ export interface IOpenEditorOverride { * If defined, will prevent the opening of an editor and replace the resulting * promise with the provided promise for the openEditor() call. */ - override?: Promise; + override?: Promise; } export interface IVisibleEditor extends IEditor { @@ -185,4 +185,4 @@ export interface IEditorService { * Converts a lightweight input to a workbench editor input. */ createInput(input: IResourceEditor): IEditorInput | null; -} \ No newline at end of file +} diff --git a/src/vs/workbench/services/preferences/browser/preferencesService.ts b/src/vs/workbench/services/preferences/browser/preferencesService.ts index 8788a416741..4ef77c8b683 100644 --- a/src/vs/workbench/services/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/services/preferences/browser/preferencesService.ts @@ -38,6 +38,7 @@ import { defaultKeybindingsContents, DefaultKeybindingsEditorModel, DefaultSetti import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; +import { withNullAsUndefined } from 'vs/base/common/types'; const emptyEditableSettingsContent = '{\n}'; @@ -196,7 +197,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic return this.editorService.openEditor({ resource: this.userSettingsResource }); } - openSettings(jsonEditor: boolean | undefined, query: string | undefined): Promise { + openSettings(jsonEditor: boolean | undefined, query: string | undefined): Promise { jsonEditor = typeof jsonEditor === 'undefined' ? this.configurationService.getValue('workbench.settings.editor') === 'json' : jsonEditor; @@ -217,7 +218,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic .then(() => this.editorGroupService.activeGroup.activeControl!); } - openGlobalSettings(jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { + openGlobalSettings(jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { jsonEditor = typeof jsonEditor === 'undefined' ? this.configurationService.getValue('workbench.settings.editor') === 'json' : jsonEditor; @@ -227,16 +228,16 @@ export class PreferencesService extends Disposable implements IPreferencesServic this.openOrSwitchSettings2(ConfigurationTarget.USER_LOCAL, undefined, options, group); } - async openRemoteSettings(): Promise { + async openRemoteSettings(): Promise { const environment = await this.remoteAgentService.getEnvironment(); if (environment) { await this.createIfNotExists(environment.settingsPath, emptyEditableSettingsContent); - return this.editorService.openEditor({ resource: environment.settingsPath, options: { pinned: true, revealIfOpened: true } }); + return this.editorService.openEditor({ resource: environment.settingsPath, options: { pinned: true, revealIfOpened: true } }).then(withNullAsUndefined); } - return null; + return undefined; } - openWorkspaceSettings(jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { + openWorkspaceSettings(jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { jsonEditor = typeof jsonEditor === 'undefined' ? this.configurationService.getValue('workbench.settings.editor') === 'json' : jsonEditor; @@ -251,7 +252,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic this.openOrSwitchSettings2(ConfigurationTarget.WORKSPACE, undefined, options, group); } - async openFolderSettings(folder: URI, jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { + async openFolderSettings(folder: URI, jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { jsonEditor = typeof jsonEditor === 'undefined' ? this.configurationService.getValue('workbench.settings.editor') === 'json' : jsonEditor; @@ -328,7 +329,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic })); } - private openOrSwitchSettings(configurationTarget: ConfigurationTarget, resource: URI, options?: ISettingsEditorOptions, group: IEditorGroup = this.editorGroupService.activeGroup): Promise { + private openOrSwitchSettings(configurationTarget: ConfigurationTarget, resource: URI, options?: ISettingsEditorOptions, group: IEditorGroup = this.editorGroupService.activeGroup): Promise { const editorInput = this.getActiveSettingsEditorInput(group); if (editorInput) { const editorInputResource = editorInput.master.getResource(); @@ -339,11 +340,11 @@ export class PreferencesService extends Disposable implements IPreferencesServic return this.doOpenSettings(configurationTarget, resource, options, group); } - private openOrSwitchSettings2(configurationTarget: ConfigurationTarget, folderUri?: URI, options?: ISettingsEditorOptions, group: IEditorGroup = this.editorGroupService.activeGroup): Promise { + private openOrSwitchSettings2(configurationTarget: ConfigurationTarget, folderUri?: URI, options?: ISettingsEditorOptions, group: IEditorGroup = this.editorGroupService.activeGroup): Promise { return this.doOpenSettings2(configurationTarget, folderUri, options, group); } - private doOpenSettings(configurationTarget: ConfigurationTarget, resource: URI, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { + private doOpenSettings(configurationTarget: ConfigurationTarget, resource: URI, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { const openSplitJSON = !!this.configurationService.getValue(USE_SPLIT_JSON_SETTING); if (openSplitJSON) { return this.doOpenSplitJSON(configurationTarget, resource, options, group); @@ -365,14 +366,14 @@ export class PreferencesService extends Disposable implements IPreferencesServic return Promise.all([ this.editorService.openEditor({ resource: this.defaultSettingsRawResource, options: { pinned: true, preserveFocus: true, revealIfOpened: true }, label: nls.localize('defaultSettings', "Default Settings"), description: '' }), this.editorService.openEditor(editableSettingsEditorInput, { pinned: true, revealIfOpened: true }, sideEditorGroup.id) - ]).then(([defaultEditor, editor]) => editor); + ]).then(([defaultEditor, editor]) => withNullAsUndefined(editor)); } else { - return this.editorService.openEditor(editableSettingsEditorInput, SettingsEditorOptions.create(options), group); + return this.editorService.openEditor(editableSettingsEditorInput, SettingsEditorOptions.create(options), group).then(withNullAsUndefined); } }); } - private doOpenSplitJSON(configurationTarget: ConfigurationTarget, resource: URI, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { + private doOpenSplitJSON(configurationTarget: ConfigurationTarget, resource: URI, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { return this.getOrCreateEditableSettingsEditorInput(configurationTarget, resource) .then(editableSettingsEditorInput => { if (!options) { @@ -384,7 +385,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic const defaultPreferencesEditorInput = this.instantiationService.createInstance(DefaultPreferencesEditorInput, this.getDefaultSettingsResource(configurationTarget)); const preferencesEditorInput = new PreferencesEditorInput(this.getPreferencesEditorInputName(configurationTarget, resource), editableSettingsEditorInput.getDescription(), defaultPreferencesEditorInput, editableSettingsEditorInput); this.lastOpenedSettingsInput = preferencesEditorInput; - return this.editorService.openEditor(preferencesEditorInput, SettingsEditorOptions.create(options), group); + return this.editorService.openEditor(preferencesEditorInput, SettingsEditorOptions.create(options), group).then(withNullAsUndefined); }); } @@ -392,7 +393,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic return this.instantiationService.createInstance(Settings2EditorModel, this.getDefaultSettings(ConfigurationTarget.USER_LOCAL)); } - private doOpenSettings2(target: ConfigurationTarget, folderUri: URI | undefined, options?: IEditorOptions, group?: IEditorGroup): Promise { + private doOpenSettings2(target: ConfigurationTarget, folderUri: URI | undefined, options?: IEditorOptions, group?: IEditorGroup): Promise { const input = this.settingsEditor2Input; const settingsOptions: ISettingsEditorOptions = { ...options, @@ -400,7 +401,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic folderUri }; - return this.editorService.openEditor(input, SettingsEditorOptions.create(settingsOptions), group); + return this.editorService.openEditor(input, SettingsEditorOptions.create(settingsOptions), group).then(withNullAsUndefined); } private async doSwitchSettings(target: ConfigurationTarget, resource: URI, input: PreferencesEditorInput, group: IEditorGroup, options?: ISettingsEditorOptions): Promise { @@ -633,4 +634,4 @@ export class PreferencesService extends Disposable implements IPreferencesServic } } -registerSingleton(IPreferencesService, PreferencesService); \ No newline at end of file +registerSingleton(IPreferencesService, PreferencesService); diff --git a/src/vs/workbench/services/preferences/common/preferences.ts b/src/vs/workbench/services/preferences/common/preferences.ts index abf288178cc..e3ffd3edf17 100644 --- a/src/vs/workbench/services/preferences/common/preferences.ts +++ b/src/vs/workbench/services/preferences/common/preferences.ts @@ -202,11 +202,11 @@ export interface IPreferencesService { createSettings2EditorModel(): Settings2EditorModel; // TODO openRawDefaultSettings(): Promise; - openSettings(jsonEditor: boolean | undefined, query: string | undefined): Promise; - openGlobalSettings(jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise; - openRemoteSettings(): Promise; - openWorkspaceSettings(jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise; - openFolderSettings(folder: URI, jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise; + openSettings(jsonEditor: boolean | undefined, query: string | undefined): Promise; + openGlobalSettings(jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise; + openRemoteSettings(): Promise; + openWorkspaceSettings(jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise; + openFolderSettings(folder: URI, jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise; switchSettings(target: ConfigurationTarget, resource: URI, jsonEditor?: boolean): Promise; openGlobalKeybindingSettings(textual: boolean): Promise; openDefaultKeybindingsFile(): Promise; From d145b27f0511a0721f9ec6f60ec8f152b64f197a Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 14 Aug 2019 18:00:03 -0700 Subject: [PATCH 623/861] Change openEditor to return undefined instead of null For #70020 --- .../contrib/debug/browser/breakpointsView.ts | 4 ++-- .../debug/browser/debugConfigurationManager.ts | 4 ++-- .../contrib/debug/common/debugSource.ts | 3 ++- .../contrib/files/browser/explorerViewlet.ts | 5 +++-- .../browser/keyboardLayoutPicker.ts | 4 ++-- .../services/editor/browser/editorService.ts | 18 +++++++++--------- .../services/editor/common/editorService.ts | 10 +++++----- .../services/history/browser/history.ts | 2 +- .../preferences/browser/preferencesService.ts | 14 +++++++------- .../services/preferences/common/preferences.ts | 4 ++-- 10 files changed, 35 insertions(+), 33 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts index 72de87a6f1c..4c8f5b36ee8 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts @@ -543,9 +543,9 @@ class FunctionBreakpointInputRenderer implements IListRenderer { +export function openBreakpointSource(breakpoint: IBreakpoint, sideBySide: boolean, preserveFocus: boolean, debugService: IDebugService, editorService: IEditorService): Promise { if (breakpoint.uri.scheme === DEBUG_SCHEME && debugService.state === State.Inactive) { - return Promise.resolve(null); + return Promise.resolve(undefined); } const selection = breakpoint.endLineNumber ? { diff --git a/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts b/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts index 6682ac405d7..3e71419c14a 100644 --- a/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts +++ b/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts @@ -578,7 +578,7 @@ class Launch extends AbstractLaunch implements ILaunch { pinned: created, revealIfVisible: true }, - }, sideBySide ? SIDE_GROUP : ACTIVE_GROUP).then(editor => ({ editor, created }))); + }, sideBySide ? SIDE_GROUP : ACTIVE_GROUP).then(editor => ({ editor: withUndefinedAsNull(editor), created }))); }, (error: Error) => { throw new Error(nls.localize('DebugConfig.failed', "Unable to create 'launch.json' file inside the '.vscode' folder ({0}).", error.message)); }); @@ -614,7 +614,7 @@ class WorkspaceLaunch extends AbstractLaunch implements ILaunch { return this.editorService.openEditor({ resource: this.contextService.getWorkspace().configuration!, options: { preserveFocus } - }, sideBySide ? SIDE_GROUP : ACTIVE_GROUP).then(editor => ({ editor, created: false })); + }, sideBySide ? SIDE_GROUP : ACTIVE_GROUP).then(editor => ({ editor: withUndefinedAsNull(editor), created: false })); } } diff --git a/src/vs/workbench/contrib/debug/common/debugSource.ts b/src/vs/workbench/contrib/debug/common/debugSource.ts index 133e3f8bec8..fa0376d936e 100644 --- a/src/vs/workbench/contrib/debug/common/debugSource.ts +++ b/src/vs/workbench/contrib/debug/common/debugSource.ts @@ -13,6 +13,7 @@ import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/ import { Schemas } from 'vs/base/common/network'; import { isUri } from 'vs/workbench/contrib/debug/common/debugUtils'; import { ITextEditor } from 'vs/workbench/common/editor'; +import { withUndefinedAsNull } from 'vs/base/common/types'; export const UNKNOWN_SOURCE_LABEL = nls.localize('unknownSource', "Unknown Source"); @@ -104,7 +105,7 @@ export class Source { revealInCenterIfOutsideViewport: true, pinned: pinned || (!preserveFocus && !this.inMemory) } - }, sideBySide ? SIDE_GROUP : ACTIVE_GROUP); + }, sideBySide ? SIDE_GROUP : ACTIVE_GROUP).then(withUndefinedAsNull); } static getEncodedDebugData(modelUri: uri): { name: string, path: string, sessionId?: string, sourceReference?: number } { diff --git a/src/vs/workbench/contrib/files/browser/explorerViewlet.ts b/src/vs/workbench/contrib/files/browser/explorerViewlet.ts index c3e3a622b58..c9713c80989 100644 --- a/src/vs/workbench/contrib/files/browser/explorerViewlet.ts +++ b/src/vs/workbench/contrib/files/browser/explorerViewlet.ts @@ -34,6 +34,7 @@ import { ViewletPanel } from 'vs/workbench/browser/parts/views/panelViewlet'; import { KeyChord, KeyMod, KeyCode } from 'vs/base/common/keyCodes'; import { Registry } from 'vs/platform/registry/common/platform'; import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress'; +import { withUndefinedAsNull } from 'vs/base/common/types'; export class ExplorerViewletViewsContribution extends Disposable implements IWorkbenchContribution { @@ -202,7 +203,7 @@ export class ExplorerViewlet extends ViewContainerViewlet { openEditorsView.setStructuralRefreshDelay(delay); } - let openedEditor: IEditor | null = null; + let openedEditor: IEditor | undefined; try { openedEditor = await this.editorService.openEditor(editor, options, group); } catch (error) { @@ -214,7 +215,7 @@ export class ExplorerViewlet extends ViewContainerViewlet { } } - return openedEditor; + return withUndefinedAsNull(openedEditor); }); const explorerInstantiator = this.instantiationService.createChild(new ServiceCollection([IEditorService, delegatingEditorService])); diff --git a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts index 35a40b06fea..7180550bc65 100644 --- a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts +++ b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts @@ -158,9 +158,9 @@ export class KeyboardLayoutPickerAction extends Action { await this.fileService.resolve(file).then(undefined, (error) => { return this.fileService.createFile(file, VSBuffer.fromString(KeyboardLayoutPickerAction.DEFAULT_CONTENT)); - }).then((stat): Promise | null => { + }).then((stat): Promise | undefined => { if (!stat) { - return null; + return undefined; } return this.editorService.openEditor({ resource: stat.resource, diff --git a/src/vs/workbench/services/editor/browser/editorService.ts b/src/vs/workbench/services/editor/browser/editorService.ts index 3bd6b03f963..bf36c64c500 100644 --- a/src/vs/workbench/services/editor/browser/editorService.ts +++ b/src/vs/workbench/services/editor/browser/editorService.ts @@ -216,11 +216,11 @@ export class EditorService extends Disposable implements EditorServiceImpl { //#region openEditor() - openEditor(editor: IEditorInput, options?: IEditorOptions | ITextEditorOptions, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; - openEditor(editor: IResourceInput | IUntitledResourceInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; - openEditor(editor: IResourceDiffInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; - openEditor(editor: IResourceSideBySideInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; - openEditor(editor: IEditorInput | IResourceEditor, optionsOrGroup?: IEditorOptions | ITextEditorOptions | IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE, group?: GroupIdentifier): Promise { + openEditor(editor: IEditorInput, options?: IEditorOptions | ITextEditorOptions, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; + openEditor(editor: IResourceInput | IUntitledResourceInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; + openEditor(editor: IResourceDiffInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; + openEditor(editor: IResourceSideBySideInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; + openEditor(editor: IEditorInput | IResourceEditor, optionsOrGroup?: IEditorOptions | ITextEditorOptions | IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE, group?: GroupIdentifier): Promise { // Typed Editor Support if (editor instanceof EditorInput) { @@ -240,11 +240,11 @@ export class EditorService extends Disposable implements EditorServiceImpl { return this.doOpenEditor(targetGroup, typedInput, editorOptions); } - return Promise.resolve(null); + return Promise.resolve(undefined); } - protected doOpenEditor(group: IEditorGroup, editor: IEditorInput, options?: IEditorOptions): Promise { - return group.openEditor(editor, options); + protected doOpenEditor(group: IEditorGroup, editor: IEditorInput, options?: IEditorOptions): Promise { + return group.openEditor(editor, options).then(withNullAsUndefined); } private findTargetGroup(input: IEditorInput, options?: IEditorOptions, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): IEditorGroup { @@ -651,7 +651,7 @@ export class DelegatingEditorService extends EditorService { this.editorOpenHandler = handler; } - protected async doOpenEditor(group: IEditorGroup, editor: IEditorInput, options?: IEditorOptions): Promise { + protected async doOpenEditor(group: IEditorGroup, editor: IEditorInput, options?: IEditorOptions): Promise { if (!this.editorOpenHandler) { return super.doOpenEditor(group, editor, options); } diff --git a/src/vs/workbench/services/editor/common/editorService.ts b/src/vs/workbench/services/editor/common/editorService.ts index be82e683eca..5664c9c8c45 100644 --- a/src/vs/workbench/services/editor/common/editorService.ts +++ b/src/vs/workbench/services/editor/common/editorService.ts @@ -117,13 +117,13 @@ export interface IEditorService { * active group. Use `SIDE_GROUP_TYPE` to open the editor in a new editor group to the side * of the currently active group. * - * @returns the editor that opened or NULL if the operation failed or the editor was not + * @returns the editor that opened or `undefined` if the operation failed or the editor was not * opened to be active. */ - openEditor(editor: IEditorInput, options?: IEditorOptions | ITextEditorOptions, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; - openEditor(editor: IResourceInput | IUntitledResourceInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; - openEditor(editor: IResourceDiffInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; - openEditor(editor: IResourceSideBySideInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; + openEditor(editor: IEditorInput, options?: IEditorOptions | ITextEditorOptions, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; + openEditor(editor: IResourceInput | IUntitledResourceInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; + openEditor(editor: IResourceDiffInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; + openEditor(editor: IResourceSideBySideInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; /** * Open editors in an editor group. diff --git a/src/vs/workbench/services/history/browser/history.ts b/src/vs/workbench/services/history/browser/history.ts index 9ae41e07977..23ad652c71c 100644 --- a/src/vs/workbench/services/history/browser/history.ts +++ b/src/vs/workbench/services/history/browser/history.ts @@ -453,7 +453,7 @@ export class HistoryService extends Disposable implements IHistoryService { this.doNavigate(this.stack[this.index], !acrossEditors).finally(() => this.navigatingInStack = false); } - private doNavigate(location: IStackEntry, withSelection: boolean): Promise { + private doNavigate(location: IStackEntry, withSelection: boolean): Promise { const options: ITextEditorOptions = { revealIfOpened: true // support to navigate across editor groups }; diff --git a/src/vs/workbench/services/preferences/browser/preferencesService.ts b/src/vs/workbench/services/preferences/browser/preferencesService.ts index 4ef77c8b683..1e579f2968b 100644 --- a/src/vs/workbench/services/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/services/preferences/browser/preferencesService.ts @@ -189,11 +189,11 @@ export class PreferencesService extends Disposable implements IPreferencesServic return null; } - openRawDefaultSettings(): Promise { + openRawDefaultSettings(): Promise { return this.editorService.openEditor({ resource: this.defaultSettingsRawResource }); } - openRawUserSettings(): Promise { + openRawUserSettings(): Promise { return this.editorService.openEditor({ resource: this.userSettingsResource }); } @@ -232,7 +232,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic const environment = await this.remoteAgentService.getEnvironment(); if (environment) { await this.createIfNotExists(environment.settingsPath, emptyEditableSettingsContent); - return this.editorService.openEditor({ resource: environment.settingsPath, options: { pinned: true, revealIfOpened: true } }).then(withNullAsUndefined); + return this.editorService.openEditor({ resource: environment.settingsPath, options: { pinned: true, revealIfOpened: true } }); } return undefined; } @@ -307,7 +307,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic return this.editorService.openEditor(this.instantiationService.createInstance(KeybindingsEditorInput), { pinned: true, revealIfOpened: true }).then(() => undefined); } - openDefaultKeybindingsFile(): Promise { + openDefaultKeybindingsFile(): Promise { return this.editorService.openEditor({ resource: this.defaultKeybindingsResource, label: nls.localize('defaultKeybindings', "Default Keybindings") }); } @@ -368,7 +368,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic this.editorService.openEditor(editableSettingsEditorInput, { pinned: true, revealIfOpened: true }, sideEditorGroup.id) ]).then(([defaultEditor, editor]) => withNullAsUndefined(editor)); } else { - return this.editorService.openEditor(editableSettingsEditorInput, SettingsEditorOptions.create(options), group).then(withNullAsUndefined); + return this.editorService.openEditor(editableSettingsEditorInput, SettingsEditorOptions.create(options), group); } }); } @@ -385,7 +385,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic const defaultPreferencesEditorInput = this.instantiationService.createInstance(DefaultPreferencesEditorInput, this.getDefaultSettingsResource(configurationTarget)); const preferencesEditorInput = new PreferencesEditorInput(this.getPreferencesEditorInputName(configurationTarget, resource), editableSettingsEditorInput.getDescription(), defaultPreferencesEditorInput, editableSettingsEditorInput); this.lastOpenedSettingsInput = preferencesEditorInput; - return this.editorService.openEditor(preferencesEditorInput, SettingsEditorOptions.create(options), group).then(withNullAsUndefined); + return this.editorService.openEditor(preferencesEditorInput, SettingsEditorOptions.create(options), group); }); } @@ -401,7 +401,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic folderUri }; - return this.editorService.openEditor(input, SettingsEditorOptions.create(settingsOptions), group).then(withNullAsUndefined); + return this.editorService.openEditor(input, SettingsEditorOptions.create(settingsOptions), group); } private async doSwitchSettings(target: ConfigurationTarget, resource: URI, input: PreferencesEditorInput, group: IEditorGroup, options?: ISettingsEditorOptions): Promise { diff --git a/src/vs/workbench/services/preferences/common/preferences.ts b/src/vs/workbench/services/preferences/common/preferences.ts index e3ffd3edf17..195631aa108 100644 --- a/src/vs/workbench/services/preferences/common/preferences.ts +++ b/src/vs/workbench/services/preferences/common/preferences.ts @@ -201,7 +201,7 @@ export interface IPreferencesService { createPreferencesEditorModel(uri: URI): Promise | null>; createSettings2EditorModel(): Settings2EditorModel; // TODO - openRawDefaultSettings(): Promise; + openRawDefaultSettings(): Promise; openSettings(jsonEditor: boolean | undefined, query: string | undefined): Promise; openGlobalSettings(jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise; openRemoteSettings(): Promise; @@ -209,7 +209,7 @@ export interface IPreferencesService { openFolderSettings(folder: URI, jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise; switchSettings(target: ConfigurationTarget, resource: URI, jsonEditor?: boolean): Promise; openGlobalKeybindingSettings(textual: boolean): Promise; - openDefaultKeybindingsFile(): Promise; + openDefaultKeybindingsFile(): Promise; configureSettingsForLanguage(language: string | null): void; } From df96e402b2c1bcd7a9cc22f647a1c33f9a906677 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 14 Aug 2019 18:06:01 -0700 Subject: [PATCH 624/861] Improve jsdoc section of walkthrough Fixes #71023 As discussed in #75033 --- .../walkThrough/browser/editor/vs_code_editor_walkthrough.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/welcome/walkThrough/browser/editor/vs_code_editor_walkthrough.md b/src/vs/workbench/contrib/welcome/walkThrough/browser/editor/vs_code_editor_walkthrough.md index 43e8bc83a89..ffd95c89718 100644 --- a/src/vs/workbench/contrib/welcome/walkThrough/browser/editor/vs_code_editor_walkthrough.md +++ b/src/vs/workbench/contrib/welcome/walkThrough/browser/editor/vs_code_editor_walkthrough.md @@ -77,6 +77,9 @@ new Book("The Martian", "Andy Weir"); /** * Represents a book. + * + * @param {string} title Title of the book + * @param {string} author Who wrote the book */ function Book(title, author) { this.title = title; @@ -84,7 +87,7 @@ function Book(title, author) { } ``` -> **JSDoc Tip:** The example above also showcased another way to get IntelliSense hints by using `JSDoc` comments. You can try this out by invoking the `Book` function and seeing the enhanced context in the IntelliSense menu for the function as well as parameters. +> **JSDoc Tip:** VS Code's IntelliSense uses JSDoc comments to provide richer suggestions. The types and documentation from JSDoc comments show up when you hover over a reference to `Book` or in IntelliSense when you create a new instance of `Book`. ### Refactoring via Extraction From 44a48f75d64333b8e33a1fe4f57f6a60553b1e6b Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Thu, 15 Aug 2019 06:38:47 +0200 Subject: [PATCH 625/861] Add installer assets for OSS (#79045) --- build/win32/code.iss | 4 ++-- resources/win32/inno-big-100.bmp | Bin 0 -> 154544 bytes .../win32/{inno-big.bmp => inno-big-125.bmp} | Bin 206038 -> 222392 bytes resources/win32/inno-big-150.bmp | Bin 0 -> 339716 bytes resources/win32/inno-big-175.bmp | Bin 0 -> 455976 bytes resources/win32/inno-big-200.bmp | Bin 0 -> 594392 bytes resources/win32/inno-big-225.bmp | Bin 0 -> 747656 bytes resources/win32/inno-big-250.bmp | Bin 0 -> 1307136 bytes resources/win32/inno-small-100.bmp | Bin 0 -> 9296 bytes resources/win32/inno-small-125.bmp | Bin 0 -> 13112 bytes resources/win32/inno-small-150.bmp | Bin 0 -> 20216 bytes resources/win32/inno-small-175.bmp | Bin 0 -> 26828 bytes resources/win32/inno-small-200.bmp | Bin 0 -> 35248 bytes resources/win32/inno-small-225.bmp | Bin 0 -> 44336 bytes resources/win32/inno-small-250.bmp | Bin 0 -> 58296 bytes resources/win32/inno-small.bmp | Bin 12814 -> 0 bytes 16 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 resources/win32/inno-big-100.bmp rename resources/win32/{inno-big.bmp => inno-big-125.bmp} (67%) mode change 100644 => 100755 create mode 100755 resources/win32/inno-big-150.bmp create mode 100755 resources/win32/inno-big-175.bmp create mode 100755 resources/win32/inno-big-200.bmp create mode 100755 resources/win32/inno-big-225.bmp create mode 100644 resources/win32/inno-big-250.bmp create mode 100755 resources/win32/inno-small-100.bmp create mode 100755 resources/win32/inno-small-125.bmp create mode 100755 resources/win32/inno-small-150.bmp create mode 100755 resources/win32/inno-small-175.bmp create mode 100755 resources/win32/inno-small-200.bmp create mode 100755 resources/win32/inno-small-225.bmp create mode 100755 resources/win32/inno-small-250.bmp delete mode 100644 resources/win32/inno-small.bmp diff --git a/build/win32/code.iss b/build/win32/code.iss index 831b31a3c71..ee70efb974d 100644 --- a/build/win32/code.iss +++ b/build/win32/code.iss @@ -19,8 +19,8 @@ Compression=lzma SolidCompression=yes AppMutex={code:GetAppMutex} SetupMutex={#AppMutex}setup -WizardImageFile={#RepoDir}\resources\win32\inno-big.bmp -WizardSmallImageFile={#RepoDir}\resources\win32\inno-small.bmp +WizardImageFile="{#RepoDir}\resources\win32\inno-big-100.bmp,{#RepoDir}\resources\win32\inno-big-125.bmp,{#RepoDir}\resources\win32\inno-big-150.bmp,{#RepoDir}\resources\win32\inno-big-175.bmp,{#RepoDir}\resources\win32\inno-big-200.bmp,{#RepoDir}\resources\win32\inno-big-225.bmp,{#RepoDir}\resources\win32\inno-big-250.bmp" +WizardSmallImageFile="{#RepoDir}\resources\win32\inno-small-100.bmp,{#RepoDir}\resources\win32\inno-small-125.bmp,{#RepoDir}\resources\win32\inno-small-150.bmp,{#RepoDir}\resources\win32\inno-small-175.bmp,{#RepoDir}\resources\win32\inno-small-200.bmp,{#RepoDir}\resources\win32\inno-small-225.bmp,{#RepoDir}\resources\win32\inno-small-250.bmp" SetupIconFile={#RepoDir}\resources\win32\code.ico UninstallDisplayIcon={app}\{#ExeBasename}.exe ChangesEnvironment=true diff --git a/resources/win32/inno-big-100.bmp b/resources/win32/inno-big-100.bmp new file mode 100644 index 0000000000000000000000000000000000000000..99cf4ba66683ae1ade11909259216a5e59177c36 GIT binary patch literal 154544 zcmeI*v8p817RTWpAHYz21fRgbK+ssh+&7uG5F;@)G%zwSF%T1l(L~IQ1qICv40JmU zO+nXLQ>XU7Rypv=nM+f-qWnuRn_q z-t!qw+@&~s+fv){wQg(r&_-JK2t4H9dA;YPV;9eLXV%rdwC)jD#c#gYb5hTBbJo@E zwC)jD#c#gYb5hTBbJo@EwC)jD#c#gYb5hTBbJo@EwC)jD#c#gYbJEG@`qv*n|LvzQ zn}5cpL7e8StJ?*SQ;(YY-%{#(SI;$naco+j=uxZlpJ#r;qdxG=o9kZns@ISgP+`Ej52p>pDuYTK6h$)O!AVd!0}t2UoRDCEGnGShF6b_3lQg8|y&9 z)tT16|NPY-zkJ*LGd2w#Kh1<9GUhzWeCyS~6R0-?aJ@23OnunQNcJ+1As@9QSGed$k>rq-qL}E=2sRIR9+geY8?7MxOuD04YHhWk734^OzXT$B77OYv1(t1ao z>@9Vm;HuWya66_2Yu2N*-ccueOC2b@x}e8I_QelCsw|0eNfr^v07^#|H_?0>hIypr`vOV%9n7t=`zQmueDyX zpYr<9zRTfSpVD`^=`zQmuiIMp|ANY~qu)`v{PMK5UT*sTdA)qT&U)RZq4imbZ~JQ9 zBX9#h@kP%`$1a}h6Dwc0*1AXF^w8r2^qkalt@TZy?JIZIMz@om_@eFX{`>mG%Ga&6 z?h!aW^!NZhCmp-YJlFm|kt1J~m!ft3J&8En4;h;Vaqj2$UkM(k9#!|6x%VJ6t?MYo zs@4a6C%2C+>SUL+-X7(kcV>eY)3iRQ;P$aao$Qj<+oK%x&TPx5MLForZRgecpn}`SYTYBSy~uIz>^bS!#dCdJ z#Ep}+?h)9S5!jf++XxUKK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF m5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAh1#3a`_i*_`;w7 literal 0 HcmV?d00001 diff --git a/resources/win32/inno-big.bmp b/resources/win32/inno-big-125.bmp old mode 100644 new mode 100755 similarity index 67% rename from resources/win32/inno-big.bmp rename to resources/win32/inno-big-125.bmp index d9aa14eb708990ac1ddb11e04681ec40d1ba3533..d781943ada50c442e7e3b731e036b3e5e2e1c9dc GIT binary patch literal 222392 zcmeI*O^cOf0LJl=_AR3i5EPi37VT?Y(7HvdK7_Qg2nDyUq*e3{TxeimV22h#K_bW~ zwh&zSf`Lej7Io*qFwAu^2j)4R=ShEYMvm9Ko%1_??$Mc3efaVBpTD;A-#_n~>#y%Te|bKPU;gnA0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009Cs z2|T)W_2JFS+rK=%eQoVMe)eE@`!{T9pK&}uYoTU*gX>?ub?u8cwtxBg{CjKf^&dZ+ z-~J6-+GiXO&|0V&-#|Z03+B-6(a#}}z27>2Doc*~Nt3bYr?TXzpES`=HL0V1DvR@{ zvgD|rG#QJ2Doc*~NfZ54lRE0BvN(S#OOEi}Rbvf9QBhX zW6@7#$x%OPqMvF~NBvY5=TBwHQ9o%i7X4I~9QBhX`l%*$)K6t`{#2G6^^+!J*;GGw zuAI5Iy10bP?xoZ9o=zO~Qvo;CPyOI8)2N^NXzHi3Zh_ee=19k z`bm?q%-GMb7e5-$RbI&DmkS?MpZ!rk`xFPS%-GM3?>;;Dy!Uyp|Mtx%2U+sEe$r$t z`q}GNKQ)iFqki(7N;#y6vmP#UlD_xI{EV?XuwEOyjSeQ5MkS#s1*nv6w1l_f|0q=|m2Ngef5 zS)4zWB}e_F$yoGLS#s1*n&_vR)KNc`#racNa@0?nj72|{B}e_FiGHd{9raULoIjN% zNByM9SZ3^Jb?)8q6xM}Ye){_D>a#!UXP@HWl^Of-{O7$N{cq&gk@vxeb!*r42*OOEi}RML(4#NByLUeyT|w^;21#Kb0j%{iMlQ^ix@K)K8k|r<&AJKb6J# zQ(1DzP9%1?#~|VZvTcY?K6%CXf2dC zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk h1PBlyK!5-N0t5&UAV7cs0RjXF5FkL{1qtlz{0qv$XLtYr literal 206038 zcmeI*-ESOM83*7%1vk(J5ls0~`6?~6_xu6ea|IGYZ~@|q548zRpiV;5Hk7}Cn+l2| zq!c9t87d_tc3cNkAyg9MICfH`LMZ)C+c+hpEga@-x{?*IW53?nnX{{Br6W6=iRbt^ zzkPS+oY~12zBqsD4V&`g^Huw7)%I2GkN->Q9h*K;eRuV-0fh2^tWxV=>9vt)mWGQSp3b7 zbY$zh(y<@Buhn*B+q=`5Uwv;)u7!hJ(~)iM_qT1Y=>GE<=dmvRadu)n9o_!kG_~`C zt+t~(ZcGaYwyw#wcxZb%x}*L6w(S+&e;(sJ)}=q>vEA2UG*=tlULIrPtUkuPqPdjE zn6Es>yyS7fUXC9Jdi<_F#`0TleH=?uq7&r zd)>UP^;I6*$>Zes2hy`o?oXGVn=hc9Npt(YQO)aaZatIo*j^rA`^TS)nPyu&`2A|W z^hSAH=ZK8j{9~?rN$Hi~(4e!X&T!+g(5lk3gd*0ny9&##~R%cIrYVGA+o_LNYj7cJ*Le-y`gNc>rp`6P`L)xwTV3zhZT}vn?q7Xu zvp&Z5U22Bv?3X;oGNC@kyrNl^$C$4?#=PWlz+SEoALuc>`WVY^v-NSTniIS!9osP^ zt?KL4&i>BT<+0Q}j-~1QK9**G@%1$K%Wn-un|BQdKQeJzC9yfNkm&cOx___4PrI*@_SZLo@E zKFVY01<~Nfqqu(EeUIw(RUR7**9LYaj~hU1_@8*cjvf2;szcG|ykD;#a(R@;)zi`Z z-^k;r=dqgaxpJxbU~O=ZZ(e?_I={Z%d{2Yt*iF4(=XH+h`)=vni#OlfbQs$Fqu=e! z;rFvfWBxH#W1Guk?pL*5Sgn`m`|J)w%YE%9i}_ey9!t(+tZ&hCvl6$L$Jm%RTOVV6 zD=}ZuKFMQj%;hoWC65F4a{c3mua#I&Hr2;ie$~gA*LpIzd>eU;`8J=&e0}RMwV3Df zEava!G3M8N9%KExc6^8J&+-@>@22vYuW6mx`{PmV{>h)`pgKf z&vdUh%WH7M@_6I*3$Dj)FpHhzn}*J>yLohdc$u$8*FTmyF3Wr6`kvUaUmeHx%^g4H z&vW^_!t%VA^u796(rEPVi~6WO_D)7S&&uQI=P`e#c~~C#+{@>$o6TgC$B#2VzCA5H zGn+2Ia(*b<#ebemGY{Ts{;|P1pQiHIIrrLib9(&#Po~Eo_|$N;s;^T!`@8S6^_f_G zZ8VShbyls@gm8CjfW6JO5v>SH-$v06{mNA+>FY_##bJj!Dmxm#_Y@+gn1WuuMf<#E*W zct`s0mDk&d)`s@^*5!-t*WB>+SWTT@=Q-u+Js(f!e!DyU?eIfG(aufm>fB@6e0Xzp zvbj9w-)XG6Pjhv@=Izz}nunpeUvuBrBS+^Uo6Tc$ud}GbptiSO7#nkWjCn zd5n3<oChvWJn*3qQ zt?EM^pPi0ouh;hKV=TXQ)yMq#{_`h(nl79>UPL?fv#)eM8__ExO+F`&?d37w7rd0m z;;--N%)K|6yeEk@634V~V5>X^Mq|{j$Ib88^0=}VsE;d6dcBWypR4ou zQ65*?%i~IuZuWY8mB*M@FT?9SCyy~-d5n2oFMGZIP99^vwdV2fe+nEy4|daqgWH_X z1c*oReCDOa->3Y4T9we|_kX*}<4uiUzjtkoR3F=^k9izs_THBM@RK`>Xw!Rc>HFS0 z*Jf)Yf0oDg^4Pftb7##kuN$`8rpELCX&kc{#P;$S8-u!z9|tj(qwq83Q65Xmu{_G7 zJO)mz-`;f8&aX?#KuLX3AJs>BR3A&qKuLX3AJs>BR3A&qKuLX3AJs>BR3A&qKuLX3 zAJs>BR3A&qKuLX3AJs>BR3A&qKuLWWmioAG=$>@=u6MS6U(UmK-;n0_e`n1X)R_Z! zrNei(-`_mG!_@K^=dmvR@#5*nJ009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ QfB*pk1PBly(4WBn0bS-;6aWAK diff --git a/resources/win32/inno-big-150.bmp b/resources/win32/inno-big-150.bmp new file mode 100755 index 0000000000000000000000000000000000000000..554461982f01c8b8d2c8943fc683587aa46a39e5 GIT binary patch literal 339716 zcmeI5zw2bx8OCRcwiYQCiJfeSRYV~vOc0c`30U|Kq|ZOF!D6)u-_kCfja|w#vVuRB zu!WGufP$!OLL}f4NES>Nb7M8EckX%5^_=&d=RO~qm9I1J-1|Py^SSSwnK^#<#a}-1 z^rNT$|MS!3&r{2vua-X_TsxhvogQC)I-UOf<3~?-9y@*W=bJm0e|^nAIB;kOVEoYW zB5rX2#=+p|4#4=)6Gk75!@$uUfbpXzj6N8LfulR{{Wp%T5Pj|rFvr~qIKF-uKYqsU z3Sr!xfaB}`$+hEaM4`6>%yIAh9n{0PL(1M7Vca`^2lX)Skg~T%828TKK|PE+r0lH` z#=Y}*P!Hn{DSK;#aqs*c)U)r-a6i!?;Dv)*@ltI(`fBFm4gEwMZDZj^9E&j9bKPEfU79-a6i!?;Dv)*@ltI(`fBzhd8^Mb6G5nd8psduWGokDQ%V!nkw#9@=5t zBWGuoFz%ebhjtkE$k|yXj60|Ap&iCOa&}e;p=;hRWj-=Rs+#xj}X#^IYthjEjjjb*~Parh?EUt-^(Nz%SDnd83M zyC{com!y4l!nkktF3MrtC23!sFz%bZi*guuN!nK@jQeKqq8!FulJ?aJl#9eRRXPPu8wVVca!&AKftSleMc-7mZ7WbLXH#$A*5(apX?pR8S#GRIw$_t6dGK3Tgeg>l#9eRMz1zC)j|O_egoO@lX* z4dX^(n@WXo)8LI{!?;n{rczlc^om9iPQ`(+d zVcau!C)F_Sl(wf<828NGNi~c+rR}K|#yxX)Qq8_Yr?fq_GRHl0cTx@GPHB5;g>lc^ zomBJt4xQ5W)XE(9%-u;fj60?6sTIaOb9Yh=<4$RNYK3vn+?`azxKrAmT4CHXcPG^_ z?v%EtRv7op-AOh34xQ5W)XE(9%-u;fj60?6sTIaOb9YkxG{5iADQ-)x%yG-utwh7P zRos?hVcaryE72*8-@SU~&aE4B-adWnwRqt7-hF*e6{1}&V8qSeU75o8lE6DRug`h= z$KS97Wm?P>udZvO5{7>Dt3;|Io5yl0LNd<}qc7*BBk#&@rR&YsA6d>}_N zpE_rbr|dg~@tHvz*jov7iODQm*jD+$I^yk|YWN?*>MFb?A>4&>mxdKMT@NtijlN?*>MFb?A> z4&>mxdKMT@Nx0t}fA5ti?!0$dc~3S*}`VO*T?s;g)BcMol!xb)l!=hef)IE=Ri zIB+x=516!CvRtmKm+=gDR!!Tg{|~6@$g95P-+4&J*>~9OJ0KV@&M?+0tX0wn`61^x z-{mvM&#ojGKQp81N7mz2b`2~(B;!A0-(j!cJ;8dM^?1s1yJ&M2iF~e7^s}mf_navg z0gRt7jSjh1;XNnsInN-6@iQ~3e)N3L`TngZ?_NEtbz6F_T5NpBV%93+YnAVqzr)jE z9L7@|7-^joclYVaj@<@^Ms7^JtvIsqe|KbYL%P!=5)G z<3D2G;ne#Mhq1c%#1k^kdYtw6UYu8-2ji8m)Vo*N@h48c9{=bMztOt=<;`Em&F8!P zlnY{V#^bywR>C-pr#LY1;(+m#gqh z``|F1k}z|88^f-T!Z?hlIM9{i?Stnq&c4IBzXRH4ME%hm#`&HT#>c%{z<7%Htj7nw z7{EA;r#NtU#(&Pf!>RWj4g@ga)XedeDaKkQf#pl5fN>a4ao`ew3HQTzO2U)R@xT4) z_gc5lZvQTRalkl?^Lw%?cSfz2^ZEGPpO3GGHuIhQe?TdtIsRI?R8GEDnHlHR-e4TY zD;-$nXy!X%yfWdciM+3vIo|e)fpHkGbf7JO2}hfdarPbZp0g?W6Ee={DliV?4IEfL z>fg6mPIwmU@dg2(9fCPtxf+G>GkP?BoRIM!uT-%%^6KGsjaL7a z`8#Omd-0uoj`w0uS|G*1UGqDsn2igLda5NaNOt{IU-aZI(ye;?>GS0q3 zK09m*`Gkz~`8bTjcmoI6ud=;f+IaNA7awZf?tgrHL(W4Fv0o)+@jm%_{2?d~_MbV7 ze~;gHIQ8#4JQ&mu$;n}y_4wTD@rR%|*nh$}Yn2oS23|KXo{})@aTss#vC7xWo6mK6qhjI2D@*U8)D=CL@zUPE-7;o?a`Et2#zh(`5l=b*P^O@r*^Q9l-@85dz z?$xtex25Myo#?`JR(G&Kys9OIftJio~kF*RATvRWqYsF>`#cx6JXq&SgIj#`ii7<9nUUejbeP zbsWa`I+y)C7~ktSjPG?W`*|?F*Kru%>s_R#u<9r9yjq&$hdE(Bi zH?(d`&&5w$8x|}t@MjlTuODH&8{-XGIO?HbJmpKG<<&VpKdQb1Ix3hAb>%SrfWK!M z#;-TTw(3whjI&l@j;Fj{uCfo~Dc-YIS*0)MP8f&r6bEu}UOfwprzFfAU!^bSP8f&r z6bEu}UOfwprzFfAU!^bSP8f&r6bEu}UOfwprzFfAU!^bSP8f&r6bEu}UOh_=~E_*{9=O?wAm zyuGI!aV`g7e6Bp`ro96&-riG=IF|!3K35)e)7}9XZ|^BboXY_ipDPc#Y41SFzQguy zb3_~nJHQ+dTScL$128Tc9Bqdkfbp_zdovH&cu9_TuM;(Cis8iIbIsoIU$>UnBzgCD3f&n#$}_U@t^}R9yE$FSqJ{bzC+pUXguZsb3En~Rk{wqxNdfI z9&-T3V?I%(>i~@FW=H2S2Vgwr6IHqnz_@O9bRKg6#$!HFrRxBU>t;viF$Z8g<`Y%A z4zTY~H#<6yIlvr``9zhj12C?e9i7JV2M3JxqFfJS(t%n?d@sLdv z2|K{PL*ejfJ>&p$JY*9^!VbW=aCo#Hasb9dHc=$(0Q(Mw!=v?(1I+P|O%w?`0OP{p z(R#=M7!TP*k+1_WE*u`Mha7V2M3JxqFfJS(t%n?d@sLdv z2|K{PL*ejfJ>&p$JY*9^!VbW=aCo#Hasb9dHc=$(z?b~KL*evjJ>md!JmL~H$_~J| za(eV0aRA06E>WZG0E{cANAD2_U_9ayHOdaaxN>^*9&rH1BQ8;+>;Q}_r$_G*2Vgwn z5;e*Wu$nh z0h1_^c7T0{((%!JzyaoXz$8kf9e{D^_-H=h0E`DrqD0z(d+a-u&X4BH4lu{d9#Ns~ z0E}zrNB3n1V7%-R71|EKxORSYUv>b-%N|jo?Es8x=STNt2VlJH5f$1Fz_@mPbYFG= z#>*a2q3r}|DUvz*uUbKh; zaR*>rJV4qnIsoHEizpCx0LH}wr2V1;FkZBX0&xdmTs%P9FFF9@MT;m9cL2u41El?; z12A5+hyrm3*mo!%Ang|&V2&3pqCngM7#9za_KOa{c+nyX#2t9RzC-Z@X}{zEbG+mb zkE=TXJGrTdV=&{asb9l4)M6U12C?hApMsdfbo(;Jg)8ljH@R| y|0M@tyyOs%t2@BHL-hpdzvKXOyyOs%t2+SW>Iu?+$pIKIImF}Y4t#Jro&E=305^I7 literal 0 HcmV?d00001 diff --git a/resources/win32/inno-big-175.bmp b/resources/win32/inno-big-175.bmp new file mode 100755 index 0000000000000000000000000000000000000000..be0e7df91cf7cab1b3caff6ddb4180b85cbcb89f GIT binary patch literal 455976 zcmeI)F^?oi6~OT|0U;6z0wN?FAVFXe5IBPvBw_--0bc+)00&4oa6*Jg1`&`DlYlf9 zCu|`ENFW3mi6sIofe^@n1G5Apy=LOsbGV32-J9ugwz@;7r1#3MrHT zXF~DXJRt$jBuuK1LJ4pt6tB$_65ve2qzWmN0B1t++B_iv&Lm8#kU|M?CKRvD6B6J| z!lVi*lmKT!@!C8g0nQ{$s*pkna3&P5%@Y#fOv0oJDU<+bLh;%>Apy=LOsbGV32-J9 zugwz@;7r1#3MrHTXF~DXJRt$jBuuK1LJ4pt6tB$_65ve2qzWmN0B1t++B_iv&Lm8# zkU|M?CKRvD6B6J|!lVi*lmKT!@!C8g0nQ{$s*pkna3&P5%@Y#fOv0oJDU<+bLh;%> zApy=LOsbGV32-J9ugwz@;7r1#3MrHTXF~DXJRt$jBuuK1LJ4pt6tB$_65ve2qzWmN z0B1t++B_iv&Lm8#kU|M?CKRvD6B6J|!lVi*l)ww2yW1Rrd<68Fd^r_SECJ5M^0j+D z0-VX0QxU}y;7lxEyXPaonS41FQ7i$@#PYR!J_4M{ms1hN5;(+eZ+8UJ5zuGSrBpz{ z1UM56*!JlNa3);825kFu z1UQo}r2+~jz?opcwogZZGwD()pkM-=2?lKYbObn)E~NqrCU6Me-}VS(BcRV@%cyvw z32-Kwu>G?U;7qoRiYJ-?XQBz)KN|tgWXq^{q6xUKIhwHjvk}l|vSm~}(F8aXP1yd~ z2yiA_M#U3NfHTpA?VpVRXR>8fJkbO=6HVCu*$8kZTSmnbP2doH0{bJ7jDS9qETO^) zC%~C-#7>Zm0B4dVR5;-TI1`T836c@uOtORuC!B!$n!^!0K{5jROtORuC!7Fh!Vx<` zG6I}QmQdk@6W~lZVkbyOfHTPwDx7cvoC!zl1jz_+CRsv-6Hed|eg-E%AQu6BCRaX1 z6HkCM@r<1z7Xi-X%BN`J32-K!u`}c%z?oe66iqw<_cg~ec7|L8^qE}w6iqw<&criz zhFk6oGgq(g zhz&WznSlsIl=#*6?CebM`ydKUBR5AL@VvUY=kTaYah`?xiEM5<12C5i+X0b*`JIEQ% z3`AfwJr=L0vor2%t`(?0vsj~}9qjCkpU-fnMqo5O7O#gh1Eo-(S*+2~4svE+&iv~2 zm;dtf*AhJ5dhPSi%O%e2%b7p?=<65!y6b>n^1B~=l`|oExqnG`USuygZ-@70oVg$` zlP~GqXWZ9ZYipd@{=%uxY-iQBQlFW;M(Q&YAQucf_Zgox>oaYydgoT_Gv~-W_P9PX zc^%bfCO|G2>NB+${tJLU=1Y7(v;8$vpV`i;ZKXalaaf<30J&hO&*(F4FGGW@)@Py; zq0dZSNA;NrkPC*L`;7aVYi-T-+6ZuF z?u`4IYc-_LaAxj|pU-fnMu0P%X{!%?hBKVuOdA2taHg$dZmZ9{`Q4ZP^pkHSc>MA^ zpKWs0ea&rU-2}IF@ohP?+kaZ1vor2%t|`iy`8$&iM_T`BfzHnO+>A3FEND9gX9`~T zFA1%0ke=gueWplWuK{NY(wvEV3Gn?)QEFiW@6Eh73oEWmH`Zqga{7!uQxwF~fHMUZ z&TytEh@}B%3M!o8Oi>U^gTb9~U$gILmdf_I9vj>lp8;^@x%#nma?TV~yf^dStSE@3 z0cQ#-oQZShjaNSTfHH;DPsMdET2f)mf&+oT(LY=S<($y)&KR zjB~oq&bY6+rYL8|5uIt>G+wx4D3I-$v)X zb=V{NOp&}^1I`qrITQB+;k{W=YGDKK&Ac}YE3Qj7)@KTG`iwqP6vWbiGX)jSaHc4T zr2%IODxBd=Q4mXm!JTnmv+rk?%J#V)8{8S60dVHI`muC!&J+Fm^ zQ>&QUx<~US>O0~hIa4d*2;!AJIa7f%&J<@jGZ2As#Hd^eX9lVmeWp^W<4kdeGXoJA zM~upqaAu&2(Pt`^I?fblI5QA|am1)xNoQx=*IX-5eWp^W<4kpS#?NOsQzI~r7?msG z%s?sBXDXFC&J<@jGZ2As#Hd^eX9lVmeWp^W<4kdeGXoJAM~upqbauvl&9wr(tv>U{ zE1!Jw>Wc{;Z@lt}iXro<&d&JUERQq(9nFPbb_qDd8O{Wh)#JAGyUhi^`!+i7t-~I< zt@md7Oi^lK1ARuH2`jEkH`Zqga{5eMQ`KjRQVSdCGx|(eab3ExK2wm>XY`q(AeIJ$ zJ9AjN=D=f|;mm4z4epHhX5O2v)^P6yoGFOwGx|(X5K9Bj6jV6FnW7+;2AnCVaE3EQ zK`ae8Q&8bdoHK8J_oYAmW;n<(8ERZ(QY1NSxO`3#_`&N40T?2OONI8!5V z6KZj0pcLNLJ(@RB-w_wd8O{tuAfm*tz9(k}su+Fd>h&G5A!j%<5P^sizxtk>8K`3P znXA`##D<*V%s>PpO8n}3c6P>n&9ws6XRcn~5gT@P#?NOsQzH;j;#c33GXteipSgN{ zM{LL$&J08#qQtMhCuat#7=7mI^&PPxXE-wufrt{n`ktMgabI(-K=qlc*LTE*ot^Qy z8E0w)B1-(~dva!=6n5w{zyIOa-h1~S2_C=w{+F*V!^RCcvoB|M`;T94^kK^~&TuC9 zcXMO5Z~Z0yEi!Ce!x_%R6m{^foQVQ_|B|rr#bbnJ9loFO-t6&-)@SsYs28lzefQI6 z+}B)FRG-{qY9{Fk4(&Rq;=I5QA|b7eZz zan1}>G5X9%m`%m7Jn2{%Q6GdGnk7drp}&J2(Q zmvB=Adf(T4Q*c}?0t*E6nFS~gAy6T}nF<_J2rLlb%mNgL5U3E~Oa+c91QrNzW&w&r z2vi7grUJ(l0t*B1GjRlg8UfDK=$J!bPJlCWCXOIbBXFoqnnM7A83BD}hQt8`ssuPw#bXkI83E4B zkT`%ql>ld|cuXQNBfyy%5(f~d65vb~k4Xe(1UNH8;s63w0-UMhF^Ry80B2@M96+E- zfHPG*CJ~qs;LHq(0|-@5ttI-%#?^R0(AnMsq-<5z?1-IrbLVps1x8!osU@rrUW=M zC1Q*~od9R*e9R&+CBT^}5n}}E1UOUYV-|ra0nSW`7$Z<8aHvn4MF4>b0exly#1MfM z0-RX^WEz190nSW-7$UGjfHNzAOd~KMz?lgULj+a`aApONX#^$&I5Poah`nH4~$5ttC*%mj!b0xJYKvjWI80uut9nE)|FV1>Y8W!^Lb2$Tf$ znUaSQ0&4^~vqs1~0wn>?lst?OSR=rhHA3bQC<$<;M z3LFLqtP~W}T502%Hk&%qb1e5m+a{nRP~1 zAaF{6Gp95>M_`@6VSR}e2q17mK%Y5*;VA+e2ykWtBufxDA;6gv7@i`qfdFSVK(YjZ z69Sw$f#E3v8whY_10+ijI3d896BwQ%uz>()HbAljffE9pIf3CR0viZ$W&EvDFPb^95$@61OWsd2# zz``>Gwh-XV7E0D2@IZhw4=g-GU<(1xY@uWg0uKZ@^T5J01hx?1%oa-4An-tdGY>30 zLtqO5&TOG%4FV4YIP<{5GX%B};LH|E)*$defHMy)JVRg$fy0(X)*yhuGXna|GZda6 zu!#U?Hes>|foB9b^9+S22y7z2nN651Lf{zz&OAfm2?Co4ys&ANMF=49lz=|-l!U(# z*hYXe+c;T;z*7R8c}l|H2y7$3nQfe`Lf|O@&O9aIZv?gx;LJ8oRw3||0B4?(@HYb6 z2pqO8vkCzO{!c)kQ3?pO5#UT4FRKyYj2b|ojR0rbcv+1AXVd@!Z3H;e#>;91IHLv- zXd}RxHeOaEz!^1wKpO$hwDGbU0nVra1lkC2rj3`?2yjLXAkaqO(6-!a1a?nApV@s0 z0MJN)GmXG3-#r1&?7jp5Xe7XyMqrljo&aZdUjhI$65vcDFw1vOfHS)<0RS2aaHbKM z<+~@qncbHF0F4AV(+JG+-4o!+GpfkWeZ%MsW+0exog z6(Igr0-R|jX8qm?aAxlnApTYYoM|Oy{oV<1X73ds{#F83+K3X$Ri*Z-4)G@DBk31PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB=DO68PrhcV0ewveN6j&)z@z0zTXyR-(Ahb1Ap< z$v40w4078;7lHUF*6L$fUb;t!rIR8gJvUb**b%Hv*Y-m#%fK>q+Bn9Ja1?t?Nc0 zlkU>Bu5~?Wyp6-wwXSvD2xQV-y4JO>Cylpp*t*uWt{Z_&x=Yu(*7csr^3+x3h0-n^>U7w^8&=qqcNu66y0U6-P(cUyk*)$^xW@isnJ z*SfCK8~Ocax^A>~$z8hEwXQ3HO`D$Ao478yxO}-?^1Ji`pOy9h3*dQufs1?0M|fVB zFA!bFZ&Cj}JZf}j&+9Hx)&gBed0j`1?yT!BQPu)oM|oXGjqa@LE>YG3T}OFcM~&{R z>n>5&0$oRWT}O@Xtm`gO)&gBed0j`1?yT!BQPu)oM|oXGjqa@LE>YG3T}OFcM~&{R z>n>5&0$oRWT}O@Xtm`gO)&gBed0j`1?yT!BQPu)oM|oXGjqa@LE>YG3T}Szmu8;Yj zE?aW}fpSa7YkHltuH$vr^#!^+_ebcu+|s(%^|?d4@cZjp*D>lcdtP6-!E=0^u63>J zbCi|)p1Rhxu5%ka$EWLB*SbDOS-J12YhCL)x50CKx~_Gt>vNQq`<}YiwXSm;JjbW& zTGzThM_IY=scT*9I=8`de7df6t?P4?mHVE$*0rv48$8FS>sr^kK1W%(@2P8D>pHi= zb9}n4b*<}jl$HCQy4JO>a~nLzr|VkRx;{r)x$miKUF$lx!E=1Nu5~?2*Y{t2Qhw*d z^}N3S{DYH|*R`%^>H6XRP#x;poB#dx@46nj#O2HFWWas?#lzk0$soJ^JxIDf{$}&M zF89B#je?>!^`9>v|Ah*AYseUSEFr z*6}~+QLQYubiAh5IqN!J_uY0~-MTg#0=h1@w61mCXk^A+y4H1!y3C%}GlpCpv#xcm z>ne%`Hg&CQT`v%Fbqc!HwXUlu7TDCau64aY$ki$6TGzU+qF7*4*SgmA0wGtYple<0 zx{6|fOGe%wXSu&K*-f8=vvph zuA*3AQ`frI^#UPRr=V+H>$-|!flXcOTGtDNT%Cfhbv;Yh|Nh&bUOj($J+E&+{bN<@ z@teBV^(p^^7M?hUijl@~kgZR3RfVz$viLpBAJI%*`&x*o*W zbp+IP)JU9lJ&3RC2&n6*kvQvm5MS33P}fl-an|)9zOEynuA@fctm{F1T}MD&M~%c; z*Ms=Fj)1z38i}*62k~_s0d*ZU5@%fx;_EsB?zU?`r|IWD;*Hv!bsdRz+x78xwUyN0y?$3P~Xb**b%Pa1FIuyw6#T{i-m zbeFDmt?NnSZ5+0)b*<}0Ad~LWwXStNX}pcY*0rv6-3VmTUAoq_t|yJRaoD=nwXPe1 zOu9?gy4Lli@iq=y*SgkqBalgV=~~yio;2RZVe4Agx^4tA=`LOCTGx}t+c<1p>sr^1 zKqlR#YhCMl(s&z(t!rJ+()HILz5Vjplk0hX`QclQa@)Ift?OC3ez-qWhr0Hr-$y!l zean|y``d52y@$KolTCK}`%-j${C((oUG9Hf$1ee0M~%eU^Lh|p*AYmvm1k`oZNSt*&h_CAisOzYaIO}>4U)K>(*HI&J*7YF1t|OqXqekMa>p^^7M?hUi zjl@~kgZR3RfV=Jb{;N;Qv0cyW`_Df({s%p(mF1R>*YrAPUB~Ob+peoy*JeXN*X5Sh zwXPeD%(zR}x{gto+4FkFkgH?XwXSttMX|u9u63>J1wyV)LD#z0brr<|o4VGut``Wo zIt5+pTGv$+3vB9I*ScOHjgrt zPC?hY)^!!d0-L(lwXPQkxjF@1>sr@U6bo$XTGzT>Amr*4bggS$S5YjmscT*9dV!Fu zQ_!`pbzMcVz^1Ns{fJ$^c<<_dUEZtbPj~n|ple<0x)Rv5sq0N#mt0)F+;;etJ90>e zyW5iiM}EJV=k>@{d&Ix%d0p;*UB@p0T}O@X?0MZK%37f7D6i|N(VcbOCCXZ$>nN}5 zsL`Eu-6hIepzA2F>!{J4b=@V(TA=GFuj{DMops$M%37f7D6i|N(VcbOCCXZ$>nN}5 zsL`Eu-6hIepzA2F>!{J4b=@V(TA=GFuj{DMops$M%37f7D6i|N(VcbOCCXZ$>nN}5 zsL`Eu-6hIepzA2F>!{J4b=@V(TA=GFKhkyi$%XQxA6NDI;@vkM@#i%j>#fQy9k1zi z&bp4*eX#4tx--4ch=8ukEv;)^k3_V?zpHCq$EeHfdA-9J z{dcsr_Q?{w=C>RQ*j-dfH6*Xvr>y54`MTaQrJy4Lm9YWBZg*SgmA{yW`zgu2$XuD4dR z|Mj}owXXNy>DD9EwXSu&wVM5}*R`&7z5hzkb*=0Dce?cmbzSc2 zZ$5tK<+CR%y}tYG{i@dEHy`c~D^XnMxs+S__$zKD0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly OK!5-N0$qWdoBspz9(5A{ literal 0 HcmV?d00001 diff --git a/resources/win32/inno-big-225.bmp b/resources/win32/inno-big-225.bmp new file mode 100755 index 0000000000000000000000000000000000000000..89cf4efb1e0b855e145ec7708bad421cf1096f8a GIT binary patch literal 747656 zcmeI*zpJlFeZcW++Ca(>@E=GgL`Y+Gtt|Gku+1$Lo1knHmTgzGl4ZG1Xe}{?|`F`rkj^{`>pefB*EcCr{q{t0zxB_T=wA>VERtZT#Q==Ez`+kOK%HkVAkgawwUD00LYg2M|CYhX7aPP%;Mr1h_&DAb>y)0j|iQWDWudaD^N| z0D&9=T#-Y`90U;H3ORrP0yzY@B8QSW2q3@}asUAYatLrm4kdFCK!7Xc00Ic)5a5a& zO6DMd09VKX1Q5s}z!f=^%s~JFu8;!=Ado|VD{?5Ag8%|tAqNmZAcp`~0R#}pA;1+ml*~Z@0j`h(2q2I{fGct+nS%fV zTpmpiX2MjAbZp$RWTLIh4#n z00FL$0|+3HLx3xCD4Bx*0$d>n5I`V@09WKtG6w+!xIzvffItobuE?Qe4gv^pg&aTt zfgA!{kweKG1Q6f~Ie-8HIRv;Ohmtu6Aix!J009JY2yjIXC36r!fGgwx0tn;~;EEhd z<{*FoSI7Yb5Xd3G6*-j5K>z`+kOK%HkVAkgawwUD00LYg2M|CYhX7aPP%;Mr1h_&D zAb>y)0j|iQWDWudaD^N|0D&9=T#-Y`90U;H3ORrP0yzY@B8QSW2q3@}asUAYatLrm z4kdFCK!7Xc00Ic)5a5a&O6DMd09VKX1Q5s}z!f=^%s~JFu8;!=Ado|VD{?5Ag8%|t zAqNmZAcp`~0R#}pA;1+ml*~Z@ z0j`h(2q2I{fGct+nS%fVTpmpiX2Mj zAbZp$RWTLIh4#n00FL$0|+3HLx3xCD4Bx*0$d>n5I`V@09WKtG6w+!xIzvf zfItobuE?Qe4gv^pg&aTtfgA!{kweKG1Q6f~Ie-8HIRv;Ohmtu6Aix!J009JY2yjIX zC36r!fGgwx0tn;~;EEhd<{*FoSI7Yb5I_I{1Q0*~0R#|0009ILKmY**5Qs>?_ckL& z&6yFno&Z-|&)gFch)94dB1X-b5xAbfE3dqA{X;zw0R+Mk;EHe|b6^Cz5a5a~*gX`1 za0Iv_T*w?4fi48Nq6>BpMIamjt_T-02S%U^0j}tR-9r%wM}RBBh0K8w=t6)ix?uNE z1i}&Eif|!wUxaG6zPW3jwa^g55(A2uFY`!iCI%5$HmI zE4pC!Pz1se;EHe|b6^Cz5a5a~*gX`1a0Iv_T*w?4fi48Nq6>BpMIamjt_T-02S%U^ z0j}tR-9r%wM}RBBh0K8w=t6)ix?uNE1i}&Eif|!wUxa zG6zPW3jwa^g55(A2uFY`!iCI%5$HmIE4pC!Pz1se;EHe|b6^Cz5a5a~*gX`1a0Iv_ zT*w?4fi48Nq6>BpMIamjt_T-02S%U^0j}tR-9r%wM}RBBh0K8w=t6)ix?uNE1i}&E zif|!wUxaG6zPW3jwa^g55(A2uEN*SN!^?-~QG2-<|m5 z55N7OCQttK`wu6E<7zhow-TtykVjfOpeug(;vfF)t-qc4f7kuHI4lq)tArwy(ssJ>WB zxZ*VPkDXj`WU}w!idcnTa9Xa|Cw!vK6$v=EA+9K>zF14RB3%O8C|7JKP8(bitMCg> z%N3`Yf9&LnBa?j(R}@rVtR-BrPxwTeD-v*SLtGK7@C#1M73mV#M!8}`aoXUDg6fO4 zgey)n|JcbDM<)9ou839m1*heTeZnW&T#Wj66E7B#fjdI0?;WBxFTHw+bCCTC{7z(5v%YE zPRkXinSbo$iX)SK4_6daU#uluu}}C!n=2A%N6Mo*haZxLvh;Rih}Bk zwS+59GymAh6-Orf9E!>00kt;?^n1b^Ro?~OW!oN{iU;7W;!Pg)K)!lXpR}}E% ziicKu{d}${NYu7VxT1h3SJc=3LwDecf<$e*gewYoa>YX{y?#Dd6eMcfC0tR!lPl_L z|Dii@MM0vrUBVRwJh|ebm0mxeD+&^|?Gmmi;K>#Bwg1o^xS}9Y+b-dX0-jv)&`PhL z&lLrU+I9(76!7GV`r3c!4qQ=?sBM>UMFCH)cxa{9&*zGQL~Xl-D++jWMSbl*bO){| zNYu7VxT1h3S3I=R>*sfO#fLxs<{y9e%auQV@Xjad;O~d^>BJTF4Cmf~E4bqSGn^~tuJrobaRpa!MSUHuume|c1y`(4 z>GgNy3a;Ra`Z`)+2d>}>u2`Yc>+i@FT)`Ffb+p0`T)`Dwu|lQS-*HS=y!F;wnI(ML zv>T{;+9U7a&rC;-&Io54(-nSh^ZMN2itCxjdg7R_c>etPWiJew5At4-237y>j>RgR z1y4JsE4)`+pNifqu4f+WiCmHXbh(Xsuh>wWHoRBFD*S@ea>Z%pA3M3?$YkHc6$RB7 zYYA8E6F$-AiUge75Ld)1{DRYRMY;sGQLflfoHn?kp!#Ah;fmADKX!7(k;%S?D`FLX z!D+c-pYVw`S0v!vhPa}j`eH5NigXEVqg=6}IBjr6timriEmxdo{;`uQj!gDFTv1Sc zv6gVfKH(E>u1LVS4UO-LpMUG~zj^;VD}Vg#-B)VtG^Q(Fym*n$%c+UbABn=7Vt#j|J6noG5EL+=%7fZi+8d`1|Z(iPq- z%H9oXR(Y=&p`0J}3|#T3c(={HS8OOw8{R8Uu?*G871xA=E7F{~BF$%nQLeZq3S5!q z%oS-qBaCvzHBsP-G-s|z^BG~3E3SzGSEM;}MVikDqg-)K6u2VInJdzKMi}LaYofpv zY0g}c<}<=5S6mYXu1Is{iZq`QM!DjeC~!rZGgqYfj4;X-*F=FU(ww;>&1ZyBuDB)& zT#@F?6=^;rjB>>_QQ(R+=kZAE<&PhI?Nc?sF?1_|bPjYG^}Ay=F)dp= z{qK&IVXz!jM?^j?t$HU4|Wmh&2A1h^ty0^2B8Y$#3}Tv1klfmU(FY33h0x#GxV z-@_Gws=n-~T(M91M4KxTaBf3fQC5I~R&hnT1h!GG*if7{xFS&1mmQTWPBZ`5$rVQ? z`yQ?+E5JajxMH91i8fax;M|6|B2d+r9hEE6C9sWh#fIXv!4+i%7-$t&oM!&9lPiu) z_B~t?sOrm(I;Jb$e*5ix9*)rFigXmXqO1S|ts2u6e#ZOy6!J6P*E5gx#4%m*xzBwr z{aNh#QSTLL=H4q}6@I~K$8^QZmoL+qdHpC?q?vO?LG{I2GNvnh4RU=J`5NSU=CPj0 z73oix+o<=74aI50dqu3mFE}k%oM!&9lPiu)_B~utP<^qMaK%316K$?Yz_|@^MXbUv zI4xJCOJE!2iVekSgDVQEFV+&SIL-WHCs!Pq?0dK(R^b<%mMiuNpJ;PM0?uuSD+;PF z))KBrm%uj46&s4v#`v!I;Jp{8Cts&?%D?mfwbx!7ErMK;jtEzz`HV0+r7Q04?nYp{ zKLc0nX&l>Jabz-D&y=q4bDP(HB|H7kZTcF7E3UD(_lh)U?-gl2BaBYziZ6cgizBez zpMfj(G>&bqI5HWnXG&N28pPKi%?bD#ge$JGxA%%PXYUnhJ|m2B#WhjjiZo}gNb?zC zlq;@@0#~Ftb48lZ2%}taO%%8y&6z9Gd`1}Miff|46=}{~k>)ePC|6t)1+GYQ=880* z5k|S@?J5S8IIQ( z(-qz;j*)uo9`6;8O*s1gT#^2Cxs7_S*if7{yjMh5!M*3_iqp(Lc5=m$$-ajx?ya@x z6S!iZ@QF58B;eeJxFWg=?ma(Oq)T8M<%$i(X@e{7t+nVAxZ*VPkDXj`WU}w!is&l1 z_xxP3PxwTeD-v*SLtJrhtwo=}73mV#M!8}`aoXUD=qkAP{9JLG`NvMKI5OGyaK*i~ z7JUL&>=QoG=86QI+YnboSHZpK=ZbU*Y@=MUp*U@D#l5u_eF9gUX8y60D~?R|JzNo8 z1^1qxEA|PWXmdpZ&TWV*?ya@x6SyK>0^2B8Y$#3}ToGLb_nx0CPBZ`5$rVQ?`yQ^i zx7MOh;EH|1C)!+*fO8w-is&l1_xxOuE`e>7D>f9T4X(Ji)}l|~iqp(Lc5=m$$-ajx zqO0KE^K->M;S+7HNWi%bjqi&0zww!0eD_N$fBficpSo8Fi3wbhE`e>7D>f9TjqzRa z!Fw-GPrgp)lz->{>#x5)S_HWw9TBcb^BG}uN>}*1c@wXKk2Ey>-_7g2f-9~uw)cuO zXYUnhJ|m2B#WhjjiZo}gNb?zClq;@@0#~Ftb48lZ2%}taO%%8y&6z9Gd`1}Miff|4 z6=}{~k>)ePC|6t)1+GYQ=880*5k|S_aKt6v>~?fwj0v8QotbH$O#XgyQ9!taAT z(l31^w)OiUqm_2^^GxZAySuyQpei@?UXcbk{(HsGzxDawy#Jk*KYsS^D~V4Q_YU1k zAe{qUM!i?u8@T2Zrhl(!PHeRexgt}B-Ye3e#(%F^t+bopmn+gGu#IxXhT^or70qjN zv<xguQx+bCCTC{7z( zFp2!ua->Exx-ay5Q>_bn>6%Qr0+I+4!YT>kpD^9U&o&FqTdUbHc zmhI^VSETuH1y`gq<*^N+v#<;ovFc;^!ZC4AYEFCCa^0dKoj4LveXYe?3MP?jF zo;G-naYbhG3?4_W$c*F2(+1BmuE+Tc0H6`9F1cpSMRGmaxq8$8Fj zA~Sggk0V!P#&P6ngXb7mWG2txapa23IF3AR@Eqfc%;Xt7j$Dx$$C0NEo?~2*nLLBX zkt;IeIP$c?b8Jjky!qyvqs4UaIC8~k2~%*M!E{_na8T0!d^n=8^Ku#IxXhT^or71K+D zD^4^2*vS<~Ci@<);EH`dT-Nseit7{4_baYv9_xwTD>4P>y&?_Ddqu3mFE}k%q)T8M z<%$i(X@e^YsxQ_Ot~ky7V<%S}ne2PGB39uSoOVoC__@u3P*yJS{fbI}(=Q*>75*)u z>l2SFu4f+WiDSCLpMzYVMO<+`^H@(D(-p72`s)5`;St(5P_ZKW(9?3oLy4_6e@s_+ zued%Bx#D`}v7X2knJ+EgE7G9+IY_L+FE}k%q)T8M<%$i(X@e^YsxQ_Ot~ky7V<%S} zne2PGB39uSoR%y037=?lMFP%kh${-JFV+&SNSDAi$`u=m(*{?>D*S@ea>Z%pA3M3? z$YkHc6$RB7YYA8E6F$-AiUge75Ld)1{DRYt=?Z^0Z$T(4m-zXLN`TWZAJY{B{w&t7 zfBNlTegEBwKmPFB57KWA>Cr#^{=EJA=Q774U#B2YP)UF* zDgj!Kz#;^=Vv#_*CIXcN-gx7U${j360D%<C%)HAdL0xJ-B_UzdT z*K|h&5U3>Jy`mDJ*T5kR1ZfcJ_Tde$Pa4gs!MC)RF?Kn($|sG(;q z0_zaqigjY`rU=v!;EEc0)*`SD0j^jl)^3VG4FRsGp=T`u>k#0Ibz<$N2-FbZiW+*> zBCrmDySuw}F6*WUAW%%edqpui3lUg~09Py(ZkI)%m;hH4qq7i!r3i4vQsH)41d0i8 zMKL-H5m<@Fvk-x$2yn$x;dWUBiV1K45d&2noIKwuF9-YXUfv}+EJA=Q774U#B2YP)UF*Dgj!Kz#;^=Vv#_*CIXcNxS|rEC%)HAdL0xJ;UiWQ>ljtJBf;EH;Nc0gbS0$i~|l-&`5dIDTg z&(IDCtU!P(R*14YB2Z6&E9x2A0f7|=aK#Eyc1Hy232;R{Lpva_0s*dAAEHxS|P0n;qA$CConh@ZMCKzpk!1M&TV)_ufAOcMYa77c0HbG!|0$eeDh+PnYCIq;m2}YYB zFg*dTm_EcVh(HqpT+sxhO%Rx#09Q;OVi!c92?4HXg3%@jOizF-rVp_TBG7~YS2V$B z69lFwz!lSn*aZ=2LVzopV6+JW(-Yu|=|k*-2s9zU6-_YO1cB)ZaK-c?c0mN15a5a? z7;S>U^aQwK`VhMy0!;{TMH7rRL120UTrqu!T@ZmL1h}FJMw=ioJprzmKEy7FKobI7 z(FCJS5SX3-S4vF@1<#5P>EHxS|P0n;qA$CConh@ZMCKzpk!1M&TV)_ufAOcMYa77c0HbG!|0$eeDh+PnYCIq;m2}YYB zFg*dTm_EcVh(HqpT+sxhO%Rx#09Q;OVi!c92?4HXg3%@jOizF-rVp_TBG7~YS2V$B z69lFwz!lSn*aZ=2LVzopV6+JW(-Yu|=|k*-2s9zU6-_YO1cB)ZaK-c?c0mN15a5a? z7;S>U^aQwK`VhMy0!;{TMH7rRL120UTrqu!T@ZmL1h}FJMw=ioJprzmKEy7FKobI7 z(FCJS5SX3-S4vF@1<#5P>EHxS|P0n;C*^yfgoF?PLWnfpEB5`u(7hVNvhRu%LSVhu?V7tg+&@ci0mSP zh!BY)5>(vAZZ&DPu=uiLJ0D#3-8tu;bG~Qc{^1{)nRlK!@B7bL#|95ru&;LGqb^qsAKmGjlA3Xj)C%*^~AV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+Krw-j@4j%lfBTl70E4gIe?9zbfBWHG-!9ItEa#}?)>`n_dh=8C&1u8fBRGTP<->j9p5hC+u0NK&V=o(@~fwS&cy8} zor$y6fy=YinVyZ=R;@E}`&DP+Y<1@HY;{Iw?EC$`*O|SEIbpIo13IHKtFtrtI-PN* zPM+`Vchec2$)33m&(j&5=`g2V)~GW&(`8mO*Qql)lR0nGpQST8GkwNa-cM(AW@T<% zbAE1gMrZ7e{oc@-y@@$tvN{7gqcf|sGx<85ai&h5@9cNe8J)?Vxem|M8J+1cr(M>l zGdj~{Rx{VBGdhzwZ_}TpGdeSU##i1?XLM#|Zd`MIZgfUx?2Y~2(3!o7IbpIo13IHK ztFtrtI-PN*PM+`Vchec2$)33m&(j&5=`g2V)~GW&(`8mO*Qql)lR0nGpQST8GkwNa z-cM(AW@T<%bAE1gMrZ7e{oc@-y@@$tvN{7gqcf|sGx<85ai&h5@9cNe8J)?Vxem|M z8J+1cr(M>lGdj~{Rx{VBGdhzwZ_}TpGdeSU##i1?XLM#|Zd`MIZgfUx?2Y~2(3!o7 zIbpIo13IHKtFtrtI-PN*PM+`Vchec2$)33m&(j&5=`g2V)~GW&(`8mO*Qql)lR0nG zpQST8GkwNa-fv20K6~q>)AwJ0z>b@GS263KDZP9{W9L;DMt9>F4dWf`{eCkSZCt?H-wDy zS!ddB!6$wJoq1w17u>Lb&gjf_fA-Ai6)|t!u=H1`epJ)7e=DL<<^s@Ut%3QzBWNLfX5du1+Gdgp` zPRhH7&g5Bp(lG)$qcb{l%wEd6i_T<8d(Ke;I-@f>bJT9ixsT4|ID5)*0y?8JI&<89 z%D9uxWGH*akpeoSGdgqRj*7pR&cqvg!m$E6qcb{l?4F9go6bZFyZ_MwI-@f>bM&r? zy`Rp+`nvn^0y?8JI&=KKioB!FMC!VCgn-WIjLt;tthjsXOq{Jd#|Y?*&ge|c-io@b z&P2(&Zg4&(em9-bne3VC z@I0N-nGSQ>WsN$cGhJpibDcV)Gnw-?{aHGrGt*~$<^6OXLQEi*zXOU z*_)UXCaW``Gdi<6JCm=|8E5L``Obbfoza=>nd|U8oza;NbJ}H%I-@gPW;Ju2I-@h0 z^EUliI-@hwXME-TbVg@Z=EgPW=SF9A#@^WP4V~GWm=h+eGoUj%vpPGIuhSW4>g4&( zem9-bne3VC@I0N-nGSQ>WsN$cGhJpibDcV)Gnw-?{aHGrGt*~$<^6O zXLQEi*zXOU*_)UXCaW``Gdi<6JCm=|8E5L``Obbfoza=>nd|U8oza;NbJ}H%I-@gP zW;Ju2I-@h0^EUliI-@hwXME-TbVg@Z=EgPW=SF9A#@^WP4V~GW962ZVU%PekQ^Vli z?dMNNe%o{R(ixpOHy4-wpXp3&XZr5Cc`JYP@PW?E`>cn((e`_UOYcF{`|FI(9JW!5 z-$-YQf1n#)p3cObg*p>wyZzq4uQ~!cQ|DV$T#3%aorO9RXR9-{P7|G}^*ySsMrY#A zLY;}T)tOo+iO$se9@SQ(GjV63&cxa3Os$hdXKHwZ2ES z)#yyzS*SB{wmMVmB+;2#-=o@UbSCaB)R{P2ovC$_=uEBeQEfFk6L%KsOq{LG)H+FY zrq=hUwi=y@I}3Ft&Q@n?og_L_>w8pNjn2fKg*p>wt24Du5}m2_J*urnXX4I6or$y6 znOY}_&eZxI)mEc3ac7~<#M$aht&>D&YJHDttI?UbvruQ^Y;~sANuo2gzDKpy=uF&M zs55c4I#cT;(V1G`quOe8ChjcMnK)aWsdbX*Os(%xZ8bU*cNXeQoUP8(I!Sb<*7vBk z8l8zd3w0*WcI(V{pS*v|a>uYWlCsbTQ1zx@6by(e`>XQF4UyiL=$2TBnK5)cPLPR--dP)SZL}zM!k7}#YnYgo1XX0#irq)TKGqt`) zwbkfM+*znIake^B>m<>cTHmAEYIG*P(!i&eS?d zbf(t#sJ0rNi8~8*CeBu8YMmrHQ|o(FTaC`dorO9RXS;RA-`QN_?`+<_gTJ@A+R0vP zJvtM27V1o#?baDTmu0Y>Retpp(3!Zssxxu68gqHJI@7Z;+p2XYZoleGoUP7Wo~_R4 zjD5e~_d2sTF(*t`XFz9kW_5NZU#Bz9)XDRm{cbv=GuboO;dwfvGacr%%Nlh?XS&R4 z<~nsoXENt)`m=OKXQt2i%KPbz&aBLhYtGM&&ghK2vELgyvo|p(Ojc(=XLM$Db|zn^ zGtSh>^PT-}I-@h$GuPpHI-@fk=CsQibw+2p%xdO3bw+10=WY74bVg^U&-lvw>5R^- z%#CZ#&yCLLjJ>hn8#=Q$F(*t`XFz9kW_5NZU#Bz9)XDRm{cbv=GuboO;dwfvGacr% z%Nlh?XS&R4<~nsoXENt)`m=OKXQt2i%KPbz&aBLhYtGM&&ghK2vELgyvo|p(Ojc(= zXLM$Db|zn^GtSh>^PT-}I-@h$GuPpHI-@fk=CsQibw+2p%xdO3bw+10=WY74bVg^U z&-lvw>5R^-%#CZ#&yCLLjJ>hn8#=Q$F(*t`XFz9kW_5NZU#By%XXP(!i z&eS?dbf(t#sJ0rNi8~8*CeBu8YMmrHQ|o(FTaC`dorO9RXR9-{P7wZ2ES z)#yyzS*SB{wmMVmB+;2#-=o@UbSCaB)R{P2ovC$_=uEBeQEfFk6L%KsOq{LG)H+FY zrq=hUwi=y@I}3Ft&Q@n?og_L_>w8pNjn2fKg*p>wt24Du5}m2_J*urnXX4I6or$y6 znOY}_&eZxI)mEc3ac7~<#M$aht&>D&YJHDttI?UbvruQ^Y;~sANuo2gzDKpy=uF&M zs55c4TW9XScFRu@gL}815C8iTx3kKxo&q`(cNXeQobA>bKbK{oGd&x#ty*W|_Nvar z*=o$?+3JkW*!TN=uQPiSbHZeG26RSeR%d7Obvolrojl*!@1`?4lRa}Co~JW9(_v1# ztWjrlrpv5mu2W}pCUf4VKTBtHX8Me;yr0hK%*x!j=KS2~jLz5_`@NwvdlPfQWOW8~ zMrT%MXYzGA<4m1A-`Ve`Gdhz!a~+ia+~|zX*cia+~|zX*cBmPu_$gxW`8zM4I?VskYt$K?IeMlh+;2)}GTx)_4$5Eo z7w^8JGx_YE_!I)$?-3@P=@s80<9z<+gFE5hFXKI)VuUa5Qk}WDPu~88btdkAL&!Lv zb*B9meBu|-nI|T5!3_)OjLuy5XTgkK-tabP^?03W^|>tev4GC#jL!5r3UsE|_p(}@ zx$ca8ntz`0=K%k`+2!qGow>Yk-u;dJdB&e-u4`#VFT3xf%=PO`rnYAtA)qrlqccbB zq`Z6ROrEtT9V4JKI-@hk?4_)`=uDQh=Nu)VGdiO)NA0GZ`{+!Lv!@&Fpfft7Gso|%$UEvxq^^5M26XCmgR`#p80*E!aG-lnf#XLM%z zjIX?(&gjg_+_>ia+~|zX*cia+~|zX*cia+~|zX*cqv1Ikp41Hi>Y6s1 zKIs#l_xE%WL|<0AkRw4t=;|LQ_AQ-yy+^7A#n~#Dpic;(au~V~qkL1u?S>t;2Jul=Gwcox1sbsI=>d%s6Pu z=%0_!96%(O4(=Q({Wy3fg&8JjBEY1JD|pdV0=ZN#KZlAthswAOuBaqQoDT6$l6!C| z9)9j5W^8aUjC*5-{J@IfDwhVsGjN@Ra}Lf0I0uSRxE94Atd~RG zvm?Oe%MT~u1e|~qZ~{)i2{?i36F6y18OP1xM!4O#hf`xzZ*HMb(rB#>8^_hbO33zd z+crk^<`xPi4SRm?-_9zDJvi8Niu~6{ayNOoJ)zeP?IjI84_=k}FSo{%RU(JS_8!hm z?Z{u5(pX9PxBYL9eSW-Vjr-#riBeZrfJaMu9=s~?$3DMhM@=eIdqwZx&Po9uE!lI{ zivROP^Zn`4KENN7j36sh9HrY?{GoHDC|v@7T%9^d3Xan4TJ?XnyLi68Y#-o{=}EMy zj-zxti@%;Kxk~$#lw_*l;Qa>_NkgJd^<=8xkj4MHxq5fhun+JLg}|VFN(zqB?X3R& z`%?lQ={j?~n#I5B`v>264|W7unc9C)<{r?L~z%EL(scz4i#owNm^`w1D3LDOf-am_l6(!nKXTw=h;$K$$`Jq35rXM%m zCz3*AB}Ljlt%|?DknZ;b?K~ literal 0 HcmV?d00001 diff --git a/resources/win32/inno-small-150.bmp b/resources/win32/inno-small-150.bmp new file mode 100755 index 0000000000000000000000000000000000000000..3f65efc5f4c33f7c8dee74826756505f186848a7 GIT binary patch literal 20216 zcmeHNy-EW?5Wc*CrT7SzB4}e1>=nV@GO2t4eFB4^MH*{cOG`mfG+L*yun0l04p=By z=wM)3hMSwYS;Fn!PS`tU=Vtci`@Xrm{B7@i?-u{BP1vu(wh!ALY@K2S_C;|I#~+sF z+rI;Lzq!5)d!EXh?xuTg3|P2A8`#(?#FZi?HzPT2FeN6U4`+x4;EPLrEK z-4z1k{j-Hzmbaw<=&nx;zo#JSxjHa&l=hKbx<$-QMu7nT@vhz2E9o-FF zJrV9BK=^2re1=W=9sLn-94SNLxrh5fB z^FxZBtiIkA3)W3xLB*!~`{RXfOz+MSImuyX3#I~ozGii?_j)~QHQ$exl}vR#@1L}m zt-#*xb|t5ffJHI!V;BDXj&Mn)I_#stx^6t3tf8t{O=H83>JOQ+*gKsm8v_A~8g#lV zPDG`!xQ4?a8`DV%dwW=h=d(fEMVk`=S!ETJT+^-?V`?)gjIwTh9mL_0t_j z$}sE{GtTexDYSLZIN{=wFjqWfG^Kmazd@s}prk4FLvGT#8}?FJS!e3H=lmZt$psr2 z!}d>8_xV6vl61pf!GP&rLC*Y;q{mPUdWxa{*P-A=Oj%Gu-Pv_g3^42|suo_e=^oBu riYu7zDXJD;v*{krVTvo5?kTDkUbE>Q&S8oxnC>a67G87ax);SC>jLOQ literal 0 HcmV?d00001 diff --git a/resources/win32/inno-small-175.bmp b/resources/win32/inno-small-175.bmp new file mode 100755 index 0000000000000000000000000000000000000000..a11b53bcfe15b9cedeac90bcb8bc286de7037b11 GIT binary patch literal 26828 zcmeI3F-{v%6h$W+phQ^$E1*PzI!IYSnsiwMyFig5McD#%3YruVO^65$qN7Giq@+th z5x$J%!Y6+7zTemOh4n6CN33Qndj!b6HaJ*SGuYGZw~`Gp{hMODXnAzRtkeYGBQQe{_gx zU5ZSIOD2;u`F(d$-+tYmv#`+%Brq_oODXnA*SWgP!CM|3>N*k4GLZ=hP_a*BLIPBZ zeNwz}{WSf*x35PR(!jvC*`*Yj1cl{?S`Dl@Kb=mdbty6-E}6)L1gI4I#5I;kpHJb+ znOBNc75k)k_F#IR0G&Z>W=JNaBompC0F`2&)Nd%Ygqht_;`+9M(moe{SR3Rlr!cKc zDfY>-jLH+4klxIg)PL}52{Zf6tLr-LGP9lXO4o^KF0LmGoJz?PptD$mObAdWG9dvf znLhDv{4(6Qtc@xSK9d7wG%zp(v6-PvpU@N3vu;QxBqNjAGx2{_GON%QJnXc*QY??_ zXEAW9>3ITl7Hg0R0m?)sBtT`BeZmz+MFJ9#fCMBU0SQPz0uqpb1SB8<2}nQ!5+H$L Fcm!k1tRnyb literal 0 HcmV?d00001 diff --git a/resources/win32/inno-small-200.bmp b/resources/win32/inno-small-200.bmp new file mode 100755 index 0000000000000000000000000000000000000000..c0ad5436b66a9ab14e87d1a9ca1198b1ce51c505 GIT binary patch literal 35248 zcmeI4J&P1U5QfJ;Ac%073M$4TCYKrO?+^qvFk3T?yu`@heu0U~1(yhdaLXbWc*%hW z3JNEFfS|!0h#;KpY%m4IOubuE<95%z%goYLSJ(7D`&NIwE)sP~ zmT?5)B2kxQ8Al*45_L(IaRlNbQI}*HM<6Z|bxD?S1mYqsqRWFXyZw*DZ*O()|NK7e zA9kXMOeO?tn@#o_s{9R{QNNMA9i>va|%!Mo!zwk}Ly88*og}`fIaL zm(*pBx_rLXrdVwUlcL*=^LP!m8xmNHv)q2P`hN3X;Ia4Y4%kWQrZv@O$#}fndwQ#_ z*FO8NANvv#SjMk)c@_5sFW&8j>#{hO)MeZ}zA>XNyAuiL^BH$N>b@pei|6>x`n9ib zo&+BITaUp`N;e!(#w_IvT4EVznelkJM1JzpWNFPPl2&(_ESJHOE`UbY5?rvB9Frfik;bsUx`T{WkH-4~(N#!^$dc zZd)Ery`v+#33XWm)nFW!5wk3It?qameNCFYv`S=Y?c6PbO?|N}(^wI^8BfttOs(C9 zl~pR1CD-bs-uFjj5p#QPrJ+lX7MlOAd3KC6pPLAfyn8w20&3wmRzgnxQC=J<8=A% zKqS0T)MJUm!nvoW>>#I`;4F*#4PVAN&fh#+!w;@YvLs7m)|pr9!OvkCu`V;df64zY ziOX?^=!a+mrEKk#@jN~R7)MO9w9*5IN|t2#|L#~&mvL$%%ki)b`Ez6b_cA`29b?Z$ z)|bZ^6ZF!_62b&IktKu)aw1Cz6XZme5GKfpEFnyg6Inu-ASbefFhNda31Nbq$P&T? sIgurV334J!2ovN)mJlY$i7X*ZkP}%#m>?&zgfKx)WC>w{oT~Kr3n0c86951J literal 0 HcmV?d00001 diff --git a/resources/win32/inno-small-225.bmp b/resources/win32/inno-small-225.bmp new file mode 100755 index 0000000000000000000000000000000000000000..9a974c4d9c07c817000d700d83f4131103e60d33 GIT binary patch literal 44336 zcmeI5ziSjh6vsC zK2L>@hvDN%_?QSTgwH|nZ#f9o&I}&|NBGp|pL+t+2M6wxFhl=3IYU&iva$ln<9ia; zXN&@Ry&fi!=UEO94?QP<8UFF{IZPtYv$R^C0{{)b-3BG{Jk8>w=Kw&%5Bj|BMxgGU z=6M~0bG!c*k;eNRM;DL0XMg~3w%bLd@jeGRgCxKcI}B*Pp90~``*je^{VtD#5YX+c z8yuT2ZmKVx56@Bu_xtCTdM-@B)ZxUPneV53dVF4e`MNwG--oDu(pgu}g$Wo9!PFpU zm5DInjr`5>RDwXOn4)IEjX_(T>i1X zTVg}5l>U27M$0fUNP;zmjC<5=j2Sz#WXPPbvHSa^N>Jh`C@$@B4T|G1+%(v zDdgaE*?Ku!?6uh>J(nSX>D!FDfnil93ptmem%lGL=Vw)BOL8tlFMnTh&d;jMmgHQ9 zUjDvbaSqRccV0hmw|ri@Z6fa#=Rf;9nd2?9f#qWlnPF>j-EC5l@RPFuGVc94(cNT{ zvmisx$vPttshH$kYtH+dZ^A>ByCr;s(j>DaH{og0anJ+-;1^VrCONCjLK3X-bUJ^9 zN0=(RA%Zxn&ms%b6ws0;^{g@-NwC5*F>y+GgsHL{B8Z22-q`pizzS0!QZYT`ytgN~ zN>c@_2;w2<+1dM&?5HgeshA#eZjzp>e1C(SM_;}+i}yu`)vU^TZqoU4l{vF+*eb>7 zx-xZxoJU#OtTLRNR5w)4Ig16cP0wH*ITr&fdS!BMQr!?^N1BzNL?&m}4Gia*nS1uRP}vO;#L<0Gey#w+xytu9npB^w%z19^QDf>xl{r(- zcA3T3@;=hA{!`DG<6xElZ-VE~LIcIjczH=}lXEe!qE{;0xRaa(v0`Q%X=;0Naw^py zIg91B_i}VSXiw^NZG_9zXtmy(Rt^0wcF#l3tQ#sqvTHS5J3W2PzKzOmh#(&7xfa)h z4fx)kTGS1GubLftNe9yjx@EM$=Sv4B=UD2Q|E%t@&q#VTs{ROgapVL zBLi|KXAA*M7V4RtF$6GKsAqD<5Wr-ip2-|OTvX^-#qrsIB$KE`G&j8=6kcV@4lb;&d%*=a`5oe+1BRQ zf#Pw0alcaBuNL=Rt$oE~t2J0W|8mdPeN!kNHt=QG0q`*lrzj14z{j=&wyQ&az{j=& zwyQ&az{j=&wyQ&az{j=&wyQ&az{j=&wyQ&az{j=&wyQ&aZ1Wiyw_P8qg9DZwKz=OK z+1LOd@UiWH?dp&p@UiWH?dp&p@UiWH?dp8;GdbL?dRtwdc?!<}<4lj=Tv z#s~JQ-hR!0p#^R!Q+Ik)58ZI*+{>go_$UuLCwa<&Q@{s&q_ZOCH<}{k2l+vMst(Yc z#88~4x`-m?H%bZfo9+3{=kx7|QE_&K{LuWQ&u8lPkxx%9G*>o@QLpN<2?ci%zh zY+vfHW;6Zs&+8k9K0fYi?B?{_SFC|jdOCeRzTQ}9Ujk6G2|l>KQ@wi2jo`5L0oR*l zy(ToJr;#7z2l=TwPzp%RCh~*)R7VeYX2AJ}h6(vWeyrqY`r)a@J|_Bb|2Q{I6gtfb zr{t8MpI_f|HbmDKK2Ly;=hOr~o`zLMnD+W0MLs^kuGksQA6XvDH zUK|aFp3(Y1!|AX-9UK^`tBZNUA&1o>-wX4b!*mZx?sQm7@bQ4*Xd33ad@t~!rss5h zR6bI)TT%`&6z!^!A4(~w^>vExPjljf>(}^vp)*6_`kVh)NHITWJHQ3sQ(qsX$VY%> zy9xMgTT#0aYksReP^kgf^5rz|dV&rm(A7WrPt5A_^;Z085_n{7VGk8M7EXXu>ADe^N(SWBFLsPpYM)i@>0 zb@^V}d{TUW`h1L|L3O#)VJ)@!qvEpAMl}LHii=G^PilqAEfyI>vPJF{7k6bQl8L@C**CltJYp0XxA_A zU+(#<6?t3v@xxkz4`s2wPBl&mb6vg{_)zD2d#T1La;L*uf)8~b>jT@LFMyA2J~_Sr z37d5__M-C`r=-tkXa9ck^yfGH{e@2UG?HHKGi?2~v-u!DozW-!ULH`v+rncN&0h4# z+Xj~-+!6VqEarbujZ=g+2R8#B&Uu+0Y`kzs@Sz+YO;e3igf<5^3*)o1|GsAW>x1Co z@E>>N5?!N(2@S0&)%a>b4YK6Y5RD#7}| z<%%6`>6@KePziNl{5#d4*m0nJ&rU6<#Noh_LxW_-frSM#rJxXp1J{NeA|x{oV0~={ zg|iUwaoS==#PtI+D4c~LKTccBh?oADDFuZ%9Jv0#Awsg_fXDB5u~T$Dm8^OE`>K3g evGYpLowid8DxnTw{YE{pq=1hl8nl*H@%0yn(VE8q literal 0 HcmV?d00001 diff --git a/resources/win32/inno-small.bmp b/resources/win32/inno-small.bmp deleted file mode 100644 index 98feb812d2542ab614c8a7125eead6e9e63866f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12814 zcmeI2+e=hI9LG24LRf0q77;-dQ6v;dm!}AXAS$DJ3yY}!fYNeZm4d89)aU}4r4MD= zqh!6LyJy!+uHkKSm2$V#h!V`pgSb#3{F>j{#+BW}x^vES&Y)-D>)GQuJ2Ri(%=~_H z+4PLWG>e?}lfOHO4iI?&V2Nc5`4mbi2^I^ACi2)!rUgt3m=-WCFpmXBx@y7yDhC2@ z@|onX&xPsHf!W+=eg|Qwu?PaM?M(TwmK*DR@dl96ZL~!S?XOfhg4C4b1nhjx_gtnqoaM@G- zk8 zQ|zm(8tttE>=(2>;=Ss_mIU6)Q?zR^U&sBD&}<*7PBSynFHC-J7M9JGy9PS$AB3O2 zdQ}>1xJ~@eS|R%+jt>{{b&@SfmC!cvj5og^|t|T=c$dpW=8lf(_?MU)}ep8`ONo*r^o%jA9#hmTG3A8FW8BDiqsL!yUl2 z0uObS9}$MlooAKji0!3&frpxJY$m=WdcJ8ypG2RAz769s4=HhB8HTZuwGR4A9>RVg zN({g@YcENIo~I|csD-S7mH3QkH;e(p(!%wV!_E@w!Zlw-ivbHYcH>;K=Sc<(k{HKB zp5i^k@6vsl@IH?b<4ukMgfG?}70WY`=E`AzjlP?Q!fh4K+qn1^s>24t#zW$;;W!wm z%Z91%UM}i*a0n!O^xE8r@g}cvTz575ewsmd#W7*#$}*c&MysazDij;(lL2xz5*+n& zQRl;S(r#k(N%SL41smmkblgkVDt7_;qiBC(#CQwUgZO@&zw?j+7nY$H8^%|bcs%!A z+}BiUm-+su2OFMAd5U+3&KdEnkx{ Date: Thu, 15 Aug 2019 09:11:33 +0200 Subject: [PATCH 626/861] Revert "Update uglify-es (#79044)" This reverts commit e677c03899d62a5814637548b904c5ac75de4a6c. --- package.json | 4 ++-- yarn.lock | 25 +++++++++++++++---------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 2074de1024a..f522296d780 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "gulp-shell": "^0.6.5", "gulp-tsb": "2.0.7", "gulp-tslint": "^8.1.3", - "gulp-uglify": "^3.0.2", + "gulp-uglify": "^3.0.0", "gulp-untar": "^0.0.7", "gulp-vinyl-zip": "^2.1.2", "http-server": "^0.11.1", @@ -133,7 +133,7 @@ "tslint": "^5.16.0", "typescript": "3.5.2", "typescript-formatter": "7.1.0", - "uglify-es": "^3.3.9", + "uglify-es": "^3.0.18", "underscore": "^1.8.2", "vinyl": "^2.0.0", "vinyl-fs": "^3.0.0", diff --git a/yarn.lock b/yarn.lock index 8fabb92cfc0..0a6b395f80d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4047,18 +4047,15 @@ gulp-tslint@^8.1.3: plugin-error "1.0.1" through "~2.3.8" -gulp-uglify@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/gulp-uglify/-/gulp-uglify-3.0.2.tgz#5f5b2e8337f879ca9dec971feb1b82a5a87850b0" - integrity sha512-gk1dhB74AkV2kzqPMQBLA3jPoIAPd/nlNzP2XMDSG8XZrqnlCiDGAqC+rZOumzFvB5zOphlFh6yr3lgcAb/OOg== +gulp-uglify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/gulp-uglify/-/gulp-uglify-3.0.0.tgz#0df0331d72a0d302e3e37e109485dddf33c6d1ca" + integrity sha1-DfAzHXKg0wLj434QlIXd3zPG0co= dependencies: - array-each "^1.0.1" - extend-shallow "^3.0.2" gulplog "^1.0.0" has-gulplog "^0.1.0" - isobject "^3.0.1" + lodash "^4.13.1" make-error-cause "^1.1.1" - safe-buffer "^5.1.2" through2 "^2.0.0" uglify-js "^3.0.5" vinyl-sourcemaps-apply "^0.2.0" @@ -5458,7 +5455,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@^4.15.0, lodash@^4.3.0: +lodash@^4.13.1, lodash@^4.15.0, lodash@^4.3.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" integrity sha1-eCA6TRwyiuHYbcpkYONptX9AVa4= @@ -9136,7 +9133,15 @@ uc.micro@^1.0.1, uc.micro@^1.0.3: resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.3.tgz#7ed50d5e0f9a9fb0a573379259f2a77458d50192" integrity sha1-ftUNXg+an7ClczeSWfKndFjVAZI= -uglify-es@^3.3.4, uglify-es@^3.3.9: +uglify-es@^3.0.18: + version "3.1.9" + resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.1.9.tgz#6c82df628ac9eb7af9c61fd70c744a084abe6161" + integrity sha512-wVSiJKHDgDDFmxTVVvnbAH6IpamAFHYDI+5JvwPdaqIMnk8kRTX2JKwq1Fx7gb2+Jj5Dus8kzvIpKkWOMNU51w== + dependencies: + commander "~2.11.0" + source-map "~0.6.1" + +uglify-es@^3.3.4: version "3.3.9" resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" integrity sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ== From 8985ff7c9d38bd2ce7d1e6b58e40d27c5bbdb67b Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Tue, 13 Aug 2019 16:46:00 +0200 Subject: [PATCH 627/861] Work around minifier bug (#79044) --- .../services/extensions/node/proxyResolver.ts | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/services/extensions/node/proxyResolver.ts b/src/vs/workbench/services/extensions/node/proxyResolver.ts index 64c2e0a526e..12a6e3ea66a 100644 --- a/src/vs/workbench/services/extensions/node/proxyResolver.ts +++ b/src/vs/workbench/services/extensions/node/proxyResolver.ts @@ -469,24 +469,26 @@ async function readCaCertificates() { } async function readWindowsCaCertificates() { - const winCA = await import('vscode-windows-ca-certs'); + // Not using await to work around minifier bug (https://github.com/microsoft/vscode/issues/79044). + return import('vscode-windows-ca-certs') + .then(winCA => { + let ders: any[] = []; + const store = winCA(); + try { + let der: any; + while (der = store.next()) { + ders.push(der); + } + } finally { + store.done(); + } - let ders: any[] = []; - const store = winCA(); - try { - let der: any; - while (der = store.next()) { - ders.push(der); - } - } finally { - store.done(); - } - - const certs = new Set(ders.map(derToPem)); - return { - certs: Array.from(certs), - append: true - }; + const certs = new Set(ders.map(derToPem)); + return { + certs: Array.from(certs), + append: true + }; + }); } async function readMacCaCertificates() { From 6ccb91b918b4494677e9e1f53ed4f877dd50586c Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 15 Aug 2019 09:25:56 +0200 Subject: [PATCH 628/861] debt - avoid some StrictNullOverride --- src/vs/base/parts/ipc/node/ipc.cp.ts | 10 ++++++---- .../files/node/watcher/win32/csharpWatcherService.ts | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/vs/base/parts/ipc/node/ipc.cp.ts b/src/vs/base/parts/ipc/node/ipc.cp.ts index 9104deb503c..42671a2e1a6 100644 --- a/src/vs/base/parts/ipc/node/ipc.cp.ts +++ b/src/vs/base/parts/ipc/node/ipc.cp.ts @@ -86,7 +86,7 @@ export interface IIPCOptions { export class Client implements IChannelClient, IDisposable { - private disposeDelayer: Delayer; + private disposeDelayer: Delayer | undefined; private activeRequests = new Set(); private child: ChildProcess | null; private _client: IPCClient | null; @@ -137,7 +137,7 @@ export class Client implements IChannelClient, IDisposable { cancellationTokenListener.dispose(); this.activeRequests.delete(disposable); - if (this.activeRequests.size === 0) { + if (this.activeRequests.size === 0 && this.disposeDelayer) { this.disposeDelayer.trigger(() => this.disposeClient()); } }); @@ -271,8 +271,10 @@ export class Client implements IChannelClient, IDisposable { dispose() { this._onDidProcessExit.dispose(); - this.disposeDelayer.cancel(); - this.disposeDelayer = null!; // StrictNullOverride: nulling out ok in dispose + if (this.disposeDelayer) { + this.disposeDelayer.cancel(); + this.disposeDelayer = undefined; + } this.disposeClient(); this.activeRequests.clear(); } diff --git a/src/vs/platform/files/node/watcher/win32/csharpWatcherService.ts b/src/vs/platform/files/node/watcher/win32/csharpWatcherService.ts index c2d96732a3c..1948481a857 100644 --- a/src/vs/platform/files/node/watcher/win32/csharpWatcherService.ts +++ b/src/vs/platform/files/node/watcher/win32/csharpWatcherService.ts @@ -134,7 +134,7 @@ export class OutOfProcessWin32FolderWatcher { public dispose(): void { if (this.handle) { this.handle.kill(); - this.handle = null!; // StrictNullOverride: nulling out ok in dispose + this.handle = undefined; } } } From 03a43bbacbc02d2946dc0397f1b8c2c66ca82df1 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 15 Aug 2019 09:31:57 +0200 Subject: [PATCH 629/861] debt - move issue service out of common since it will not be supported in the web for now --- src/vs/code/electron-browser/issue/issueReporterMain.ts | 2 +- src/vs/code/electron-browser/issue/issueReporterModel.ts | 2 +- .../code/electron-browser/issue/test/testReporterModel.test.ts | 2 +- .../electron-browser/processExplorer/processExplorerMain.ts | 2 +- src/vs/code/electron-main/app.ts | 2 +- src/vs/platform/issue/electron-browser/issueService.ts | 2 +- src/vs/platform/issue/electron-main/issueService.ts | 2 +- src/vs/platform/issue/{common => node}/issue.ts | 0 src/vs/platform/issue/node/issueIpc.ts | 2 +- .../contrib/issue/electron-browser/issue.contribution.ts | 2 +- src/vs/workbench/contrib/issue/electron-browser/issue.ts | 2 +- src/vs/workbench/contrib/issue/electron-browser/issueActions.ts | 2 +- src/vs/workbench/contrib/issue/electron-browser/issueService.ts | 2 +- src/vs/workbench/workbench.desktop.main.ts | 2 +- 14 files changed, 13 insertions(+), 13 deletions(-) rename src/vs/platform/issue/{common => node}/issue.ts (100%) diff --git a/src/vs/code/electron-browser/issue/issueReporterMain.ts b/src/vs/code/electron-browser/issue/issueReporterMain.ts index e6ee71c50f0..b6be9c71cc9 100644 --- a/src/vs/code/electron-browser/issue/issueReporterMain.ts +++ b/src/vs/code/electron-browser/issue/issueReporterMain.ts @@ -31,7 +31,7 @@ import { WindowsService } from 'vs/platform/windows/electron-browser/windowsServ import { MainProcessService, IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService'; import { EnvironmentService } from 'vs/platform/environment/node/environmentService'; import { IssueReporterModel, IssueReporterData as IssueReporterModelData } from 'vs/code/electron-browser/issue/issueReporterModel'; -import { IssueReporterData, IssueReporterStyles, IssueType, ISettingsSearchIssueReporterData, IssueReporterFeatures, IssueReporterExtensionData } from 'vs/platform/issue/common/issue'; +import { IssueReporterData, IssueReporterStyles, IssueType, ISettingsSearchIssueReporterData, IssueReporterFeatures, IssueReporterExtensionData } from 'vs/platform/issue/node/issue'; import BaseHtml from 'vs/code/electron-browser/issue/issueReporterPage'; import { LogLevelSetterChannelClient, FollowerLogService } from 'vs/platform/log/common/logIpc'; import { ILogService, getLogLevel } from 'vs/platform/log/common/log'; diff --git a/src/vs/code/electron-browser/issue/issueReporterModel.ts b/src/vs/code/electron-browser/issue/issueReporterModel.ts index c1f78969153..0d51dc8f300 100644 --- a/src/vs/code/electron-browser/issue/issueReporterModel.ts +++ b/src/vs/code/electron-browser/issue/issueReporterModel.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { assign } from 'vs/base/common/objects'; -import { IssueType, ISettingSearchResult, IssueReporterExtensionData } from 'vs/platform/issue/common/issue'; +import { IssueType, ISettingSearchResult, IssueReporterExtensionData } from 'vs/platform/issue/node/issue'; import { SystemInfo, isRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnosticsService'; export interface IssueReporterData { diff --git a/src/vs/code/electron-browser/issue/test/testReporterModel.test.ts b/src/vs/code/electron-browser/issue/test/testReporterModel.test.ts index 95857638e41..c6945463991 100644 --- a/src/vs/code/electron-browser/issue/test/testReporterModel.test.ts +++ b/src/vs/code/electron-browser/issue/test/testReporterModel.test.ts @@ -6,7 +6,7 @@ import * as assert from 'assert'; import { IssueReporterModel } from 'vs/code/electron-browser/issue/issueReporterModel'; import { normalizeGitHubUrl } from 'vs/code/electron-browser/issue/issueReporterUtil'; -import { IssueType } from 'vs/platform/issue/common/issue'; +import { IssueType } from 'vs/platform/issue/node/issue'; suite('IssueReporter', () => { diff --git a/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts b/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts index 321a5611e74..bf714084261 100644 --- a/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts +++ b/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts @@ -9,7 +9,7 @@ import { repeat } from 'vs/base/common/strings'; import { totalmem } from 'os'; import product from 'vs/platform/product/node/product'; import { localize } from 'vs/nls'; -import { ProcessExplorerStyles, ProcessExplorerData } from 'vs/platform/issue/common/issue'; +import { ProcessExplorerStyles, ProcessExplorerData } from 'vs/platform/issue/node/issue'; import * as browser from 'vs/base/browser/browser'; import * as platform from 'vs/base/common/platform'; import { IContextMenuItem } from 'vs/base/parts/contextmenu/common/contextmenu'; diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 15e9c438ddb..a8787943fc9 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -47,7 +47,7 @@ import { getMachineId } from 'vs/base/node/id'; import { Win32UpdateService } from 'vs/platform/update/electron-main/updateService.win32'; import { LinuxUpdateService } from 'vs/platform/update/electron-main/updateService.linux'; import { DarwinUpdateService } from 'vs/platform/update/electron-main/updateService.darwin'; -import { IIssueService } from 'vs/platform/issue/common/issue'; +import { IIssueService } from 'vs/platform/issue/node/issue'; import { IssueChannel } from 'vs/platform/issue/node/issueIpc'; import { IssueService } from 'vs/platform/issue/electron-main/issueService'; import { LogLevelSetterChannel } from 'vs/platform/log/common/logIpc'; diff --git a/src/vs/platform/issue/electron-browser/issueService.ts b/src/vs/platform/issue/electron-browser/issueService.ts index 29ea55b6044..6228ef33671 100644 --- a/src/vs/platform/issue/electron-browser/issueService.ts +++ b/src/vs/platform/issue/electron-browser/issueService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IChannel } from 'vs/base/parts/ipc/common/ipc'; -import { IIssueService, IssueReporterData, ProcessExplorerData } from 'vs/platform/issue/common/issue'; +import { IIssueService, IssueReporterData, ProcessExplorerData } from 'vs/platform/issue/node/issue'; import { IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService'; import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; diff --git a/src/vs/platform/issue/electron-main/issueService.ts b/src/vs/platform/issue/electron-main/issueService.ts index 48b0293e933..65aa0fb4c05 100644 --- a/src/vs/platform/issue/electron-main/issueService.ts +++ b/src/vs/platform/issue/electron-main/issueService.ts @@ -6,7 +6,7 @@ import { localize } from 'vs/nls'; import * as objects from 'vs/base/common/objects'; import { parseArgs } from 'vs/platform/environment/node/argv'; -import { IIssueService, IssueReporterData, IssueReporterFeatures, ProcessExplorerData } from 'vs/platform/issue/common/issue'; +import { IIssueService, IssueReporterData, IssueReporterFeatures, ProcessExplorerData } from 'vs/platform/issue/node/issue'; import { BrowserWindow, ipcMain, screen, Event, dialog } from 'electron'; import { ILaunchService } from 'vs/platform/launch/electron-main/launchService'; import { PerformanceInfo, IDiagnosticsService, isRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnosticsService'; diff --git a/src/vs/platform/issue/common/issue.ts b/src/vs/platform/issue/node/issue.ts similarity index 100% rename from src/vs/platform/issue/common/issue.ts rename to src/vs/platform/issue/node/issue.ts diff --git a/src/vs/platform/issue/node/issueIpc.ts b/src/vs/platform/issue/node/issueIpc.ts index 4eca97ef53c..271bcf5ceee 100644 --- a/src/vs/platform/issue/node/issueIpc.ts +++ b/src/vs/platform/issue/node/issueIpc.ts @@ -5,7 +5,7 @@ import { IServerChannel } from 'vs/base/parts/ipc/common/ipc'; import { Event } from 'vs/base/common/event'; -import { IIssueService } from 'vs/platform/issue/common/issue'; +import { IIssueService } from 'vs/platform/issue/node/issue'; export class IssueChannel implements IServerChannel { diff --git a/src/vs/workbench/contrib/issue/electron-browser/issue.contribution.ts b/src/vs/workbench/contrib/issue/electron-browser/issue.contribution.ts index 3aa862c7599..1cb252b5e68 100644 --- a/src/vs/workbench/contrib/issue/electron-browser/issue.contribution.ts +++ b/src/vs/workbench/contrib/issue/electron-browser/issue.contribution.ts @@ -13,7 +13,7 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IWorkbenchIssueService } from 'vs/workbench/contrib/issue/electron-browser/issue'; import { WorkbenchIssueService } from 'vs/workbench/contrib/issue/electron-browser/issueService'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; -import { IIssueService } from 'vs/platform/issue/common/issue'; +import { IIssueService } from 'vs/platform/issue/node/issue'; const helpCategory = { value: nls.localize('help', "Help"), original: 'Help' }; const workbenchActionsRegistry = Registry.as(Extensions.WorkbenchActions); diff --git a/src/vs/workbench/contrib/issue/electron-browser/issue.ts b/src/vs/workbench/contrib/issue/electron-browser/issue.ts index 2cc057f6bcc..ca98eb60aca 100644 --- a/src/vs/workbench/contrib/issue/electron-browser/issue.ts +++ b/src/vs/workbench/contrib/issue/electron-browser/issue.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IssueReporterData } from 'vs/platform/issue/common/issue'; +import { IssueReporterData } from 'vs/platform/issue/node/issue'; export const IWorkbenchIssueService = createDecorator('workbenchIssueService'); diff --git a/src/vs/workbench/contrib/issue/electron-browser/issueActions.ts b/src/vs/workbench/contrib/issue/electron-browser/issueActions.ts index 4eaaf7c3029..4b6b25c31c0 100644 --- a/src/vs/workbench/contrib/issue/electron-browser/issueActions.ts +++ b/src/vs/workbench/contrib/issue/electron-browser/issueActions.ts @@ -5,7 +5,7 @@ import { Action } from 'vs/base/common/actions'; import * as nls from 'vs/nls'; -import { IssueType } from 'vs/platform/issue/common/issue'; +import { IssueType } from 'vs/platform/issue/node/issue'; import { IWorkbenchIssueService } from 'vs/workbench/contrib/issue/electron-browser/issue'; export class OpenProcessExplorer extends Action { diff --git a/src/vs/workbench/contrib/issue/electron-browser/issueService.ts b/src/vs/workbench/contrib/issue/electron-browser/issueService.ts index e93eac14556..5dfea6f09da 100644 --- a/src/vs/workbench/contrib/issue/electron-browser/issueService.ts +++ b/src/vs/workbench/contrib/issue/electron-browser/issueService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IssueReporterStyles, IIssueService, IssueReporterData, ProcessExplorerData, IssueReporterExtensionData } from 'vs/platform/issue/common/issue'; +import { IssueReporterStyles, IIssueService, IssueReporterData, ProcessExplorerData, IssueReporterExtensionData } from 'vs/platform/issue/node/issue'; import { ITheme, IThemeService } from 'vs/platform/theme/common/themeService'; import { textLinkForeground, inputBackground, inputBorder, inputForeground, buttonBackground, buttonHoverBackground, buttonForeground, inputValidationErrorBorder, foreground, inputActiveOptionBorder, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground, editorBackground, editorForeground, listHoverBackground, listHoverForeground, listHighlightForeground, textLinkActiveForeground } from 'vs/platform/theme/common/colorRegistry'; import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme'; diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index d426224accf..6da5363c04a 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -66,7 +66,7 @@ import { IWindowsService } from 'vs/platform/windows/common/windows'; import { WindowsService } from 'vs/platform/windows/electron-browser/windowsService'; import { IUpdateService } from 'vs/platform/update/common/update'; import { UpdateService } from 'vs/platform/update/electron-browser/updateService'; -import { IIssueService } from 'vs/platform/issue/common/issue'; +import { IIssueService } from 'vs/platform/issue/node/issue'; import { IssueService } from 'vs/platform/issue/electron-browser/issueService'; import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces'; import { WorkspacesService } from 'vs/platform/workspaces/electron-browser/workspacesService'; From 262bb4c4ad50b3cb1e4fd72db7a895a9b042a0ba Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 15 Aug 2019 09:42:43 +0200 Subject: [PATCH 630/861] debt - make diagnostics service only accessible from node --- .../electron-browser/issue/issueReporterMain.ts | 2 +- .../electron-browser/issue/issueReporterModel.ts | 2 +- .../processExplorer/processExplorerMain.ts | 2 +- .../sharedProcess/sharedProcessMain.ts | 3 +-- src/vs/code/electron-main/app.ts | 2 +- .../{diagnosticsService.ts => diagnostics.ts} | 14 -------------- .../platform/diagnostics/node/diagnosticsIpc.ts | 3 ++- .../diagnostics/node/diagnosticsService.ts | 15 ++++++++++++++- .../platform/issue/electron-main/issueService.ts | 3 ++- .../launch/electron-main/launchService.ts | 2 +- .../electron-browser/remote.contribution.ts | 2 +- .../stats/electron-browser/workspaceStats.ts | 2 +- .../remote/common/abstractRemoteAgentService.ts | 2 +- .../common/remoteAgentEnvironmentChannel.ts | 2 +- .../services/remote/common/remoteAgentService.ts | 2 +- 15 files changed, 29 insertions(+), 29 deletions(-) rename src/vs/platform/diagnostics/common/{diagnosticsService.ts => diagnostics.ts} (69%) diff --git a/src/vs/code/electron-browser/issue/issueReporterMain.ts b/src/vs/code/electron-browser/issue/issueReporterMain.ts index b6be9c71cc9..591cbed96f3 100644 --- a/src/vs/code/electron-browser/issue/issueReporterMain.ts +++ b/src/vs/code/electron-browser/issue/issueReporterMain.ts @@ -39,7 +39,7 @@ import { OcticonLabel } from 'vs/base/browser/ui/octiconLabel/octiconLabel'; import { normalizeGitHubUrl } from 'vs/code/electron-browser/issue/issueReporterUtil'; import { Button } from 'vs/base/browser/ui/button/button'; import { withUndefinedAsNull } from 'vs/base/common/types'; -import { SystemInfo, isRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { SystemInfo, isRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnostics'; import { SpdLogService } from 'vs/platform/log/node/spdlogService'; const MAX_URL_LENGTH = 2045; diff --git a/src/vs/code/electron-browser/issue/issueReporterModel.ts b/src/vs/code/electron-browser/issue/issueReporterModel.ts index 0d51dc8f300..6c7fa528e37 100644 --- a/src/vs/code/electron-browser/issue/issueReporterModel.ts +++ b/src/vs/code/electron-browser/issue/issueReporterModel.ts @@ -5,7 +5,7 @@ import { assign } from 'vs/base/common/objects'; import { IssueType, ISettingSearchResult, IssueReporterExtensionData } from 'vs/platform/issue/node/issue'; -import { SystemInfo, isRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { SystemInfo, isRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnostics'; export interface IssueReporterData { issueType: IssueType; diff --git a/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts b/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts index bf714084261..557957dfd0b 100644 --- a/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts +++ b/src/vs/code/electron-browser/processExplorer/processExplorerMain.ts @@ -17,7 +17,7 @@ import { popup } from 'vs/base/parts/contextmenu/electron-browser/contextmenu'; import { ProcessItem } from 'vs/base/common/processes'; import { addDisposableListener } from 'vs/base/browser/dom'; import { DisposableStore } from 'vs/base/common/lifecycle'; -import { isRemoteDiagnosticError, IRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { isRemoteDiagnosticError, IRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnostics'; let mapPidToWindowTitle = new Map(); diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index 905e9fd88db..8ef5cc8dd0d 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -48,8 +48,7 @@ import { LogsDataCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/ import { IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService'; import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { SpdLogService } from 'vs/platform/log/node/spdlogService'; -import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsService'; -import { IDiagnosticsService } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { DiagnosticsService, IDiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsService'; import { DiagnosticsChannel } from 'vs/platform/diagnostics/node/diagnosticsIpc'; import { FileService } from 'vs/platform/files/common/fileService'; import { IFileService } from 'vs/platform/files/common/files'; diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index a8787943fc9..159eb32b49c 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -81,8 +81,8 @@ import { nodeSocketFactory } from 'vs/platform/remote/node/nodeSocketFactory'; import { VSBuffer } from 'vs/base/common/buffer'; import { statSync } from 'fs'; import { ISignService } from 'vs/platform/sign/common/sign'; -import { IDiagnosticsService } from 'vs/platform/diagnostics/common/diagnosticsService'; import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsIpc'; +import { IDiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsService'; import { FileService } from 'vs/platform/files/common/fileService'; import { IFileService } from 'vs/platform/files/common/files'; import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider'; diff --git a/src/vs/platform/diagnostics/common/diagnosticsService.ts b/src/vs/platform/diagnostics/common/diagnostics.ts similarity index 69% rename from src/vs/platform/diagnostics/common/diagnosticsService.ts rename to src/vs/platform/diagnostics/common/diagnostics.ts index 48cc4eb9081..9adfc578f64 100644 --- a/src/vs/platform/diagnostics/common/diagnosticsService.ts +++ b/src/vs/platform/diagnostics/common/diagnostics.ts @@ -5,8 +5,6 @@ import { UriComponents } from 'vs/base/common/uri'; import { ProcessItem } from 'vs/base/common/processes'; -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IMainProcessInfo } from 'vs/platform/launch/common/launchService'; import { IWorkspace } from 'vs/platform/workspace/common/workspace'; import { IStringDictionary } from 'vs/base/common/collections'; @@ -67,18 +65,6 @@ export interface IWorkspaceInformation extends IWorkspace { telemetryId: string | undefined; } -export const ID = 'diagnosticsService'; -export const IDiagnosticsService = createDecorator(ID); - -export interface IDiagnosticsService { - _serviceBrand: any; - - getPerformanceInfo(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise; - getSystemInfo(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise; - getDiagnostics(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise; - reportWorkspaceStats(workspace: IWorkspaceInformation): Promise; -} - export function isRemoteDiagnosticError(x: any): x is IRemoteDiagnosticError { return !!x.hostName && !!x.errorMessage; } diff --git a/src/vs/platform/diagnostics/node/diagnosticsIpc.ts b/src/vs/platform/diagnostics/node/diagnosticsIpc.ts index 2e2bf87472b..76af1758163 100644 --- a/src/vs/platform/diagnostics/node/diagnosticsIpc.ts +++ b/src/vs/platform/diagnostics/node/diagnosticsIpc.ts @@ -4,7 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import { IServerChannel, IChannel } from 'vs/base/parts/ipc/common/ipc'; -import { IDiagnosticsService, IRemoteDiagnosticInfo, IRemoteDiagnosticError, SystemInfo, PerformanceInfo } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { IRemoteDiagnosticInfo, IRemoteDiagnosticError, SystemInfo, PerformanceInfo } from 'vs/platform/diagnostics/common/diagnostics'; +import { IDiagnosticsService } from './diagnosticsService'; import { Event } from 'vs/base/common/event'; import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { IMainProcessInfo } from 'vs/platform/launch/common/launchService'; diff --git a/src/vs/platform/diagnostics/node/diagnosticsService.ts b/src/vs/platform/diagnostics/node/diagnosticsService.ts index 13552c9ab44..b94ff1f9145 100644 --- a/src/vs/platform/diagnostics/node/diagnosticsService.ts +++ b/src/vs/platform/diagnostics/node/diagnosticsService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as osLib from 'os'; import { virtualMachineHint } from 'vs/base/node/id'; -import { IMachineInfo, WorkspaceStats, WorkspaceStatItem, IDiagnosticsService, PerformanceInfo, SystemInfo, IRemoteDiagnosticInfo, IRemoteDiagnosticError, isRemoteDiagnosticError, IWorkspaceInformation } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { IMachineInfo, WorkspaceStats, WorkspaceStatItem, PerformanceInfo, SystemInfo, IRemoteDiagnosticInfo, IRemoteDiagnosticError, isRemoteDiagnosticError, IWorkspaceInformation } from 'vs/platform/diagnostics/common/diagnostics'; import { readdir, stat, exists, readFile } from 'fs'; import { join, basename } from 'vs/base/common/path'; import { parse, ParseError } from 'vs/base/common/json'; @@ -17,6 +17,19 @@ import { URI } from 'vs/base/common/uri'; import { ProcessItem } from 'vs/base/common/processes'; import { IMainProcessInfo } from 'vs/platform/launch/common/launchService'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; + +export const ID = 'diagnosticsService'; +export const IDiagnosticsService = createDecorator(ID); + +export interface IDiagnosticsService { + _serviceBrand: any; + + getPerformanceInfo(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise; + getSystemInfo(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise; + getDiagnostics(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise; + reportWorkspaceStats(workspace: IWorkspaceInformation): Promise; +} export interface VersionInfo { vscodeVersion: string; diff --git a/src/vs/platform/issue/electron-main/issueService.ts b/src/vs/platform/issue/electron-main/issueService.ts index 65aa0fb4c05..aa31eb1913a 100644 --- a/src/vs/platform/issue/electron-main/issueService.ts +++ b/src/vs/platform/issue/electron-main/issueService.ts @@ -9,7 +9,8 @@ import { parseArgs } from 'vs/platform/environment/node/argv'; import { IIssueService, IssueReporterData, IssueReporterFeatures, ProcessExplorerData } from 'vs/platform/issue/node/issue'; import { BrowserWindow, ipcMain, screen, Event, dialog } from 'electron'; import { ILaunchService } from 'vs/platform/launch/electron-main/launchService'; -import { PerformanceInfo, IDiagnosticsService, isRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { PerformanceInfo, isRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnostics'; +import { IDiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsService'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { isMacintosh, IProcessEnvironment } from 'vs/base/common/platform'; import { ILogService } from 'vs/platform/log/common/log'; diff --git a/src/vs/platform/launch/electron-main/launchService.ts b/src/vs/platform/launch/electron-main/launchService.ts index 95e56eae4da..c9924cf39d5 100644 --- a/src/vs/platform/launch/electron-main/launchService.ts +++ b/src/vs/platform/launch/electron-main/launchService.ts @@ -19,7 +19,7 @@ import { BrowserWindow, ipcMain, Event as IpcEvent, app } from 'electron'; import { Event } from 'vs/base/common/event'; import { hasArgs } from 'vs/platform/environment/node/argv'; import { coalesce } from 'vs/base/common/arrays'; -import { IDiagnosticInfoOptions, IDiagnosticInfo, IRemoteDiagnosticInfo, IRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { IDiagnosticInfoOptions, IDiagnosticInfo, IRemoteDiagnosticInfo, IRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnostics'; import { IMainProcessInfo, IWindowInfo } from 'vs/platform/launch/common/launchService'; export const ID = 'launchService'; diff --git a/src/vs/workbench/contrib/remote/electron-browser/remote.contribution.ts b/src/vs/workbench/contrib/remote/electron-browser/remote.contribution.ts index 99f4eefd121..00e601638ec 100644 --- a/src/vs/workbench/contrib/remote/electron-browser/remote.contribution.ts +++ b/src/vs/workbench/contrib/remote/electron-browser/remote.contribution.ts @@ -27,7 +27,7 @@ import { DialogChannel } from 'vs/platform/dialogs/node/dialogIpc'; import { DownloadServiceChannel } from 'vs/platform/download/common/downloadIpc'; import { LogLevelSetterChannel } from 'vs/platform/log/common/logIpc'; import { ipcRenderer as ipc } from 'electron'; -import { IDiagnosticInfoOptions, IRemoteDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { IDiagnosticInfoOptions, IRemoteDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnostics'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IProgressService, IProgress, IProgressStep, ProgressLocation } from 'vs/platform/progress/common/progress'; import { PersistentConnectionEventType } from 'vs/platform/remote/common/remoteAgentConnection'; diff --git a/src/vs/workbench/contrib/stats/electron-browser/workspaceStats.ts b/src/vs/workbench/contrib/stats/electron-browser/workspaceStats.ts index d6d6c795e0c..7457e3b6bcd 100644 --- a/src/vs/workbench/contrib/stats/electron-browser/workspaceStats.ts +++ b/src/vs/workbench/contrib/stats/electron-browser/workspaceStats.ts @@ -15,7 +15,7 @@ import { endsWith } from 'vs/base/common/strings'; import { ITextFileService, } from 'vs/workbench/services/textfile/common/textfiles'; import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; import { IWorkspaceStatsService, Tags } from 'vs/workbench/contrib/stats/common/workspaceStats'; -import { IWorkspaceInformation } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { IWorkspaceInformation } from 'vs/platform/diagnostics/common/diagnostics'; const SshProtocolMatcher = /^([^@:]+@)?([^:]+):/; const SshUrlMatcher = /^([^@:]+@)?([^:]+):(.+)$/; diff --git a/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts b/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts index 3a789e23d98..167e7a5bf14 100644 --- a/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts +++ b/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts @@ -17,7 +17,7 @@ import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions } f import { Registry } from 'vs/platform/registry/common/platform'; import { RemoteExtensionEnvironmentChannelClient } from 'vs/workbench/services/remote/common/remoteAgentEnvironmentChannel'; import { INotificationService } from 'vs/platform/notification/common/notification'; -import { IDiagnosticInfoOptions, IDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { IDiagnosticInfoOptions, IDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnostics'; import { Emitter } from 'vs/base/common/event'; import { ISignService } from 'vs/platform/sign/common/sign'; diff --git a/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts b/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts index ae87e384bb4..9f0fb09442e 100644 --- a/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts +++ b/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts @@ -8,7 +8,7 @@ import { URI, UriComponents } from 'vs/base/common/uri'; import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment'; -import { IDiagnosticInfoOptions, IDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { IDiagnosticInfoOptions, IDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnostics'; export interface IGetEnvironmentDataArguments { language: string; diff --git a/src/vs/workbench/services/remote/common/remoteAgentService.ts b/src/vs/workbench/services/remote/common/remoteAgentService.ts index bc4d49641e1..fdd61483fd5 100644 --- a/src/vs/workbench/services/remote/common/remoteAgentService.ts +++ b/src/vs/workbench/services/remote/common/remoteAgentService.ts @@ -6,7 +6,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { RemoteAgentConnectionContext, IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment'; import { IChannel, IServerChannel } from 'vs/base/parts/ipc/common/ipc'; -import { IDiagnosticInfoOptions, IDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { IDiagnosticInfoOptions, IDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnostics'; import { Event } from 'vs/base/common/event'; import { PersistenConnectionEvent as PersistentConnectionEvent, ISocketFactory } from 'vs/platform/remote/common/remoteAgentConnection'; From ce3052c94bd4126858e1cddcd32edc24c994263c Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 15 Aug 2019 09:54:14 +0200 Subject: [PATCH 631/861] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f522296d780..f1d6a015cff 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "8ee1612ab2b050f366c2c4c1500fc243b407581f", + "distro": "27bb4f0e93f58466a9b7813e31d69010675d5a19", "author": { "name": "Microsoft Corporation" }, From 86aa7c850ed70837e9d9df86c7e6af398bdf33cc Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 15 Aug 2019 10:54:11 +0200 Subject: [PATCH 632/861] tests - add more debug for randomly failing getUntitledWorkspacesSync --- .../workspacesMainService.test.ts | 361 ++++++++---------- 1 file changed, 164 insertions(+), 197 deletions(-) diff --git a/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts b/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts index 6d3f1024f3e..42556b610fa 100644 --- a/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts +++ b/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts @@ -17,6 +17,7 @@ import { URI } from 'vs/base/common/uri'; import { getRandomTestPath } from 'vs/base/test/node/testUtils'; import { isWindows } from 'vs/base/common/platform'; import { normalizeDriveLetter } from 'vs/base/common/labels'; +import { dirname, joinPath } from 'vs/base/common/resources'; suite('WorkspacesMainService', () => { const parentDir = getRandomTestPath(os.tmpdir(), 'vsctests', 'workspacesservice'); @@ -51,13 +52,13 @@ suite('WorkspacesMainService', () => { let service: TestWorkspacesMainService; - setup(() => { + setup(async () => { service = new TestWorkspacesMainService(environmentService, logService); // Delete any existing backups completely and then re-create it. - return pfs.rimraf(untitledWorkspacesHomePath, pfs.RimRafMode.MOVE).then(() => { - return pfs.mkdirp(untitledWorkspacesHomePath); - }); + await pfs.rimraf(untitledWorkspacesHomePath, pfs.RimRafMode.MOVE); + + return pfs.mkdirp(untitledWorkspacesHomePath); }); teardown(() => { @@ -77,57 +78,50 @@ suite('WorkspacesMainService', () => { assert.equal(u1.toString(), u2.toString()); } - test('createWorkspace (folders)', () => { - return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { - assert.ok(workspace); - assert.ok(fs.existsSync(workspace.configPath.fsPath)); - assert.ok(service.isUntitledWorkspace(workspace)); + test('createWorkspace (folders)', async () => { + const workspace = await createWorkspace([process.cwd(), os.tmpdir()]); + assert.ok(workspace); + assert.ok(fs.existsSync(workspace.configPath.fsPath)); + assert.ok(service.isUntitledWorkspace(workspace)); - const ws = JSON.parse(fs.readFileSync(workspace.configPath.fsPath).toString()) as IStoredWorkspace; - assert.equal(ws.folders.length, 2); // - assertPathEquals((ws.folders[0]).path, process.cwd()); - assertPathEquals((ws.folders[1]).path, os.tmpdir()); - - assert.ok(!(ws.folders[0]).name); - assert.ok(!(ws.folders[1]).name); - }); + const ws = (JSON.parse(fs.readFileSync(workspace.configPath.fsPath).toString()) as IStoredWorkspace); + assert.equal(ws.folders.length, 2); + assertPathEquals((ws.folders[0]).path, process.cwd()); + assertPathEquals((ws.folders[1]).path, os.tmpdir()); + assert.ok(!(ws.folders[0]).name); + assert.ok(!(ws.folders[1]).name); }); - test('createWorkspace (folders with name)', () => { - return createWorkspace([process.cwd(), os.tmpdir()], ['currentworkingdirectory', 'tempdir']).then(workspace => { - assert.ok(workspace); - assert.ok(fs.existsSync(workspace.configPath.fsPath)); - assert.ok(service.isUntitledWorkspace(workspace)); + test('createWorkspace (folders with name)', async () => { + const workspace = await createWorkspace([process.cwd(), os.tmpdir()], ['currentworkingdirectory', 'tempdir']); + assert.ok(workspace); + assert.ok(fs.existsSync(workspace.configPath.fsPath)); + assert.ok(service.isUntitledWorkspace(workspace)); - const ws = JSON.parse(fs.readFileSync(workspace.configPath.fsPath).toString()) as IStoredWorkspace; - assert.equal(ws.folders.length, 2); // - assertPathEquals((ws.folders[0]).path, process.cwd()); - assertPathEquals((ws.folders[1]).path, os.tmpdir()); - - assert.equal((ws.folders[0]).name, 'currentworkingdirectory'); - assert.equal((ws.folders[1]).name, 'tempdir'); - }); + const ws = (JSON.parse(fs.readFileSync(workspace.configPath.fsPath).toString()) as IStoredWorkspace); + assert.equal(ws.folders.length, 2); + assertPathEquals((ws.folders[0]).path, process.cwd()); + assertPathEquals((ws.folders[1]).path, os.tmpdir()); + assert.equal((ws.folders[0]).name, 'currentworkingdirectory'); + assert.equal((ws.folders[1]).name, 'tempdir'); }); - test('createUntitledWorkspace (folders as other resource URIs)', () => { + test('createUntitledWorkspace (folders as other resource URIs)', async () => { const folder1URI = URI.parse('myscheme://server/work/p/f1'); const folder2URI = URI.parse('myscheme://server/work/o/f3'); - return service.createUntitledWorkspace([{ uri: folder1URI }, { uri: folder2URI }], 'server').then(workspace => { - assert.ok(workspace); - assert.ok(fs.existsSync(workspace.configPath.fsPath)); - assert.ok(service.isUntitledWorkspace(workspace)); + const workspace = await service.createUntitledWorkspace([{ uri: folder1URI }, { uri: folder2URI }], 'server'); + assert.ok(workspace); + assert.ok(fs.existsSync(workspace.configPath.fsPath)); + assert.ok(service.isUntitledWorkspace(workspace)); - const ws = JSON.parse(fs.readFileSync(workspace.configPath.fsPath).toString()) as IStoredWorkspace; - assert.equal(ws.folders.length, 2); - assert.equal((ws.folders[0]).uri, folder1URI.toString(true)); - assert.equal((ws.folders[1]).uri, folder2URI.toString(true)); - - assert.ok(!(ws.folders[0]).name); - assert.ok(!(ws.folders[1]).name); - - assert.equal(ws.remoteAuthority, 'server'); - }); + const ws = (JSON.parse(fs.readFileSync(workspace.configPath.fsPath).toString()) as IStoredWorkspace); + assert.equal(ws.folders.length, 2); + assert.equal((ws.folders[0]).uri, folder1URI.toString(true)); + assert.equal((ws.folders[1]).uri, folder2URI.toString(true)); + assert.ok(!(ws.folders[0]).name); + assert.ok(!(ws.folders[1]).name); + assert.equal(ws.remoteAuthority, 'server'); }); test('createWorkspaceSync (folders)', () => { @@ -178,145 +172,130 @@ suite('WorkspacesMainService', () => { assert.ok(!(ws.folders[1]).name); }); - test('resolveWorkspaceSync', () => { - return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { - assert.ok(service.resolveLocalWorkspaceSync(workspace.configPath)); + test('resolveWorkspaceSync', async () => { + const workspace = await createWorkspace([process.cwd(), os.tmpdir()]); + assert.ok(service.resolveLocalWorkspaceSync(workspace.configPath)); - // make it a valid workspace path - const newPath = path.join(path.dirname(workspace.configPath.fsPath), `workspace.${WORKSPACE_EXTENSION}`); - fs.renameSync(workspace.configPath.fsPath, newPath); - workspace.configPath = URI.file(newPath); + // make it a valid workspace path + const newPath = path.join(path.dirname(workspace.configPath.fsPath), `workspace.${WORKSPACE_EXTENSION}`); + fs.renameSync(workspace.configPath.fsPath, newPath); + workspace.configPath = URI.file(newPath); - const resolved = service.resolveLocalWorkspaceSync(workspace.configPath); - assert.equal(2, resolved!.folders.length); - assertEqualURI(resolved!.configPath, workspace.configPath); - assert.ok(resolved!.id); + const resolved = service.resolveLocalWorkspaceSync(workspace.configPath); + assert.equal(2, resolved!.folders.length); + assertEqualURI(resolved!.configPath, workspace.configPath); + assert.ok(resolved!.id); + fs.writeFileSync(workspace.configPath.fsPath, JSON.stringify({ something: 'something' })); // invalid workspace - fs.writeFileSync(workspace.configPath.fsPath, JSON.stringify({ something: 'something' })); // invalid workspace - const resolvedInvalid = service.resolveLocalWorkspaceSync(workspace.configPath); - assert.ok(!resolvedInvalid); - }); + const resolvedInvalid = service.resolveLocalWorkspaceSync(workspace.configPath); + assert.ok(!resolvedInvalid); }); - test('resolveWorkspaceSync (support relative paths)', () => { - return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { - fs.writeFileSync(workspace.configPath.fsPath, JSON.stringify({ folders: [{ path: './ticino-playground/lib' }] })); + test('resolveWorkspaceSync (support relative paths)', async () => { + const workspace = await createWorkspace([process.cwd(), os.tmpdir()]); + fs.writeFileSync(workspace.configPath.fsPath, JSON.stringify({ folders: [{ path: './ticino-playground/lib' }] })); - const resolved = service.resolveLocalWorkspaceSync(workspace.configPath); - assertEqualURI(resolved!.folders[0].uri, URI.file(path.join(path.dirname(workspace.configPath.fsPath), 'ticino-playground', 'lib'))); - }); + const resolved = service.resolveLocalWorkspaceSync(workspace.configPath); + assertEqualURI(resolved!.folders[0].uri, URI.file(path.join(path.dirname(workspace.configPath.fsPath), 'ticino-playground', 'lib'))); }); - test('resolveWorkspaceSync (support relative paths #2)', () => { - return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { - fs.writeFileSync(workspace.configPath.fsPath, JSON.stringify({ folders: [{ path: './ticino-playground/lib/../other' }] })); + test('resolveWorkspaceSync (support relative paths #2)', async () => { + const workspace = await createWorkspace([process.cwd(), os.tmpdir()]); + fs.writeFileSync(workspace.configPath.fsPath, JSON.stringify({ folders: [{ path: './ticino-playground/lib/../other' }] })); - const resolved = service.resolveLocalWorkspaceSync(workspace.configPath); - assertEqualURI(resolved!.folders[0].uri, URI.file(path.join(path.dirname(workspace.configPath.fsPath), 'ticino-playground', 'other'))); - }); + const resolved = service.resolveLocalWorkspaceSync(workspace.configPath); + assertEqualURI(resolved!.folders[0].uri, URI.file(path.join(path.dirname(workspace.configPath.fsPath), 'ticino-playground', 'other'))); }); - test('resolveWorkspaceSync (support relative paths #3)', () => { - return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { - fs.writeFileSync(workspace.configPath.fsPath, JSON.stringify({ folders: [{ path: 'ticino-playground/lib' }] })); + test('resolveWorkspaceSync (support relative paths #3)', async () => { + const workspace = await createWorkspace([process.cwd(), os.tmpdir()]); + fs.writeFileSync(workspace.configPath.fsPath, JSON.stringify({ folders: [{ path: 'ticino-playground/lib' }] })); - const resolved = service.resolveLocalWorkspaceSync(workspace.configPath); - assertEqualURI(resolved!.folders[0].uri, URI.file(path.join(path.dirname(workspace.configPath.fsPath), 'ticino-playground', 'lib'))); - }); + const resolved = service.resolveLocalWorkspaceSync(workspace.configPath); + assertEqualURI(resolved!.folders[0].uri, URI.file(path.join(path.dirname(workspace.configPath.fsPath), 'ticino-playground', 'lib'))); }); - test('resolveWorkspaceSync (support invalid JSON via fault tolerant parsing)', () => { - return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { - fs.writeFileSync(workspace.configPath.fsPath, '{ "folders": [ { "path": "./ticino-playground/lib" } , ] }'); // trailing comma + test('resolveWorkspaceSync (support invalid JSON via fault tolerant parsing)', async () => { + const workspace = await createWorkspace([process.cwd(), os.tmpdir()]); + fs.writeFileSync(workspace.configPath.fsPath, '{ "folders": [ { "path": "./ticino-playground/lib" } , ] }'); // trailing comma - const resolved = service.resolveLocalWorkspaceSync(workspace.configPath); - assertEqualURI(resolved!.folders[0].uri, URI.file(path.join(path.dirname(workspace.configPath.fsPath), 'ticino-playground', 'lib'))); - }); + const resolved = service.resolveLocalWorkspaceSync(workspace.configPath); + assertEqualURI(resolved!.folders[0].uri, URI.file(path.join(path.dirname(workspace.configPath.fsPath), 'ticino-playground', 'lib'))); }); - test('rewriteWorkspaceFileForNewLocation', () => { + test('rewriteWorkspaceFileForNewLocation', async () => { const folder1 = process.cwd(); // absolute path because outside of tmpDir const tmpDir = os.tmpdir(); const tmpInsideDir = path.join(os.tmpdir(), 'inside'); - return createWorkspace([folder1, tmpInsideDir, path.join(tmpInsideDir, 'somefolder')]).then(workspace => { - const origContent = fs.readFileSync(workspace.configPath.fsPath).toString(); + const workspace = await createWorkspace([folder1, tmpInsideDir, path.join(tmpInsideDir, 'somefolder')]); + const origContent = fs.readFileSync(workspace.configPath.fsPath).toString(); - let origConfigPath = workspace.configPath; - let workspaceConfigPath = URI.file(path.join(tmpDir, 'inside', 'myworkspace1.code-workspace')); - let newContent = rewriteWorkspaceFileForNewLocation(origContent, origConfigPath, workspaceConfigPath); + let origConfigPath = workspace.configPath; + let workspaceConfigPath = URI.file(path.join(tmpDir, 'inside', 'myworkspace1.code-workspace')); + let newContent = rewriteWorkspaceFileForNewLocation(origContent, origConfigPath, workspaceConfigPath); + let ws = (JSON.parse(newContent) as IStoredWorkspace); + assert.equal(ws.folders.length, 3); + assertPathEquals((ws.folders[0]).path, folder1); // absolute path because outside of tmpdir + assertPathEquals((ws.folders[1]).path, '.'); + assertPathEquals((ws.folders[2]).path, 'somefolder'); - let ws = JSON.parse(newContent) as IStoredWorkspace; - assert.equal(ws.folders.length, 3); - assertPathEquals((ws.folders[0]).path, folder1); // absolute path because outside of tmpdir - assertPathEquals((ws.folders[1]).path, '.'); - assertPathEquals((ws.folders[2]).path, 'somefolder'); + origConfigPath = workspaceConfigPath; + workspaceConfigPath = URI.file(path.join(tmpDir, 'myworkspace2.code-workspace')); + newContent = rewriteWorkspaceFileForNewLocation(newContent, origConfigPath, workspaceConfigPath); + ws = (JSON.parse(newContent) as IStoredWorkspace); + assert.equal(ws.folders.length, 3); + assertPathEquals((ws.folders[0]).path, folder1); + assertPathEquals((ws.folders[1]).path, 'inside'); + assertPathEquals((ws.folders[2]).path, isWindows ? 'inside\\somefolder' : 'inside/somefolder'); - origConfigPath = workspaceConfigPath; - workspaceConfigPath = URI.file(path.join(tmpDir, 'myworkspace2.code-workspace')); - newContent = rewriteWorkspaceFileForNewLocation(newContent, origConfigPath, workspaceConfigPath); + origConfigPath = workspaceConfigPath; + workspaceConfigPath = URI.file(path.join(tmpDir, 'other', 'myworkspace2.code-workspace')); + newContent = rewriteWorkspaceFileForNewLocation(newContent, origConfigPath, workspaceConfigPath); + ws = (JSON.parse(newContent) as IStoredWorkspace); + assert.equal(ws.folders.length, 3); + assertPathEquals((ws.folders[0]).path, folder1); + assertPathEquals((ws.folders[1]).path, tmpInsideDir); + assertPathEquals((ws.folders[2]).path, path.join(tmpInsideDir, 'somefolder')); - ws = JSON.parse(newContent) as IStoredWorkspace; - assert.equal(ws.folders.length, 3); - assertPathEquals((ws.folders[0]).path, folder1); - assertPathEquals((ws.folders[1]).path, 'inside'); - assertPathEquals((ws.folders[2]).path, isWindows ? 'inside\\somefolder' : 'inside/somefolder'); + origConfigPath = workspaceConfigPath; + workspaceConfigPath = URI.parse('foo://foo/bar/myworkspace2.code-workspace'); + newContent = rewriteWorkspaceFileForNewLocation(newContent, origConfigPath, workspaceConfigPath); + ws = (JSON.parse(newContent) as IStoredWorkspace); + assert.equal(ws.folders.length, 3); + assert.equal((ws.folders[0]).uri, URI.file(folder1).toString(true)); + assert.equal((ws.folders[1]).uri, URI.file(tmpInsideDir).toString(true)); + assert.equal((ws.folders[2]).uri, URI.file(path.join(tmpInsideDir, 'somefolder')).toString(true)); - origConfigPath = workspaceConfigPath; - workspaceConfigPath = URI.file(path.join(tmpDir, 'other', 'myworkspace2.code-workspace')); - newContent = rewriteWorkspaceFileForNewLocation(newContent, origConfigPath, workspaceConfigPath); - - ws = JSON.parse(newContent) as IStoredWorkspace; - assert.equal(ws.folders.length, 3); - assertPathEquals((ws.folders[0]).path, folder1); - assertPathEquals((ws.folders[1]).path, tmpInsideDir); - assertPathEquals((ws.folders[2]).path, path.join(tmpInsideDir, 'somefolder')); - - origConfigPath = workspaceConfigPath; - workspaceConfigPath = URI.parse('foo://foo/bar/myworkspace2.code-workspace'); - newContent = rewriteWorkspaceFileForNewLocation(newContent, origConfigPath, workspaceConfigPath); - - ws = JSON.parse(newContent) as IStoredWorkspace; - assert.equal(ws.folders.length, 3); - assert.equal((ws.folders[0]).uri, URI.file(folder1).toString(true)); - assert.equal((ws.folders[1]).uri, URI.file(tmpInsideDir).toString(true)); - assert.equal((ws.folders[2]).uri, URI.file(path.join(tmpInsideDir, 'somefolder')).toString(true)); - - service.deleteUntitledWorkspaceSync(workspace); - }); + service.deleteUntitledWorkspaceSync(workspace); }); - test('rewriteWorkspaceFileForNewLocation (preserves comments)', () => { - return createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]).then(workspace => { - const workspaceConfigPath = URI.file(path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`)); + test('rewriteWorkspaceFileForNewLocation (preserves comments)', async () => { + const workspace = await createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]); + const workspaceConfigPath = URI.file(path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`)); - let origContent = fs.readFileSync(workspace.configPath.fsPath).toString(); - origContent = `// this is a comment\n${origContent}`; + let origContent = fs.readFileSync(workspace.configPath.fsPath).toString(); + origContent = `// this is a comment\n${origContent}`; - let newContent = rewriteWorkspaceFileForNewLocation(origContent, workspace.configPath, workspaceConfigPath); - - assert.equal(0, newContent.indexOf('// this is a comment')); - - service.deleteUntitledWorkspaceSync(workspace); - }); + let newContent = rewriteWorkspaceFileForNewLocation(origContent, workspace.configPath, workspaceConfigPath); + assert.equal(0, newContent.indexOf('// this is a comment')); + service.deleteUntitledWorkspaceSync(workspace); }); - test('rewriteWorkspaceFileForNewLocation (preserves forward slashes)', () => { - return createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]).then(workspace => { - const workspaceConfigPath = URI.file(path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`)); - let origContent = fs.readFileSync(workspace.configPath.fsPath).toString(); - origContent = origContent.replace(/[\\]/g, '/'); // convert backslash to slash + test('rewriteWorkspaceFileForNewLocation (preserves forward slashes)', async () => { + const workspace = await createWorkspace([process.cwd(), os.tmpdir(), path.join(os.tmpdir(), 'somefolder')]); + const workspaceConfigPath = URI.file(path.join(os.tmpdir(), `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`)); - const newContent = rewriteWorkspaceFileForNewLocation(origContent, workspace.configPath, workspaceConfigPath); + let origContent = fs.readFileSync(workspace.configPath.fsPath).toString(); + origContent = origContent.replace(/[\\]/g, '/'); // convert backslash to slash - const ws = JSON.parse(newContent) as IStoredWorkspace; - assert.ok(ws.folders.every(f => (f).path.indexOf('\\') < 0)); - - service.deleteUntitledWorkspaceSync(workspace); - }); + const newContent = rewriteWorkspaceFileForNewLocation(origContent, workspace.configPath, workspaceConfigPath); + const ws = (JSON.parse(newContent) as IStoredWorkspace); + assert.ok(ws.folders.every(f => (f).path.indexOf('\\') < 0)); + service.deleteUntitledWorkspaceSync(workspace); }); - test('rewriteWorkspaceFileForNewLocation (unc paths)', () => { + test('rewriteWorkspaceFileForNewLocation (unc paths)', async () => { if (!isWindows) { return Promise.resolve(); } @@ -326,68 +305,56 @@ suite('WorkspacesMainService', () => { const folder2Location = '\\\\server\\share2\\some\\path'; const folder3Location = path.join(os.tmpdir(), 'wsloc', 'inner', 'more'); - return createWorkspace([folder1Location, folder2Location, folder3Location]).then(workspace => { - const workspaceConfigPath = URI.file(path.join(workspaceLocation, `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`)); - let origContent = fs.readFileSync(workspace.configPath.fsPath).toString(); + const workspace = await createWorkspace([folder1Location, folder2Location, folder3Location]); + const workspaceConfigPath = URI.file(path.join(workspaceLocation, `myworkspace.${Date.now()}.${WORKSPACE_EXTENSION}`)); + let origContent = fs.readFileSync(workspace.configPath.fsPath).toString(); + const newContent = rewriteWorkspaceFileForNewLocation(origContent, workspace.configPath, workspaceConfigPath); + const ws = (JSON.parse(newContent) as IStoredWorkspace); + assertPathEquals((ws.folders[0]).path, folder1Location); + assertPathEquals((ws.folders[1]).path, folder2Location); + assertPathEquals((ws.folders[2]).path, 'inner\\more'); - const newContent = rewriteWorkspaceFileForNewLocation(origContent, workspace.configPath, workspaceConfigPath); - - const ws = JSON.parse(newContent) as IStoredWorkspace; - assertPathEquals((ws.folders[0]).path, folder1Location); - assertPathEquals((ws.folders[1]).path, folder2Location); - assertPathEquals((ws.folders[2]).path, 'inner\\more'); - - service.deleteUntitledWorkspaceSync(workspace); - }); + service.deleteUntitledWorkspaceSync(workspace); }); - test('deleteUntitledWorkspaceSync (untitled)', () => { - return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { - assert.ok(fs.existsSync(workspace.configPath.fsPath)); - - service.deleteUntitledWorkspaceSync(workspace); - - assert.ok(!fs.existsSync(workspace.configPath.fsPath)); - }); + test('deleteUntitledWorkspaceSync (untitled)', async () => { + const workspace = await createWorkspace([process.cwd(), os.tmpdir()]); + assert.ok(fs.existsSync(workspace.configPath.fsPath)); + service.deleteUntitledWorkspaceSync(workspace); + assert.ok(!fs.existsSync(workspace.configPath.fsPath)); }); - test('deleteUntitledWorkspaceSync (saved)', () => { - return createWorkspace([process.cwd(), os.tmpdir()]).then(workspace => { - service.deleteUntitledWorkspaceSync(workspace); - }); + test('deleteUntitledWorkspaceSync (saved)', async () => { + const workspace = await createWorkspace([process.cwd(), os.tmpdir()]); + service.deleteUntitledWorkspaceSync(workspace); }); - test('getUntitledWorkspaceSync', () => { + test('getUntitledWorkspaceSync', async () => { let untitled = service.getUntitledWorkspacesSync(); assert.equal(untitled.length, 0); - return createWorkspace([process.cwd(), os.tmpdir()]).then(untitledOne => { - assert.ok(fs.existsSync(untitledOne.configPath.fsPath)); + const untitledOne = await createWorkspace([process.cwd(), os.tmpdir()]); + assert.ok(fs.existsSync(untitledOne.configPath.fsPath)); - untitled = service.getUntitledWorkspacesSync(); + untitled = service.getUntitledWorkspacesSync(); + assert.equal(1, untitled.length); + assert.equal(untitledOne.id, untitled[0].workspace.id); - assert.equal(1, untitled.length); - assert.equal(untitledOne.id, untitled[0].workspace.id); + const untitledTwo = await createWorkspace([os.tmpdir(), process.cwd()]); + assert.ok(fs.existsSync(untitledTwo.configPath.fsPath)); + untitled = service.getUntitledWorkspacesSync(); + if (untitled.length === 1) { + const untitledHome = dirname(dirname(untitledTwo.configPath)); + assert.fail(`Unexpected workspaces count of 1 (expected 2), all workspaces:\n ${fs.readdirSync(untitledHome.fsPath).map(name => fs.readFileSync(joinPath(untitledHome, name, 'workspace.json').fsPath, 'utf8'))}`); + } + assert.equal(2, untitled.length); - return createWorkspace([os.tmpdir(), process.cwd()]).then(untitledTwo => { - assert.ok(fs.existsSync(untitledTwo.configPath.fsPath)); + service.deleteUntitledWorkspaceSync(untitledOne); + untitled = service.getUntitledWorkspacesSync(); + assert.equal(1, untitled.length); - untitled = service.getUntitledWorkspacesSync(); - - if (untitled.length === 1) { - assert.fail('Unexpected workspaces count, contents:\n' + fs.readFileSync(untitledTwo.configPath.fsPath, 'utf8')); - } - - assert.equal(2, untitled.length); - - service.deleteUntitledWorkspaceSync(untitledOne); - untitled = service.getUntitledWorkspacesSync(); - assert.equal(1, untitled.length); - - service.deleteUntitledWorkspaceSync(untitledTwo); - untitled = service.getUntitledWorkspacesSync(); - assert.equal(0, untitled.length); - }); - }); + service.deleteUntitledWorkspaceSync(untitledTwo); + untitled = service.getUntitledWorkspacesSync(); + assert.equal(0, untitled.length); }); }); From 15bf846973c7d534bd91a596fb0e211bff7a2b3e Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 15 Aug 2019 10:55:01 +0200 Subject: [PATCH 633/861] fix mispell --- .../contrib/relauncher/common/relauncher.contribution.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/relauncher/common/relauncher.contribution.ts b/src/vs/workbench/contrib/relauncher/common/relauncher.contribution.ts index d3c0d4f064f..2ec3089894f 100644 --- a/src/vs/workbench/contrib/relauncher/common/relauncher.contribution.ts +++ b/src/vs/workbench/contrib/relauncher/common/relauncher.contribution.ts @@ -159,7 +159,7 @@ export class WorkspaceChangeExtHostRelauncher extends Disposable implements IWor constructor( @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, @IExtensionService extensionService: IExtensionService, - @IWindowService windowSevice: IWindowService, + @IWindowService windowService: IWindowService, @IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService ) { super(); @@ -170,7 +170,7 @@ export class WorkspaceChangeExtHostRelauncher extends Disposable implements IWor } if (environmentService.configuration.remoteAuthority) { - windowSevice.reloadWindow(); // TODO@aeschli, workaround + windowService.reloadWindow(); // TODO@aeschli, workaround } else { extensionService.restartExtensionHost(); } From 2e4c7199ceb7ae88228fd552cde60e5387d64adc Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 15 Aug 2019 10:49:13 +0200 Subject: [PATCH 634/861] :lipstick: --- src/vs/workbench/browser/web.simpleservices.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 33737a02966..3c0cc078e01 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -847,7 +847,7 @@ registerSingleton(ITunnelService, SimpleTunnelService); //#region workspace stats -class WorkspaceStatsService implements IWorkspaceStatsService { +class SimpleWorkspaceStatsService implements IWorkspaceStatsService { _serviceBrand: any; @@ -865,6 +865,6 @@ class WorkspaceStatsService implements IWorkspaceStatsService { } -registerSingleton(IWorkspaceStatsService, WorkspaceStatsService); +registerSingleton(IWorkspaceStatsService, SimpleWorkspaceStatsService); //#endregion From bca9d85350d757f870989ccfc76a351d32091c32 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 15 Aug 2019 10:56:03 +0200 Subject: [PATCH 635/861] update distro --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index f1d6a015cff..93f89b87fcc 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "27bb4f0e93f58466a9b7813e31d69010675d5a19", + "distro": "714d51354d7a0135859224aefc1cd6893ff3bc4a", "author": { "name": "Microsoft Corporation" }, @@ -158,4 +158,4 @@ "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} +} \ No newline at end of file From 634e8ea93aa1431e4bb41faa1487ecab9ab04559 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Thu, 15 Aug 2019 10:57:48 +0200 Subject: [PATCH 636/861] Simplify tasks command --- .../tasks/browser/runAutomaticTasks.ts | 40 +++++++------------ .../tasks/browser/task.contribution.ts | 5 +-- 2 files changed, 17 insertions(+), 28 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/runAutomaticTasks.ts b/src/vs/workbench/contrib/tasks/browser/runAutomaticTasks.ts index b3bccaf94e0..cbe96131cb7 100644 --- a/src/vs/workbench/contrib/tasks/browser/runAutomaticTasks.ts +++ b/src/vs/workbench/contrib/tasks/browser/runAutomaticTasks.ts @@ -12,6 +12,7 @@ import { RunOnOptions, Task, TaskRunSource } from 'vs/workbench/contrib/tasks/co import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { Action } from 'vs/base/common/actions'; +import { IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; const ARE_AUTOMATIC_TASKS_ALLOWED_IN_WORKSPACE = 'tasks.run.allowAutomatic'; @@ -131,38 +132,27 @@ export class RunAutomaticTasks extends Disposable implements IWorkbenchContribut } -export class AllowAutomaticTaskRunning extends Action { +export class ManageAutomaticTaskRunning extends Action { - public static readonly ID = 'workbench.action.tasks.allowAutomaticRunning'; - public static readonly LABEL = nls.localize('workbench.action.tasks.allowAutomaticRunning', "Allow Automatic Tasks in Folder"); + public static readonly ID = 'workbench.action.tasks.manageAutomaticRunning'; + public static readonly LABEL = nls.localize('workbench.action.tasks.manageAutomaticRunning', "Manage Automatic Tasks in Folder"); constructor( id: string, label: string, - @IStorageService private readonly storageService: IStorageService + @IStorageService private readonly storageService: IStorageService, + @IQuickInputService private readonly quickInputService: IQuickInputService ) { super(id, label); } - public run(event?: any): Promise { - this.storageService.store(ARE_AUTOMATIC_TASKS_ALLOWED_IN_WORKSPACE, true, StorageScope.WORKSPACE); - return Promise.resolve(undefined); - } -} - -export class DisallowAutomaticTaskRunning extends Action { - - public static readonly ID = 'workbench.action.tasks.disallowAutomaticRunning'; - public static readonly LABEL = nls.localize('workbench.action.tasks.disallowAutomaticRunning', "Disallow Automatic Tasks in Folder"); - - constructor( - id: string, label: string, - @IStorageService private readonly storageService: IStorageService - ) { - super(id, label); - } - - public run(event?: any): Promise { - this.storageService.store(ARE_AUTOMATIC_TASKS_ALLOWED_IN_WORKSPACE, false, StorageScope.WORKSPACE); - return Promise.resolve(undefined); + public async run(event?: any): Promise { + const allowItem: IQuickPickItem = { label: nls.localize('workbench.action.tasks.allowAutomaticTasks', "Allow Automatic Tasks in Folder") }; + const disallowItem: IQuickPickItem = { label: nls.localize('workbench.action.tasks.disallowAutomaticTasks', "Disallow Automatic Tasks in Folder") }; + const value = await this.quickInputService.pick([allowItem, disallowItem], { canPickMany: false }); + if (!value) { + return; + } + + this.storageService.store(ARE_AUTOMATIC_TASKS_ALLOWED_IN_WORKSPACE, value === allowItem, StorageScope.WORKSPACE); } } diff --git a/src/vs/workbench/contrib/tasks/browser/task.contribution.ts b/src/vs/workbench/contrib/tasks/browser/task.contribution.ts index de6fbc81085..92d2f493108 100644 --- a/src/vs/workbench/contrib/tasks/browser/task.contribution.ts +++ b/src/vs/workbench/contrib/tasks/browser/task.contribution.ts @@ -32,7 +32,7 @@ import { QuickOpenActionContributor } from '../browser/quickOpen'; import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry, IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; -import { RunAutomaticTasks, AllowAutomaticTaskRunning, DisallowAutomaticTaskRunning } from 'vs/workbench/contrib/tasks/browser/runAutomaticTasks'; +import { RunAutomaticTasks, ManageAutomaticTaskRunning } from 'vs/workbench/contrib/tasks/browser/runAutomaticTasks'; let tasksCategory = nls.localize('tasksCategory', "Tasks"); @@ -40,8 +40,7 @@ const workbenchRegistry = Registry.as(Workbench workbenchRegistry.registerWorkbenchContribution(RunAutomaticTasks, LifecyclePhase.Eventually); const actionRegistry = Registry.as(ActionExtensions.WorkbenchActions); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(AllowAutomaticTaskRunning, AllowAutomaticTaskRunning.ID, AllowAutomaticTaskRunning.LABEL), 'Tasks: Allow Automatic Tasks in Folder', tasksCategory); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(DisallowAutomaticTaskRunning, DisallowAutomaticTaskRunning.ID, DisallowAutomaticTaskRunning.LABEL), 'Tasks: Disallow Automatic Tasks in Folder', tasksCategory); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ManageAutomaticTaskRunning, ManageAutomaticTaskRunning.ID, ManageAutomaticTaskRunning.LABEL), 'Tasks: Manage Automatic Tasks in Folder', tasksCategory); export class TaskStatusBarContributions extends Disposable implements IWorkbenchContribution { private runningTasksStatusItem: IStatusbarEntryAccessor | undefined; From 88e76958cfd2d517e5c11a0655f946e391b32ba5 Mon Sep 17 00:00:00 2001 From: DiamondYuan Date: Thu, 15 Aug 2019 17:09:16 +0800 Subject: [PATCH 637/861] docs: fix type (#79129) --- src/vs/base/parts/storage/node/storage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/parts/storage/node/storage.ts b/src/vs/base/parts/storage/node/storage.ts index 6cebac12c9f..edf313654aa 100644 --- a/src/vs/base/parts/storage/node/storage.ts +++ b/src/vs/base/parts/storage/node/storage.ts @@ -206,7 +206,7 @@ export class SQLiteStorageDatabase implements IStorageDatabase { return this.doUpdateItems(recoveryConnection, { insert: recovery() }).then(() => closeRecoveryConnection(), error => { // In case of an error updating items, still ensure to close the connection - // to prevent SQLITE_BUSY errors when the connection is restablished + // to prevent SQLITE_BUSY errors when the connection is reestablished closeRecoveryConnection(); return Promise.reject(error); From 7c53175eef11996733e3301a3e4fce349ddd8140 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 15 Aug 2019 11:11:50 +0200 Subject: [PATCH 638/861] web - add todo for potentially cyclic dependency --- src/vs/workbench/browser/web.simpleservices.ts | 2 ++ .../contrib/debug/browser/extensionHostDebugService.ts | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 3c0cc078e01..ce9a691a28b 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -412,6 +412,8 @@ export class SimpleWindowService extends Disposable implements IWindowService { } closeWindow(): Promise { + window.close(); + return Promise.resolve(); } diff --git a/src/vs/workbench/contrib/debug/browser/extensionHostDebugService.ts b/src/vs/workbench/contrib/debug/browser/extensionHostDebugService.ts index 3f5b703c4ce..5be0fa24b5c 100644 --- a/src/vs/workbench/contrib/debug/browser/extensionHostDebugService.ts +++ b/src/vs/workbench/contrib/debug/browser/extensionHostDebugService.ts @@ -17,7 +17,7 @@ class BrowserExtensionHostDebugService extends ExtensionHostDebugChannelClient { constructor( @IRemoteAgentService remoteAgentService: IRemoteAgentService, - //@IWindowService windowService: IWindowService, + // @IWindowService windowService: IWindowService, // TODO@weinand TODO@isidorn cyclic dependency? @IEnvironmentService environmentService: IEnvironmentService ) { const connection = remoteAgentService.getConnection(); @@ -30,13 +30,11 @@ class BrowserExtensionHostDebugService extends ExtensionHostDebugChannelClient { this._register(this.onReload(event => { if (environmentService.isExtensionDevelopment && environmentService.debugExtensionHost.debugId === event.sessionId) { - //windowService.reloadWindow(); window.location.reload(); } })); this._register(this.onClose(event => { if (environmentService.isExtensionDevelopment && environmentService.debugExtensionHost.debugId === event.sessionId) { - //this._windowService.closeWindow(); window.close(); } })); From cdea3dcf3b6f5f1ca6dda9809f93d57eec9dde64 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Thu, 15 Aug 2019 11:15:31 +0200 Subject: [PATCH 639/861] Multi-select in custom tree view (#78625) Part of #76941 The first argument is now the element that the command is executed on. The second argurment is an array of the other selected items --- src/vs/vscode.proposed.d.ts | 9 +++ .../api/browser/mainThreadTreeViews.ts | 3 +- .../workbench/api/common/extHost.protocol.ts | 2 +- .../workbench/api/common/extHostTreeViews.ts | 17 +++++- .../browser/parts/views/customView.ts | 57 +++++++++++++------ src/vs/workbench/common/views.ts | 2 + 6 files changed, 67 insertions(+), 23 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 6328f593b3f..0b9ad6976fa 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1046,6 +1046,15 @@ declare module 'vscode' { */ constructor(label: TreeItemLabel, collapsibleState?: TreeItemCollapsibleState); } + + export interface TreeViewOptions2 extends TreeViewOptions { + /** + * Whether the tree supports multi-select. When the tree supports multi-select and a command is executed from the tree, + * the first argument to the command is the tree item that the command was executed on and the second argument is an + * array containing the other selected tree items. + */ + canSelectMany?: boolean; + } //#endregion //#region CustomExecution diff --git a/src/vs/workbench/api/browser/mainThreadTreeViews.ts b/src/vs/workbench/api/browser/mainThreadTreeViews.ts index 79968a69f71..3e42831d23f 100644 --- a/src/vs/workbench/api/browser/mainThreadTreeViews.ts +++ b/src/vs/workbench/api/browser/mainThreadTreeViews.ts @@ -27,13 +27,14 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTreeViews); } - $registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean }): void { + $registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean, canSelectMany: boolean }): void { const dataProvider = new TreeViewDataProvider(treeViewId, this._proxy, this.notificationService); this._dataProviders.set(treeViewId, dataProvider); const viewer = this.getTreeView(treeViewId); if (viewer) { viewer.dataProvider = dataProvider; viewer.showCollapseAllAction = !!options.showCollapseAll; + viewer.canSelectMany = !!options.canSelectMany; this.registerListeners(treeViewId, viewer); this._proxy.$setVisible(treeViewId, viewer.visible); } else { diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index e4a618d695b..259f0d50658 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -242,7 +242,7 @@ export interface MainThreadTextEditorsShape extends IDisposable { } export interface MainThreadTreeViewsShape extends IDisposable { - $registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean }): void; + $registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean, canSelectMany: boolean }): void; $refresh(treeViewId: string, itemsToRefresh?: { [treeItemHandle: string]: ITreeItem }): Promise; $reveal(treeViewId: string, treeItem: ITreeItem, parentChain: ITreeItem[], options: IRevealOptions): Promise; $setMessage(treeViewId: string, message: string): void; diff --git a/src/vs/workbench/api/common/extHostTreeViews.ts b/src/vs/workbench/api/common/extHostTreeViews.ts index 71c8ecf346f..66c8e3ed7f7 100644 --- a/src/vs/workbench/api/common/extHostTreeViews.ts +++ b/src/vs/workbench/api/common/extHostTreeViews.ts @@ -52,10 +52,21 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape { private commands: ExtHostCommands, private logService: ILogService ) { + + function isTreeViewItemHandleArg(arg: any): boolean { + return arg && arg.$treeViewId && arg.$treeItemHandle; + } commands.registerArgumentProcessor({ processArgument: arg => { - if (arg && arg.$treeViewId && arg.$treeItemHandle) { + if (isTreeViewItemHandleArg(arg)) { return this.convertArgument(arg); + } else if (Array.isArray(arg) && (arg.length > 0)) { + return arg.map(item => { + if (isTreeViewItemHandleArg(item)) { + return this.convertArgument(item); + } + return item; + }); } return arg; } @@ -182,10 +193,10 @@ class ExtHostTreeView extends Disposable { private refreshPromise: Promise = Promise.resolve(); private refreshQueue: Promise = Promise.resolve(); - constructor(private viewId: string, options: vscode.TreeViewOptions, private proxy: MainThreadTreeViewsShape, private commands: CommandsConverter, private logService: ILogService, private extension: IExtensionDescription) { + constructor(private viewId: string, options: vscode.TreeViewOptions2, private proxy: MainThreadTreeViewsShape, private commands: CommandsConverter, private logService: ILogService, private extension: IExtensionDescription) { super(); this.dataProvider = options.treeDataProvider; - this.proxy.$registerTreeViewDataProvider(viewId, { showCollapseAll: !!options.showCollapseAll }); + this.proxy.$registerTreeViewDataProvider(viewId, { showCollapseAll: !!options.showCollapseAll, canSelectMany: !!options.canSelectMany }); if (this.dataProvider.onDidChangeTreeData) { this._register(this.dataProvider.onDidChangeTreeData(element => this._onDidChangeData.fire({ message: false, element }))); } diff --git a/src/vs/workbench/browser/parts/views/customView.ts b/src/vs/workbench/browser/parts/views/customView.ts index 6c714028d8f..9fd89851d9d 100644 --- a/src/vs/workbench/browser/parts/views/customView.ts +++ b/src/vs/workbench/browser/parts/views/customView.ts @@ -164,9 +164,11 @@ export class CustomTreeView extends Disposable implements ITreeView { private domNode!: HTMLElement; private treeContainer!: HTMLElement; private _messageValue: string | undefined; + private _canSelectMany: boolean = false; private messageElement!: HTMLDivElement; private tree: WorkbenchAsyncDataTree | undefined; private treeLabels: ResourceLabels | undefined; + private root: ITreeItem; private elementsToRefresh: ITreeItem[] = []; private menus: TitleMenus; @@ -253,6 +255,14 @@ export class CustomTreeView extends Disposable implements ITreeView { this.updateMessage(); } + get canSelectMany(): boolean { + return this._canSelectMany; + } + + set canSelectMany(canSelectMany: boolean) { + this._canSelectMany = canSelectMany; + } + get hasIconForParentNode(): boolean { return this._hasIconForParentNode; } @@ -372,12 +382,14 @@ export class CustomTreeView extends Disposable implements ITreeView { collapseByDefault: (e: ITreeItem): boolean => { return e.collapsibleState !== TreeItemCollapsibleState.Expanded; }, - multipleSelectionSupport: false - })); + multipleSelectionSupport: this.canSelectMany, + }) as WorkbenchAsyncDataTree); aligner.tree = this.tree; + const actionRunner = new MultipleSelectionActionRunner(() => this.tree!.getSelection()); + renderer.actionRunner = actionRunner; this.tree.contextKeyService.createKey(this.id, true); - this._register(this.tree.onContextMenu(e => this.onContextMenu(treeMenus, e))); + this._register(this.tree.onContextMenu(e => this.onContextMenu(treeMenus, e, actionRunner))); this._register(this.tree.onDidChangeSelection(e => this._onDidChangeSelection.fire(e.elements))); this._register(this.tree.onDidChangeCollapseState(e => { if (!e.node.element) { @@ -406,7 +418,7 @@ export class CustomTreeView extends Disposable implements ITreeView { })); } - private onContextMenu(treeMenus: TreeMenus, treeEvent: ITreeContextMenuEvent): void { + private onContextMenu(treeMenus: TreeMenus, treeEvent: ITreeContextMenuEvent, actionRunner: MultipleSelectionActionRunner): void { const node: ITreeItem | null = treeEvent.element; if (node === null) { return; @@ -442,7 +454,7 @@ export class CustomTreeView extends Disposable implements ITreeView { getActionsContext: () => ({ $treeViewId: this.id, $treeItemHandle: node.handle }), - actionRunner: new MultipleSelectionActionRunner(() => this.tree!.getSelection()) + actionRunner }); } @@ -686,6 +698,8 @@ class TreeRenderer extends Disposable implements ITreeRenderer{ $treeViewId: this.treeViewId, $treeItemHandle: node.handle }); + templateData.actionBar.context = { $treeViewId: this.treeViewId, $treeItemHandle: node.handle }; templateData.actionBar.push(this.menus.getResourceActions(node), { icon: true, label: false }); + if (this._actionRunner) { + templateData.actionBar.actionRunner = this._actionRunner; + } this.setAlignment(templateData.container, node); templateData.elementDisposable = (this.themeService.onDidFileIconThemeChange(() => this.setAlignment(templateData.container, node))); } @@ -822,23 +843,23 @@ class Aligner extends Disposable { class MultipleSelectionActionRunner extends ActionRunner { - constructor(private getSelectedResources: (() => any[])) { + constructor(private getSelectedResources: (() => ITreeItem[])) { super(); } - runAction(action: IAction, context: any): Promise { - if (action instanceof MenuItemAction) { - const selection = this.getSelectedResources(); - const filteredSelection = selection.filter(s => s !== context); - - if (selection.length === filteredSelection.length || selection.length === 1) { - return action.run(context); - } - - return action.run(context, ...filteredSelection); + runAction(action: IAction, context: TreeViewItemHandleArg): Promise { + const selection = this.getSelectedResources(); + let selectionHandleArgs: TreeViewItemHandleArg[] | undefined = undefined; + if (selection.length > 1) { + selectionHandleArgs = []; + selection.forEach(selected => { + if (selected.handle !== context.$treeItemHandle) { + selectionHandleArgs!.push({ $treeViewId: context.$treeViewId, $treeItemHandle: selected.handle }); + } + }); } - return super.runAction(action, context); + return action.run(...[context, selectionHandleArgs]); } } diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index f5663067bf0..ab8b188c72d 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -310,6 +310,8 @@ export interface ITreeView extends IDisposable { showCollapseAllAction: boolean; + canSelectMany: boolean; + message?: string; readonly visible: boolean; From 35b9b7fbe3e01e801d2ab0f37aeb3117dfe85eac Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 15 Aug 2019 11:20:09 +0200 Subject: [PATCH 640/861] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 93f89b87fcc..337b97fc017 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "714d51354d7a0135859224aefc1cd6893ff3bc4a", + "distro": "5645023d26f429c60aff97c4ce9f3192bfbf5945", "author": { "name": "Microsoft Corporation" }, From 2147b8a9d93aa44951fdbc759f4fc9bea522b0c9 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 15 Aug 2019 11:36:38 +0200 Subject: [PATCH 641/861] web - enable feedback contribution --- .../preferences/browser/preferencesSearch.ts | 3 +++ .../integrity/browser/integrityService.ts | 19 +++++++++++++++++++ .../integrity/node/integrityService.ts | 5 +++-- src/vs/workbench/workbench.common.main.ts | 7 ++++--- src/vs/workbench/workbench.desktop.main.ts | 3 --- src/vs/workbench/workbench.web.main.ts | 1 + 6 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 src/vs/workbench/services/integrity/browser/integrityService.ts diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts b/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts index ef36014032d..b876c396a7f 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts @@ -25,6 +25,7 @@ import { nullRange } from 'vs/workbench/services/preferences/common/preferencesM import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IStringDictionary } from 'vs/base/common/collections'; import { IProductService } from 'vs/platform/product/common/product'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export interface IEndpointDetails { urlBase?: string; @@ -564,3 +565,5 @@ export class SettingMatches { }; } } + +registerSingleton(IPreferencesSearchService, PreferencesSearchService, true); diff --git a/src/vs/workbench/services/integrity/browser/integrityService.ts b/src/vs/workbench/services/integrity/browser/integrityService.ts new file mode 100644 index 00000000000..5ddf9d5b3f9 --- /dev/null +++ b/src/vs/workbench/services/integrity/browser/integrityService.ts @@ -0,0 +1,19 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IIntegrityService, IntegrityTestResult } from 'vs/workbench/services/integrity/common/integrity'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; + +export class BrowserIntegrityServiceImpl implements IIntegrityService { + + _serviceBrand!: ServiceIdentifier; + + async isPure(): Promise { + return { isPure: true, proof: [] }; + } +} + +registerSingleton(IIntegrityService, BrowserIntegrityServiceImpl, true); diff --git a/src/vs/workbench/services/integrity/node/integrityService.ts b/src/vs/workbench/services/integrity/node/integrityService.ts index 00e083a9b99..021fb9543b5 100644 --- a/src/vs/workbench/services/integrity/node/integrityService.ts +++ b/src/vs/workbench/services/integrity/node/integrityService.ts @@ -14,6 +14,7 @@ import product from 'vs/platform/product/node/product'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; interface IStorageData { dontShowPrompt: boolean; @@ -55,7 +56,7 @@ class IntegrityStorage { export class IntegrityServiceImpl implements IIntegrityService { - _serviceBrand: any; + _serviceBrand!: ServiceIdentifier; private _storage: IntegrityStorage; private _isPurePromise: Promise; @@ -159,4 +160,4 @@ export class IntegrityServiceImpl implements IIntegrityService { } } -registerSingleton(IIntegrityService, IntegrityServiceImpl, true); \ No newline at end of file +registerSingleton(IIntegrityService, IntegrityServiceImpl, true); diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index 59355a0c6c4..e58f7058329 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -123,9 +123,7 @@ import 'vs/workbench/contrib/telemetry/browser/telemetry.contribution'; // Preferences import 'vs/workbench/contrib/preferences/browser/preferences.contribution'; import 'vs/workbench/contrib/preferences/browser/keybindingsEditorContribution'; -import { IPreferencesSearchService } from 'vs/workbench/contrib/preferences/common/preferences'; -import { PreferencesSearchService } from 'vs/workbench/contrib/preferences/browser/preferencesSearch'; -registerSingleton(IPreferencesSearchService, PreferencesSearchService, true); +import 'vs/workbench/contrib/preferences/browser/preferencesSearch'; // Logs import 'vs/workbench/contrib/logs/common/logs.contribution'; @@ -231,4 +229,7 @@ import 'vs/workbench/contrib/outline/browser/outline.contribution'; // Experiments import 'vs/workbench/contrib/experiments/browser/experiments.contribution'; +// Send a Smile +import 'vs/workbench/contrib/feedback/browser/feedback.contribution'; + //#endregion diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index 6da5363c04a..f6a48a02812 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -131,9 +131,6 @@ import 'vs/workbench/contrib/codeEditor/electron-browser/codeEditor.contribution // Execution import 'vs/workbench/contrib/externalTerminal/node/externalTerminalService'; -// Send a Smile -import 'vs/workbench/contrib/feedback/browser/feedback.contribution'; - // Update import 'vs/workbench/contrib/update/electron-browser/update.contribution'; diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 169b3c07ef6..8d06f34a906 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -26,6 +26,7 @@ import 'vs/workbench/browser/web.main'; //#region --- workbench services +import 'vs/workbench/services/integrity/browser/integrityService'; import 'vs/workbench/services/textMate/browser/textMateService'; import 'vs/workbench/services/search/common/searchService'; import 'vs/workbench/services/output/common/outputChannelModelService'; From dad6117f363d06f3e13c7f0f0148a543d4de78b5 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 15 Aug 2019 11:39:31 +0200 Subject: [PATCH 642/861] debt - more tests diag --- .../workspaces/test/electron-main/workspacesMainService.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts b/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts index 42556b610fa..395e709bd28 100644 --- a/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts +++ b/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts @@ -342,7 +342,9 @@ suite('WorkspacesMainService', () => { const untitledTwo = await createWorkspace([os.tmpdir(), process.cwd()]); assert.ok(fs.existsSync(untitledTwo.configPath.fsPath)); + assert.ok(fs.existsSync(untitledOne.configPath.fsPath), `Unexpected workspaces count of 1 (expected 2): ${untitledOne.configPath.fsPath} does not exist anymore?`); untitled = service.getUntitledWorkspacesSync(); + assert.ok(fs.existsSync(untitledOne.configPath.fsPath), `Unexpected workspaces count of 1 (expected 2): ${untitledOne.configPath.fsPath} does not exist anymore?`); if (untitled.length === 1) { const untitledHome = dirname(dirname(untitledTwo.configPath)); assert.fail(`Unexpected workspaces count of 1 (expected 2), all workspaces:\n ${fs.readdirSync(untitledHome.fsPath).map(name => fs.readFileSync(joinPath(untitledHome, name, 'workspace.json').fsPath, 'utf8'))}`); From 0a08b58f522fa794d4054bf56298e59ee1408569 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 15 Aug 2019 11:45:27 +0200 Subject: [PATCH 643/861] do not look for executables in web --- .../electron-browser/extensionTipsService.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts index 5610f403056..79255156105 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts @@ -22,7 +22,6 @@ import { IFileService } from 'vs/platform/files/common/files'; import { IExtensionsConfiguration, ConfigurationKey, ShowRecommendationsOnlyOnDemandKey, IExtensionsViewlet, IExtensionsWorkbenchService, EXTENSIONS_CONFIG } from 'vs/workbench/contrib/extensions/common/extensions'; import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import * as os from 'os'; import { flatten, distinct, shuffle, coalesce } from 'vs/base/common/arrays'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { guessMimeTypes, MIME_UNKNOWN } from 'vs/base/common/mime'; @@ -42,6 +41,7 @@ import { extname } from 'vs/base/common/resources'; import { IExeBasedExtensionTip, IProductService } from 'vs/platform/product/common/product'; import { timeout } from 'vs/base/common/async'; import { IWorkspaceStatsService } from 'vs/workbench/contrib/stats/common/workspaceStats'; +import { Platform } from 'vs/base/common/platform'; const milliSecondsInADay = 1000 * 60 * 60 * 24; const choiceNever = localize('neverShowAgain', "Don't Show Again"); @@ -982,11 +982,13 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe /** * If user has any of the tools listed in this.productService.productConfiguration.exeBasedExtensionTips, fetch corresponding recommendations */ - private fetchExecutableRecommendations(important: boolean): Promise { - const homeDir = os.homedir(); - let foundExecutables: Set = new Set(); + private async fetchExecutableRecommendations(important: boolean): Promise { + if (Platform.Web) { + return; + } - let findExecutable = (exeName: string, tip: IExeBasedExtensionTip, path: string) => { + const foundExecutables: Set = new Set(); + const findExecutable = (exeName: string, tip: IExeBasedExtensionTip, path: string) => { return this.fileService.exists(URI.file(path)).then(exists => { if (exists && !foundExecutables.has(exeName)) { foundExecutables.add(exeName); @@ -1002,7 +1004,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe }); }; - let promises: Promise[] = []; + const promises: Promise[] = []; // Loop through recommended extensions forEach(this.productService.productConfiguration.exeBasedExtensionTips, entry => { if (typeof entry.value !== 'object' || !Array.isArray(entry.value['recommendations'])) { @@ -1025,11 +1027,11 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe promises.push(findExecutable(exeName, entry.value, windowsPath)); } else { promises.push(findExecutable(exeName, entry.value, join('/usr/local/bin', exeName))); - promises.push(findExecutable(exeName, entry.value, join(homeDir, exeName))); + promises.push(findExecutable(exeName, entry.value, join(this.environmentService.userHome, exeName))); } }); - return Promise.all(promises).then(() => undefined); + await Promise.all(promises); } /** From 29761995336a8bc70847d3a0eb53ecbbe4443cdd Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 15 Aug 2019 11:50:36 +0200 Subject: [PATCH 644/861] Move extension tips service to web and enable extension recommendations --- .../{electron-browser => browser}/extensionTipsService.ts | 0 .../contrib/extensions/browser/extensions.contribution.ts | 4 +++- .../extensions/electron-browser/extensions.contribution.ts | 5 +---- .../test/electron-browser/extensionsActions.test.ts | 2 +- .../test/electron-browser/extensionsTipsService.test.ts | 2 +- .../extensions/test/electron-browser/extensionsViews.test.ts | 2 +- .../test/electron-browser/extensionsWorkbenchService.test.ts | 2 +- 7 files changed, 8 insertions(+), 9 deletions(-) rename src/vs/workbench/contrib/extensions/{electron-browser => browser}/extensionTipsService.ts (100%) diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts rename to src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts index 32bd703fba0..8dfa256fcf6 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts @@ -10,7 +10,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ExtensionsLabel, ExtensionsChannelId, PreferencesLabel, IExtensionManagementService, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; +import { IExtensionManagementServerService, IExtensionTipsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { IWorkbenchActionRegistry, Extensions as WorkbenchActionExtensions } from 'vs/workbench/common/actions'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { IOutputChannelRegistry, Extensions as OutputExtensions } from 'vs/workbench/contrib/output/common/output'; @@ -45,8 +45,10 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { ExtensionType } from 'vs/platform/extensions/common/extensions'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { RemoteExtensionsInstaller } from 'vs/workbench/contrib/extensions/browser/remoteExtensionsInstaller'; +import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/browser/extensionTipsService'; // Singletons +registerSingleton(IExtensionTipsService, ExtensionTipsService); registerSingleton(IExtensionsWorkbenchService, ExtensionsWorkbenchService); Registry.as(OutputExtensions.OutputChannels) diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts index 643c6e1b456..4c21e1e9181 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts @@ -7,9 +7,7 @@ import { localize } from 'vs/nls'; import { Registry } from 'vs/platform/registry/common/platform'; import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IExtensionTipsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { IWorkbenchActionRegistry, Extensions as WorkbenchActionExtensions } from 'vs/workbench/common/actions'; -import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/electron-browser/extensionTipsService'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; @@ -25,7 +23,6 @@ import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { ExtensionsAutoProfiler } from 'vs/workbench/contrib/extensions/electron-browser/extensionsAutoProfiler'; // Singletons -registerSingleton(IExtensionTipsService, ExtensionTipsService); registerSingleton(IExtensionHostProfileService, ExtensionHostProfileService, true); const workbenchRegistry = Registry.as(WorkbenchExtensions.Workbench); @@ -134,4 +131,4 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitle, { }, group: 'navigation', when: ContextKeyExpr.and(ActiveEditorContext.isEqualTo(RuntimeExtensionsEditor.ID)) -}); \ No newline at end of file +}); diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts index bce6e57e287..32c9e48f8aa 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts @@ -16,7 +16,7 @@ import { import { IExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer, IExtensionTipsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService'; -import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/electron-browser/extensionTipsService'; +import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/browser/extensionTipsService'; import { TestExtensionEnablementService } from 'vs/workbench/services/extensionManagement/test/electron-browser/extensionEnablementService.test'; import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; import { IURLService } from 'vs/platform/url/common/url'; diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts index b66c6143f24..941a3b69a46 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts @@ -15,7 +15,7 @@ import { DidInstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionEvent, IExtensionIdentifier } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IExtensionEnablementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; -import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/electron-browser/extensionTipsService'; +import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/browser/extensionTipsService'; import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { Emitter } from 'vs/base/common/event'; diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts index a618098b66c..318a7e17e45 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts @@ -17,7 +17,7 @@ import { import { IExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer, IExtensionTipsService, ExtensionRecommendationReason } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService'; -import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/electron-browser/extensionTipsService'; +import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/browser/extensionTipsService'; import { TestExtensionEnablementService } from 'vs/workbench/services/extensionManagement/test/electron-browser/extensionEnablementService.test'; import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; import { IURLService } from 'vs/platform/url/common/url'; diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts index 04ed61d0d8a..c87fed721f4 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts @@ -17,7 +17,7 @@ import { import { IExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionTipsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService'; -import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/electron-browser/extensionTipsService'; +import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/browser/extensionTipsService'; import { TestExtensionEnablementService } from 'vs/workbench/services/extensionManagement/test/electron-browser/extensionEnablementService.test'; import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; import { IURLService } from 'vs/platform/url/common/url'; From 7639d9b78e7d2f80aba10267b63ad7c9f053e190 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 15 Aug 2019 12:00:12 +0200 Subject: [PATCH 645/861] use process.setImmediate --- .../contrib/extensions/browser/extensionTipsService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts b/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts index 79255156105..6a6987a2bf8 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts @@ -41,7 +41,7 @@ import { extname } from 'vs/base/common/resources'; import { IExeBasedExtensionTip, IProductService } from 'vs/platform/product/common/product'; import { timeout } from 'vs/base/common/async'; import { IWorkspaceStatsService } from 'vs/workbench/contrib/stats/common/workspaceStats'; -import { Platform } from 'vs/base/common/platform'; +import { Platform, setImmediate } from 'vs/base/common/platform'; const milliSecondsInADay = 1000 * 60 * 60 * 24; const choiceNever = localize('neverShowAgain', "Don't Show Again"); From eed66ab862624ec8be2d6ac138f304382f02158c Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 15 Aug 2019 12:29:21 +0200 Subject: [PATCH 646/861] minor polish --- .../workbench/contrib/debug/browser/debugEditorActions.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts b/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts index 645e55984a5..bf802266912 100644 --- a/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts +++ b/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts @@ -35,23 +35,25 @@ class ToggleBreakpointAction extends EditorAction { } public run(accessor: ServicesAccessor, editor: ICodeEditor): Promise { - if (editor.hasModel() && editor.getSelections()) { + if (editor.hasModel()) { const debugService = accessor.get(IDebugService); const modelUri = editor.getModel().uri; const canSet = debugService.getConfigurationManager().canSetBreakpointsIn(editor.getModel()); // Does not account for multi line selections, Set to remove multiple cursor on the same line const lineNumbers = [...new Set(editor.getSelections().map(s => s.getPosition().lineNumber))]; + return Promise.all(lineNumbers.map(line => { const bps = debugService.getModel().getBreakpoints({ lineNumber: line, uri: modelUri }); if (bps.length) { return Promise.all(bps.map(bp => debugService.removeBreakpoints(bp.getId()))); } else if (canSet) { return (debugService.addBreakpoints(modelUri, [{ lineNumber: line }], 'debugEditorActions.toggleBreakpointAction')); - } else { //Line where a breakpoint cant be set + } else { return Promise.resolve([]); } })); } + return Promise.resolve(); } } From fd9ecea286378377978b551fb164576bb1ed9667 Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 15 Aug 2019 12:34:21 +0200 Subject: [PATCH 647/861] fixes #79168 --- src/vs/workbench/contrib/debug/browser/callStackView.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/callStackView.ts b/src/vs/workbench/contrib/debug/browser/callStackView.ts index a366a0555e3..97836b9a964 100644 --- a/src/vs/workbench/contrib/debug/browser/callStackView.ts +++ b/src/vs/workbench/contrib/debug/browser/callStackView.ts @@ -576,7 +576,7 @@ function isDebugModel(obj: any): obj is IDebugModel { } function isDebugSession(obj: any): obj is IDebugSession { - return typeof obj.getAllThreads === 'function'; + return obj && typeof obj.getAllThreads === 'function'; } function isDeemphasized(frame: IStackFrame): boolean { From 163aed3817c0ae3829ec79ec765cb18e73333a7e Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 15 Aug 2019 12:06:48 +0200 Subject: [PATCH 648/861] fix exports trap --- .../api/worker/extHostExtensionService.ts | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/api/worker/extHostExtensionService.ts b/src/vs/workbench/api/worker/extHostExtensionService.ts index 0b49644e7cc..ada9786cd0f 100644 --- a/src/vs/workbench/api/worker/extHostExtensionService.ts +++ b/src/vs/workbench/api/worker/extHostExtensionService.ts @@ -82,36 +82,35 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { throw new Error(`Cannot load module '${mod}'`); } - const exports = Object.create(null); - patchSelf.module = { exports }; - patchSelf.exports = exports; + const moduleExportsTrap = { exports: Object.create(null) }; + patchSelf.module = moduleExportsTrap; + patchSelf.exports = moduleExportsTrap.exports; const next = joinPath(parent, '..', ensureSuffix(mod, '.js')); moduleStack.push(next); importScripts(asDomUri(next).toString(true)); moduleStack.pop(); - return exports; + return moduleExportsTrap.exports; }; try { activationTimesBuilder.codeLoadingStart(); - const exports = Object.create(null); - patchSelf.module = { exports }; - patchSelf.exports = exports; + const moduleExportsTrap = { exports: Object.create(null) }; + patchSelf.module = moduleExportsTrap; + patchSelf.exports = moduleExportsTrap.exports; module = module.with({ path: ensureSuffix(module.path, '.js') }); moduleStack.push(module); importScripts(asDomUri(module).toString(true)); moduleStack.pop(); + return Promise.resolve(moduleExportsTrap.exports); } finally { activationTimesBuilder.codeLoadingStop(); } - - return Promise.resolve(exports); } async $setRemoteEnvironment(env: { [key: string]: string | null }): Promise { From f6484fd3478ef218afedd59b5b14df6380304fb6 Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 15 Aug 2019 12:52:23 +0200 Subject: [PATCH 649/861] debug: prevent expression.value being undefined fixes #79169 --- src/vs/workbench/contrib/debug/common/debugModel.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/debug/common/debugModel.ts b/src/vs/workbench/contrib/debug/common/debugModel.ts index 7166ad996a7..16a838721c4 100644 --- a/src/vs/workbench/contrib/debug/common/debugModel.ts +++ b/src/vs/workbench/contrib/debug/common/debugModel.ts @@ -227,14 +227,14 @@ export class Expression extends ExpressionContainer implements IExpression { const response = await session.evaluate(this.name, stackFrame ? stackFrame.frameId : undefined, context); this.available = !!(response && response.body); if (response && response.body) { - this.value = response.body.result; + this.value = response.body.result || ''; this.reference = response.body.variablesReference; this.namedVariables = response.body.namedVariables; this.indexedVariables = response.body.indexedVariables; this.type = response.body.type || this.type; } } catch (e) { - this.value = e.message; + this.value = e.message || ''; this.available = false; this.reference = 0; } @@ -256,7 +256,7 @@ export class Variable extends ExpressionContainer implements IExpression { reference: number | undefined, public name: string, public evaluateName: string | undefined, - value: string, + value: string | undefined, namedVariables: number | undefined, indexedVariables: number | undefined, public presentationHint: DebugProtocol.VariablePresentationHint | undefined, @@ -265,7 +265,7 @@ export class Variable extends ExpressionContainer implements IExpression { startOfVariables = 0 ) { super(session, reference, `variable:${parent.getId()}:${name}`, namedVariables, indexedVariables, startOfVariables); - this.value = value; + this.value = value || ''; } async setVariable(value: string): Promise { @@ -276,7 +276,7 @@ export class Variable extends ExpressionContainer implements IExpression { try { const response = await this.session.setVariable((this.parent).reference, this.name, value); if (response && response.body) { - this.value = response.body.value; + this.value = response.body.value || ''; this.type = response.body.type || this.type; this.reference = response.body.variablesReference; this.namedVariables = response.body.namedVariables; From 2b22c0a0b293644cc7484d1f53383838f6c1b3a0 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 15 Aug 2019 13:04:56 +0200 Subject: [PATCH 650/861] update distro --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 337b97fc017..e5af8e0f351 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "5645023d26f429c60aff97c4ce9f3192bfbf5945", + "distro": "c2664514acafa174a6b0b5a960931699641d6989", "author": { "name": "Microsoft Corporation" }, @@ -158,4 +158,4 @@ "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} \ No newline at end of file +} From 92dafb390cdfed6abc029c833a53cb4be7caebbf Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 15 Aug 2019 13:13:58 +0200 Subject: [PATCH 651/861] web - implement credentials provider and add API --- .../workbench/api/browser/mainThreadKeytar.ts | 52 +++---- src/vs/workbench/browser/web.main.ts | 7 +- .../credentials/browser/credentialsService.ts | 132 ++++++++++++++++++ .../credentials/common/credentials.ts | 6 +- .../credentials/node/credentialsService.ts | 8 +- .../environment/browser/environmentService.ts | 18 +-- .../environment/common/environmentService.ts | 3 + .../fileUserDataProvider.test.ts | 6 +- src/vs/workbench/workbench.desktop.main.ts | 4 +- src/vs/workbench/workbench.web.api.ts | 6 + src/vs/workbench/workbench.web.main.ts | 1 + tslint.json | 1 + 12 files changed, 186 insertions(+), 58 deletions(-) create mode 100644 src/vs/workbench/services/credentials/browser/credentialsService.ts rename src/vs/{platform => workbench/services}/credentials/common/credentials.ts (84%) rename src/vs/{platform => workbench/services}/credentials/node/credentialsService.ts (80%) diff --git a/src/vs/workbench/api/browser/mainThreadKeytar.ts b/src/vs/workbench/api/browser/mainThreadKeytar.ts index fff0a902e2c..f07b7688801 100644 --- a/src/vs/workbench/api/browser/mainThreadKeytar.ts +++ b/src/vs/workbench/api/browser/mainThreadKeytar.ts @@ -5,49 +5,33 @@ import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { MainContext, MainThreadKeytarShape, IExtHostContext } from 'vs/workbench/api/common/extHost.protocol'; -import { ICredentialsService } from 'vs/platform/credentials/common/credentials'; -import { optional } from 'vs/platform/instantiation/common/instantiation'; +import { ICredentialsService } from 'vs/workbench/services/credentials/common/credentials'; @extHostNamedCustomer(MainContext.MainThreadKeytar) export class MainThreadKeytar implements MainThreadKeytarShape { - private readonly _credentialsService?: ICredentialsService; - constructor( _extHostContext: IExtHostContext, - @optional(ICredentialsService) credentialsService: ICredentialsService, - ) { - this._credentialsService = credentialsService; + @ICredentialsService private readonly _credentialsService: ICredentialsService, + ) { } + + async $getPassword(service: string, account: string): Promise { + return this._credentialsService.getPassword(service, account); + } + + async $setPassword(service: string, account: string, password: string): Promise { + return this._credentialsService.setPassword(service, account, password); + } + + async $deletePassword(service: string, account: string): Promise { + return this._credentialsService.deletePassword(service, account); + } + + async $findPassword(service: string): Promise { + return this._credentialsService.findPassword(service); } dispose(): void { // } - - async $getPassword(service: string, account: string): Promise { - if (this._credentialsService) { - return this._credentialsService.getPassword(service, account); - } - return null; - } - - async $setPassword(service: string, account: string, password: string): Promise { - if (this._credentialsService) { - return this._credentialsService.setPassword(service, account, password); - } - } - - async $deletePassword(service: string, account: string): Promise { - if (this._credentialsService) { - return this._credentialsService.deletePassword(service, account); - } - return false; - } - - async $findPassword(service: string): Promise { - if (this._credentialsService) { - return this._credentialsService.findPassword(service); - } - return null; - } } diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index 909f7578e4c..812663e25d4 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -117,12 +117,7 @@ class CodeRendererMain extends Disposable { const payload = await this.resolveWorkspaceInitializationPayload(); // Environment - const environmentService = new BrowserWorkbenchEnvironmentService({ - workspaceId: payload.id, - remoteAuthority: this.configuration.remoteAuthority, - webviewEndpoint: this.configuration.webviewEndpoint, - connectionToken: this.configuration.connectionToken - }); + const environmentService = new BrowserWorkbenchEnvironmentService(payload.id, this.configuration); serviceCollection.set(IWorkbenchEnvironmentService, environmentService); // Product diff --git a/src/vs/workbench/services/credentials/browser/credentialsService.ts b/src/vs/workbench/services/credentials/browser/credentialsService.ts new file mode 100644 index 00000000000..b7613b9c23c --- /dev/null +++ b/src/vs/workbench/services/credentials/browser/credentialsService.ts @@ -0,0 +1,132 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ICredentialsService } from 'vs/workbench/services/credentials/common/credentials'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; + +export interface ICredentialsProvider { + getPassword(service: string, account: string): Promise; + setPassword(service: string, account: string, password: string): Promise; + deletePassword(service: string, account: string): Promise; + findPassword(service: string): Promise; +} + +export class BrowserCredentialsService implements ICredentialsService { + + _serviceBrand!: ServiceIdentifier; + + private credentialsProvider: ICredentialsProvider; + + constructor(@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService) { + if (environmentService.options && environmentService.options.credentialsProvider) { + this.credentialsProvider = environmentService.options.credentialsProvider; + } else { + this.credentialsProvider = new LocalStorageCredentialsProvider(); + } + } + + async getPassword(service: string, account: string): Promise { + return this.credentialsProvider.getPassword(service, account); + } + + async setPassword(service: string, account: string, password: string): Promise { + return this.credentialsProvider.setPassword(service, account, password); + } + + async deletePassword(service: string, account: string): Promise { + return this.credentialsProvider.deletePassword(service, account); + } + + async findPassword(service: string): Promise { + return this.credentialsProvider.findPassword(service); + } +} + +interface ICredential { + service: string; + account: string; + password: string; +} + +class LocalStorageCredentialsProvider implements ICredentialsProvider { + + static readonly CREDENTIALS_OPENED_KEY = 'credentials.provider'; + + private _credentials: ICredential[]; + private get credentials(): ICredential[] { + if (!this._credentials) { + try { + const serializedCredentials = window.localStorage.getItem(LocalStorageCredentialsProvider.CREDENTIALS_OPENED_KEY); + if (serializedCredentials) { + this._credentials = JSON.parse(serializedCredentials); + } + } catch (error) { + // ignore + } + + if (!Array.isArray(this._credentials)) { + this._credentials = []; + } + } + + return this._credentials; + } + + private save(): void { + window.localStorage.setItem(LocalStorageCredentialsProvider.CREDENTIALS_OPENED_KEY, JSON.stringify(this.credentials)); + } + + async getPassword(service: string, account: string): Promise { + return this.doGetPassword(service, account); + } + + private async doGetPassword(service: string, account?: string): Promise { + for (const credential of this.credentials) { + if (credential.service === service) { + if (typeof account !== 'string' || account === credential.account) { + return credential.password; + } + } + } + + return null; + } + + async setPassword(service: string, account: string, password: string): Promise { + this.deletePassword(service, account); + + this.credentials.push({ service, account, password }); + + this.save(); + } + + async deletePassword(service: string, account: string): Promise { + let found = false; + + this._credentials = this.credentials.filter(credential => { + if (credential.service === service && credential.account === account) { + found = true; + + return false; + } + + return true; + }); + + if (found) { + this.save(); + } + + return found; + } + + async findPassword(service: string): Promise { + return this.doGetPassword(service); + } +} + +registerSingleton(ICredentialsService, BrowserCredentialsService, true); diff --git a/src/vs/platform/credentials/common/credentials.ts b/src/vs/workbench/services/credentials/common/credentials.ts similarity index 84% rename from src/vs/platform/credentials/common/credentials.ts rename to src/vs/workbench/services/credentials/common/credentials.ts index dc6618d89f7..8fa520c374e 100644 --- a/src/vs/platform/credentials/common/credentials.ts +++ b/src/vs/workbench/services/credentials/common/credentials.ts @@ -3,12 +3,14 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; export const ICredentialsService = createDecorator('ICredentialsService'); export interface ICredentialsService { - _serviceBrand: any; + + _serviceBrand: ServiceIdentifier; + getPassword(service: string, account: string): Promise; setPassword(service: string, account: string, password: string): Promise; deletePassword(service: string, account: string): Promise; diff --git a/src/vs/platform/credentials/node/credentialsService.ts b/src/vs/workbench/services/credentials/node/credentialsService.ts similarity index 80% rename from src/vs/platform/credentials/node/credentialsService.ts rename to src/vs/workbench/services/credentials/node/credentialsService.ts index 282b761fe2e..1361f169be3 100644 --- a/src/vs/platform/credentials/node/credentialsService.ts +++ b/src/vs/workbench/services/credentials/node/credentialsService.ts @@ -3,8 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ICredentialsService } from 'vs/platform/credentials/common/credentials'; +import { ICredentialsService } from 'vs/workbench/services/credentials/common/credentials'; import { IdleValue } from 'vs/base/common/async'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; type KeytarModule = { getPassword(service: string, account: string): Promise; @@ -15,7 +17,7 @@ type KeytarModule = { export class KeytarCredentialsService implements ICredentialsService { - _serviceBrand: any; + _serviceBrand!: ServiceIdentifier; private readonly _keytar = new IdleValue>(() => import('keytar')); @@ -39,3 +41,5 @@ export class KeytarCredentialsService implements ICredentialsService { return keytar.findPassword(service); } } + +registerSingleton(ICredentialsService, KeytarCredentialsService, true); diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts index 250fd43582e..c8e2227fc0d 100644 --- a/src/vs/workbench/services/environment/browser/environmentService.ts +++ b/src/vs/workbench/services/environment/browser/environmentService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IWindowConfiguration, IPath, IPathsToWaitFor } from 'vs/platform/windows/common/windows'; -import { IEnvironmentService, IExtensionHostDebugParams, IDebugParams, BACKUPS } from 'vs/platform/environment/common/environment'; +import { IExtensionHostDebugParams, IDebugParams, BACKUPS } from 'vs/platform/environment/common/environment'; import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { URI } from 'vs/base/common/uri'; import { IProcessEnvironment } from 'vs/base/common/platform'; @@ -13,6 +13,8 @@ import { ExportData } from 'vs/base/common/performance'; import { LogLevel } from 'vs/platform/log/common/log'; import { joinPath } from 'vs/base/common/resources'; import { Schemas } from 'vs/base/common/network'; +import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; +import { IWorkbenchConstructionOptions } from 'vs/workbench/workbench.web.api'; export class BrowserWindowConfiguration implements IWindowConfiguration { @@ -66,26 +68,26 @@ export interface IBrowserWindowConfiguration { connectionToken?: string; } -export class BrowserWorkbenchEnvironmentService implements IEnvironmentService { +export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironmentService { - _serviceBrand!: ServiceIdentifier; + _serviceBrand!: ServiceIdentifier; readonly configuration: IWindowConfiguration = new BrowserWindowConfiguration(); - constructor(configuration: IBrowserWindowConfiguration) { + constructor(workspaceId: string, public readonly options: IWorkbenchConstructionOptions) { this.args = { _: [] }; this.appRoot = '/web/'; this.appNameLong = 'Visual Studio Code - Web'; - this.configuration.remoteAuthority = configuration.remoteAuthority; + this.configuration.remoteAuthority = options.remoteAuthority; this.userRoamingDataHome = URI.file('/User').with({ scheme: Schemas.userData }); this.settingsResource = joinPath(this.userRoamingDataHome, 'settings.json'); this.keybindingsResource = joinPath(this.userRoamingDataHome, 'keybindings.json'); this.keyboardLayoutResource = joinPath(this.userRoamingDataHome, 'keyboardLayout.json'); this.localeResource = joinPath(this.userRoamingDataHome, 'locale.json'); this.backupHome = joinPath(this.userRoamingDataHome, BACKUPS); - this.configuration.backupWorkspaceResource = joinPath(this.backupHome, configuration.workspaceId); - this.configuration.connectionToken = configuration.connectionToken || this.getConnectionTokenFromLocation(); + this.configuration.backupWorkspaceResource = joinPath(this.backupHome, workspaceId); + this.configuration.connectionToken = options.connectionToken || this.getConnectionTokenFromLocation(); this.logsPath = '/web/logs'; @@ -94,7 +96,7 @@ export class BrowserWorkbenchEnvironmentService implements IEnvironmentService { break: false }; - this.webviewEndpoint = configuration.webviewEndpoint; + this.webviewEndpoint = options.webviewEndpoint; this.untitledWorkspacesHome = URI.from({ scheme: Schemas.untitled, path: 'Workspaces' }); if (document && document.location && document.location.search) { diff --git a/src/vs/workbench/services/environment/common/environmentService.ts b/src/vs/workbench/services/environment/common/environmentService.ts index fd4beaf134d..72c98796b9a 100644 --- a/src/vs/workbench/services/environment/common/environmentService.ts +++ b/src/vs/workbench/services/environment/common/environmentService.ts @@ -6,6 +6,7 @@ import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IWorkbenchConstructionOptions } from 'vs/workbench/workbench.web.api'; export const IWorkbenchEnvironmentService = createDecorator('environmentService'); @@ -14,4 +15,6 @@ export interface IWorkbenchEnvironmentService extends IEnvironmentService { _serviceBrand: ServiceIdentifier; readonly configuration: IWindowConfiguration; + + readonly options?: IWorkbenchConstructionOptions; } diff --git a/src/vs/workbench/services/userData/test/electron-browser/fileUserDataProvider.test.ts b/src/vs/workbench/services/userData/test/electron-browser/fileUserDataProvider.test.ts index b8ba819bba8..854e9582f5a 100644 --- a/src/vs/workbench/services/userData/test/electron-browser/fileUserDataProvider.test.ts +++ b/src/vs/workbench/services/userData/test/electron-browser/fileUserDataProvider.test.ts @@ -47,7 +47,7 @@ suite('FileUserDataProvider', () => { userDataResource = URI.file(userDataPath).with({ scheme: Schemas.userData }); await Promise.all([pfs.mkdirp(userDataPath), pfs.mkdirp(backupsPath)]); - const environmentService = new BrowserWorkbenchEnvironmentService({ workspaceId: 'workspaceId' }); + const environmentService = new BrowserWorkbenchEnvironmentService('workspaceId', { remoteAuthority: 'remote' }); environmentService.userRoamingDataHome = userDataResource; const userDataFileSystemProvider = new FileUserDataProvider(URI.file(userDataPath), URI.file(backupsPath), diskFileSystemProvider, environmentService); @@ -321,7 +321,7 @@ suite('FileUserDataProvider - Watching', () => { localUserDataResource = URI.file(userDataPath); userDataResource = localUserDataResource.with({ scheme: Schemas.userData }); - const environmentService = new BrowserWorkbenchEnvironmentService({ workspaceId: 'workspaceId' }); + const environmentService = new BrowserWorkbenchEnvironmentService('workspaceId', { remoteAuthority: 'remote' }); environmentService.userRoamingDataHome = userDataResource; const userDataFileSystemProvider = new FileUserDataProvider(localUserDataResource, localBackupsResource, new TestFileSystemProvider(fileEventEmitter.event), environmentService); @@ -475,4 +475,4 @@ suite('FileUserDataProvider - Watching', () => { type: FileChangeType.DELETED }]); }); -}); \ No newline at end of file +}); diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index f6a48a02812..3373be0bd35 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -49,6 +49,7 @@ import 'vs/workbench/services/accessibility/node/accessibilityService'; import 'vs/workbench/services/remote/node/tunnelService'; import 'vs/workbench/services/backup/node/backupFileService'; import 'vs/workbench/services/opener/electron-browser/openerService'; +import 'vs/workbench/services/credentials/node/credentialsService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; @@ -74,8 +75,6 @@ import { IMenubarService } from 'vs/platform/menubar/common/menubar'; import { MenubarService } from 'vs/platform/menubar/electron-browser/menubarService'; import { IURLService } from 'vs/platform/url/common/url'; import { RelayURLService } from 'vs/platform/url/electron-browser/urlService'; -import { ICredentialsService } from 'vs/platform/credentials/common/credentials'; -import { KeytarCredentialsService } from 'vs/platform/credentials/node/credentialsService'; registerSingleton(IClipboardService, ClipboardService, true); registerSingleton(IRequestService, RequestService, true); @@ -89,7 +88,6 @@ registerSingleton(IIssueService, IssueService); registerSingleton(IWorkspacesService, WorkspacesService); registerSingleton(IMenubarService, MenubarService); registerSingleton(IURLService, RelayURLService); -registerSingleton(ICredentialsService, KeytarCredentialsService, true); //#endregion diff --git a/src/vs/workbench/workbench.web.api.ts b/src/vs/workbench/workbench.web.api.ts index 15156252d69..2727fa5eb5d 100644 --- a/src/vs/workbench/workbench.web.api.ts +++ b/src/vs/workbench/workbench.web.api.ts @@ -8,6 +8,7 @@ import { main } from 'vs/workbench/browser/web.main'; import { UriComponents } from 'vs/base/common/uri'; import { IFileSystemProvider } from 'vs/platform/files/common/files'; import { IWebSocketFactory } from 'vs/platform/remote/browser/browserSocketFactory'; +import { ICredentialsProvider } from 'vs/workbench/services/credentials/browser/credentialsService'; export interface IWorkbenchConstructionOptions { @@ -53,6 +54,11 @@ export interface IWorkbenchConstructionOptions { * Experimental: Whether to enable the smoke test driver. */ driver?: boolean; + + /** + * Experimental: The credentials provider to store and retrieve secrets. + */ + credentialsProvider?: ICredentialsProvider; } /** diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 8d06f34a906..40384b249b0 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -36,6 +36,7 @@ import 'vs/workbench/services/extensions/browser/extensionService'; import 'vs/workbench/services/extensionManagement/common/extensionManagementServerService'; import 'vs/workbench/services/telemetry/browser/telemetryService'; import 'vs/workbench/services/configurationResolver/browser/configurationResolverService'; +import 'vs/workbench/services/credentials/browser/credentialsService'; import 'vs/workbench/browser/web.simpleservices'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; diff --git a/tslint.json b/tslint.json index 548b9a51191..4b23918f0fc 100644 --- a/tslint.json +++ b/tslint.json @@ -436,6 +436,7 @@ "**/vs/base/**/common/**", "**/vs/platform/**/common/**", "**/vs/editor/common/**", + "**/vs/workbench/workbench.web.api", "**/vs/workbench/common/**", "**/vs/workbench/services/**/common/**", "**/vs/workbench/api/**/common/**", From 40b5ba9cf24e344db916a5ab65e79ca4b3b636fa Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 15 Aug 2019 13:57:15 +0200 Subject: [PATCH 652/861] web - workaround clipboard issue with selection type --- src/vs/platform/clipboard/browser/clipboardService.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/vs/platform/clipboard/browser/clipboardService.ts b/src/vs/platform/clipboard/browser/clipboardService.ts index 8ea9e8e026d..c5e8a2676d2 100644 --- a/src/vs/platform/clipboard/browser/clipboardService.ts +++ b/src/vs/platform/clipboard/browser/clipboardService.ts @@ -15,10 +15,18 @@ export class BrowserClipboardService implements IClipboardService { private _internalResourcesClipboard: URI[] | undefined; async writeText(text: string, type?: string): Promise { + if (type) { + return; // TODO@sbatten + } + return navigator.clipboard.writeText(text); } async readText(type?: string): Promise { + if (type) { + return ''; // TODO@sbatten + } + return navigator.clipboard.readText(); } From 032ffe6ae1e81c344377cafde58d47784aefdd9c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 15 Aug 2019 14:03:14 +0200 Subject: [PATCH 653/861] better exports trapping --- .../api/worker/extHostExtensionService.ts | 82 +++++++++++++++---- 1 file changed, 68 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/api/worker/extHostExtensionService.ts b/src/vs/workbench/api/worker/extHostExtensionService.ts index ada9786cd0f..d3d36327339 100644 --- a/src/vs/workbench/api/worker/extHostExtensionService.ts +++ b/src/vs/workbench/api/worker/extHostExtensionService.ts @@ -43,6 +43,69 @@ class ApiInstances { } } +class ExportsTrap { + + static readonly Instance = new ExportsTrap(); + + private readonly _names: string[] = []; + private readonly _exports = new Map(); + + private constructor() { + + const exportsProxy = new Proxy({}, { + set: (target: any, p: PropertyKey, value: any, receiver: any) => { + // store in target + target[p] = value; + // store in named-bucket + const name = this._names[this._names.length - 1]; + this._exports.get(name)![p] = value; + return true; + } + }); + + + const moduleProxy = new Proxy({}, { + + get: (target: any, p: PropertyKey) => { + if (p === 'exports') { + return exportsProxy; + } + + return target[p]; + }, + + set: (target: any, p: PropertyKey, value: any, receiver: any) => { + // store in target + target[p] = value; + + // override bucket + if (p === 'exports') { + const name = this._names[this._names.length - 1]; + this._exports.set(name, value); + } + return true; + } + }); + + (self).exports = exportsProxy; + (self).module = moduleProxy; + } + + add(name: string) { + this._exports.set(name, Object.create(null)); + this._names.push(name); + + return { + claim: () => { + const result = this._exports.get(name); + this._exports.delete(name); + this._names.pop(); + return result; + } + }; + } +} + export class ExtHostExtensionService extends AbstractExtHostExtensionService { private _apiInstances?: ApiInstances; @@ -57,7 +120,6 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { protected _loadCommonJSModule(module: URI, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { - interface FakeCommonJSSelf { module?: object; exports?: object; @@ -82,38 +144,30 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { throw new Error(`Cannot load module '${mod}'`); } - const moduleExportsTrap = { exports: Object.create(null) }; - patchSelf.module = moduleExportsTrap; - patchSelf.exports = moduleExportsTrap.exports; - const next = joinPath(parent, '..', ensureSuffix(mod, '.js')); moduleStack.push(next); + const trap = ExportsTrap.Instance.add(next.toString()); importScripts(asDomUri(next).toString(true)); moduleStack.pop(); - return moduleExportsTrap.exports; + return trap.claim(); }; try { activationTimesBuilder.codeLoadingStart(); - - const moduleExportsTrap = { exports: Object.create(null) }; - patchSelf.module = moduleExportsTrap; - patchSelf.exports = moduleExportsTrap.exports; - module = module.with({ path: ensureSuffix(module.path, '.js') }); moduleStack.push(module); - + const trap = ExportsTrap.Instance.add(module.toString()); importScripts(asDomUri(module).toString(true)); moduleStack.pop(); - return Promise.resolve(moduleExportsTrap.exports); + return Promise.resolve(trap.claim()); } finally { activationTimesBuilder.codeLoadingStop(); } } - async $setRemoteEnvironment(env: { [key: string]: string | null }): Promise { + async $setRemoteEnvironment(_env: { [key: string]: string | null }): Promise { throw new Error('Not supported'); } } From f5ade17659504c1b305959b265fbe0712b757e1a Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 15 Aug 2019 14:37:08 +0200 Subject: [PATCH 654/861] fix process layer-breaker --- src/vs/workbench/contrib/extensions/browser/extensionEditor.ts | 3 ++- .../contrib/extensions/browser/extensionTipsService.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index 2a19adea3df..e31c90cb95b 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -53,6 +53,7 @@ import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/work import { IWebviewService, Webview } from 'vs/workbench/contrib/webview/common/webview'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { generateUuid } from 'vs/base/common/uuid'; +import { platform } from 'vs/base/common/process'; function removeEmbeddedSVGs(documentContent: string): string { const newDocument = new DOMParser().parseFromString(documentContent, 'text/html'); @@ -1275,7 +1276,7 @@ export class ExtensionEditor extends BaseEditor { private resolveKeybinding(rawKeyBinding: IKeyBinding): ResolvedKeybinding | null { let key: string | undefined; - switch (process.platform) { + switch (platform) { case 'win32': key = rawKeyBinding.win; break; case 'linux': key = rawKeyBinding.linux; break; case 'darwin': key = rawKeyBinding.mac; break; diff --git a/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts b/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts index 6a6987a2bf8..4597b0270e7 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts @@ -42,6 +42,7 @@ import { IExeBasedExtensionTip, IProductService } from 'vs/platform/product/comm import { timeout } from 'vs/base/common/async'; import { IWorkspaceStatsService } from 'vs/workbench/contrib/stats/common/workspaceStats'; import { Platform, setImmediate } from 'vs/base/common/platform'; +import { platform } from 'vs/base/common/process'; const milliSecondsInADay = 1000 * 60 * 60 * 24; const choiceNever = localize('neverShowAgain', "Don't Show Again"); @@ -1014,7 +1015,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe return; } const exeName = entry.key; - if (process.platform === 'win32') { + if (platform === 'win32') { let windowsPath = entry.value['windowsPath']; if (!windowsPath || typeof windowsPath !== 'string') { return; From 5d4a2514c9db09909bc06b34033a4f0117c1ba72 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 15 Aug 2019 14:57:21 +0200 Subject: [PATCH 655/861] debt - avoid process dependency in common --- src/vs/base/parts/ipc/common/ipc.net.ts | 9 ++------- src/vs/base/test/common/path.test.ts | 1 + .../contrib/search/test/common/queryBuilder.test.ts | 3 ++- .../contrib/search/test/common/searchModel.test.ts | 1 + 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/vs/base/parts/ipc/common/ipc.net.ts b/src/vs/base/parts/ipc/common/ipc.net.ts index 459a5b94bd8..207fceb65b9 100644 --- a/src/vs/base/parts/ipc/common/ipc.net.ts +++ b/src/vs/base/parts/ipc/common/ipc.net.ts @@ -8,8 +8,7 @@ import { IMessagePassingProtocol, IPCClient } from 'vs/base/parts/ipc/common/ipc import { IDisposable, Disposable, dispose } from 'vs/base/common/lifecycle'; import { VSBuffer } from 'vs/base/common/buffer'; import * as platform from 'vs/base/common/platform'; - -declare var process: any; +import * as process from 'vs/base/common/process'; export interface ISocket extends IDisposable { onData(listener: (e: VSBuffer) => void): IDisposable; @@ -434,11 +433,7 @@ export function createBufferedEvent(source: Event): Event { // it is important to deliver these messages after this call, but before // other messages have a chance to be received (to guarantee in order delivery) // that's why we're using here nextTick and not other types of timeouts - if (typeof process !== 'undefined') { - process.nextTick(deliverMessages); - } else { - platform.setImmediate(deliverMessages); - } + process.nextTick(deliverMessages); }, onLastListenerRemove: () => { hasListeners = false; diff --git a/src/vs/base/test/common/path.test.ts b/src/vs/base/test/common/path.test.ts index cfceaedc9e9..f5230c4a35c 100644 --- a/src/vs/base/test/common/path.test.ts +++ b/src/vs/base/test/common/path.test.ts @@ -30,6 +30,7 @@ import * as assert from 'assert'; import * as path from 'vs/base/common/path'; import { isWindows } from 'vs/base/common/platform'; +import * as process from 'vs/base/common/process'; suite('Paths (Node Implementation)', () => { test('join', () => { diff --git a/src/vs/workbench/contrib/search/test/common/queryBuilder.test.ts b/src/vs/workbench/contrib/search/test/common/queryBuilder.test.ts index 0c14fd010f7..ed8fd458877 100644 --- a/src/vs/workbench/contrib/search/test/common/queryBuilder.test.ts +++ b/src/vs/workbench/contrib/search/test/common/queryBuilder.test.ts @@ -14,6 +14,7 @@ import { IFolderQuery, IPatternInfo, QueryType, ITextQuery, IFileQuery } from 'v import { IWorkspaceContextService, toWorkspaceFolder, Workspace, toWorkspaceFolders } from 'vs/platform/workspace/common/workspace'; import { ISearchPathsInfo, QueryBuilder } from 'vs/workbench/contrib/search/common/queryBuilder'; import { TestContextService, TestEnvironmentService } from 'vs/workbench/test/workbenchTestServices'; +import { isWindows } from 'vs/base/common/platform'; const DEFAULT_EDITOR_CONFIG = {}; const DEFAULT_USER_CONFIG = { useRipgrep: true, useIgnoreFiles: true, useGlobalIgnoreFiles: true }; @@ -1032,7 +1033,7 @@ function getUri(...slashPathParts: string[]): uri { } function fixPath(...slashPathParts: string[]): string { - if (process.platform === 'win32' && slashPathParts.length && !slashPathParts[0].match(/^c:/i)) { + if (isWindows && slashPathParts.length && !slashPathParts[0].match(/^c:/i)) { slashPathParts.unshift('c:'); } diff --git a/src/vs/workbench/contrib/search/test/common/searchModel.test.ts b/src/vs/workbench/contrib/search/test/common/searchModel.test.ts index ba00d3b20a1..7ad9e679d1f 100644 --- a/src/vs/workbench/contrib/search/test/common/searchModel.test.ts +++ b/src/vs/workbench/contrib/search/test/common/searchModel.test.ts @@ -18,6 +18,7 @@ import { IFileMatch, IFileSearchStats, IFolderQuery, ISearchComplete, ISearchPro import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { SearchModel } from 'vs/workbench/contrib/search/common/searchModel'; +import * as process from 'vs/base/common/process'; const nullEvent = new class { id: number; From 985c775b38a7a29907e050ab37e5daef8e2e87eb Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 15 Aug 2019 15:23:35 +0200 Subject: [PATCH 656/861] rawDebugSession: do not use process #79210 --- src/vs/workbench/contrib/debug/browser/rawDebugSession.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts b/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts index 39bb171c4ec..0d1772ff111 100644 --- a/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts @@ -16,6 +16,7 @@ import { ParsedArgs } from 'vs/platform/environment/common/environment'; import { IWindowsService } from 'vs/platform/windows/common/windows'; import { URI } from 'vs/base/common/uri'; import { IProcessEnvironment } from 'vs/base/common/platform'; +import { env as processEnv } from 'vs/base/common/process'; /** * This interface represents a single command line argument split into a "prefix" and a "path" half. @@ -594,10 +595,7 @@ export class RawDebugSession { let env: IProcessEnvironment = {}; if (vscodeArgs.env) { // merge environment variables into a copy of the process.env - if (typeof process === 'object' && process.env) { - env = objects.mixin(env, process.env); - } - env = objects.mixin(env, vscodeArgs.env); + env = objects.mixin(processEnv, vscodeArgs.env); // and delete some if necessary Object.keys(env).filter(k => env[k] === null).forEach(key => delete env[key]); } From 21de711cdfb32d5798abbd60fc4ef92e640d23dd Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 15 Aug 2019 15:22:45 +0200 Subject: [PATCH 657/861] remove proposed API `vscode.commands.onDidExecuteCommand` --- src/vs/vscode.proposed.d.ts | 16 -------------- .../api/browser/mainThreadCommands.ts | 14 ------------ .../workbench/api/common/extHost.api.impl.ts | 6 +---- .../workbench/api/common/extHost.protocol.ts | 5 +---- .../workbench/api/common/extHostCommands.ts | 22 ++----------------- 5 files changed, 4 insertions(+), 59 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 0b9ad6976fa..328fcae5896 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -565,22 +565,6 @@ declare module 'vscode' { //#endregion - //#region Joh: onDidExecuteCommand - - export interface CommandExecutionEvent { - command: string; - arguments: any[]; - } - - export namespace commands { - /** - * An event that is emitted when a [command](#Command) is executed. - */ - export const onDidExecuteCommand: Event; - } - - //#endregion - //#region Joh: decorations //todo@joh -> make class diff --git a/src/vs/workbench/api/browser/mainThreadCommands.ts b/src/vs/workbench/api/browser/mainThreadCommands.ts index 25dc1138055..2f4d043f048 100644 --- a/src/vs/workbench/api/browser/mainThreadCommands.ts +++ b/src/vs/workbench/api/browser/mainThreadCommands.ts @@ -15,7 +15,6 @@ export class MainThreadCommands implements MainThreadCommandsShape { private readonly _commandRegistrations = new Map(); private readonly _generateCommandsDocumentationRegistration: IDisposable; private readonly _proxy: ExtHostCommandsShape; - private _onDidExecuteCommandListener?: IDisposable; constructor( extHostContext: IExtHostContext, @@ -78,19 +77,6 @@ export class MainThreadCommands implements MainThreadCommandsShape { return this._commandService.executeCommand(id, ...args); } - $registerCommandListener() { - if (!this._onDidExecuteCommandListener) { - this._onDidExecuteCommandListener = this._commandService.onDidExecuteCommand(command => this._proxy.$handleDidExecuteCommand(command)); - } - } - - $unregisterCommandListener() { - if (this._onDidExecuteCommandListener) { - this._onDidExecuteCommandListener.dispose(); - this._onDidExecuteCommandListener = undefined; - } - } - $getCommands(): Promise { return Promise.resolve([...CommandsRegistry.getCommands().keys()]); } diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 0c4b489095d..5370f6a01ba 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -223,11 +223,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I }, getCommands(filterInternal: boolean = false): Thenable { return extHostCommands.getCommands(filterInternal); - }, - onDidExecuteCommand: proposedApiFunction(extension, (listener, thisArgs?, disposables?) => { - checkProposedApiEnabled(extension); - return extHostCommands.onDidExecuteCommand(listener, thisArgs, disposables); - }), + } }; // namespace: env diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 259f0d50658..1cc498a9ca4 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -21,7 +21,7 @@ import { EndOfLineSequence, ISingleEditOperation } from 'vs/editor/common/model' import { IModelChangedEvent } from 'vs/editor/common/model/mirrorTextModel'; import * as modes from 'vs/editor/common/modes'; import { CharacterPair, CommentRule, EnterAction } from 'vs/editor/common/modes/languageConfiguration'; -import { ICommandHandlerDescription, ICommandEvent } from 'vs/platform/commands/common/commands'; +import { ICommandHandlerDescription } from 'vs/platform/commands/common/commands'; import { ConfigurationTarget, IConfigurationData, IConfigurationModel } from 'vs/platform/configuration/common/configuration'; import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; @@ -115,8 +115,6 @@ export interface MainThreadClipboardShape extends IDisposable { export interface MainThreadCommandsShape extends IDisposable { $registerCommand(id: string): void; - $registerCommandListener(): void; - $unregisterCommandListener(): void; $unregisterCommand(id: string): void; $executeCommand(id: string, args: any[]): Promise; $getCommands(): Promise; @@ -735,7 +733,6 @@ export interface MainThreadWindowShape extends IDisposable { export interface ExtHostCommandsShape { $executeContributedCommand(id: string, ...args: any[]): Promise; $getContributedCommandHandlerDescriptions(): Promise<{ [id: string]: string | ICommandHandlerDescription }>; - $handleDidExecuteCommand(command: ICommandEvent): void; } export interface ExtHostConfigurationShape { diff --git a/src/vs/workbench/api/common/extHostCommands.ts b/src/vs/workbench/api/common/extHostCommands.ts index 1e229fc3dad..8111a7687cf 100644 --- a/src/vs/workbench/api/common/extHostCommands.ts +++ b/src/vs/workbench/api/common/extHostCommands.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { validateConstraint } from 'vs/base/common/types'; -import { ICommandHandlerDescription, ICommandEvent } from 'vs/platform/commands/common/commands'; +import { ICommandHandlerDescription } from 'vs/platform/commands/common/commands'; import * as extHostTypes from 'vs/workbench/api/common/extHostTypes'; import * as extHostTypeConverter from 'vs/workbench/api/common/extHostTypeConverters'; import { cloneAndChange } from 'vs/base/common/objects'; @@ -17,7 +17,6 @@ import { revive } from 'vs/base/common/marshalling'; import { Range } from 'vs/editor/common/core/range'; import { Position } from 'vs/editor/common/core/position'; import { URI } from 'vs/base/common/uri'; -import { Event, Emitter } from 'vs/base/common/event'; import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; @@ -36,9 +35,6 @@ export class ExtHostCommands implements ExtHostCommandsShape { readonly _serviceBrand: any; - private readonly _onDidExecuteCommand: Emitter; - readonly onDidExecuteCommand: Event; - private readonly _commands = new Map(); private readonly _proxy: MainThreadCommandsShape; private readonly _converter: CommandsConverter; @@ -50,11 +46,6 @@ export class ExtHostCommands implements ExtHostCommandsShape { @ILogService logService: ILogService ) { this._proxy = extHostRpc.getProxy(MainContext.MainThreadCommands); - this._onDidExecuteCommand = new Emitter({ - onFirstListenerDidAdd: () => this._proxy.$registerCommandListener(), - onLastListenerRemove: () => this._proxy.$unregisterCommandListener(), - }); - this.onDidExecuteCommand = Event.filter(this._onDidExecuteCommand.event, e => e.command[0] !== '_'); // filter 'private' commands this._logService = logService; this._converter = new CommandsConverter(this); this._argumentProcessors = [ @@ -119,22 +110,13 @@ export class ExtHostCommands implements ExtHostCommandsShape { }); } - $handleDidExecuteCommand(command: ICommandEvent): void { - this._onDidExecuteCommand.fire({ - command: command.commandId, - arguments: command.args.map(arg => this._argumentProcessors.reduce((r, p) => p.processArgument(r), arg)) - }); - } - executeCommand(id: string, ...args: any[]): Promise { this._logService.trace('ExtHostCommands#executeCommand', id); if (this._commands.has(id)) { // we stay inside the extension host and support // to pass any kind of parameters around - const res = this._executeContributedCommand(id, args); - this._onDidExecuteCommand.fire({ command: id, arguments: args }); - return res; + return this._executeContributedCommand(id, args); } else { // automagically convert some argument types From bc433d65c4a4c7ce776895d924c5d8f8da121fad Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 15 Aug 2019 15:36:57 +0200 Subject: [PATCH 658/861] Fix #79206 --- .../browser/extensionTipsService.ts | 30 +++++++++++++------ .../browser/extensions.contribution.ts | 4 +-- .../browser/extensions.web.contribution.ts | 11 +++++++ .../electron-browser/extensionTipsService.ts | 15 ++++++++++ .../extensions.contribution.ts | 3 ++ src/vs/workbench/workbench.web.main.ts | 3 ++ 6 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 src/vs/workbench/contrib/extensions/browser/extensions.web.contribution.ts create mode 100644 src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts diff --git a/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts b/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts index 4597b0270e7..c080f868407 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts @@ -23,7 +23,6 @@ import { IExtensionsConfiguration, ConfigurationKey, ShowRecommendationsOnlyOnDe import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { flatten, distinct, shuffle, coalesce } from 'vs/base/common/arrays'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { guessMimeTypes, MIME_UNKNOWN } from 'vs/base/common/mime'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IRequestService, asJson } from 'vs/platform/request/common/request'; @@ -41,8 +40,9 @@ import { extname } from 'vs/base/common/resources'; import { IExeBasedExtensionTip, IProductService } from 'vs/platform/product/common/product'; import { timeout } from 'vs/base/common/async'; import { IWorkspaceStatsService } from 'vs/workbench/contrib/stats/common/workspaceStats'; -import { Platform, setImmediate } from 'vs/base/common/platform'; +import { Platform, setImmediate, IProcessEnvironment } from 'vs/base/common/platform'; import { platform } from 'vs/base/common/process'; +import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; const milliSecondsInADay = 1000 * 60 * 60 * 24; const choiceNever = localize('neverShowAgain', "Don't Show Again"); @@ -66,7 +66,7 @@ function caseInsensitiveGet(obj: { [key: string]: T }, key: string): T | unde return undefined; } -export class ExtensionTipsService extends Disposable implements IExtensionTipsService { +export abstract class BaseExtensionTipsService extends Disposable implements IExtensionTipsService { _serviceBrand: any; @@ -99,7 +99,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, @IConfigurationService private readonly configurationService: IConfigurationService, @ITelemetryService private readonly telemetryService: ITelemetryService, - @IEnvironmentService private readonly environmentService: IEnvironmentService, + @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService, @IExtensionService private readonly extensionService: IExtensionService, @IRequestService private readonly requestService: IRequestService, @IViewletService private readonly viewletService: IViewletService, @@ -1020,11 +1020,12 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe if (!windowsPath || typeof windowsPath !== 'string') { return; } - windowsPath = windowsPath.replace('%USERPROFILE%', process.env['USERPROFILE']!) - .replace('%ProgramFiles(x86)%', process.env['ProgramFiles(x86)']!) - .replace('%ProgramFiles%', process.env['ProgramFiles']!) - .replace('%APPDATA%', process.env['APPDATA']!) - .replace('%WINDIR%', process.env['WINDIR']!); + const processEnv = this.getProcessEnvironment(); + windowsPath = windowsPath.replace('%USERPROFILE%', processEnv['USERPROFILE']!) + .replace('%ProgramFiles(x86)%', processEnv['ProgramFiles(x86)']!) + .replace('%ProgramFiles%', processEnv['ProgramFiles']!) + .replace('%APPDATA%', processEnv['APPDATA']!) + .replace('%WINDIR%', processEnv['WINDIR']!); promises.push(findExecutable(exeName, entry.value, windowsPath)); } else { promises.push(findExecutable(exeName, entry.value, join('/usr/local/bin', exeName))); @@ -1144,4 +1145,15 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe private isExtensionAllowedToBeRecommended(id: string): boolean { return this._allIgnoredRecommendations.indexOf(id.toLowerCase()) === -1; } + + protected abstract getProcessEnvironment(): IProcessEnvironment; +} + + +export class ExtensionTipsService extends BaseExtensionTipsService implements IExtensionTipsService { + + protected getProcessEnvironment(): IProcessEnvironment { + return {}; + } + } diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts index 8dfa256fcf6..32bd703fba0 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts @@ -10,7 +10,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ExtensionsLabel, ExtensionsChannelId, PreferencesLabel, IExtensionManagementService, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { IExtensionManagementServerService, IExtensionTipsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; +import { IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { IWorkbenchActionRegistry, Extensions as WorkbenchActionExtensions } from 'vs/workbench/common/actions'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { IOutputChannelRegistry, Extensions as OutputExtensions } from 'vs/workbench/contrib/output/common/output'; @@ -45,10 +45,8 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { ExtensionType } from 'vs/platform/extensions/common/extensions'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { RemoteExtensionsInstaller } from 'vs/workbench/contrib/extensions/browser/remoteExtensionsInstaller'; -import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/browser/extensionTipsService'; // Singletons -registerSingleton(IExtensionTipsService, ExtensionTipsService); registerSingleton(IExtensionsWorkbenchService, ExtensionsWorkbenchService); Registry.as(OutputExtensions.OutputChannels) diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.web.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.web.contribution.ts new file mode 100644 index 00000000000..439f218cfb3 --- /dev/null +++ b/src/vs/workbench/contrib/extensions/browser/extensions.web.contribution.ts @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IExtensionTipsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; +import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/browser/extensionTipsService'; + +// Singletons +registerSingleton(IExtensionTipsService, ExtensionTipsService); diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts new file mode 100644 index 00000000000..f866ccbb7a8 --- /dev/null +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts @@ -0,0 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { BaseExtensionTipsService } from 'vs/workbench/contrib/extensions/browser/extensionTipsService'; +import { IProcessEnvironment } from 'vs/base/common/platform'; + +export class ExtensionTipsService extends BaseExtensionTipsService { + + protected getProcessEnvironment(): IProcessEnvironment { + return process.env as IProcessEnvironment; + } + +} diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts index 4c21e1e9181..74f15f54393 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts @@ -21,8 +21,11 @@ import { RuntimeExtensionsInput } from 'vs/workbench/contrib/extensions/electron import { URI } from 'vs/base/common/uri'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { ExtensionsAutoProfiler } from 'vs/workbench/contrib/extensions/electron-browser/extensionsAutoProfiler'; +import { IExtensionTipsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; +import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/electron-browser/extensionTipsService'; // Singletons +registerSingleton(IExtensionTipsService, ExtensionTipsService); registerSingleton(IExtensionHostProfileService, ExtensionHostProfileService, true); const workbenchRegistry = Registry.as(WorkbenchExtensions.Workbench); diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 40384b249b0..0c80d322d2a 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -87,6 +87,9 @@ import 'vs/workbench/contrib/debug/browser/extensionHostDebugService'; import 'vs/workbench/contrib/webview/browser/webviewService'; import 'vs/workbench/contrib/webview/browser/webviewEditorService'; +// Extensions Management +import 'vs/workbench/contrib/extensions/browser/extensions.web.contribution'; + // Terminal import 'vs/workbench/contrib/terminal/browser/terminalNativeService'; import 'vs/workbench/contrib/terminal/browser/terminalInstanceService'; From 998a6d7cf965800bc1c298f3714b63d3a9806413 Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 15 Aug 2019 15:48:52 +0200 Subject: [PATCH 659/861] callStack view: do not show thread when there is only one to be compact fixes #79121 --- src/vs/workbench/contrib/debug/browser/callStackView.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/contrib/debug/browser/callStackView.ts b/src/vs/workbench/contrib/debug/browser/callStackView.ts index 97836b9a964..bc5758380cd 100644 --- a/src/vs/workbench/contrib/debug/browser/callStackView.ts +++ b/src/vs/workbench/contrib/debug/browser/callStackView.ts @@ -608,6 +608,10 @@ class CallStackDataSource implements IAsyncDataSource s.parentSession === element); const threads: CallStackItem[] = element.getAllThreads(); + if (threads.length === 1 && childSessions.length === 0) { + // Do not show thread when there is only one to be compact. + return this.getThreadChildren(threads[0]); + } return Promise.resolve(threads.concat(childSessions)); } else { From 926e27cb4f60a08d4b18d4f27d0de06df0853119 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 15 Aug 2019 16:04:50 +0200 Subject: [PATCH 660/861] fix compile error --- .../src/singlefolder-tests/commands.test.ts | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/commands.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/commands.test.ts index 9ea76e6a119..7dba2cfa93c 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/commands.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/commands.test.ts @@ -113,31 +113,4 @@ suite('commands namespace tests', () => { return Promise.all([a, b, c, d]); }); - - test('onDidExecuteCommand', async function () { - let args: any[]; - let d1 = commands.registerCommand('t1', function () { - args = [...arguments]; - }); - - - const p = new Promise((resolve, reject) => { - - let d2 = commands.onDidExecuteCommand(event => { - d2.dispose(); - d1.dispose(); - - try { - assert.equal(event.command, 't1'); - assert.deepEqual(args, event.arguments); - resolve(); - } catch (e) { - reject(e); - } - }); - }); - - await commands.executeCommand('t1', { foo: 1 }); - await p; - }); }); From 8095541d7d617e3071b397598530756e9fce8544 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 15 Aug 2019 16:03:41 +0200 Subject: [PATCH 661/861] inline product configuration in produt service --- .../sharedProcess/sharedProcessMain.ts | 3 +-- src/vs/code/node/cliProcessMain.ts | 3 +-- .../common/extensionGalleryService.ts | 14 +++++----- .../product/browser/productService.ts | 26 ------------------- src/vs/platform/product/common/product.ts | 9 +++---- src/vs/platform/product/node/product.ts | 3 +++ .../platform/product/node/productService.ts | 23 ---------------- .../api/browser/mainThreadWebview.ts | 2 +- src/vs/workbench/browser/web.main.ts | 17 +++++++++--- .../workbench/browser/web.simpleservices.ts | 8 +++--- .../contrib/debug/browser/debugSession.ts | 2 +- .../experiments/common/experimentService.ts | 4 +-- .../browser/extensionTipsService.ts | 26 +++++++++---------- .../extensions/browser/extensionsActions.ts | 4 +-- .../browser/extensionsWorkbenchService.ts | 8 +++--- .../contrib/feedback/browser/feedback.ts | 4 +-- .../feedback/browser/feedbackStatusbarItem.ts | 2 +- .../preferences/browser/preferencesSearch.ts | 4 +-- .../browser/terminalProcessManager.ts | 2 +- .../electron-browser/desktop.main.ts | 5 ++++ .../extensionEnablementService.test.ts | 4 +-- .../browser/webWorkerExtensionHostStarter.ts | 8 +++--- .../common/abstractExtensionService.ts | 6 ++--- .../extensions/common/extensionsUtil.ts | 2 +- .../common/remoteExtensionHostClient.ts | 10 +++---- .../remoteExtensionManagementIpc.ts | 2 +- .../remote/browser/remoteAgentServiceImpl.ts | 2 +- .../telemetry/browser/telemetryService.ts | 6 ++--- .../electron-browser/telemetryService.ts | 4 +-- .../workbench/test/workbenchTestServices.ts | 4 +++ src/vs/workbench/workbench.desktop.main.ts | 3 --- 31 files changed, 94 insertions(+), 126 deletions(-) delete mode 100644 src/vs/platform/product/browser/productService.ts delete mode 100644 src/vs/platform/product/node/productService.ts diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index 8ef5cc8dd0d..c5514f4eff7 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -55,7 +55,6 @@ import { IFileService } from 'vs/platform/files/common/files'; import { DiskFileSystemProvider } from 'vs/platform/files/electron-browser/diskFileSystemProvider'; import { Schemas } from 'vs/base/common/network'; import { IProductService } from 'vs/platform/product/common/product'; -import { ProductService } from 'vs/platform/product/node/productService'; export interface ISharedProcessConfiguration { readonly machineId: string; @@ -111,10 +110,10 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat await configurationService.initialize(); services.set(IEnvironmentService, environmentService); + services.set(IProductService, { _serviceBrand: undefined, ...product }); services.set(ILogService, logService); services.set(IConfigurationService, configurationService); services.set(IRequestService, new SyncDescriptor(RequestService)); - services.set(IProductService, new SyncDescriptor(ProductService)); const mainProcessService = new MainProcessService(server, mainRouter); services.set(IMainProcessService, mainProcessService); diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index d9ed94ff68e..32005dd153e 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -47,7 +47,6 @@ import { IFileService } from 'vs/platform/files/common/files'; import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { IProductService } from 'vs/platform/product/common/product'; -import { ProductService } from 'vs/platform/product/node/productService'; const notFound = (id: string) => localize('notFound', "Extension '{0}' not found.", id); const notInstalled = (id: string) => localize('notInstalled', "Extension '{0}' is not installed.", id); @@ -325,7 +324,7 @@ export async function main(argv: ParsedArgs): Promise { services.set(ILogService, logService); services.set(IConfigurationService, configurationService); services.set(IStateService, new SyncDescriptor(StateService)); - services.set(IProductService, new SyncDescriptor(ProductService)); + services.set(IProductService, { _serviceBrand: undefined, ...product }); // Files const fileService = new FileService(logService); diff --git a/src/vs/platform/extensionManagement/common/extensionGalleryService.ts b/src/vs/platform/extensionManagement/common/extensionGalleryService.ts index 42fbff47fe2..2d39c512975 100644 --- a/src/vs/platform/extensionManagement/common/extensionGalleryService.ts +++ b/src/vs/platform/extensionManagement/common/extensionGalleryService.ts @@ -342,10 +342,10 @@ export class ExtensionGalleryService implements IExtensionGalleryService { @IProductService private readonly productService: IProductService, @optional(IStorageService) private readonly storageService: IStorageService, ) { - const config = productService.productConfiguration.extensionsGallery; + const config = productService.extensionsGallery; this.extensionsGalleryUrl = config && config.serviceUrl; this.extensionsControlUrl = config && config.controlUrl; - this.commonHeadersPromise = resolveMarketplaceHeaders(productService.productConfiguration.version, this.environmentService, this.fileService, this.storageService); + this.commonHeadersPromise = resolveMarketplaceHeaders(productService.version, this.environmentService, this.fileService, this.storageService); } private api(path = ''): string { @@ -358,7 +358,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { getCompatibleExtension(arg1: IExtensionIdentifier | IGalleryExtension, version?: string): Promise { const extension: IGalleryExtension | null = isIExtensionIdentifier(arg1) ? null : arg1; - if (extension && extension.properties.engine && isEngineValid(extension.properties.engine, this.productService.productConfiguration.version)) { + if (extension && extension.properties.engine && isEngineValid(extension.properties.engine, this.productService.version)) { return Promise.resolve(extension); } const { id, uuid } = extension ? extension.identifier : arg1; @@ -384,7 +384,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { const versionAsset = rawExtension.versions.filter(v => v.version === version)[0]; if (versionAsset) { const extension = toExtension(rawExtension, versionAsset, 0, query); - if (extension.properties.engine && isEngineValid(extension.properties.engine, this.productService.productConfiguration.version)) { + if (extension.properties.engine && isEngineValid(extension.properties.engine, this.productService.version)) { return extension; } } @@ -619,7 +619,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { return this.queryGallery(query, CancellationToken.None).then(({ galleryExtensions }) => { if (galleryExtensions.length) { if (compatible) { - return Promise.all(galleryExtensions[0].versions.map(v => this.getEngine(v).then(engine => isEngineValid(engine, this.productService.productConfiguration.version) ? v : null))) + return Promise.all(galleryExtensions[0].versions.map(v => this.getEngine(v).then(engine => isEngineValid(engine, this.productService.version) ? v : null))) .then(versions => versions .filter(v => !!v) .map(v => ({ version: v!.version, date: v!.lastUpdated }))); @@ -705,7 +705,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { if (!engine) { return null; } - if (isEngineValid(engine, this.productService.productConfiguration.version)) { + if (isEngineValid(engine, this.productService.version)) { return Promise.resolve(version); } } @@ -737,7 +737,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { const version = versions[0]; return this.getEngine(version) .then(engine => { - if (!isEngineValid(engine, this.productService.productConfiguration.version)) { + if (!isEngineValid(engine, this.productService.version)) { return this.getLastValidExtensionVersionRecursively(extension, versions.slice(1)); } diff --git a/src/vs/platform/product/browser/productService.ts b/src/vs/platform/product/browser/productService.ts deleted file mode 100644 index fae6e1d5fa7..00000000000 --- a/src/vs/platform/product/browser/productService.ts +++ /dev/null @@ -1,26 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IProductService, IProductConfiguration } from 'vs/platform/product/common/product'; -import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; - -export class ProductService implements IProductService { - - _serviceBrand!: ServiceIdentifier; - - readonly productConfiguration: IProductConfiguration; - - constructor() { - const element = document.getElementById('vscode-remote-product-configuration'); - this.productConfiguration = { - ...element ? JSON.parse(element.getAttribute('data-settings')!) : { - version: '1.38.0-unknown', - nameLong: 'Unknown', - extensionAllowedProposedApi: [], - }, ...{ urlProtocol: '', enableTelemetry: false } - }; - } - -} diff --git a/src/vs/platform/product/common/product.ts b/src/vs/platform/product/common/product.ts index ec42094d94c..3797e18a25e 100644 --- a/src/vs/platform/product/common/product.ts +++ b/src/vs/platform/product/common/product.ts @@ -3,19 +3,18 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; export const IProductService = createDecorator('productService'); -export interface IProductService { +export interface IProductService extends Readonly { - _serviceBrand: ServiceIdentifier; + _serviceBrand: undefined; - readonly productConfiguration: IProductConfiguration; } export interface IProductConfiguration { - readonly version: string; + version: string; nameShort: string; nameLong: string; readonly applicationName: string; diff --git a/src/vs/platform/product/node/product.ts b/src/vs/platform/product/node/product.ts index 08610d71a1a..3d13f26c576 100644 --- a/src/vs/platform/product/node/product.ts +++ b/src/vs/platform/product/node/product.ts @@ -6,6 +6,7 @@ import * as path from 'vs/base/common/path'; import { getPathFromAmdModule } from 'vs/base/common/amd'; import { IProductConfiguration } from 'vs/platform/product/common/product'; +import pkg from 'vs/platform/product/node/package'; const rootPath = path.dirname(getPathFromAmdModule(require, '')); const productJsonPath = path.join(rootPath, 'product.json'); @@ -17,4 +18,6 @@ if (process.env['VSCODE_DEV']) { product.dataFolderName += '-dev'; } +product.version = pkg.version; + export default product; diff --git a/src/vs/platform/product/node/productService.ts b/src/vs/platform/product/node/productService.ts deleted file mode 100644 index f3986577355..00000000000 --- a/src/vs/platform/product/node/productService.ts +++ /dev/null @@ -1,23 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IProductService, IProductConfiguration } from 'vs/platform/product/common/product'; -import product from 'vs/platform/product/node/product'; -import pkg from 'vs/platform/product/node/package'; -import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; - -export class ProductService implements IProductService { - - _serviceBrand!: ServiceIdentifier; - - readonly productConfiguration: IProductConfiguration; - - constructor() { - this.productConfiguration = { - ...product, ...{ version: pkg.version } - }; - } - -} diff --git a/src/vs/workbench/api/browser/mainThreadWebview.ts b/src/vs/workbench/api/browser/mainThreadWebview.ts index f2c3141d063..90bdeb5ea74 100644 --- a/src/vs/workbench/api/browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/browser/mainThreadWebview.ts @@ -327,7 +327,7 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews if (MainThreadWebviews.standardSupportedLinkSchemes.has(link.scheme)) { return true; } - if (this._productService.productConfiguration.urlProtocol === link.scheme) { + if (this._productService.urlProtocol === link.scheme) { return true; } return !!webview.webview.contentOptions.enableCommandUris && link.scheme === 'command'; diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index 812663e25d4..c28e693fc47 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -14,7 +14,7 @@ import { Workbench } from 'vs/workbench/browser/workbench'; import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { REMOTE_FILE_SYSTEM_CHANNEL_NAME, RemoteExtensionsFileSystemProvider } from 'vs/platform/remote/common/remoteAgentFileSystemChannel'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; -import { IProductService } from 'vs/platform/product/common/product'; +import { IProductService, IProductConfiguration } from 'vs/platform/product/common/product'; import { RemoteAgentService } from 'vs/workbench/services/remote/browser/remoteAgentServiceImpl'; import { RemoteAuthorityResolverService } from 'vs/platform/remote/browser/remoteAuthorityResolverService'; import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver'; @@ -33,7 +33,6 @@ import { ISignService } from 'vs/platform/sign/common/sign'; import { SignService } from 'vs/platform/sign/browser/signService'; import { hash } from 'vs/base/common/hash'; import { IWorkbenchConstructionOptions } from 'vs/workbench/workbench.web.api'; -import { ProductService } from 'vs/platform/product/browser/productService'; import { FileUserDataProvider } from 'vs/workbench/services/userData/common/fileUserDataProvider'; import { BACKUPS } from 'vs/platform/environment/common/environment'; import { joinPath } from 'vs/base/common/resources'; @@ -121,7 +120,7 @@ class CodeRendererMain extends Disposable { serviceCollection.set(IWorkbenchEnvironmentService, environmentService); // Product - const productService = new ProductService(); + const productService = this.createProductService(); serviceCollection.set(IProductService, productService); // Remote @@ -187,6 +186,18 @@ class CodeRendererMain extends Disposable { return { serviceCollection, logService, storageService: services[1] }; } + private createProductService(): IProductService { + const element = document.getElementById('vscode-remote-product-configuration'); + const productConfiguration: IProductConfiguration = { + ...element ? JSON.parse(element.getAttribute('data-settings')!) : { + version: '1.38.0-unknown', + nameLong: 'Unknown', + extensionAllowedProposedApi: [], + }, ...{ urlProtocol: '', enableTelemetry: false } + }; + return { _serviceBrand: undefined, ...productConfiguration }; + } + private async createStorageService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, fileService: IFileService, logService: ILogService): Promise { const storageService = new BrowserStorageService(environmentService, fileService); diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index ce9a691a28b..ce24f3df7bf 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -743,13 +743,13 @@ export class SimpleWindowsService implements IWindowsService { async openAboutDialog(): Promise { const detail = localize('aboutDetail', "Version: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}", - this.productService.productConfiguration.version || 'Unknown', - this.productService.productConfiguration.commit || 'Unknown', - this.productService.productConfiguration.date || 'Unknown', + this.productService.version || 'Unknown', + this.productService.commit || 'Unknown', + this.productService.date || 'Unknown', navigator.userAgent ); - const result = await this.dialogService.show(Severity.Info, this.productService.productConfiguration.nameLong, [localize('copy', "Copy"), localize('ok', "OK")], { detail }); + const result = await this.dialogService.show(Severity.Info, this.productService.nameLong, [localize('copy', "Copy"), localize('ok', "OK")], { detail }); if (result === 0) { this.clipboardService.writeText(detail); diff --git a/src/vs/workbench/contrib/debug/browser/debugSession.ts b/src/vs/workbench/contrib/debug/browser/debugSession.ts index 6fdc99451a6..d4548944019 100644 --- a/src/vs/workbench/contrib/debug/browser/debugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/debugSession.ts @@ -175,7 +175,7 @@ export class DebugSession implements IDebugSession { return this.raw!.initialize({ clientID: 'vscode', - clientName: this.productService.productConfiguration.nameLong, + clientName: this.productService.nameLong, adapterID: this.configuration.type, pathFormat: 'path', linesStartAt1: true, diff --git a/src/vs/workbench/contrib/experiments/common/experimentService.ts b/src/vs/workbench/contrib/experiments/common/experimentService.ts index bef55ac4b26..5707377ce4b 100644 --- a/src/vs/workbench/contrib/experiments/common/experimentService.ts +++ b/src/vs/workbench/contrib/experiments/common/experimentService.ts @@ -170,10 +170,10 @@ export class ExperimentService extends Disposable implements IExperimentService } protected getExperiments(): Promise { - if (!this.productService.productConfiguration.experimentsUrl || this.configurationService.getValue('workbench.enableExperiments') === false) { + if (!this.productService.experimentsUrl || this.configurationService.getValue('workbench.enableExperiments') === false) { return Promise.resolve([]); } - return this.requestService.request({ type: 'GET', url: this.productService.productConfiguration.experimentsUrl }, CancellationToken.None).then(context => { + return this.requestService.request({ type: 'GET', url: this.productService.experimentsUrl }, CancellationToken.None).then(context => { if (context.res.statusCode !== 200) { return Promise.resolve(null); } diff --git a/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts b/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts index c080f868407..12a05302a75 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts @@ -116,8 +116,8 @@ export abstract class BaseExtensionTipsService extends Disposable implements IEx return; } - if (this.productService.productConfiguration.extensionsGallery && this.productService.productConfiguration.extensionsGallery.recommendationsUrl) { - this._extensionsRecommendationsUrl = this.productService.productConfiguration.extensionsGallery.recommendationsUrl; + if (this.productService.extensionsGallery && this.productService.extensionsGallery.recommendationsUrl) { + this._extensionsRecommendationsUrl = this.productService.extensionsGallery.recommendationsUrl; } this.sessionSeed = +new Date(); @@ -243,7 +243,7 @@ export abstract class BaseExtensionTipsService extends Disposable implements IEx } getKeymapRecommendations(): IExtensionRecommendation[] { - return (this.productService.productConfiguration.keymapExtensionTips || []) + return (this.productService.keymapExtensionTips || []) .filter(extensionId => this.isExtensionAllowedToBeRecommended(extensionId)) .map(extensionId => ({ extensionId, sources: ['application'] })); } @@ -600,10 +600,10 @@ export abstract class BaseExtensionTipsService extends Disposable implements IEx return Object.keys(this._fileBasedRecommendations) .sort((a, b) => { if (this._fileBasedRecommendations[a].recommendedTime === this._fileBasedRecommendations[b].recommendedTime) { - if (!this.productService.productConfiguration.extensionImportantTips || caseInsensitiveGet(this.productService.productConfiguration.extensionImportantTips, a)) { + if (!this.productService.extensionImportantTips || caseInsensitiveGet(this.productService.extensionImportantTips, a)) { return -1; } - if (caseInsensitiveGet(this.productService.productConfiguration.extensionImportantTips, b)) { + if (caseInsensitiveGet(this.productService.extensionImportantTips, b)) { return 1; } } @@ -614,11 +614,11 @@ export abstract class BaseExtensionTipsService extends Disposable implements IEx } /** - * Parse all file based recommendations from this.productService.productConfiguration.extensionTips - * Retire existing recommendations if they are older than a week or are not part of this.productService.productConfiguration.extensionTips anymore + * Parse all file based recommendations from this.productService.extensionTips + * Retire existing recommendations if they are older than a week or are not part of this.productService.extensionTips anymore */ private fetchFileBasedRecommendations() { - const extensionTips = this.productService.productConfiguration.extensionTips; + const extensionTips = this.productService.extensionTips; if (!extensionTips) { return; } @@ -635,7 +635,7 @@ export abstract class BaseExtensionTipsService extends Disposable implements IEx } }); - forEach(this.productService.productConfiguration.extensionImportantTips, entry => { + forEach(this.productService.extensionImportantTips, entry => { let { key: id, value } = entry; const { pattern } = value; let ids = this._availableRecommendations[pattern]; @@ -697,7 +697,7 @@ export abstract class BaseExtensionTipsService extends Disposable implements IEx let { key: pattern, value: ids } = entry; if (match(pattern, model.uri.toString())) { for (let id of ids) { - if (caseInsensitiveGet(this.productService.productConfiguration.extensionImportantTips, id)) { + if (caseInsensitiveGet(this.productService.extensionImportantTips, id)) { recommendationsToSuggest.push(id); } const filedBasedRecommendation = this._fileBasedRecommendations[id.toLowerCase()] || { recommendedTime: now, sources: [] }; @@ -751,7 +751,7 @@ export abstract class BaseExtensionTipsService extends Disposable implements IEx } const id = recommendationsToSuggest[0]; - const entry = caseInsensitiveGet(this.productService.productConfiguration.extensionImportantTips, id); + const entry = caseInsensitiveGet(this.productService.extensionImportantTips, id); if (!entry) { return false; } @@ -981,7 +981,7 @@ export abstract class BaseExtensionTipsService extends Disposable implements IEx } /** - * If user has any of the tools listed in this.productService.productConfiguration.exeBasedExtensionTips, fetch corresponding recommendations + * If user has any of the tools listed in this.productService.exeBasedExtensionTips, fetch corresponding recommendations */ private async fetchExecutableRecommendations(important: boolean): Promise { if (Platform.Web) { @@ -1007,7 +1007,7 @@ export abstract class BaseExtensionTipsService extends Disposable implements IEx const promises: Promise[] = []; // Loop through recommended extensions - forEach(this.productService.productConfiguration.exeBasedExtensionTips, entry => { + forEach(this.productService.exeBasedExtensionTips, entry => { if (typeof entry.value !== 'object' || !Array.isArray(entry.value['recommendations'])) { return; } diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index 05bef903d9e..ec19e774ab1 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -76,10 +76,10 @@ export function toExtensionDescription(local: ILocalExtension): IExtensionDescri const promptDownloadManually = (extension: IGalleryExtension | undefined, message: string, error: Error, instantiationService: IInstantiationService, notificationService: INotificationService, openerService: IOpenerService, productService: IProductService) => { - if (!extension || error.name === INSTALL_ERROR_INCOMPATIBLE || error.name === INSTALL_ERROR_MALICIOUS || !productService.productConfiguration.extensionsGallery) { + if (!extension || error.name === INSTALL_ERROR_INCOMPATIBLE || error.name === INSTALL_ERROR_MALICIOUS || !productService.extensionsGallery) { return Promise.reject(error); } else { - const downloadUrl = `${productService.productConfiguration.extensionsGallery.serviceUrl}/publishers/${extension.publisher}/vsextensions/${extension.name}/${extension.version}/vspackage`; + const downloadUrl = `${productService.extensionsGallery.serviceUrl}/publishers/${extension.publisher}/vsextensions/${extension.name}/${extension.version}/vspackage`; notificationService.prompt(Severity.Error, message, [{ label: localize('download', "Download Manually"), run: () => openerService.open(URI.parse(downloadUrl)).then(() => { diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index 99ec538b442..b64689e02c6 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -114,11 +114,11 @@ class Extension implements IExtension { } get url(): string | undefined { - if (!this.productService.productConfiguration.extensionsGallery || !this.gallery) { + if (!this.productService.extensionsGallery || !this.gallery) { return undefined; } - return `${this.productService.productConfiguration.extensionsGallery.itemUrl}?itemName=${this.publisher}.${this.name}`; + return `${this.productService.extensionsGallery.itemUrl}?itemName=${this.publisher}.${this.name}`; } get iconUrl(): string { @@ -615,7 +615,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension text = text.replace(extensionRegex, (m, ext) => { // Get curated keywords - const lookup = this.productService.productConfiguration.extensionKeywords || {}; + const lookup = this.productService.extensionKeywords || {}; const keywords = lookup[ext] || []; // Get mode name @@ -1022,7 +1022,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension get allowedBadgeProviders(): string[] { if (!this._extensionAllowedBadgeProviders) { - this._extensionAllowedBadgeProviders = (this.productService.productConfiguration.extensionAllowedBadgeProviders || []).map(s => s.toLowerCase()); + this._extensionAllowedBadgeProviders = (this.productService.extensionAllowedBadgeProviders || []).map(s => s.toLowerCase()); } return this._extensionAllowedBadgeProviders; } diff --git a/src/vs/workbench/contrib/feedback/browser/feedback.ts b/src/vs/workbench/contrib/feedback/browser/feedback.ts index 130c7fd3a04..618dc7edaa9 100644 --- a/src/vs/workbench/contrib/feedback/browser/feedback.ts +++ b/src/vs/workbench/contrib/feedback/browser/feedback.ts @@ -73,8 +73,8 @@ export class FeedbackDropdown extends Dropdown { this.feedbackDelegate = options.feedbackService; this.maxFeedbackCharacters = this.feedbackDelegate.getCharacterLimit(this.sentiment); - if (productService.productConfiguration.sendASmile) { - this.requestFeatureLink = productService.productConfiguration.sendASmile.requestFeatureUrl; + if (productService.sendASmile) { + this.requestFeatureLink = productService.sendASmile.requestFeatureUrl; } this.integrityService.isPure().then(result => { diff --git a/src/vs/workbench/contrib/feedback/browser/feedbackStatusbarItem.ts b/src/vs/workbench/contrib/feedback/browser/feedbackStatusbarItem.ts index 458dc93b0b6..c609aa4132f 100644 --- a/src/vs/workbench/contrib/feedback/browser/feedbackStatusbarItem.ts +++ b/src/vs/workbench/contrib/feedback/browser/feedbackStatusbarItem.ts @@ -58,7 +58,7 @@ export class FeedbackStatusbarConribution extends Disposable implements IWorkben ) { super(); - if (productService.productConfiguration.sendASmile) { + if (productService.sendASmile) { this.entry = this._register(statusbarService.addEntry(this.getStatusEntry(), 'status.feedback', localize('status.feedback', "Tweet Feedback"), StatusbarAlignment.RIGHT, -100 /* towards the end of the right hand side */)); CommandsRegistry.registerCommand('_feedback.open', () => this.toggleFeedback()); diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts b/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts index b876c396a7f..37de5e7766e 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts @@ -74,7 +74,7 @@ export class PreferencesSearchService extends Disposable implements IPreferences }; } else { return { - urlBase: this.productService.productConfiguration.settingsSearchUrl + urlBase: this.productService.settingsSearchUrl }; } } @@ -365,7 +365,7 @@ class RemoteSearchProvider implements ISearchProvider { const extensions = await this.installedExtensions; const filters = this.options.newExtensionsOnly ? [`diminish eq 'latest'`] : - this.getVersionFilters(extensions, this.productService.productConfiguration.settingsSearchBuildId); + this.getVersionFilters(extensions, this.productService.settingsSearchBuildId); const filterStr = filters .slice(filterPage * RemoteSearchProvider.MAX_REQUEST_FILTERS, (filterPage + 1) * RemoteSearchProvider.MAX_REQUEST_FILTERS) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index b1ecf1026f3..b3ff7db5e88 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -226,7 +226,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce const isWorkspaceShellAllowed = this._configHelper.checkWorkspaceShellPermissions(); this._configHelper.showRecommendations(shellLaunchConfig); const baseEnv = this._configHelper.config.inheritEnv ? process.env as platform.IProcessEnvironment : await this._terminalInstanceService.getMainProcessParentEnv(); - const env = terminalEnvironment.createTerminalEnvironment(shellLaunchConfig, lastActiveWorkspace, envFromConfigValue, this._configurationResolverService, isWorkspaceShellAllowed, this._productService.productConfiguration.version, this._configHelper.config.setLocaleVariables, baseEnv); + const env = terminalEnvironment.createTerminalEnvironment(shellLaunchConfig, lastActiveWorkspace, envFromConfigValue, this._configurationResolverService, isWorkspaceShellAllowed, this._productService.version, this._configHelper.config.setLocaleVariables, baseEnv); const useConpty = this._configHelper.config.windowsEnableConpty && !isScreenReaderModeEnabled; return this._terminalInstanceService.createTerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, useConpty); diff --git a/src/vs/workbench/electron-browser/desktop.main.ts b/src/vs/workbench/electron-browser/desktop.main.ts index 40ea992a2a1..a6836c38075 100644 --- a/src/vs/workbench/electron-browser/desktop.main.ts +++ b/src/vs/workbench/electron-browser/desktop.main.ts @@ -51,6 +51,8 @@ import { SignService } from 'vs/platform/sign/node/signService'; import { ISignService } from 'vs/platform/sign/common/sign'; import { FileUserDataProvider } from 'vs/workbench/services/userData/common/fileUserDataProvider'; import { basename } from 'vs/base/common/resources'; +import { IProductService } from 'vs/platform/product/common/product'; +import product from 'vs/platform/product/node/product'; class CodeRendererMain extends Disposable { @@ -177,6 +179,9 @@ class CodeRendererMain extends Disposable { // Environment serviceCollection.set(IWorkbenchEnvironmentService, this.environmentService); + // Product + serviceCollection.set(IProductService, { _serviceBrand: undefined, ...product }); + // Log const logService = this._register(this.createLogService(mainProcessService, this.environmentService)); serviceCollection.set(ILogService, logService); diff --git a/src/vs/workbench/services/extensionManagement/test/electron-browser/extensionEnablementService.test.ts b/src/vs/workbench/services/extensionManagement/test/electron-browser/extensionEnablementService.test.ts index 5852ce2d53c..4536a5ad507 100644 --- a/src/vs/workbench/services/extensionManagement/test/electron-browser/extensionEnablementService.test.ts +++ b/src/vs/workbench/services/extensionManagement/test/electron-browser/extensionEnablementService.test.ts @@ -16,12 +16,12 @@ import { IExtensionContributions, ExtensionType, IExtension } from 'vs/platform/ import { isUndefinedOrNull } from 'vs/base/common/types'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { ProductService } from 'vs/platform/product/node/productService'; import { URI } from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts'; import { assign } from 'vs/base/common/objects'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; +import { productService } from 'vs/workbench/test/workbenchTestServices'; function storageService(instantiationService: TestInstantiationService): IStorageService { let service = instantiationService.get(IStorageService); @@ -46,7 +46,7 @@ export class TestExtensionEnablementService extends ExtensionEnablementService { instantiationService.get(IExtensionManagementService) || instantiationService.stub(IExtensionManagementService, { onDidInstallExtension: new Emitter().event, onDidUninstallExtension: new Emitter().event } as IExtensionManagementService), instantiationService.get(IConfigurationService), instantiationService.get(IExtensionManagementServerService), - new ProductService() + productService ); } diff --git a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts index 7848fdee127..5794b259061 100644 --- a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts +++ b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts @@ -117,15 +117,15 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { const [telemetryInfo, extensionDescriptions] = await Promise.all([this._telemetryService.getTelemetryInfo(), this._extensions]); const workspace = this._contextService.getWorkspace(); return { - commit: this._productService.productConfiguration.commit, - version: this._productService.productConfiguration.version, + commit: this._productService.commit, + version: this._productService.version, parentPid: -1, environment: { isExtensionDevelopmentDebug: false, appRoot: this._environmentService.appRoot ? URI.file(this._environmentService.appRoot) : undefined, appSettingsHome: this._environmentService.appSettingsHome ? this._environmentService.appSettingsHome : undefined, - appName: this._productService.productConfiguration.nameLong, - appUriScheme: this._productService.productConfiguration.urlProtocol, + appName: this._productService.nameLong, + appUriScheme: this._productService.urlProtocol, appLanguage: platform.language, extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI, extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI, diff --git a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts index 51f991375a6..6445a03a6e6 100644 --- a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts +++ b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts @@ -462,12 +462,12 @@ class ProposedApiController { } this.enableProposedApiForAll = !environmentService.isBuilt || - (!!environmentService.extensionDevelopmentLocationURI && productService.productConfiguration.nameLong !== 'Visual Studio Code') || + (!!environmentService.extensionDevelopmentLocationURI && productService.nameLong !== 'Visual Studio Code') || (this.enableProposedApiFor.length === 0 && 'enable-proposed-api' in environmentService.args); this.productAllowProposedApi = new Set(); - if (isNonEmptyArray(productService.productConfiguration.extensionAllowedProposedApi)) { - productService.productConfiguration.extensionAllowedProposedApi.forEach((id) => this.productAllowProposedApi.add(ExtensionIdentifier.toKey(id))); + if (isNonEmptyArray(productService.extensionAllowedProposedApi)) { + productService.extensionAllowedProposedApi.forEach((id) => this.productAllowProposedApi.add(ExtensionIdentifier.toKey(id))); } } diff --git a/src/vs/workbench/services/extensions/common/extensionsUtil.ts b/src/vs/workbench/services/extensions/common/extensionsUtil.ts index 2f7d4e01039..a1496708db6 100644 --- a/src/vs/workbench/services/extensions/common/extensionsUtil.ts +++ b/src/vs/workbench/services/extensions/common/extensionsUtil.ts @@ -24,7 +24,7 @@ export function isUIExtension(manifest: IExtensionManifest, productService: IPro case 'workspace': return false; default: { // Tagged as UI extension in product - if (isNonEmptyArray(productService.productConfiguration.uiExtensions) && productService.productConfiguration.uiExtensions.some(id => areSameExtensions({ id }, { id: extensionId }))) { + if (isNonEmptyArray(productService.uiExtensions) && productService.uiExtensions.some(id => areSameExtensions({ id }, { id: extensionId }))) { return true; } // Not an UI extension if it has main diff --git a/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts b/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts index ca657398990..47aaf4a22bb 100644 --- a/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts +++ b/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts @@ -71,7 +71,7 @@ export class RemoteExtensionHostClient extends Disposable implements IExtensionH public start(): Promise { const options: IConnectionOptions = { - commit: this._productService.productConfiguration.commit, + commit: this._productService.commit, socketFactory: this._socketFactory, addressProvider: { getAddress: async () => { @@ -181,15 +181,15 @@ export class RemoteExtensionHostClient extends Disposable implements IExtensionH const hostExtensions = allExtensions.filter(extension => extension.main && extension.api === 'none').map(extension => extension.identifier); const workspace = this._contextService.getWorkspace(); const r: IInitData = { - commit: this._productService.productConfiguration.commit, - version: this._productService.productConfiguration.version, + commit: this._productService.commit, + version: this._productService.version, parentPid: remoteExtensionHostData.pid, environment: { isExtensionDevelopmentDebug, appRoot: remoteExtensionHostData.appRoot, appSettingsHome: remoteExtensionHostData.appSettingsHome, - appName: this._productService.productConfiguration.nameLong, - appUriScheme: this._productService.productConfiguration.urlProtocol, + appName: this._productService.nameLong, + appUriScheme: this._productService.urlProtocol, appLanguage: platform.language, extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI, extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI, diff --git a/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts b/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts index 75787071f85..f94d89adb16 100644 --- a/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts +++ b/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts @@ -69,7 +69,7 @@ export class RemoteExtensionManagementChannelClient extends ExtensionManagementC const installed = await this.getInstalled(ExtensionType.User); const compatible = await this.galleryService.getCompatibleExtension(extension); if (!compatible) { - return Promise.reject(new Error(localize('incompatible', "Unable to install extension '{0}' as it is not compatible with VS Code '{1}'.", extension.identifier.id, this.productService.productConfiguration.version))); + return Promise.reject(new Error(localize('incompatible', "Unable to install extension '{0}' as it is not compatible with VS Code '{1}'.", extension.identifier.id, this.productService.version))); } const manifest = await this.galleryService.getManifest(compatible, CancellationToken.None); if (manifest) { diff --git a/src/vs/workbench/services/remote/browser/remoteAgentServiceImpl.ts b/src/vs/workbench/services/remote/browser/remoteAgentServiceImpl.ts index db4d2038ca3..fd979ca094c 100644 --- a/src/vs/workbench/services/remote/browser/remoteAgentServiceImpl.ts +++ b/src/vs/workbench/services/remote/browser/remoteAgentServiceImpl.ts @@ -28,7 +28,7 @@ export class RemoteAgentService extends AbstractRemoteAgentService implements IR super(environmentService); this.socketFactory = new BrowserSocketFactory(webSocketFactory); - this._connection = this._register(new RemoteAgentConnection(environmentService.configuration.remoteAuthority!, productService.productConfiguration.commit, this.socketFactory, remoteAuthorityResolverService, signService)); + this._connection = this._register(new RemoteAgentConnection(environmentService.configuration.remoteAuthority!, productService.commit, this.socketFactory, remoteAuthorityResolverService, signService)); } getConnection(): IRemoteAgentConnection | null { diff --git a/src/vs/workbench/services/telemetry/browser/telemetryService.ts b/src/vs/workbench/services/telemetry/browser/telemetryService.ts index 2632d935d80..eac9dcfb1d0 100644 --- a/src/vs/workbench/services/telemetry/browser/telemetryService.ts +++ b/src/vs/workbench/services/telemetry/browser/telemetryService.ts @@ -79,11 +79,11 @@ export class TelemetryService extends Disposable implements ITelemetryService { ) { super(); - const aiKey = productService.productConfiguration.aiConfig && productService.productConfiguration.aiConfig.asimovKey; - if (!environmentService.isExtensionDevelopment && !environmentService.args['disable-telemetry'] && !!productService.productConfiguration.enableTelemetry && !!aiKey) { + const aiKey = productService.aiConfig && productService.aiConfig.asimovKey; + if (!environmentService.isExtensionDevelopment && !environmentService.args['disable-telemetry'] && !!productService.enableTelemetry && !!aiKey) { const config: ITelemetryServiceConfig = { appender: combinedAppender(new WebTelemetryAppender(aiKey, logService), new LogAppender(logService)), - commonProperties: resolveWorkbenchCommonProperties(storageService, productService.productConfiguration.commit, productService.productConfiguration.version, environmentService.configuration.machineId, environmentService.configuration.remoteAuthority), + commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.configuration.machineId, environmentService.configuration.remoteAuthority), piiPaths: [environmentService.appRoot] }; diff --git a/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts b/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts index 002b6ae4ce3..c5561e44295 100644 --- a/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts +++ b/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts @@ -34,11 +34,11 @@ export class TelemetryService extends Disposable implements ITelemetryService { ) { super(); - if (!environmentService.isExtensionDevelopment && !environmentService.args['disable-telemetry'] && !!productService.productConfiguration.enableTelemetry) { + if (!environmentService.isExtensionDevelopment && !environmentService.args['disable-telemetry'] && !!productService.enableTelemetry) { const channel = sharedProcessService.getChannel('telemetryAppender'); const config: ITelemetryServiceConfig = { appender: combinedAppender(new TelemetryAppenderClient(channel), new LogAppender(logService)), - commonProperties: resolveWorkbenchCommonProperties(storageService, productService.productConfiguration.commit, productService.productConfiguration.version, environmentService.configuration.machineId, environmentService.installSourcePath, environmentService.configuration.remoteAuthority), + commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.configuration.machineId, environmentService.installSourcePath, environmentService.configuration.remoteAuthority), piiPaths: environmentService.extensionsPath ? [environmentService.appRoot, environmentService.extensionsPath] : [environmentService.appRoot] }; diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 0ca22ba62b8..576df9cb63c 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -84,6 +84,8 @@ import { WorkbenchEnvironmentService } from 'vs/workbench/services/environment/n import { VSBuffer, VSBufferReadable } from 'vs/base/common/buffer'; import { NodeTextFileService } from 'vs/workbench/services/textfile/node/textFileService'; import { Schemas } from 'vs/base/common/network'; +import { IProductService } from 'vs/platform/product/common/product'; +import product from 'vs/platform/product/node/product'; export function createFileInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined); @@ -1631,3 +1633,5 @@ export class RemoteFileSystemProvider implements IFileSystemProvider { private toFileResource(resource: URI): URI { return resource.with({ scheme: Schemas.file, authority: '' }); } } + +export const productService: IProductService = { _serviceBrand: undefined, ...product }; diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index 3373be0bd35..90f3e4c63d1 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -61,8 +61,6 @@ import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { ILocalizationsService } from 'vs/platform/localizations/common/localizations'; import { LocalizationsService } from 'vs/platform/localizations/electron-browser/localizationsService'; import { ISharedProcessService, SharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; -import { IProductService } from 'vs/platform/product/common/product'; -import { ProductService } from 'vs/platform/product/node/productService'; import { IWindowsService } from 'vs/platform/windows/common/windows'; import { WindowsService } from 'vs/platform/windows/electron-browser/windowsService'; import { IUpdateService } from 'vs/platform/update/common/update'; @@ -81,7 +79,6 @@ registerSingleton(IRequestService, RequestService, true); registerSingleton(ILifecycleService, LifecycleService); registerSingleton(ILocalizationsService, LocalizationsService); registerSingleton(ISharedProcessService, SharedProcessService, true); -registerSingleton(IProductService, ProductService, true); registerSingleton(IWindowsService, WindowsService); registerSingleton(IUpdateService, UpdateService); registerSingleton(IIssueService, IssueService); From 28c375c701ffb85c8d3cc617165e2aa8bf55f395 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 15 Aug 2019 16:14:54 +0200 Subject: [PATCH 662/861] update distro --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index e5af8e0f351..09b59b17c09 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "c2664514acafa174a6b0b5a960931699641d6989", + "distro": "a8a3be6f7445a6f3ce736a0ba3cbca717a2372cb", "author": { "name": "Microsoft Corporation" }, @@ -158,4 +158,4 @@ "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} +} \ No newline at end of file From 221a6ca43c6230180be895c9b9382fca0ea7ac25 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 15 Aug 2019 07:15:59 -0700 Subject: [PATCH 663/861] Fix strict error --- test/smoke/src/vscode/puppeteerDriver.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/smoke/src/vscode/puppeteerDriver.ts b/test/smoke/src/vscode/puppeteerDriver.ts index ba2c8359de1..2e2f2280dd6 100644 --- a/test/smoke/src/vscode/puppeteerDriver.ts +++ b/test/smoke/src/vscode/puppeteerDriver.ts @@ -6,7 +6,6 @@ import * as puppeteer from 'puppeteer'; import { ChildProcess, spawn } from 'child_process'; import { join } from 'path'; -import { tmpdir } from 'os'; import { mkdir } from 'fs'; import { promisify } from 'util'; @@ -226,7 +225,7 @@ export function connect(headless: boolean, outPath: string, handle: string): Pro const page = (await browser.pages())[0]; await page.setViewport({ width, height }); const endpointSplit = endpoint!.split('#'); - await page.goto(`${endpointSplit[0]}?folder=${args[1]}#${endpointSplit[1]}`); + await page.goto(`${endpointSplit[0]}?folder=${args![1]}#${endpointSplit[1]}`); const result = { client: { dispose: () => teardown }, driver: buildDriver(browser, page) From 790cb4e284d0e3d29170f80c780c5c4fad9eaf07 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 15 Aug 2019 16:19:48 +0200 Subject: [PATCH 664/861] fix tests --- .../extensionsTipsService.test.ts | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts index 941a3b69a46..83231f515ea 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts @@ -22,7 +22,7 @@ import { Emitter } from 'vs/base/common/event'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { TestContextService, TestLifecycleService, TestSharedProcessService } from 'vs/workbench/test/workbenchTestServices'; +import { TestContextService, TestLifecycleService, TestSharedProcessService, productService } from 'vs/workbench/test/workbenchTestServices'; import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { URI } from 'vs/base/common/uri'; @@ -36,7 +36,6 @@ import { ConfigurationKey } from 'vs/workbench/contrib/extensions/common/extensi import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService'; import { TestExtensionEnablementService } from 'vs/workbench/services/extensionManagement/test/electron-browser/extensionEnablementService.test'; import { IURLService } from 'vs/platform/url/common/url'; -import product from 'vs/platform/product/node/product'; import { ITextModel } from 'vs/editor/common/model'; import { IModelService } from 'vs/editor/common/services/modelService'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; @@ -202,23 +201,22 @@ suite('ExtensionsTipsService Test', () => { instantiationService.stub(IExtensionEnablementService, new TestExtensionEnablementService(instantiationService)); instantiationService.stub(ITelemetryService, NullTelemetryService); instantiationService.stub(IURLService, URLService); - instantiationService.stub(IProductService, >{ - productConfiguration: { - ...product, ...{ - extensionTips: { - 'ms-vscode.csharp': '{**/*.cs,**/project.json,**/global.json,**/*.csproj,**/*.sln,**/appsettings.json}', - 'msjsdiag.debugger-for-chrome': '{**/*.ts,**/*.tsx**/*.js,**/*.jsx,**/*.es6,**/.babelrc}', - 'lukehoban.Go': '**/*.go' + instantiationService.set(IProductService, { + ...productService, + ...{ + extensionTips: { + 'ms-vscode.csharp': '{**/*.cs,**/project.json,**/global.json,**/*.csproj,**/*.sln,**/appsettings.json}', + 'msjsdiag.debugger-for-chrome': '{**/*.ts,**/*.tsx**/*.js,**/*.jsx,**/*.es6,**/.babelrc}', + 'lukehoban.Go': '**/*.go' + }, + extensionImportantTips: { + 'ms-python.python': { + 'name': 'Python', + 'pattern': '{**/*.py}' }, - extensionImportantTips: { - 'ms-python.python': { - 'name': 'Python', - 'pattern': '{**/*.py}' - }, - 'ms-vscode.PowerShell': { - 'name': 'PowerShell', - 'pattern': '{**/*.ps,**/*.ps1}' - } + 'ms-vscode.PowerShell': { + 'name': 'PowerShell', + 'pattern': '{**/*.ps,**/*.ps1}' } } } From 40921e097e5bfd61ea9a489db837c0548c95f144 Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 15 Aug 2019 16:19:53 +0200 Subject: [PATCH 665/861] Do not expand session tree node when selecting it fixes #79184 --- src/vs/workbench/contrib/debug/browser/callStackView.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/callStackView.ts b/src/vs/workbench/contrib/debug/browser/callStackView.ts index bc5758380cd..4786ae44870 100644 --- a/src/vs/workbench/contrib/debug/browser/callStackView.ts +++ b/src/vs/workbench/contrib/debug/browser/callStackView.ts @@ -144,7 +144,8 @@ export class CallStackView extends ViewletPanel { return nls.localize('showMoreStackFrames2', "Show More Stack Frames"); } - } + }, + expandOnlyOnTwistieClick: true }); this.tree.setInput(this.debugService.getModel()).then(undefined, onUnexpectedError); From 0e56130bdf2a4cb3f79f9ec4a52e480b4937149f Mon Sep 17 00:00:00 2001 From: Gabriel DeBacker <6741868+GabeDeBacker@users.noreply.github.com> Date: Thu, 15 Aug 2019 07:24:53 -0700 Subject: [PATCH 666/861] Fix issue with CustomExecutions not working through tasks.executeTask (#79132) * Do not clear out the map, and track the provided execution during execute task * Clear provided custom executions map on execution complete * Save last custom execution --- src/vs/workbench/api/node/extHostTask.ts | 25 +++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index 647a2be3f08..cf9b522ef11 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -444,6 +444,14 @@ export class ExtHostTask implements ExtHostTaskShape { if (dto === undefined) { return Promise.reject(new Error('Task is not valid')); } + + // If this task is a custom execution, then we need to save it away + // in the provided custom execution map that is cleaned up after the + // task is executed. + if (CustomExecution2DTO.is(dto.execution)) { + await this.addCustomExecution2(dto, task); + } + return this._proxy.$executeTask(dto).then(value => this.getTaskExecution(value, task)); } } @@ -529,11 +537,6 @@ export class ExtHostTask implements ExtHostTaskShape { return Promise.reject(new Error('no handler found')); } - // For custom execution tasks, we need to store the execution objects locally - // since we obviously cannot send callback functions through the proxy. - // So, clear out any existing ones. - this._providedCustomExecutions2.clear(); - // Set up a list of task ID promises that we can wait on // before returning the provided tasks. The ensures that // our task IDs are calculated for any custom execution tasks. @@ -692,5 +695,17 @@ export class ExtHostTask implements ExtHostTaskShape { if (extensionCallback2) { this._activeCustomExecutions2.delete(execution.id); } + + const lastCustomExecution = this._providedCustomExecutions2.get(execution.id); + // Technically we don't really need to do this, however, if an extension + // is executing a task through "executeTask" over and over again + // with different properties in the task definition, then this list + // could grow indefinitely, something we don't want. + this._providedCustomExecutions2.clear(); + // We do still need to hang on to the last custom execution so that the + // Rerun Task command doesn't choke when it tries to rerun a custom execution + if (lastCustomExecution) { + this._providedCustomExecutions2.set(execution.id, lastCustomExecution); + } } } From b303e7acb5be641f0d7440c327be198436327061 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 15 Aug 2019 16:25:46 +0200 Subject: [PATCH 667/861] use safeprocess env --- src/vs/base/common/process.ts | 4 ++-- .../extensions/browser/extensionTipsService.ts | 17 +++-------------- .../browser/extensions.contribution.ts | 4 +++- .../electron-browser/extensionTipsService.ts | 15 --------------- .../electron-browser/extensions.contribution.ts | 3 --- src/vs/workbench/workbench.web.main.ts | 3 --- 6 files changed, 8 insertions(+), 38 deletions(-) delete mode 100644 src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts diff --git a/src/vs/base/common/process.ts b/src/vs/base/common/process.ts index a8447d58eea..7b9edd30963 100644 --- a/src/vs/base/common/process.ts +++ b/src/vs/base/common/process.ts @@ -3,11 +3,11 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { isWindows, isMacintosh, setImmediate } from 'vs/base/common/platform'; +import { isWindows, isMacintosh, setImmediate, IProcessEnvironment } from 'vs/base/common/platform'; interface IProcess { platform: string; - env: object; + env: IProcessEnvironment; cwd(): string; nextTick(callback: (...args: any[]) => void): number; diff --git a/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts b/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts index 12a05302a75..ec9b7e82c0f 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts @@ -40,8 +40,8 @@ import { extname } from 'vs/base/common/resources'; import { IExeBasedExtensionTip, IProductService } from 'vs/platform/product/common/product'; import { timeout } from 'vs/base/common/async'; import { IWorkspaceStatsService } from 'vs/workbench/contrib/stats/common/workspaceStats'; -import { Platform, setImmediate, IProcessEnvironment } from 'vs/base/common/platform'; -import { platform } from 'vs/base/common/process'; +import { Platform, setImmediate } from 'vs/base/common/platform'; +import { platform, env as processEnv } from 'vs/base/common/process'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; const milliSecondsInADay = 1000 * 60 * 60 * 24; @@ -66,7 +66,7 @@ function caseInsensitiveGet(obj: { [key: string]: T }, key: string): T | unde return undefined; } -export abstract class BaseExtensionTipsService extends Disposable implements IExtensionTipsService { +export class ExtensionTipsService extends Disposable implements IExtensionTipsService { _serviceBrand: any; @@ -1020,7 +1020,6 @@ export abstract class BaseExtensionTipsService extends Disposable implements IEx if (!windowsPath || typeof windowsPath !== 'string') { return; } - const processEnv = this.getProcessEnvironment(); windowsPath = windowsPath.replace('%USERPROFILE%', processEnv['USERPROFILE']!) .replace('%ProgramFiles(x86)%', processEnv['ProgramFiles(x86)']!) .replace('%ProgramFiles%', processEnv['ProgramFiles']!) @@ -1146,14 +1145,4 @@ export abstract class BaseExtensionTipsService extends Disposable implements IEx return this._allIgnoredRecommendations.indexOf(id.toLowerCase()) === -1; } - protected abstract getProcessEnvironment(): IProcessEnvironment; -} - - -export class ExtensionTipsService extends BaseExtensionTipsService implements IExtensionTipsService { - - protected getProcessEnvironment(): IProcessEnvironment { - return {}; - } - } diff --git a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts index 32bd703fba0..b7bed063f07 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts @@ -10,7 +10,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ExtensionsLabel, ExtensionsChannelId, PreferencesLabel, IExtensionManagementService, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; +import { IExtensionManagementServerService, IExtensionTipsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { IWorkbenchActionRegistry, Extensions as WorkbenchActionExtensions } from 'vs/workbench/common/actions'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { IOutputChannelRegistry, Extensions as OutputExtensions } from 'vs/workbench/contrib/output/common/output'; @@ -45,9 +45,11 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { ExtensionType } from 'vs/platform/extensions/common/extensions'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { RemoteExtensionsInstaller } from 'vs/workbench/contrib/extensions/browser/remoteExtensionsInstaller'; +import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/browser/extensionTipsService'; // Singletons registerSingleton(IExtensionsWorkbenchService, ExtensionsWorkbenchService); +registerSingleton(IExtensionTipsService, ExtensionTipsService); Registry.as(OutputExtensions.OutputChannels) .registerChannel({ id: ExtensionsChannelId, label: ExtensionsLabel, log: false }); diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts deleted file mode 100644 index f866ccbb7a8..00000000000 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts +++ /dev/null @@ -1,15 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { BaseExtensionTipsService } from 'vs/workbench/contrib/extensions/browser/extensionTipsService'; -import { IProcessEnvironment } from 'vs/base/common/platform'; - -export class ExtensionTipsService extends BaseExtensionTipsService { - - protected getProcessEnvironment(): IProcessEnvironment { - return process.env as IProcessEnvironment; - } - -} diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts index 74f15f54393..4c21e1e9181 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts @@ -21,11 +21,8 @@ import { RuntimeExtensionsInput } from 'vs/workbench/contrib/extensions/electron import { URI } from 'vs/base/common/uri'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { ExtensionsAutoProfiler } from 'vs/workbench/contrib/extensions/electron-browser/extensionsAutoProfiler'; -import { IExtensionTipsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; -import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/electron-browser/extensionTipsService'; // Singletons -registerSingleton(IExtensionTipsService, ExtensionTipsService); registerSingleton(IExtensionHostProfileService, ExtensionHostProfileService, true); const workbenchRegistry = Registry.as(WorkbenchExtensions.Workbench); diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 0c80d322d2a..40384b249b0 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -87,9 +87,6 @@ import 'vs/workbench/contrib/debug/browser/extensionHostDebugService'; import 'vs/workbench/contrib/webview/browser/webviewService'; import 'vs/workbench/contrib/webview/browser/webviewEditorService'; -// Extensions Management -import 'vs/workbench/contrib/extensions/browser/extensions.web.contribution'; - // Terminal import 'vs/workbench/contrib/terminal/browser/terminalNativeService'; import 'vs/workbench/contrib/terminal/browser/terminalInstanceService'; From 520fac5336782b8eee87870873f8057d14b2d4b8 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 15 Aug 2019 07:49:06 -0700 Subject: [PATCH 668/861] Remove click code from puppeteer driver, move interfaces to common --- src/vs/platform/driver/browser/baseDriver.ts | 33 +++++- src/vs/platform/driver/common/driver.ts | 7 +- .../driver/electron-browser/driver.ts | 26 ----- .../platform/driver/electron-main/driver.ts | 8 +- src/vs/platform/driver/node/driver.ts | 60 ++-------- test/smoke/src/vscode/puppeteerDriver.ts | 109 ++---------------- test/smoke/tools/copy-driver-definition.js | 4 +- 7 files changed, 64 insertions(+), 183 deletions(-) diff --git a/src/vs/platform/driver/browser/baseDriver.ts b/src/vs/platform/driver/browser/baseDriver.ts index df59dd6e879..38b5626a500 100644 --- a/src/vs/platform/driver/browser/baseDriver.ts +++ b/src/vs/platform/driver/browser/baseDriver.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { getTopLeftOffset } from 'vs/base/browser/dom'; +import { getTopLeftOffset, getClientArea } from 'vs/base/browser/dom'; import { coalesce } from 'vs/base/common/arrays'; import { IElement, IWindowDriver } from 'vs/platform/driver/common/driver'; @@ -45,7 +45,6 @@ export abstract class BaseWindowDriver implements IWindowDriver { constructor() { } - // TODO: This doesn't work in browser driver abstract click(selector: string, xoffset?: number, yoffset?: number): Promise; abstract doubleClick(selector: string): Promise; @@ -101,6 +100,11 @@ export abstract class BaseWindowDriver implements IWindowDriver { return result; } + async getElementXY(selector: string, xoffset?: number, yoffset?: number): Promise<{ x: number; y: number; }> { + const offset = typeof xoffset === 'number' && typeof yoffset === 'number' ? { x: xoffset, y: yoffset } : undefined; + return this._getElementXY(selector, offset); + } + async typeInEditor(selector: string, text: string): Promise { const element = document.querySelector(selector); @@ -159,5 +163,30 @@ export abstract class BaseWindowDriver implements IWindowDriver { xterm._core._coreService.triggerDataEvent(text); } + protected async _getElementXY(selector: string, offset?: { x: number, y: number }): Promise<{ x: number; y: number; }> { + const element = document.querySelector(selector); + + if (!element) { + return Promise.reject(new Error(`Element not found: ${selector}`)); + } + + const { left, top } = getTopLeftOffset(element as HTMLElement); + const { width, height } = getClientArea(element as HTMLElement); + let x: number, y: number; + + if (offset) { + x = left + offset.x; + y = top + offset.y; + } else { + x = left + (width / 2); + y = top + (height / 2); + } + + x = Math.round(x); + y = Math.round(y); + + return { x, y }; + } + abstract async openDevTools(): Promise; } diff --git a/src/vs/platform/driver/common/driver.ts b/src/vs/platform/driver/common/driver.ts index 299628846a4..29fde875994 100644 --- a/src/vs/platform/driver/common/driver.ts +++ b/src/vs/platform/driver/common/driver.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -// TODO: Change smoketest build to read off common instead +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; // !! Do not remove the following START and END markers, they are parsed by the smoketest build @@ -32,12 +32,16 @@ export interface IDriver { getTitle(windowId: number): Promise; isActiveElement(windowId: number, selector: string): Promise; getElements(windowId: number, selector: string, recursive?: boolean): Promise; + getElementXY(windowId: number, selector: string, xoffset?: number, yoffset?: number): Promise<{ x: number; y: number; }>; typeInEditor(windowId: number, selector: string, text: string): Promise; getTerminalBuffer(windowId: number, selector: string): Promise; writeInTerminal(windowId: number, selector: string, text: string): Promise; } //*END +export const ID = 'driverService'; +export const IDriver = createDecorator(ID); + export interface IWindowDriver { click(selector: string, xoffset?: number | undefined, yoffset?: number | undefined): Promise; doubleClick(selector: string): Promise; @@ -45,6 +49,7 @@ export interface IWindowDriver { getTitle(): Promise; isActiveElement(selector: string): Promise; getElements(selector: string, recursive: boolean): Promise; + getElementXY(selector: string, xoffset?: number, yoffset?: number): Promise<{ x: number; y: number; }>; typeInEditor(selector: string, text: string): Promise; getTerminalBuffer(selector: string): Promise; writeInTerminal(selector: string, text: string): Promise; diff --git a/src/vs/platform/driver/electron-browser/driver.ts b/src/vs/platform/driver/electron-browser/driver.ts index 931b898d55f..09e2d6b3379 100644 --- a/src/vs/platform/driver/electron-browser/driver.ts +++ b/src/vs/platform/driver/electron-browser/driver.ts @@ -7,7 +7,6 @@ import { IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { WindowDriverChannel, WindowDriverRegistryChannelClient } from 'vs/platform/driver/node/driver'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService'; -import { getTopLeftOffset, getClientArea } from 'vs/base/browser/dom'; import * as electron from 'electron'; import { IWindowService } from 'vs/platform/windows/common/windows'; import { timeout } from 'vs/base/common/async'; @@ -30,31 +29,6 @@ class WindowDriver extends BaseWindowDriver { return this._click(selector, 2); } - private async _getElementXY(selector: string, offset?: { x: number, y: number }): Promise<{ x: number; y: number; }> { - const element = document.querySelector(selector); - - if (!element) { - return Promise.reject(new Error(`Element not found: ${selector}`)); - } - - const { left, top } = getTopLeftOffset(element as HTMLElement); - const { width, height } = getClientArea(element as HTMLElement); - let x: number, y: number; - - if (offset) { - x = left + offset.x; - y = top + offset.y; - } else { - x = left + (width / 2); - y = top + (height / 2); - } - - x = Math.round(x); - y = Math.round(y); - - return { x, y }; - } - private async _click(selector: string, clickCount: number, offset?: { x: number, y: number }): Promise { const { x, y } = await this._getElementXY(selector, offset); diff --git a/src/vs/platform/driver/electron-main/driver.ts b/src/vs/platform/driver/electron-main/driver.ts index 2b341fb2ed6..8096b8f6abd 100644 --- a/src/vs/platform/driver/electron-main/driver.ts +++ b/src/vs/platform/driver/electron-main/driver.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IDriver, DriverChannel, IElement, WindowDriverChannelClient, IWindowDriverRegistry, WindowDriverRegistryChannel, IWindowDriver, IDriverOptions } from 'vs/platform/driver/node/driver'; +import { DriverChannel, WindowDriverChannelClient, IWindowDriverRegistry, WindowDriverRegistryChannel, IDriverOptions } from 'vs/platform/driver/node/driver'; import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows'; import { serve as serveNet } from 'vs/base/parts/ipc/node/ipc.net'; import { combinedDisposable, IDisposable } from 'vs/base/common/lifecycle'; @@ -17,6 +17,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { ScanCodeBinding } from 'vs/base/common/scanCode'; import { KeybindingParser } from 'vs/base/common/keybindingParser'; import { timeout } from 'vs/base/common/async'; +import { IDriver, IElement, IWindowDriver } from 'vs/platform/driver/common/driver'; function isSilentKeyCode(keyCode: KeyCode) { return keyCode < KeyCode.KEY_0; @@ -163,6 +164,11 @@ export class Driver implements IDriver, IWindowDriverRegistry { return await windowDriver.getElements(selector, recursive); } + async getElementXY(windowId: number, selector: string, xoffset?: number, yoffset?: number): Promise<{ x: number; y: number; }> { + const windowDriver = await this.getWindowDriver(windowId); + return await windowDriver.getElementXY(selector, xoffset, yoffset); + } + async typeInEditor(windowId: number, selector: string, text: string): Promise { const windowDriver = await this.getWindowDriver(windowId); await windowDriver.typeInEditor(selector, text); diff --git a/src/vs/platform/driver/node/driver.ts b/src/vs/platform/driver/node/driver.ts index e77790a5183..2c525c0e694 100644 --- a/src/vs/platform/driver/node/driver.ts +++ b/src/vs/platform/driver/node/driver.ts @@ -5,45 +5,9 @@ import { Client } from 'vs/base/parts/ipc/common/ipc.net'; import { connect as connectNet } from 'vs/base/parts/ipc/node/ipc.net'; -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IChannel, IServerChannel } from 'vs/base/parts/ipc/common/ipc'; import { Event } from 'vs/base/common/event'; - -export const ID = 'driverService'; -export const IDriver = createDecorator(ID); - -// !! Do not remove the following START and END markers, they are parsed by the smoketest build - -//*START -export interface IElement { - tagName: string; - className: string; - textContent: string; - attributes: { [name: string]: string; }; - children: IElement[]; - top: number; - left: number; -} - -export interface IDriver { - _serviceBrand: any; - - getWindowIds(): Promise; - capturePage(windowId: number): Promise; - reloadWindow(windowId: number): Promise; - exitApplication(): Promise; - dispatchKeybinding(windowId: number, keybinding: string): Promise; - click(windowId: number, selector: string, xoffset?: number | undefined, yoffset?: number | undefined): Promise; - doubleClick(windowId: number, selector: string): Promise; - setValue(windowId: number, selector: string, text: string): Promise; - getTitle(windowId: number): Promise; - isActiveElement(windowId: number, selector: string): Promise; - getElements(windowId: number, selector: string, recursive?: boolean): Promise; - typeInEditor(windowId: number, selector: string, text: string): Promise; - getTerminalBuffer(windowId: number, selector: string): Promise; - writeInTerminal(windowId: number, selector: string, text: string): Promise; -} -//*END +import { IDriver, IElement, IWindowDriver } from 'vs/platform/driver/common/driver'; export class DriverChannel implements IServerChannel { @@ -66,6 +30,7 @@ export class DriverChannel implements IServerChannel { case 'getTitle': return this.driver.getTitle(arg[0]); case 'isActiveElement': return this.driver.isActiveElement(arg[0], arg[1]); case 'getElements': return this.driver.getElements(arg[0], arg[1], arg[2]); + case 'getElementXY': return this.driver.getElementXY(arg[0], arg[1], arg[2]); case 'typeInEditor': return this.driver.typeInEditor(arg[0], arg[1], arg[2]); case 'getTerminalBuffer': return this.driver.getTerminalBuffer(arg[0], arg[1]); case 'writeInTerminal': return this.driver.writeInTerminal(arg[0], arg[1], arg[2]); @@ -125,6 +90,10 @@ export class DriverChannelClient implements IDriver { return this.channel.call('getElements', [windowId, selector, recursive]); } + getElementXY(windowId: number, selector: string, xoffset: number | undefined, yoffset: number | undefined): Promise<{ x: number, y: number }> { + return this.channel.call('getElementXY', [windowId, selector, xoffset, yoffset]); + } + typeInEditor(windowId: number, selector: string, text: string): Promise { return this.channel.call('typeInEditor', [windowId, selector, text]); } @@ -180,18 +149,6 @@ export class WindowDriverRegistryChannelClient implements IWindowDriverRegistry } } -export interface IWindowDriver { - click(selector: string, xoffset?: number | undefined, yoffset?: number | undefined): Promise; - doubleClick(selector: string): Promise; - setValue(selector: string, text: string): Promise; - getTitle(): Promise; - isActiveElement(selector: string): Promise; - getElements(selector: string, recursive: boolean): Promise; - typeInEditor(selector: string, text: string): Promise; - getTerminalBuffer(selector: string): Promise; - writeInTerminal(selector: string, text: string): Promise; -} - export class WindowDriverChannel implements IServerChannel { constructor(private driver: IWindowDriver) { } @@ -208,6 +165,7 @@ export class WindowDriverChannel implements IServerChannel { case 'getTitle': return this.driver.getTitle(); case 'isActiveElement': return this.driver.isActiveElement(arg); case 'getElements': return this.driver.getElements(arg[0], arg[1]); + case 'getElementXY': return this.driver.getElementXY(arg[0], arg[1], arg[2]); case 'typeInEditor': return this.driver.typeInEditor(arg[0], arg[1]); case 'getTerminalBuffer': return this.driver.getTerminalBuffer(arg); case 'writeInTerminal': return this.driver.writeInTerminal(arg[0], arg[1]); @@ -247,6 +205,10 @@ export class WindowDriverChannelClient implements IWindowDriver { return this.channel.call('getElements', [selector, recursive]); } + getElementXY(selector: string, xoffset?: number, yoffset?: number): Promise<{ x: number, y: number }> { + return this.channel.call('getElementXY', [selector, xoffset, yoffset]); + } + typeInEditor(selector: string, text: string): Promise { return this.channel.call('typeInEditor', [selector, text]); } diff --git a/test/smoke/src/vscode/puppeteerDriver.ts b/test/smoke/src/vscode/puppeteerDriver.ts index 2e2f2280dd6..7205ce266a6 100644 --- a/test/smoke/src/vscode/puppeteerDriver.ts +++ b/test/smoke/src/vscode/puppeteerDriver.ts @@ -26,7 +26,7 @@ const vscodeToPuppeteerKey = { }; function buildDriver(browser: puppeteer.Browser, page: puppeteer.Page): IDriver { - return { + const driver = { _serviceBrand: undefined, getWindowIds: () => { return Promise.resolve([1]); @@ -57,121 +57,25 @@ function buildDriver(browser: puppeteer.Browser, page: puppeteer.Page): IDriver await timeout(100); }, click: async (windowId, selector, xoffset, yoffset) => { - const { x, y } = await page.evaluate(` - (function() { - function convertToPixels(element, value) { - return parseFloat(value) || 0; - } - function getDimension(element, cssPropertyName, jsPropertyName) { - let computedStyle = getComputedStyle(element); - let value = '0'; - if (computedStyle) { - if (computedStyle.getPropertyValue) { - value = computedStyle.getPropertyValue(cssPropertyName); - } else { - // IE8 - value = (computedStyle).getAttribute(jsPropertyName); - } - } - return convertToPixels(element, value); - } - function getBorderLeftWidth(element) { - return getDimension(element, 'border-left-width', 'borderLeftWidth'); - } - function getBorderRightWidth(element) { - return getDimension(element, 'border-right-width', 'borderRightWidth'); - } - function getBorderTopWidth(element) { - return getDimension(element, 'border-top-width', 'borderTopWidth'); - } - function getBorderBottomWidth(element) { - return getDimension(element, 'border-bottom-width', 'borderBottomWidth'); - } - function getClientArea(element) { - // Try with DOM clientWidth / clientHeight - if (element !== document.body) { - return { width: element.clientWidth, height: element.clientHeight }; - } - - // Try innerWidth / innerHeight - if (window.innerWidth && window.innerHeight) { - return { width: window.innerWidth, height: window.innerHeight }; - } - - // Try with document.body.clientWidth / document.body.clientHeight - if (document.body && document.body.clientWidth && document.body.clientHeight) { - return { width: document.body.clientWidth, height: document.body.clientHeight }; - } - - // Try with document.documentElement.clientWidth / document.documentElement.clientHeight - if (document.documentElement && document.documentElement.clientWidth && document.documentElement.clientHeight) { - return { width: document.documentElement.clientWidth, height: document.documentElement.clientHeight }; - } - - throw new Error('Unable to figure out browser width and height'); - } - function getTopLeftOffset(element) { - // Adapted from WinJS.Utilities.getPosition - // and added borders to the mix - - let offsetParent = element.offsetParent, top = element.offsetTop, left = element.offsetLeft; - - while ((element = element.parentNode) !== null && element !== document.body && element !== document.documentElement) { - top -= element.scrollTop; - let c = getComputedStyle(element); - if (c) { - left -= c.direction !== 'rtl' ? element.scrollLeft : -element.scrollLeft; - } - - if (element === offsetParent) { - left += getBorderLeftWidth(element); - top += getBorderTopWidth(element); - top += element.offsetTop; - left += element.offsetLeft; - offsetParent = element.offsetParent; - } - } - - return { - left: left, - top: top - }; - } - const element = document.querySelector('${selector}'); - - if (!element) { - throw new Error('Element not found: ${selector}'); - } - - const { left, top } = getTopLeftOffset(element); - const { width, height } = getClientArea(element); - let x, y; - - x = left + (width / 2); - y = top + (height / 2); - - x = Math.round(x); - y = Math.round(y); - - return { x, y }; - })(); - `); + const { x, y } = await driver.getElementXY(windowId, selector, xoffset, yoffset); await page.mouse.click(x + (xoffset ? xoffset : 0), y + (yoffset ? yoffset : 0)); }, doubleClick: async (windowId, selector) => { - await this.click(windowId, selector, 0, 0); + await driver.click(windowId, selector, 0, 0); await timeout(60); - await this.click(windowId, selector, 0, 0); + await driver.click(windowId, selector, 0, 0); await timeout(100); }, setValue: async (windowId, selector, text) => page.evaluate(`window.driver.setValue('${selector}', '${text}')`), getTitle: (windowId) => page.evaluate(`window.driver.getTitle()`), isActiveElement: (windowId, selector) => page.evaluate(`window.driver.isActiveElement('${selector}')`), getElements: (windowId, selector, recursive) => page.evaluate(`window.driver.getElements('${selector}', ${recursive})`), + getElementXY: (windowId, selector, xoffset?, yoffset?) => page.evaluate(`window.driver.getElementXY('${selector}', ${xoffset}, ${yoffset})`), typeInEditor: (windowId, selector, text) => page.evaluate(`window.driver.typeInEditor('${selector}', '${text}')`), getTerminalBuffer: (windowId, selector) => page.evaluate(`window.driver.getTerminalBuffer('${selector}')`), writeInTerminal: (windowId, selector, text) => page.evaluate(`window.driver.writeInTerminal('${selector}', '${text}')`) }; + return driver; } function timeout(ms: number): Promise { @@ -275,6 +179,7 @@ export interface IDriver { getTitle(windowId: number): Promise; isActiveElement(windowId: number, selector: string): Promise; getElements(windowId: number, selector: string, recursive?: boolean): Promise; + getElementXY(selector: string, xoffset?: number, yoffset?: number): Promise<{ x: number; y: number; }>; typeInEditor(windowId: number, selector: string, text: string): Promise; getTerminalBuffer(windowId: number, selector: string): Promise; writeInTerminal(windowId: number, selector: string, text: string): Promise; diff --git a/test/smoke/tools/copy-driver-definition.js b/test/smoke/tools/copy-driver-definition.js index 2af7a3acd2a..fdebfcc6b0a 100644 --- a/test/smoke/tools/copy-driver-definition.js +++ b/test/smoke/tools/copy-driver-definition.js @@ -7,7 +7,7 @@ const fs = require('fs'); const path = require('path'); const root = path.dirname(path.dirname(path.dirname(__dirname))); -const driverPath = path.join(root, 'src/vs/platform/driver/node/driver.ts'); +const driverPath = path.join(root, 'src/vs/platform/driver/common/driver.ts'); let contents = fs.readFileSync(driverPath, 'utf8'); contents = /\/\/\*START([\s\S]*)\/\/\*END/mi.exec(contents)[1].trim(); @@ -47,4 +47,4 @@ export function connect(outPath: string, handle: string): Promise<{ client: IDis const srcPath = path.join(path.dirname(__dirname), 'src/vscode'); const outDriverPath = path.join(srcPath, 'driver.d.ts'); -fs.writeFileSync(outDriverPath, contents); \ No newline at end of file +fs.writeFileSync(outDriverPath, contents); From 173b8c5cc6c6f6bda577cb1b020fbfef0254841b Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 15 Aug 2019 07:52:23 -0700 Subject: [PATCH 669/861] Reduce diff --- test/smoke/src/vscode/code.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/smoke/src/vscode/code.ts b/test/smoke/src/vscode/code.ts index 8a7ffc3d7b1..44cfcfe419f 100644 --- a/test/smoke/src/vscode/code.ts +++ b/test/smoke/src/vscode/code.ts @@ -227,7 +227,7 @@ export class Code { private driver: IDriver; constructor( - private client: IDisposable | undefined, + private client: IDisposable, driver: IDriver, readonly logger: Logger ) { @@ -343,9 +343,7 @@ export class Code { } dispose(): void { - if (this.client) { - this.client.dispose(); - } + this.client.dispose(); } } From 14ee0218838a3eeac988b40c8c68b7419adf40dd Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 15 Aug 2019 16:06:50 +0200 Subject: [PATCH 670/861] fix typos --- .../api/node/extHostRequireInterceptor.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/api/node/extHostRequireInterceptor.ts b/src/vs/workbench/api/node/extHostRequireInterceptor.ts index 876d6716a67..2b0839e319f 100644 --- a/src/vs/workbench/api/node/extHostRequireInterceptor.ts +++ b/src/vs/workbench/api/node/extHostRequireInterceptor.ts @@ -22,7 +22,7 @@ interface LoadFunction { interface INodeModuleFactory { readonly nodeModuleName: string | string[]; load(request: string, parent: { filename: string; }, isMain: any, original: LoadFunction): any; - alternaiveModuleName?(name: string): string | undefined; + alternativeModuleName?(name: string): string | undefined; } export class NodeModuleRequireInterceptor { @@ -63,9 +63,9 @@ export class NodeModuleRequireInterceptor { } else { this._factories.set(interceptor.nodeModuleName, interceptor); } - if (typeof interceptor.alternaiveModuleName === 'function') { + if (typeof interceptor.alternativeModuleName === 'function') { this._alternatives.push((moduleName) => { - return interceptor.alternaiveModuleName!(moduleName); + return interceptor.alternativeModuleName!(moduleName); }); } } @@ -155,7 +155,7 @@ export class KeytarNodeModuleFactory implements INodeModuleFactory { return this._impl; } - public alternaiveModuleName(name: string): string | undefined { + public alternativeModuleName(name: string): string | undefined { const length = name.length; // We need at least something like: `?/keytar` which requires // more than 7 characters. @@ -194,7 +194,7 @@ export class OpenNodeModuleFactory implements INodeModuleFactory { private _original?: IOriginalOpen; private _impl: IOpenModule; - constructor(mainThreadWindow: MainThreadWindowShape, private _mainThreadTelemerty: MainThreadTelemetryShape, private readonly _extensionPaths: TernarySearchTree) { + constructor(mainThreadWindow: MainThreadWindowShape, private _mainThreadTelemetry: MainThreadTelemetryShape, private readonly _extensionPaths: TernarySearchTree) { this._impl = (target, options) => { const uri: URI = URI.parse(target); // If we have options use the original method. @@ -234,7 +234,7 @@ export class OpenNodeModuleFactory implements INodeModuleFactory { type ShimmingOpenClassification = { extension: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; }; - this._mainThreadTelemerty.$publicLog2<{ extension: string }, ShimmingOpenClassification>('shimming.open', { extension: this._extensionId }); + this._mainThreadTelemetry.$publicLog2<{ extension: string }, ShimmingOpenClassification>('shimming.open', { extension: this._extensionId }); } private sendNoForwardTelemetry(): void { @@ -244,6 +244,6 @@ export class OpenNodeModuleFactory implements INodeModuleFactory { type ShimmingOpenCallNoForwardClassification = { extension: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }; }; - this._mainThreadTelemerty.$publicLog2<{ extension: string }, ShimmingOpenCallNoForwardClassification>('shimming.open.call.noForward', { extension: this._extensionId }); + this._mainThreadTelemetry.$publicLog2<{ extension: string }, ShimmingOpenCallNoForwardClassification>('shimming.open.call.noForward', { extension: this._extensionId }); } } From 5e63f6e00fc9b8b049b1145ca88845853c70050d Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 15 Aug 2019 16:55:56 +0200 Subject: [PATCH 671/861] web - reuse require interceptor logic --- .../extHostRequireInterceptor.ts | 113 ++++++++++++------ .../api/node/extHostExtensionService.ts | 38 ++++-- .../api/worker/extHostExtensionService.ts | 76 ++++++------ 3 files changed, 135 insertions(+), 92 deletions(-) rename src/vs/workbench/api/{node => common}/extHostRequireInterceptor.ts (67%) diff --git a/src/vs/workbench/api/node/extHostRequireInterceptor.ts b/src/vs/workbench/api/common/extHostRequireInterceptor.ts similarity index 67% rename from src/vs/workbench/api/node/extHostRequireInterceptor.ts rename to src/vs/workbench/api/common/extHostRequireInterceptor.ts index 2b0839e319f..ad16a75c56b 100644 --- a/src/vs/workbench/api/node/extHostRequireInterceptor.ts +++ b/src/vs/workbench/api/common/extHostRequireInterceptor.ts @@ -5,14 +5,19 @@ import { TernarySearchTree } from 'vs/base/common/map'; import { URI } from 'vs/base/common/uri'; -import { MainThreadKeytarShape, IEnvironment, MainThreadWindowShape, MainThreadTelemetryShape } from 'vs/workbench/api/common/extHost.protocol'; -import { ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration'; +import { MainThreadTelemetryShape, MainContext } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostConfigProvider, IExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration'; import { nullExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; import * as vscode from 'vscode'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { endsWith } from 'vs/base/common/strings'; import { IExtensionApiFactory } from 'vs/workbench/api/common/extHost.api.impl'; +import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; +import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; +import { platform } from 'vs/base/common/process'; interface LoadFunction { @@ -21,40 +26,43 @@ interface LoadFunction { interface INodeModuleFactory { readonly nodeModuleName: string | string[]; - load(request: string, parent: { filename: string; }, isMain: any, original: LoadFunction): any; + load(request: string, parent: URI, isMain: any, original: LoadFunction): any; alternativeModuleName?(name: string): string | undefined; } -export class NodeModuleRequireInterceptor { - public static INSTANCE = new NodeModuleRequireInterceptor(); +export abstract class RequireInterceptor { - private readonly _factories: Map; - private readonly _alternatives: ((moduleName: string) => string | undefined)[]; + protected readonly _factories: Map; + protected readonly _alternatives: ((moduleName: string) => string | undefined)[]; - constructor() { + constructor( + private _apiFactory: IExtensionApiFactory, + private _extensionRegistry: ExtensionDescriptionRegistry, + @IInstantiationService private readonly _instaService: IInstantiationService, + @IExtHostConfiguration private readonly _extHostConfiguration: IExtHostConfiguration, + @IExtHostExtensionService private readonly _extHostExtensionService: IExtHostExtensionService, + @IExtHostInitDataService private readonly _initData: IExtHostInitDataService + ) { this._factories = new Map(); this._alternatives = []; - this._installInterceptor(this._factories, this._alternatives); } - private _installInterceptor(factories: Map, alternatives: ((moduleName: string) => string | undefined)[]): void { - const node_module = require.__$__nodeRequire('module'); - const original = node_module._load; - node_module._load = function load(request: string, parent: { filename: string; }, isMain: any) { - for (let alternativeModuleName of alternatives) { - let alternative = alternativeModuleName(request); - if (alternative) { - request = alternative; - break; - } - } - if (!factories.has(request)) { - return original.apply(this, arguments); - } - return factories.get(request)!.load(request, parent, isMain, original); - }; + async install(): Promise { + + this._installInterceptor(); + + const configProvider = await this._extHostConfiguration.getConfigProvider(); + const extensionPaths = await this._extHostExtensionService.getExtensionPathIndex(); + + this.register(new VSCodeNodeModuleFactory(this._apiFactory, extensionPaths, this._extensionRegistry, configProvider)); + this.register(this._instaService.createInstance(KeytarNodeModuleFactory)); + if (this._initData.remote.isRemote) { + this.register(this._instaService.createInstance(OpenNodeModuleFactory, extensionPaths)); + } } + protected abstract _installInterceptor(): void; + public register(interceptor: INodeModuleFactory): void { if (Array.isArray(interceptor.nodeModuleName)) { for (let moduleName of interceptor.nodeModuleName) { @@ -71,7 +79,9 @@ export class NodeModuleRequireInterceptor { } } -export class VSCodeNodeModuleFactory implements INodeModuleFactory { +//#region --- vscode-module + +class VSCodeNodeModuleFactory implements INodeModuleFactory { public readonly nodeModuleName = 'vscode'; private readonly _extApiImpl = new Map(); @@ -85,10 +95,10 @@ export class VSCodeNodeModuleFactory implements INodeModuleFactory { ) { } - public load(request: string, parent: { filename: string; }): any { + public load(_request: string, parent: URI): any { // get extension id from filename and api for extension - const ext = this._extensionPaths.findSubstr(URI.file(parent.filename).fsPath); + const ext = this._extensionPaths.findSubstr(parent.fsPath); if (ext) { let apiImpl = this._extApiImpl.get(ExtensionIdentifier.toKey(ext.identifier)); if (!apiImpl) { @@ -102,13 +112,18 @@ export class VSCodeNodeModuleFactory implements INodeModuleFactory { if (!this._defaultApiImpl) { let extensionPathsPretty = ''; this._extensionPaths.forEach((value, index) => extensionPathsPretty += `\t${index} -> ${value.identifier.value}\n`); - console.warn(`Could not identify extension for 'vscode' require call from ${parent.filename}. These are the extension path mappings: \n${extensionPathsPretty}`); + console.warn(`Could not identify extension for 'vscode' require call from ${parent.fsPath}. These are the extension path mappings: \n${extensionPathsPretty}`); this._defaultApiImpl = this._apiFactory(nullExtensionDescription, this._extensionRegistry, this._configProvider); } return this._defaultApiImpl; } } +//#endregion + + +//#region --- keytar-module + interface IKeytarModule { getPassword(service: string, account: string): Promise; setPassword(service: string, account: string, password: string): Promise; @@ -116,16 +131,23 @@ interface IKeytarModule { findPassword(service: string): Promise; } -export class KeytarNodeModuleFactory implements INodeModuleFactory { +class KeytarNodeModuleFactory implements INodeModuleFactory { public readonly nodeModuleName: string = 'keytar'; private alternativeNames: Set | undefined; private _impl: IKeytarModule; - constructor(mainThreadKeytar: MainThreadKeytarShape, environment: IEnvironment) { + constructor( + @IExtHostRpcService rpcService: IExtHostRpcService, + @IExtHostInitDataService initData: IExtHostInitDataService, + + ) { + const { environment } = initData; + const mainThreadKeytar = rpcService.getProxy(MainContext.MainThreadKeytar); + if (environment.appRoot) { let appRoot = environment.appRoot.fsPath; - if (process.platform === 'win32') { + if (platform === 'win32') { appRoot = appRoot.replace(/\\/g, '/'); } if (appRoot[appRoot.length - 1] === '/') { @@ -151,7 +173,7 @@ export class KeytarNodeModuleFactory implements INodeModuleFactory { }; } - public load(request: string, parent: { filename: string; }): any { + public load(_request: string, _parent: URI): any { return this._impl; } @@ -173,6 +195,11 @@ export class KeytarNodeModuleFactory implements INodeModuleFactory { } } +//#endregion + + +//#region --- opn/open-module + interface OpenOptions { wait: boolean; app: string | string[]; @@ -186,15 +213,23 @@ interface IOpenModule { (target: string, options?: OpenOptions): Thenable; } -export class OpenNodeModuleFactory implements INodeModuleFactory { +class OpenNodeModuleFactory implements INodeModuleFactory { public readonly nodeModuleName: string[] = ['open', 'opn']; private _extensionId: string | undefined; private _original?: IOriginalOpen; private _impl: IOpenModule; + private _mainThreadTelemetry: MainThreadTelemetryShape; + + constructor( + private readonly _extensionPaths: TernarySearchTree, + @IExtHostRpcService rpcService: IExtHostRpcService, + ) { + + this._mainThreadTelemetry = rpcService.getProxy(MainContext.MainThreadTelemetry); + const mainThreadWindow = rpcService.getProxy(MainContext.MainThreadWindow); - constructor(mainThreadWindow: MainThreadWindowShape, private _mainThreadTelemetry: MainThreadTelemetryShape, private readonly _extensionPaths: TernarySearchTree) { this._impl = (target, options) => { const uri: URI = URI.parse(target); // If we have options use the original method. @@ -210,15 +245,15 @@ export class OpenNodeModuleFactory implements INodeModuleFactory { }; } - public load(request: string, parent: { filename: string; }, isMain: any, original: LoadFunction): any { + public load(request: string, parent: URI, isMain: any, original: LoadFunction): any { // get extension id from filename and api for extension - const extension = this._extensionPaths.findSubstr(URI.file(parent.filename).fsPath); + const extension = this._extensionPaths.findSubstr(parent.fsPath); if (extension) { this._extensionId = extension.identifier.value; this.sendShimmingTelemetry(); } - this._original = original(request, parent, isMain); + this._original = original(request, { filename: parent.fsPath }, isMain); return this._impl; } @@ -247,3 +282,5 @@ export class OpenNodeModuleFactory implements INodeModuleFactory { this._mainThreadTelemetry.$publicLog2<{ extension: string }, ShimmingOpenCallNoForwardClassification>('shimming.open.call.noForward', { extension: this._extensionId }); } } + +//#endregion diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 5b03a318564..10161ac3355 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { createApiFactoryAndRegisterActors } from 'vs/workbench/api/common/extHost.api.impl'; -import { NodeModuleRequireInterceptor, VSCodeNodeModuleFactory, KeytarNodeModuleFactory, OpenNodeModuleFactory } from 'vs/workbench/api/node/extHostRequireInterceptor'; +import { RequireInterceptor } from 'vs/workbench/api/common/extHostRequireInterceptor'; import { MainContext } from 'vs/workbench/api/common/extHost.protocol'; import { ExtensionActivationTimesBuilder } from 'vs/workbench/api/common/extHostExtensionActivator'; import { connectProxyResolver } from 'vs/workbench/services/extensions/node/proxyResolver'; @@ -14,6 +14,28 @@ import { CLIServer } from 'vs/workbench/api/node/extHostCLIServer'; import { URI } from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; +class NodeModuleRequireInterceptor extends RequireInterceptor { + + protected _installInterceptor(): void { + const that = this; + const node_module = require.__$__nodeRequire('module'); + const original = node_module._load; + node_module._load = function load(request: string, parent: { filename: string; }, isMain: any) { + for (let alternativeModuleName of that._alternatives) { + let alternative = alternativeModuleName(request); + if (alternative) { + request = alternative; + break; + } + } + if (!that._factories.has(request)) { + return original.apply(this, arguments); + } + return that._factories.get(request)!.load(request, URI.file(parent.filename), isMain, original); + }; + } +} + export class ExtHostExtensionService extends AbstractExtHostExtensionService { protected async _beforeAlmostReadyToRunExtensions(): Promise { @@ -30,19 +52,11 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { } // Module loading tricks - const configProvider = await this._extHostConfiguration.getConfigProvider(); - const extensionPaths = await this.getExtensionPathIndex(); - NodeModuleRequireInterceptor.INSTANCE.register(new VSCodeNodeModuleFactory(extensionApiFactory, extensionPaths, this._registry, configProvider)); - NodeModuleRequireInterceptor.INSTANCE.register(new KeytarNodeModuleFactory(this._extHostContext.getProxy(MainContext.MainThreadKeytar), this._initData.environment)); - if (this._initData.remote.isRemote) { - NodeModuleRequireInterceptor.INSTANCE.register(new OpenNodeModuleFactory( - this._extHostContext.getProxy(MainContext.MainThreadWindow), - this._extHostContext.getProxy(MainContext.MainThreadTelemetry), - extensionPaths - )); - } + const interceptor = this._instaService.createInstance(NodeModuleRequireInterceptor, extensionApiFactory, this._registry); + await interceptor.install(); // Do this when extension service exists, but extensions are not being activated yet. + const configProvider = await this._extHostConfiguration.getConfigProvider(); await connectProxyResolver(this._extHostWorkspace, configProvider, this, this._logService, this._mainThreadTelemetryProxy); // Use IPC messages to forward console-calls, note that the console is diff --git a/src/vs/workbench/api/worker/extHostExtensionService.ts b/src/vs/workbench/api/worker/extHostExtensionService.ts index d3d36327339..3dc4c2a97cb 100644 --- a/src/vs/workbench/api/worker/extHostExtensionService.ts +++ b/src/vs/workbench/api/worker/extHostExtensionService.ts @@ -3,45 +3,14 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { createApiFactoryAndRegisterActors, IExtensionApiFactory } from 'vs/workbench/api/common/extHost.api.impl'; +import { createApiFactoryAndRegisterActors } from 'vs/workbench/api/common/extHost.api.impl'; import { ExtensionActivationTimesBuilder } from 'vs/workbench/api/common/extHostExtensionActivator'; import { AbstractExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; import { endsWith, startsWith } from 'vs/base/common/strings'; -import { IExtensionDescription, ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; -import { ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration'; -import * as vscode from 'vscode'; -import { TernarySearchTree } from 'vs/base/common/map'; -import { nullExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; -import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; import { URI } from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; import { joinPath } from 'vs/base/common/resources'; - -class ApiInstances { - - private readonly _apiInstances = new Map(); - - constructor( - private readonly _apiFactory: IExtensionApiFactory, - private readonly _extensionPaths: TernarySearchTree, - private readonly _extensionRegistry: ExtensionDescriptionRegistry, - private readonly _configProvider: ExtHostConfigProvider, - ) { - // - } - - get(modulePath: string): typeof vscode { - const extension = this._extensionPaths.findSubstr(modulePath) || nullExtensionDescription; - const id = ExtensionIdentifier.toKey(extension.identifier); - - let apiInstance = this._apiInstances.get(id); - if (!apiInstance) { - apiInstance = this._apiFactory(extension, this._extensionRegistry, this._configProvider); - this._apiInstances.set(id, apiInstance); - } - return apiInstance; - } -} +import { RequireInterceptor } from 'vs/workbench/api/common/extHostRequireInterceptor'; class ExportsTrap { @@ -53,7 +22,7 @@ class ExportsTrap { private constructor() { const exportsProxy = new Proxy({}, { - set: (target: any, p: PropertyKey, value: any, receiver: any) => { + set: (target: any, p: PropertyKey, value: any) => { // store in target target[p] = value; // store in named-bucket @@ -74,7 +43,7 @@ class ExportsTrap { return target[p]; }, - set: (target: any, p: PropertyKey, value: any, receiver: any) => { + set: (target: any, p: PropertyKey, value: any) => { // store in target target[p] = value; @@ -106,16 +75,35 @@ class ExportsTrap { } } +class WorkerRequireInterceptor extends RequireInterceptor { + + _installInterceptor() { } + + getModule(request: string, parent: URI): undefined | any { + for (let alternativeModuleName of this._alternatives) { + let alternative = alternativeModuleName(request); + if (alternative) { + request = alternative; + break; + } + } + + if (this._factories.has(request)) { + return this._factories.get(request)!.load(request, parent, false, () => { throw new Error(); }); + } + return undefined; + } +} + export class ExtHostExtensionService extends AbstractExtHostExtensionService { - private _apiInstances?: ApiInstances; + private _fakeModules: WorkerRequireInterceptor; protected async _beforeAlmostReadyToRunExtensions(): Promise { // initialize API and register actors const apiFactory = this._instaService.invokeFunction(createApiFactoryAndRegisterActors); - const configProvider = await this._extHostConfiguration.getConfigProvider(); - const extensionPath = await this.getExtensionPathIndex(); - this._apiInstances = new ApiInstances(apiFactory, extensionPath, this._registry, configProvider); + this._fakeModules = this._instaService.createInstance(WorkerRequireInterceptor, apiFactory, this._registry); + await this._fakeModules.install(); } protected _loadCommonJSModule(module: URI, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { @@ -135,11 +123,15 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { // FAKE require function that only works for the vscode-module const moduleStack: URI[] = []; - patchSelf.require = (mod: string) => { + (self).require = (mod: string) => { + const parent = moduleStack[moduleStack.length - 1]; - if (mod === 'vscode') { - return this._apiInstances!.get(parent.fsPath); + const result = this._fakeModules.getModule(mod, parent); + + if (result !== undefined) { + return result; } + if (!startsWith(mod, '.')) { throw new Error(`Cannot load module '${mod}'`); } From 15496555ea85233b48205f56604730ac2f1b16d8 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 15 Aug 2019 16:57:41 +0200 Subject: [PATCH 672/861] remove FakeCommonJSSelf --- .../workbench/api/worker/extHostExtensionService.ts | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/vs/workbench/api/worker/extHostExtensionService.ts b/src/vs/workbench/api/worker/extHostExtensionService.ts index 3dc4c2a97cb..fdc57cbb2ec 100644 --- a/src/vs/workbench/api/worker/extHostExtensionService.ts +++ b/src/vs/workbench/api/worker/extHostExtensionService.ts @@ -108,18 +108,7 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService { protected _loadCommonJSModule(module: URI, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise { - interface FakeCommonJSSelf { - module?: object; - exports?: object; - require?: (module: string) => any; - window?: object; - __dirname: never; - __filename: never; - } - - // FAKE commonjs world that only collects exports - const patchSelf: FakeCommonJSSelf = self; - patchSelf.window = self; // <- that's improper but might help extensions that aren't authored correctly + (self).window = self; // <- that's improper but might help extensions that aren't authored correctly // FAKE require function that only works for the vscode-module const moduleStack: URI[] = []; From 6e8d4cf70f05e932248f544ddb1b324edced90f2 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 15 Aug 2019 07:58:24 -0700 Subject: [PATCH 673/861] Fix dispatch keybinding when called multiple times --- test/smoke/src/vscode/puppeteerDriver.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/smoke/src/vscode/puppeteerDriver.ts b/test/smoke/src/vscode/puppeteerDriver.ts index 7205ce266a6..6b1f51d8ce8 100644 --- a/test/smoke/src/vscode/puppeteerDriver.ts +++ b/test/smoke/src/vscode/puppeteerDriver.ts @@ -36,8 +36,9 @@ function buildDriver(browser: puppeteer.Browser, page: puppeteer.Page): IDriver exitApplication: () => browser.close(), dispatchKeybinding: async (windowId, keybinding) => { const chords = keybinding.split(' '); - chords.forEach(async (chord, index) => { - if (index > 0) { + for (let i = 0; i < chords.length; i++) { + const chord = chords[i]; + if (i > 0) { await timeout(100); } const keys = chord.split('+'); @@ -52,7 +53,7 @@ function buildDriver(browser: puppeteer.Browser, page: puppeteer.Page): IDriver while (keysDown.length > 0) { await page.keyboard.up(keysDown.pop()!); } - }); + } await timeout(100); }, From 8e55695fd55f96e491a2f7079972b8c24fb0a25c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 15 Aug 2019 08:09:50 -0700 Subject: [PATCH 674/861] Fix layer breakage Part of #79210 --- .../contrib/terminal/browser/terminalProcessManager.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index b3ff7db5e88..d99d8de0ab1 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -5,6 +5,7 @@ import * as platform from 'vs/base/common/platform'; import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; +import { env as processEnv } from 'vs/base/common/process'; import { ProcessState, ITerminalProcessManager, IShellLaunchConfig, ITerminalConfigHelper, ITerminalChildProcess, IBeforeProcessDataEvent, ITerminalEnvironment, ITerminalDimensions } from 'vs/workbench/contrib/terminal/common/terminal'; import { ILogService } from 'vs/platform/log/common/log'; import { Emitter, Event } from 'vs/base/common/event'; @@ -225,7 +226,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce const envFromConfigValue = this._workspaceConfigurationService.inspect(`terminal.integrated.env.${platformKey}`); const isWorkspaceShellAllowed = this._configHelper.checkWorkspaceShellPermissions(); this._configHelper.showRecommendations(shellLaunchConfig); - const baseEnv = this._configHelper.config.inheritEnv ? process.env as platform.IProcessEnvironment : await this._terminalInstanceService.getMainProcessParentEnv(); + const baseEnv = this._configHelper.config.inheritEnv ? processEnv : await this._terminalInstanceService.getMainProcessParentEnv(); const env = terminalEnvironment.createTerminalEnvironment(shellLaunchConfig, lastActiveWorkspace, envFromConfigValue, this._configurationResolverService, isWorkspaceShellAllowed, this._productService.version, this._configHelper.config.setLocaleVariables, baseEnv); const useConpty = this._configHelper.config.windowsEnableConpty && !isScreenReaderModeEnabled; From 2bceb25547ab539f565d68b6dfcef96e32da455f Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 15 Aug 2019 17:25:50 +0200 Subject: [PATCH 675/861] Fixes #78975: Look for autoclosing pairs in edits coming in from suggestions --- src/vs/editor/browser/editorBrowser.ts | 4 +- .../editor/browser/widget/codeEditorWidget.ts | 18 +-- src/vs/editor/common/controller/cursor.ts | 119 +++++++++++++++--- .../editor/contrib/snippet/snippetSession.ts | 14 +-- .../test/browser/controller/cursor.test.ts | 22 ++++ src/vs/monaco.d.ts | 2 +- 6 files changed, 140 insertions(+), 39 deletions(-) diff --git a/src/vs/editor/browser/editorBrowser.ts b/src/vs/editor/browser/editorBrowser.ts index 91e6ea3864b..a5e31344d3c 100644 --- a/src/vs/editor/browser/editorBrowser.ts +++ b/src/vs/editor/browser/editorBrowser.ts @@ -13,7 +13,7 @@ import { IPosition, Position } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; import * as editorCommon from 'vs/editor/common/editorCommon'; -import { IIdentifiedSingleEditOperation, IModelDecoration, IModelDeltaDecoration, ITextModel } from 'vs/editor/common/model'; +import { IIdentifiedSingleEditOperation, IModelDecoration, IModelDeltaDecoration, ITextModel, ICursorStateComputer } from 'vs/editor/common/model'; import { IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelOptionsChangedEvent } from 'vs/editor/common/model/textModelEvents'; import { OverviewRulerZone } from 'vs/editor/common/view/overviewZoneManager'; import { IEditorWhitespace } from 'vs/editor/common/viewLayout/whitespaceComputer'; @@ -612,7 +612,7 @@ export interface ICodeEditor extends editorCommon.IEditor { * @param edits The edits to execute. * @param endCursorState Cursor state after the edits were applied. */ - executeEdits(source: string, edits: IIdentifiedSingleEditOperation[], endCursorState?: Selection[]): boolean; + executeEdits(source: string, edits: IIdentifiedSingleEditOperation[], endCursorState?: ICursorStateComputer | Selection[]): boolean; /** * Execute multiple (concomitant) commands on the editor. diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index e6a4fd05977..0ac879ee78a 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -33,7 +33,7 @@ import { ISelection, Selection } from 'vs/editor/common/core/selection'; import { InternalEditorAction } from 'vs/editor/common/editorAction'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; -import { EndOfLinePreference, IIdentifiedSingleEditOperation, IModelDecoration, IModelDecorationOptions, IModelDecorationsChangeAccessor, IModelDeltaDecoration, ITextModel } from 'vs/editor/common/model'; +import { EndOfLinePreference, IIdentifiedSingleEditOperation, IModelDecoration, IModelDecorationOptions, IModelDecorationsChangeAccessor, IModelDeltaDecoration, ITextModel, ICursorStateComputer } from 'vs/editor/common/model'; import { ClassName } from 'vs/editor/common/model/intervalTree'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; import { IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelOptionsChangedEvent } from 'vs/editor/common/model/textModelEvents'; @@ -980,7 +980,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE return true; } - public executeEdits(source: string, edits: IIdentifiedSingleEditOperation[], endCursorState?: Selection[]): boolean { + public executeEdits(source: string, edits: IIdentifiedSingleEditOperation[], endCursorState?: ICursorStateComputer | Selection[]): boolean { if (!this._modelData) { return false; } @@ -989,14 +989,16 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE return false; } - this._modelData.model.pushEditOperations(this._modelData.cursor.getSelections(), edits, () => { - return endCursorState ? endCursorState : null; - }); - - if (endCursorState) { - this._modelData.cursor.setSelections(source, endCursorState); + let cursorStateComputer: ICursorStateComputer; + if (!endCursorState) { + cursorStateComputer = () => null; + } else if (Array.isArray(endCursorState)) { + cursorStateComputer = () => endCursorState; + } else { + cursorStateComputer = endCursorState; } + this._modelData.cursor.executeEdits(source, edits, cursorStateComputer); return true; } diff --git a/src/vs/editor/common/controller/cursor.ts b/src/vs/editor/common/controller/cursor.ts index 789d3a97b02..fefca3cd9b5 100644 --- a/src/vs/editor/common/controller/cursor.ts +++ b/src/vs/editor/common/controller/cursor.ts @@ -15,7 +15,7 @@ import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { ISelection, Selection, SelectionDirection } from 'vs/editor/common/core/selection'; import * as editorCommon from 'vs/editor/common/editorCommon'; -import { IIdentifiedSingleEditOperation, ITextModel, TrackedRangeStickiness, IModelDeltaDecoration } from 'vs/editor/common/model'; +import { IIdentifiedSingleEditOperation, ITextModel, TrackedRangeStickiness, IModelDeltaDecoration, ICursorStateComputer } from 'vs/editor/common/model'; import { RawContentChangedType } from 'vs/editor/common/model/textModelEvents'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; import { IViewModel } from 'vs/editor/common/viewModel/viewModel'; @@ -429,6 +429,31 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors { // ------ auxiliary handling logic + private _pushAutoClosedAction(autoClosedCharactersRanges: Range[], autoClosedEnclosingRanges: Range[]): void { + let autoClosedCharactersDeltaDecorations: IModelDeltaDecoration[] = []; + let autoClosedEnclosingDeltaDecorations: IModelDeltaDecoration[] = []; + + for (let i = 0, len = autoClosedCharactersRanges.length; i < len; i++) { + autoClosedCharactersDeltaDecorations.push({ + range: autoClosedCharactersRanges[i], + options: { + inlineClassName: 'auto-closed-character', + stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges + } + }); + autoClosedEnclosingDeltaDecorations.push({ + range: autoClosedEnclosingRanges[i], + options: { + stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges + } + }); + } + + const autoClosedCharactersDecorations = this._model.deltaDecorations([], autoClosedCharactersDeltaDecorations); + const autoClosedEnclosingDecorations = this._model.deltaDecorations([], autoClosedEnclosingDeltaDecorations); + this._autoClosedActions.push(new AutoClosedAction(this._model, autoClosedCharactersDecorations, autoClosedEnclosingDecorations)); + } + private _executeEditOperation(opResult: EditOperationResult | null): void { if (!opResult) { @@ -446,32 +471,19 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors { this._interpretCommandResult(result); // Check for auto-closing closed characters - let autoClosedCharactersRanges: IModelDeltaDecoration[] = []; - let autoClosedEnclosingRanges: IModelDeltaDecoration[] = []; + let autoClosedCharactersRanges: Range[] = []; + let autoClosedEnclosingRanges: Range[] = []; for (let i = 0; i < opResult.commands.length; i++) { const command = opResult.commands[i]; if (command instanceof TypeWithAutoClosingCommand && command.enclosingRange && command.closeCharacterRange) { - autoClosedCharactersRanges.push({ - range: command.closeCharacterRange, - options: { - inlineClassName: 'auto-closed-character', - stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges - } - }); - autoClosedEnclosingRanges.push({ - range: command.enclosingRange, - options: { - stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges - } - }); + autoClosedCharactersRanges.push(command.closeCharacterRange); + autoClosedEnclosingRanges.push(command.enclosingRange); } } if (autoClosedCharactersRanges.length > 0) { - const autoClosedCharactersDecorations = this._model.deltaDecorations([], autoClosedCharactersRanges); - const autoClosedEnclosingDecorations = this._model.deltaDecorations([], autoClosedEnclosingRanges); - this._autoClosedActions.push(new AutoClosedAction(this._model, autoClosedCharactersDecorations, autoClosedEnclosingDecorations)); + this._pushAutoClosedAction(autoClosedCharactersRanges, autoClosedEnclosingRanges); } this._prevEditOperationType = opResult.type; @@ -563,6 +575,75 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors { // ----------------------------------------------------------------------------------------------------------- // ----- handlers beyond this point + private _findAutoClosingPairs(edits: IIdentifiedSingleEditOperation[]): [number, number][] | null { + if (!edits.length) { + return null; + } + + let indices: [number, number][] = []; + for (let i = 0, len = edits.length; i < len; i++) { + const edit = edits[i]; + if (!edit.text || edit.text.indexOf('\n') >= 0) { + return null; + } + + const m = edit.text.match(/([)\]}>'"`])([^)\]}>'"`]*)$/); + if (!m) { + return null; + } + const closeChar = m[1]; + + const openChar = this.context.config.autoClosingPairsClose[closeChar]; + if (!openChar) { + return null; + } + + const closeCharIndex = edit.text.length - m[2].length - 1; + const openCharIndex = edit.text.lastIndexOf(openChar, closeCharIndex - 1); + if (openCharIndex === -1) { + return null; + } + + indices.push([openCharIndex, closeCharIndex]); + } + + return indices; + } + + public executeEdits(source: string, edits: IIdentifiedSingleEditOperation[], cursorStateComputer: ICursorStateComputer): void { + let autoClosingIndices: [number, number][] | null = null; + if (source === 'snippet') { + autoClosingIndices = this._findAutoClosingPairs(edits); + } + + if (autoClosingIndices) { + edits[0]._isTracked = true; + } + let autoClosedCharactersRanges: Range[] = []; + let autoClosedEnclosingRanges: Range[] = []; + const selections = this._model.pushEditOperations(this.getSelections(), edits, (undoEdits) => { + if (autoClosingIndices) { + for (let i = 0, len = autoClosingIndices.length; i < len; i++) { + const [openCharInnerIndex, closeCharInnerIndex] = autoClosingIndices[i]; + const undoEdit = undoEdits[i]; + const lineNumber = undoEdit.range.startLineNumber; + const openCharIndex = undoEdit.range.startColumn - 1 + openCharInnerIndex; + const closeCharIndex = undoEdit.range.startColumn - 1 + closeCharInnerIndex; + + autoClosedCharactersRanges.push(new Range(lineNumber, closeCharIndex + 1, lineNumber, closeCharIndex + 2)); + autoClosedEnclosingRanges.push(new Range(lineNumber, openCharIndex + 1, lineNumber, closeCharIndex + 2)); + } + } + return cursorStateComputer(undoEdits); + }); + if (selections) { + this.setSelections(source, selections); + } + if (autoClosedCharactersRanges.length > 0) { + this._pushAutoClosedAction(autoClosedCharactersRanges, autoClosedEnclosingRanges); + } + } + public trigger(source: string, handlerId: string, payload: any): void { const H = editorCommon.Handler; diff --git a/src/vs/editor/contrib/snippet/snippetSession.ts b/src/vs/editor/contrib/snippet/snippetSession.ts index 689b5567ed1..63aa8a230eb 100644 --- a/src/vs/editor/contrib/snippet/snippetSession.ts +++ b/src/vs/editor/contrib/snippet/snippetSession.ts @@ -489,21 +489,18 @@ export class SnippetSession { return; } - const model = this._editor.getModel(); - // make insert edit and start with first selections const { edits, snippets } = SnippetSession.createEditsAndSnippets(this._editor, this._template, this._options.overwriteBefore, this._options.overwriteAfter, false, this._options.adjustWhitespace, this._options.clipboardText); this._snippets = snippets; - const selections = model.pushEditOperations(this._editor.getSelections(), edits, undoEdits => { + this._editor.executeEdits('snippet', edits, undoEdits => { if (this._snippets[0].hasPlaceholder) { return this._move(true); } else { return undoEdits.map(edit => Selection.fromPositions(edit.range.getEndPosition())); } - })!; - this._editor.setSelections(selections); - this._editor.revealRange(selections[0]); + }); + this._editor.revealRange(this._editor.getSelections()[0]); } merge(template: string, options: ISnippetSessionInsertOptions = _defaultOptions): void { @@ -513,8 +510,7 @@ export class SnippetSession { this._templateMerges.push([this._snippets[0]._nestingLevel, this._snippets[0]._placeholderGroupsIdx, template]); const { edits, snippets } = SnippetSession.createEditsAndSnippets(this._editor, template, options.overwriteBefore, options.overwriteAfter, true, options.adjustWhitespace, options.clipboardText); - this._editor.setSelections(this._editor.getModel().pushEditOperations(this._editor.getSelections(), edits, undoEdits => { - + this._editor.executeEdits('snippet', edits, undoEdits => { for (const snippet of this._snippets) { snippet.merge(snippets); } @@ -525,7 +521,7 @@ export class SnippetSession { } else { return undoEdits.map(edit => Selection.fromPositions(edit.range.getEndPosition())); } - })!); + }); } next(): void { diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index a42bd6d06c3..e925406c1b4 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -4692,6 +4692,28 @@ suite('autoClosingPairs', () => { mode.dispose(); }); + test('issue #78975 - Parentheses swallowing does not work when parentheses are inserted by autocomplete', () => { + let mode = new AutoClosingMode(); + usingCursor({ + text: [ + '
{ + cursor.setSelections('test', [new Selection(1, 8, 1, 8)]); + + cursor.executeEdits('snippet', [{ range: new Range(1, 6, 1, 8), text: 'id=""' }], () => [new Selection(1, 10, 1, 10)]); + assert.strictEqual(model.getLineContent(1), '
{ let mode = new AutoClosingMode(); usingCursor({ diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index b44b3ae08ad..222b9e84666 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -4054,7 +4054,7 @@ declare namespace monaco.editor { * @param edits The edits to execute. * @param endCursorState Cursor state after the edits were applied. */ - executeEdits(source: string, edits: IIdentifiedSingleEditOperation[], endCursorState?: Selection[]): boolean; + executeEdits(source: string, edits: IIdentifiedSingleEditOperation[], endCursorState?: ICursorStateComputer | Selection[]): boolean; /** * Execute multiple (concomitant) commands on the editor. * @param source The source of the call. From 6bf9508af6186b6206a428ce622f6e0d0ea8d9d0 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 15 Aug 2019 08:36:02 -0700 Subject: [PATCH 676/861] Remove smoke tests from CI for now --- build/azure-pipelines/web/product-build-web.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/build/azure-pipelines/web/product-build-web.yml b/build/azure-pipelines/web/product-build-web.yml index 8dde071b485..fe5231dacc1 100644 --- a/build/azure-pipelines/web/product-build-web.yml +++ b/build/azure-pipelines/web/product-build-web.yml @@ -88,15 +88,6 @@ steps: yarn gulp vscode-web-min-ci displayName: Build -- script: | - set -e - cd test/smoke - yarn compile - cd - - yarn smoketest --web --headless - continueOnError: true - displayName: Smoke tests - # upload only the workbench.web.api.js source maps because # we just compiled these bits in the previous step and the # general task to upload source maps has already been run From d8cb87bd2125665fd24c2cb48658afbc025c541a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 15 Aug 2019 08:45:30 -0700 Subject: [PATCH 677/861] Reduce diff --- src/vs/platform/driver/browser/driver.ts | 13 ------------- test/smoke/src/main.ts | 5 ----- 2 files changed, 18 deletions(-) diff --git a/src/vs/platform/driver/browser/driver.ts b/src/vs/platform/driver/browser/driver.ts index 72cf321f076..f13d45a5f13 100644 --- a/src/vs/platform/driver/browser/driver.ts +++ b/src/vs/platform/driver/browser/driver.ts @@ -20,20 +20,7 @@ class BrowserWindowDriver extends BaseWindowDriver { export async function registerWindowDriver(): Promise { (window).driver = new BrowserWindowDriver(); - // const windowDriverChannel = new WindowDriverChannel(windowDriver); - // mainProcessService.registerChannel('windowDriver', windowDriverChannel); - // const windowDriverRegistryChannel = mainProcessService.getChannel('windowDriverRegistry'); - // const windowDriverRegistry = new WindowDriverRegistryChannelClient(windowDriverRegistryChannel); - - // await windowDriverRegistry.registerWindowDriver(windowService.windowId); - // const options = await windowDriverRegistry.registerWindowDriver(windowId); - - // if (options.verbose) { - // windowDriver.openDevTools(); - // } - - // return toDisposable(() => windowDriverRegistry.reloadWindowDriver(windowService.windowId)); return toDisposable(() => { return { dispose: () => { } }; }); diff --git a/test/smoke/src/main.ts b/test/smoke/src/main.ts index 8427b540809..432528f7546 100644 --- a/test/smoke/src/main.ts +++ b/test/smoke/src/main.ts @@ -247,11 +247,6 @@ describe('Running Code', () => { const app = new Application(this.defaultOptions); await app!.start(opts.web ? false : undefined); this.app = app; - - // TODO: User data dir is not cleared for web yet - if (opts.web) { - await app.workbench.settingsEditor.clearUserSettings(); - } }); after(async function () { From 75af7716f8ab132ddf32c082850d38c8b53665f4 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Thu, 15 Aug 2019 18:25:04 +0200 Subject: [PATCH 678/861] Add setting to toggle new octicon style --- .../browser/ui/octiconLabel/octiconLabel.ts | 4 +- .../octiconLabel/octicons/octicons-main.css | 24 + .../ui/octiconLabel/octicons/octicons.css | 31 +- .../ui/octiconLabel/octicons/octicons.svg | 22 +- .../ui/octiconLabel/octicons/octicons.ttf | Bin 37504 -> 37448 bytes .../ui/octiconLabel/octicons/octicons2.css | 251 ++++++++ .../ui/octiconLabel/octicons/octicons2.svg | 570 ++++++++++++++++++ .../ui/octiconLabel/octicons/octicons2.ttf | Bin 0 -> 35152 bytes src/vs/workbench/browser/layout.ts | 29 + 9 files changed, 904 insertions(+), 27 deletions(-) create mode 100644 src/vs/base/browser/ui/octiconLabel/octicons/octicons-main.css create mode 100644 src/vs/base/browser/ui/octiconLabel/octicons/octicons2.css create mode 100644 src/vs/base/browser/ui/octiconLabel/octicons/octicons2.svg create mode 100644 src/vs/base/browser/ui/octiconLabel/octicons/octicons2.ttf diff --git a/src/vs/base/browser/ui/octiconLabel/octiconLabel.ts b/src/vs/base/browser/ui/octiconLabel/octiconLabel.ts index 0b1154a98fd..70c4a9e8cd2 100644 --- a/src/vs/base/browser/ui/octiconLabel/octiconLabel.ts +++ b/src/vs/base/browser/ui/octiconLabel/octiconLabel.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import 'vs/css!./octicons/octicons'; +import 'vs/css!./octicons/octicons-main'; import 'vs/css!./octicons/octicons-animations'; import { escape } from 'vs/base/common/strings'; @@ -30,4 +30,4 @@ export class OcticonLabel { set title(title: string) { this._container.title = title; } -} \ No newline at end of file +} diff --git a/src/vs/base/browser/ui/octiconLabel/octicons/octicons-main.css b/src/vs/base/browser/ui/octiconLabel/octicons/octicons-main.css new file mode 100644 index 00000000000..d06eca484d1 --- /dev/null +++ b/src/vs/base/browser/ui/octiconLabel/octicons/octicons-main.css @@ -0,0 +1,24 @@ +@import 'octicons.css'; +@import 'octicons2.css'; + +body[data-octicons-update="enabled"] { + --version: octicons2; +} + +body { + --version: octicons; +} + +.octicon, .mega-octicon { + font-family: var(--version); +} + +body[data-octicons-update="enabled"] .monaco-workbench .part.statusbar > .items-container > .statusbar-item span.octicon { + font-size: 16px; +} + +body[data-octicons-update="enabled"] .monaco-workbench .part.statusbar > .items-container > .statusbar-item > a { + display: flex; + align-items: center; + justify-content: center; +} diff --git a/src/vs/base/browser/ui/octiconLabel/octicons/octicons.css b/src/vs/base/browser/ui/octiconLabel/octicons/octicons.css index d9cc1b7a4fa..29ed93db1b1 100644 --- a/src/vs/base/browser/ui/octiconLabel/octicons/octicons.css +++ b/src/vs/base/browser/ui/octiconLabel/octicons/octicons.css @@ -1,7 +1,7 @@ @font-face { font-family: "octicons"; - src: url("./octicons.ttf?1b0f2a9535896866c74dd24eedeb4374") format("truetype"), -url("./octicons.svg?1b0f2a9535896866c74dd24eedeb4374#octicons") format("svg"); + src: url("./octicons.ttf?dda6b6d46f87b1fa91a76fc0389eeb1d") format("truetype"), +url("./octicons.svg?dda6b6d46f87b1fa91a76fc0389eeb1d#octicons") format("svg"); } .octicon, .mega-octicon { @@ -169,7 +169,7 @@ url("./octicons.svg?1b0f2a9535896866c74dd24eedeb4374#octicons") format("svg"); .octicon-person-outline:before { content: "\f018" } .octicon-pin:before { content: "\f041" } .octicon-plug:before { content: "\f0d4" } -.octicon-plus-small:before { content: "\f28a" } +.octicon-plus-small:before { content: "\f05d" } .octicon-plus:before { content: "\f05d" } .octicon-primitive-dot:before { content: "\f052" } .octicon-primitive-square:before { content: "\f053" } @@ -233,16 +233,19 @@ url("./octicons.svg?1b0f2a9535896866c74dd24eedeb4374#octicons") format("svg"); .octicon-watch:before { content: "\f0e0" } .octicon-x:before { content: "\f081" } .octicon-zap:before { content: "\26a1" } +.octicon-error:before { content: "\26a2" } +.octicon-eye-closed:before { content: "\26a3" } +.octicon-fold-down:before { content: "\26a4" } +.octicon-fold-up:before { content: "\26a5" } +.octicon-github-action:before { content: "\26a6" } +.octicon-info-outline:before { content: "\26a7" } +.octicon-play:before { content: "\26a8" } +.octicon-remote:before { content: "\26a9" } +.octicon-request-changes:before { content: "\26aa" } +.octicon-smiley-outline:before { content: "\f27d" } +.octicon-warning:before { content: "\f02d" } +.octicon-controls:before { content: "\26ad" } +.octicon-event:before { content: "\26ae" } +.octicon-record-keys:before { content: "\26af" } .octicon-archive:before { content: "\f101" } .octicon-arrow-both:before { content: "\f102" } -.octicon-error:before { content: "\f103" } -.octicon-eye-closed:before { content: "\f104" } -.octicon-fold-down:before { content: "\f105" } -.octicon-fold-up:before { content: "\f106" } -.octicon-github-action:before { content: "\f107" } -.octicon-info-outline:before { content: "\f108" } -.octicon-play:before { content: "\f109" } -.octicon-remote:before { content: "\f10a" } -.octicon-request-changes:before { content: "\f10b" } -.octicon-smiley-outline:before { content: "\f10c" } -.octicon-warning:before { content: "\f10d" } diff --git a/src/vs/base/browser/ui/octiconLabel/octicons/octicons.svg b/src/vs/base/browser/ui/octiconLabel/octicons/octicons.svg index 3f4ab4f1807..48f7d1b2220 100644 --- a/src/vs/base/browser/ui/octiconLabel/octicons/octicons.svg +++ b/src/vs/base/browser/ui/octiconLabel/octicons/octicons.svg @@ -167,10 +167,10 @@ unicode="" horiz-adv-x="750" d=" M687.5 507.5H62.5C28.125 507.5 0 479.375 0 445V195C0 160.625 28.125 132.5 62.5 132.5H687.5C721.875 132.5 750 160.625 750 195V445C750 479.375 721.875 507.5 687.5 507.5zM250 257.5H125V382.5H250V257.5zM437.5 257.5H312.5V382.5H437.5V257.5zM625 257.5H500V382.5H625V257.5z" /> +=y8Xq&=d?#f{lO&{&SxnNTqzo2QWTde0wPB&=c^Z}) zGrkr!ZzBsS7PGTuqe+s5Vlnm(H|O84bGx_B@1FIPl1?hI7VklIVFjRNfc&?a$ntb_ zFdGJn27qXGHat1y`ntR~f~|_4HnuBuKcJM(&qWtsJhwhzCum%?xP11`hY6?u8+qzG zxSm$qF8{lw(Wlzr2K`>BWl;Z4jofqD>V~F#@IwgQu%TRp#f9m%4U=L_Y==0P@IN3fB#2x6j-?#4TQ8x6HLBNd`~c5JTv-4B delta 487 zcmXw#-7CXU7{|ZQ@3$8-^DmxL&@a^ceW z3wEQ_Qf}l*?i3|g?sPQb2G4f#eEamA&gneg?>RSTO8i_o^whNnOQ!+dGhlHBL(8+_ z!E691j|1WCTwrp>QSYlw_}dgK5<4|z5kRpmE`%d5?kg{_yPvr5IDXCb^AjbVA26%0 z;CirqKmGT#j^5NJ4V2qZT~PC@X6}XTszIk@`Ct@1(8I0;v{cfmA0|sOq`w{;#}p#0 z4Qyc>d$`3N?(vBq0vX6k6=b7ImYwAwC%LFGuU3-sPzS4vdTD@$XojK`WiLN6h#{Un zF?3Uv7e4f%A0r%L69+iPDK621RQl1_K&G!;YOYMO*yOgv04*iq`$wiF + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.ttf b/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.ttf new file mode 100644 index 0000000000000000000000000000000000000000..97d221792967c3dc9182078b5514358637c80843 GIT binary patch literal 35152 zcmeFad3+nyxj%f)jP`w(EZZ8%vLxGDY)h8pB^f!kv+tX;JNrTiWCM}_3Q$5IVF_JG zSjo&d6;%*}3;ybr(Ucbp(dHNLY{W++x4JY&={tq}F z1vPHF8p}+P732}ZM=XPDPe*Z4|6N>w305^p%U4O~upZ@00 z(+D~EE!^L*YvkC3zMD_-oniL?=sa0Aok zEFrcX>o2>M1c^qus$QRXOm|$gbv?>guTb2_u2P(#L^pnx{}sKRXz|U&u^zic{X{L= zDQdtGEswMR;I&}O)J>!}zWLOxN`I_GTb{#h6MBQS`hVzu`rv;z9srlK`NHN!3WPbO z$*6qKH{mRs0V#Z9=Hk4DJA>~-q!+&l#W%+vjz1QEQsN|=& zTdL(Bm+q2=rTdlgpQ@Js9q9zhe^Yu#dRO}SNA%RyDF0?w{{O-kMIQ~3ZDa?zlSxmk{;zU5ZTx31DnH(h@q>D6?>&U0TF-dY2SxKHCUnX0~wd6~rfn0?C z*h&tQuaPLZ1AXBo+es_Ql6I0K%ZQQeCVsLL^4~%3B28o|*-S2j46Z}peSv(D%p!y2 z0pcOuq?z0at&t~}ljYz_J>-8abW9C-lFTJjz?t`vh2&|niyRq#7g!0Cj+BSx4DM1u5Ugjqo(P9@9_ z$P<+?Q;397WrR6HB)v+QJw!67gn2|HAT&mpQAC0yWQ4gzB(qAGWkf>HFv5Hzl2s+8 zJ~kYKFawF?P)Rv<;TVK@NhG&Qn4v`SsD!ynB(F-CwM6o%g!xM(zebTSBN7`A5ab$>Sf7F*;fTb> z0|Z$|BsK;hhA$=7*C3`LrCybo=9H$W1er)AHhv&TMAjkyu$E$XFuHQVG(QNNij|kh?^hs}dwIk=VF`Ad88__!R`H zOr%9BK|T|S)d>ViO{77UnD&>JsRZdwq~$6>juUBxN|5M8suE;7kyfb$DNiKEHz3G+ zA~C)Jk!$feq!M%hk=CjNZ9t@TDnTz0iM0&`4MC(0DnVBeX`@Qe8bsQp67&a=Hmd|p zLL~M)5OfNW*l$44E<|EwfuLuIv|S}=93rtX20`}_X@^SCLPWYmCFmm}U8)i^6OneQ z1RX`B-6}y_5$ST3ptp#0g-Xz1MB1kkbQzHtFM^=eh{XC41pP*&t5t%gBNF2q5Of}q z4ypw0N2F_1f*vH&wJJd)5{Zo;h}kF7A(fydiFAWX(3eEIQ6*?jBHg4CbSRN-Q3=|V zNVlp4y-K8GDv<~9`DvA)Yl-wZm7sNr#QGEj{Y#|Js{~C^?dQc^1M@p;>AZU9cJ*E=$K9Lyz zfq(#r#O65&Sb#`Rt3-P7`HV`y2Sj3h2Le(c(hDj9GZ5*UDgiwZ={qU`M-b^1m4GOS zbV4Oy3nIOy5>N(_zN-@O29aJ@3CM#;Z>j_gLZp9H321~!|E3af36XxF5)cZJey9?# z3X$GY38;lg@2CX)LZlz51SCVGAFBjRL!@_A0=gm6NtJ+ei1eOHKs-cxUnO84BK=e) zpdcdsTqWQkBK<-oAS3b-Rf$>fA61E23#Y)tjDVZSDex~NASiMQJj@7Kikw2d839$1 zQ`f2ld__)OrxK7BIrS-(fVs%2>s12!BBu_i1RO?Afwvg}k&#o71&kPvodTaTBJ1#Z zL?z%ga_VN4fZWKbTT}vuBd5Ugj2N0zUU5jYD-!s%11`Jmi4jF^SqsDI; z|6p2V+Hbns^c~ah%t7-c^9J*<`CUuOvc&R&)nwgneZ=}}n`rx{-Dclrf67tkSnjNI z_BuB?54(tKhwD4;LHDpH?)kcR(0jM9(>KR=+)w;7{8#$F6^I8`2Oh4m)QB~A*SryI z3T_GhxVEqMncCBJ4R!a`CD|3N4mniJY1bO=Mj-C;|3QutHh6Ja?rBeK6i*Lb+` z+p$z^QS4vhns_L_I(}LF%kdNOza{DtpGmyaw4>>^rstXq&9}AqS`N4TI@z1NEcsNb zF109ib?R%WQ|aFHQ|U9AYctNbz0kg{{i*hU&2rgL_EXv4v=K!LPQh%fvGjcg^)C=Mq zMR`jtpQ}CdTe_KUlFK4q-02F0{3BMA-B6MAEEoW)8P@J@&{b>2qVMg za^(&Bv23CHl;?o=VHzK!e`bi#?bj#rMZZ3hDEhtnL~-Q5K zNb2xmyp5(9i!uy!_AY({>S-jTNOLqnolz%!g?6TBS4ysw)~=P7NowmbTKs@NjAi zT`hlcD=Q!OeuJK2_r}y-@J9Uf`0#Lgt8&Zd?@ivD!mq~5t=>zOoDSuJrm8}@*B`X^o7z9^l{p$ z9IFjxa_a0+eh2#B3mq9o-|+cdKAP8p+jw1w%SEyxM~luP_(orh`1wtL7Df5h(w_~S zv(CZo#?<8GeqH%W`S$D9)2G(g(jSkBl!||q8*Sk_hode`->^~*mH+y?Pew-+FAAQw zjr#=XG|Q|V>JiYj9vjz?;qvI>!erVZa{dsnr_l*tytqy4@ns8nJ{gFGPP(I+_DrMu z-B2u$-*B+6=c0MdRNncPzcx8h^dVS~0ojvj$Qx^>$&99pg(dyGPR<<4-Tr{;5Y-|j&e!+PD3H)LM78Wq3&Ro{# z_2~2=iuVNX&7m$G(S-65Pg2_TgKgV$>HMT!TaVt-GxgwY*LL=crGo};_tHhFez$FY zamjj08-FpWV|QO6)6t6J!6|2d0G@mvGu@B=XaM4E0V2;bi!kQT6){s25j$ z5og5jO!!L_2X+c^poc*4Vt(6bVMkB;dYGFylKiZ{yFb6R?`#C-helak8 zq}0p^{@@c)y)(jFD{lw|%2BRZ`c>vv^kc}5GjDmRApgS4rz){CXPDDj%lcMnw-q|P z7QNeylA`$p1QbeP0xE{4XubM8O7$kdj9^HoAJVIs$D@wE81hO z2_xY#`dnFlbxar)#<=bw0rFk8pz$9MmBhANgm73mmL3(wF*@a#PY^t}$=_CFq{{mR zMaw~-QjzAeA1(e`*EKAAQo z+VS3j`+I2C=l9i9kKXOk~o3D)tskYjV8OzqJTHKd%85?^NMpG@npeK>{nUmA#Vxz@n>8HG1W3(8Jye{IM z?2YJnTy9_#yXZnWKom*lZjhGDFb3(Z5qNB4qFJ3*}tLORJ zxX~L*T~^AhoI5FMa;N$htzI)YBdFIJYjtWgM(e#sqvfE< z=&q^p7)%E(M%tEb2}N~IPuJAc;!*>hbMSCGr)>;bZLJ%oyW@+q!B{L8iv`tr{~E^p zG?1)W(G_53C<><^8Yl+wH-y0iuYmbJthf|99j>^bbUu6+%I0Gc;EBnq2l$6jMiJO` zF-D8^s*TpuXhQGT>%1Pnq9xJCdVkR$qS-=;`iqb$B?_6w2BDP}6Z%NLL!{XdekV{& zX+4uYG!f5tlqmN|`;v`I+B>$zHq$V@_C`mFyDE0Mrg__*EzO#Jv8%bXgWmKhO2gcS z#%=QP=%neBqHDQ2pLgb}^{ZxjeRUjH+n8P4PP2=%jVOd)Jmhlm9o+KiJS(TQBb(9e zj~(P^tmHa)muu}3enV_)V{}p!e~o#5){>e1y=$}CwY~i_m&{@^2pAXglJ%Rts>cP` zbP3p>t+2g{@RO8)1*gMrF<+TOQEwz49iK%!Bt@R7#{WcExN+V;L3m93&f`3PbWKUN zh?qc_Ln2fnKZ zIE`jh<--ByRWQ;7UvyLcvC2#7v#r1565LFg@>FP%|4x6W*g|JN0A_j~_nIJ)T#(lF zu;!CMBTQiz1*YfOKW&xx99RJSqFnV?zx^&XC6!v9TCE@(hHfU%UsF4ADRqf@%RTBh zuC6cHvOMJ~mC@R=NSEWDWV$jXom`%h-)3J@)poSdH(5Jk(8f_9l|NHQLVhnHzaRf+ zcJw}Ymo-<_^VdV)C~ejQq4?=ub+-A0+%TFY7-E@z(AXlOv)x{ zS7Qon9cRdgl?!=|iL;zmP%dm3^d>NtzWRYyzLuhM*`NH{xkLH_JDev!lcL4(BW3O# z=AQr``oMo}sBlPY(_}PxkGU;!%VUwo%?p0#%65Zf88~ER!lbxI{Vm&9jYtlpkH#<84imx4RsFO&7E#I^W#W_Z~8;!H{7q~uP{{N zu#L$l?9MUBWrwZuCb!Gxl-Iply3tVYR7>3Bw96;PYz~S$&`yTuZ|3hs{|Dg*$ub|O zHtLLcb5N1_Xh(*(agcpXd*+-X2km3y5*aXt9%vEFo&&V5LdOJsZj^pp3a=>vLuE5j zci&1uI0;n{HCwgel-ptB=tzI5KYbv*U*3>9kQxvNQUxws9uA8&nW&56XEkCNIDz}b zU8}b_T9g8aY6dV)M5H!eaF<^*4~yil(1i<9H{Pi7%kTL+75T;xB5W_k zu#DitUu1$YLE{fSlo}bKzf7^u$}mELo%BZ!J(M0zji!|k`CE0|?mDGk4lDZ8%TPRR z0FKj$ntUO{@lNm{`shChs~GKvuwrNojKiJ2fc;dl)PLrO+=sY$9QUa8{jBl~7f?JT zbcw?Hg)!rV!Q_OQ?acYLsCbUSdCbrvv%DFw9V^YqL%DJv3Swo!kU)=IR#*e%4%j;O zE`4@Ln6am{V!Ce_AQoqTJ0{N#zk8Vv_jTgy2|*ki6S5dL+*K@@_k|0_l&^hDt|N`-W8@FqddqOH0m+f zy*$vG>N^0e@IsW*NQ2JnguIW4G~tA3WGLa{bI8EOWEb~gFh(2SE|=+wQ%9n@eX88`V^Q+qc22c_ia8i3 zev}<;rBRsmei(^>P%v%cdM%6;8<)Yc$Q7&S6OiTHy?<0}CE<^G->6Uaavz@b<^L(~ zJ2_P48neqvYvQGPdw%w`7DX2grF;u_UertL@>973p;$HqdzD4Jn8@_L8S z>ZW4LwAp!keM!+|rQVBnF7%~_x?)rFbrZ*f*&{^7SwJ4JI`WFV85cElIZ(z3U8dR% zOwt?^N}^ao_g9|aa%^mwJ$F>`B~)!fTD1w?tfwJaXpJKIEJBGsE6;}OQE?}*u|4x= zn25(9E0~Q$P{#9$UFjdM5tDq*h&IQ3rf?oa^EtRCj$zDpqdsqNS^0!GI*LEFUe!94 zMoJ?i@M@~{8n;!Uf7}!5g)-r)xWHPaAHz?2Vcp8?%=tEsmxZXzcv;NurBKZos3f=o z{1Zx)kK_ikG&i_KdC#3|H0&s}`i(5RpuE9oP}_fTwf)QoJE5)=dgi3U?ut{V@_qW8 z{OScwh9|G|@7n9Sundet8lY!F^(wCND03o?o~sxe4SDwH*w_e@-KZ4vv#Mjte9uhp zs?*5H16L;iTD2GvCs6nJh|{;_SK+MbVoD7TooCs*{M)LcJIAnTIdF2p441cBvUMxghD8`bx2yHx|EnmFg8}mvqCS?oX%unvit-ba$pF6a<%aB@e^{4mWb!Y0XyHa=FmAvy# z?pa+ilRr9p%2k{CYh2>G{humdG$UNpPsxj4ST^U_OB2<&=4mA#xJMXu{9as5{EjH#^_xII=S>_iws>PUj!KMqm8k zjW^!rei+^O&UU$ThP1L){u+G^gFc%LFYp246ig;tk=u}AaYVSfpmkbl0r;7EV{pYV zOkaTg4eSQ>;>|H-<5$l^zclC*%+tp7kvH1Glo9t7Uo!MGl>z}Uzx-q@JD7|121i>e zu9hwB!Mc*)*Zd7{LsvtpVcx~7TJz=peOoqm_lUXd(q)u$+Pe}(ZI>>)EW5K^%q`2- z_`aOsp2`e$PoFivzci`+(QrJ{-9T&UPr6c#iAmiXx9r=pd}(_}b^b7Z4WKO$OEI-N z4NNJbYE0XplBg!*9{7n=*O4E%ksV{^dilpntQM~?Tbj*@Jt+D^Rx|lTL)So8gYs5V z=CU$nU*5uQWA~#58@ne__Je(BSM~0O3#Pv6-#E%&jIlGqyAgnIBZ2sPkD@^Ys(8?f z5iMj%LhDgrPqabj@5p)@{LG5ddyBwlm}_}`zUa*rFT91jnd%>sBr|QaLbX@>PA4mpu|| z`JOjvJ}%$aa@?HsesA7><^13yO!tBJ)cRYXF@h}n2iT-qbA2uWIqi%l@;r37*I(k4 zaL9z3*+xg@+1&1v!e95KZn`P8KXv3tYR`mn=v%4ualQo}Q0+fsWxGgS!xTT!9iL$RJ-H7?}$2Me->i<%0YdYRUUb z@&}arqrAVs-6hYJSMSnDcC|WTq(m3-}l<7XpB#drK1!d1 z-Lp*fZHG%+QZsKzHB((~-Ddf9@xH69u+M`o7x(;0K|JDr!&r5xj*JTO5ma}dFt%yd z;g&=4U$X1gl!i~baBmPYL5W4E<77jvYhcGD!Dk};ic2wGN(3SYcY{)WecrECP>~a1 z5T<6CimgURbO}iHYzGi`q61M8Zw_cOfs4%A2PjR%lzX9+bNmLhs2-{vtrN#aD?6c` z5q$(s;C9OvPqHuCXfg#F9FB(fY&M$B_Vsz!QW zV9Ut)hRP=pwHOsg!XazG;9lL`eT}WrlSz+ItIe>_;P6?3Zi5lNg^>mpi(xWN#hE-f zB?*j1m>&Z1hAPWMss>dT`>X~z>mWN)`?&y zC`jC*NP&~1C&9X?^sgWZhUD4k(Pz<{h)av5htdyU`i-hA5Sb7dqc!2N5g7q}*4f6Ky^yKT2&S?Pw~I^qR(XW)9;j@S4quL_8ZIEp_=P+0qQUZ{340t7PEQbXVe`T@6Fz`8|*A_6{;LkdDoc@udJyBv#d({>=$j^mtn#*!ek(r%{!_HO>O1#6^ZfD^##A7@H z=M7OrPj&i+c%mKmX`S@esjSA^#qt8t>S_B~t8l#=#v>KgJZ_${vTAj(DN$Cx| z&u%jsYtp6JEvr{0=Z1R&7OpO3jOB#(-NnXIF6OaXI4!TU)Wy86h8j#Atj5b0@i)!J;v#2 z(&#jqtPX3i-qsjy$k~jV0dZbWsusMZI7m*!9iz+jYezyI6c6V!sg$}i8#3Hd|(argi2Z*lo!oLV5u z3F?wRJSUG&gOiK!Ys>|IC14-Jmu;tBCBP?8$Xv;Yf+LYjIZ18J& zN_9yA!PtP7H*oxEmUbhu^ce2OP_~}8nv(VPNt2bY&xV>}%yG!nRV<*_xuXR$baDvB zlyc}0+%*Wtip(>@_*2yb%m#KNc9BN(2u@QKQ}~%$RdI#SpXc!nS{D!-Xo3aMb4+w1S)997ilf721Wy!z05GTRf}2FB z@x|`1TrZ3%xBETO))J1#MuBDJ*`-pA602rdU>3iF??7yIHnLhbqP7L*PDJ0bp+I=Z zDe@V_I=f+edlR|t z&Wxaw59vbb&aRGTKksa8@9Jug8in|@F21%U|D*a=uepg8Q#nwF5}P_Z!bN&%xTDyN zXW~IsnRAr;6Z*)_@}g;5yAE=j8GRxLscT0+y5SX5KRDcZT>L7@);Gi}yCf^Ui8E2dA%& zh2E#5P9-{`m>)%?^Z2|@rKYM6E)k#TPCnT-FXrycP!`L%Y(eUV8&V4{OBC(4q*Bjn z?}sTZa>>92w}gU;Mpyru<@taw@~HrZO&vhKBfo4-zfpdO1&B~y>W1|EVuG&XweERs zLRTs3$}!|p9Q@!_A~O&{lA^qO|U>2Ei&q4d*y z%4*X#PhHV=uKG&r=zut@&1S1l1@g<+VBizMPzE2f&UXVxCv;uqPvIw87;!3<^68ts!_O`0O}Eh&wcX?&HuNe zf)MtiE0-Uo>oQw%9bfG_)^+Twmz|XF-2Qmv*&i$|-}SP{oa|xwolEbnyzvvd?c!DI zV)BXQbl<4_SqY{c{J$mz`#gnu_@OmZ&@9ss|6hu=IP2It3#9oVYYRiExZ^ZhFgnmE zqC<(O&x_MKeXfw`$QSTkhfoo|uxSvDH`plzTC`BKQ9IRn{5fO?!7hhLiDTkKeMOxf z+Lm)q-n(h8KV~rWM22?mzhe7fXTXw~vw1JQG_+A{aXmti?(&?MxY7sXI0jqV`$_GE!cyR8dYbJ-k5k4tQo>y+B*(q z#<6K@9gF*Cty;Be!(zu;gt`@+#(cH(MR>vV=qu=1_K$z;%pLs2jOdFnIaGfJ{C$x1 zIwiv<2=4&PR3v^_zOZ`07*UA(9{oKNd9{b7@bRSsZ2pk6RJu8^^>+tP-9d+qL-IE{Bjx2@Y2@;?MU?>MHo< zV|2H_&^4*&-<)ph_Igu3FFu_Ch_%5%_U=ryq+1eB8JV#vZoUC+`aAlz9iB*$DtR4x z=uYM=Vi^ZWnBWrF@Br==z+0T>=VaP4%k~{TcKDK*D4aYZ3|&?}uw{0fPtD(c<<)yu z))yPLAO7rZS3i_`Ml@!-kACK+Jqr?s{2K8%{3XRjt@?)PoA;G3U*A_}$q#ncPuV=# z7F}>f`k6nD`IJ6>4RQFN!6Ssw53Gs=MwvYp?@oP!@-T=o#ITeToQd9+Dj`w43@WAQ zEx#%w6SF+V{Zu}l>XNs?bA^OW`gx>vZRpPjG6syw z(Dzhu7Hc11C~LG5)MuUmfK>dkz#Nh{k;SQZPX^$Ia}2S(gifE=#W6@oKZNvy*A<=u z&NU`P1pK``To@JrP{WZiyNe|Pxoq#rmf`R&-!q3Av&{?ZQ{knnmW0oi5R58u-NH4( zWc1^geaD-=ildu+(^-O$nt&v~IQbg+(}pA0nC@vbQ9~e<4o9Qm$KWYITUZQB&9^iH zp}`x&vTAumGkKP6nS&RLRh0!C;mFFnmGsLe>g81ZlgQI`-QQYE>+6zVpkJ*`{=K#K z=`YepkVqG#KlOR#cKMy~3-j!bxuRq4JUd69Rcy8MF_1Ll-Tx{Ig8qbKI+y={838fE z`|pmB6-2uBTc9z|DxqPC`SYPR{Z}KOwdqEBKXoTgLxzPno=J<0+vEW#5 zC^Hiei6Mpsg~}&#dH8M+n})Gn{(j)o?wK3+UVhP{cAcm#t~qeijr&#xv)xPRZsqAu zF6qt%SM9&)rUPpV8nI>WMfQarZW68zc0|z%x@zxA%>%B7Y z-N)g>6(4@BuH3tAAmHuWa?Mm>((W~ryq-yGI=j1sqQ)N+f+T12Z7LF*fgb?%OYmtC}nNy5`SDUo#)kv)x)6Op*gGA%&stMwvj;48+w{F~ z|EYX)g3EC)0Hf8gRmcixPbj9W&t1i_4Cy-0AJczxC~;6VCYl|OdY+Ge#!}{3&=s~D z5E!M6N*I-ePLbWCgiaAtMd(z0_EG+6o?=`|N=7E@D8R62LjrxI%2NnZ3TGaN%${Nn z8CkgOg_jyp169Iet|F$DU^$t{zk^9#;9glWDc5W_<>stvZ*Iy4CWY5P-@vzIqjdd! z57##ts99KWac5(1Yc1!{$=@l%2S2YEjW@@q`^~W$ci6@vx}4;koI5(LZIKwU^qAM6 zknru8@-6AXTYKenpf^_BF+XfJB)X@?lT8isE1QN;Ovz{uzHCSDc%$*40ikxRe?UW7 z?2xa{%rK(QO+cY-$a3sdq|N|X6mA$m4VE^A)ii}X(xw0qFpY{;fXYHRg-78L9)Cwr919#qL~#^eT%2dF8~Pm6 zBJynHUO(WcYT#0A9%)yvkxQcQK0SdN5KXhI~$ zvg}!CLP$nCTcHLe;+%LzYXc(7AsAF-R}tp&>!R)O{N{9e{xh3J%xh#|Yz`Rhi#9EC z80)vaTn>~2Tn=yLm$%g$9Sb)vbQmkc-qsfDutkgf>Z5bz*>mYpv3!v?5NNgzn|<^e zEOjf1W2Lt4?zYmHY_Z&%&ECtBanv(w%{1WgEIux`4-L`pA0M&=yk3hkk5BNeXkUzB z4S3G5OoQb~BC8XNHyAjC|4EY#Y1qWT0uLV+a}@I2PlN`mFN8&iA)hr8Zcce(xzdbz zGnlhD_2^NvVUxj3{leVzCTG3RYW3ASH>KwaO&hxt>=w71-JR&(c+XM2#R90UVm&pl z--4`I;s#S8S3jqOau}vYiX*`F5Um;GJ}j{y9)EF3UYVv}lAoo=xxY|k<0C;L9A+U( zI$K_mrVlG}oIA&pZLolVUSI%KTL|O?QO%Z2ptUx37Ry;Oyt3XZr_Dpqdu{x9M~F(Q ztBuE9EbA4&WW7V(FSX2@6b?_C*Afba3M~jyv=l=xg^Dfy>4n5VM;*IDPbQ}3>L_K$ zxV)=`F!W@<_<(~*2+pNv9nfI1}n^3Tx=9IjomX6%EdD!ZDaS$ghhF5&%72J zI}oWaSqxdKKdHABmN33m=HmHv0G({V0XLgZc`RI0O&hib0J(5Vt}!eH=mvBHb2wsg zCiTKK0^c&&ngIZoL9N#%bQ#TLn)8M@^Z-%{nFXsHaY_%uBMEmOn8lA(B=lHKGVOm1 z`AtBa=ct#{@EYFWFk3@5vmItIuhqiUs?+qAyAm2+%W0_2VYb`NZktiZ;j%`n(Qv$m zvzrlv;5po`;b{(m1e?d_wwrVu)o=#xLC?rhmzHHLm8cW<7%e)Bfh;`Eq#p2v?+ zwoYf&&S*%z#A|d0lh@H!}^w`=KBd9WQe6MB$uU3ku_* z=qfC|T{SJiHGQYyJ55~TCt7W+pYdntfd@jA*5&$VpBL);!%EVdngGY$5=|tgt;)`r zB=4rjCe6sMYNeD58#?PZeSV`OsnLL#RnZFdh}XEZ2_Z-4$lR!e+Qljj5Y} z+QMiB(&W_q5wDgVu&Fto23P|%!967(QL;qj+5LNO+S`w4U*#AC_-=ZpTt;q7c3JM~ za{t}|+P}BIj2I{|-M*4Mi-lm6A;R+*=KTRi$pVc;XcVjFfcs+rMvx~6O#=0Eny|bI zamFxyxNflWheg~EE3T> zBF{?lqMPNgMQKD^V&zp+4dmfCom;tuc5^Eb14o`DJte2<59L46>?u|5jpt)y4f?r! zY)BSU7p5BIGF!OLBW~w7o--OO2r-)5>jBRwCY6Tky=Z#S zJ7vqk!w0ua@dl?~)cX(f$@|XyhS%yfTir3M#%gH|$C~Ooye6O7R%fFIvrQKaTJ;FA z;H%kZ@^;iE;zFCn3V*oGL<26p&8&x)2^G*lWSMO?QxG}Ed`V+~pz$o;bLi0J%QBf| zm)~&xp2gq_rUTh{Vy!Y;cM2WhjJo+K?{l|9iK9DXQ1np*>u$Y%m1gIhT^wC>xUHSz z3|Ag_?s%WPM&=3ImYV>k8FZ$PwB>At_j6amT1Sj9W}^_<2oYlqtD0TL1T%cw zI1m3n0?LIP^0|sRy$;Y);Vu|`;2$h?F8YcImLOFuD5tpFk{hz!I~F%-`1W-Nr_Pz& z+ZYc77H0=IS5Kt1n2N>Ip`5|ml{FcCLSDFP>w@0N1C$TT@TOk<7yObvv38M;5oP=#OYL z$jX5x z>f4ytt)`MhVEieI{J8+V-rgo(DPP%Yqt_20C+SgSxzOeN(nvepBp=zBLI&bidNp@? zEKqqVI5rmKN`bM;EAP|4oP6f1@5`2-QkqO6Ninr)6W;DgZeuJ|<)Z_r3B%Ha#vsJ7 zYk>}v9dTcTeBr?>>Jb<0U;$5f8=<)qX{zNPlb8DBLGku>N?m^oo_5i;AHMhQNgD8d z!T*3S@UHwA9i+?X55Dvz`7+woHEk)BTg}ehHML8pE&RQ9<0g)49H0E56}j zZe9A4OVT@bq}U(*MDk%B^ha2_A;0$>?v9s@W2bRp{0=+}F-JCkFehzjc^%uA$zAZP z%N0E9x)B5M~ zi&_5iIZY1?Ffl>+n7ToPnnN-+b}r)>L1Qjgu4a#@K8Kf3{t@{7W@C3W#O>Hp>G2d2 z=E#K!jSmFj+I0|2(C`eHg_((;?@&!^Wlm#OW41%KoSXD8zIhhrXW{?&W}q&OxyfyX_?^@ft(|l6jq_&; zwY9>``8QrH?=e_oEsKTjfLpKE;HB5Qv!zAJ7}im{x)yew`(xdXy?oAoNwLGMu-%J@ zPF;%q*N$Ufv9FMCkRM^w85>R00>JECx&oOQpQcaH@6&ha&(Md6!z#f`7}S8Z>H>m- zKWYQO*8%b~lg7vJJeTYB z76E$YewOAZQdXW~UBt#$wQI+7EfW7zqyM&#=*JV+YgGL%-o{P$c$-2F%Ef9^!a7I2 z-&_k%i!0pnzTWCGect4@8AJemev8(ye~(sA#X8SIQ(&*JS-|?qSTH5*;rO!Oyuwqb z+_rO1C<#}MGt?w&i}Q;3qsJ5Mqxi%BgP+cwrY+NE6>M1X639e7rSoe8-la~V$@frg z6a9>kq84Ah{dU?^`;Z^qEB{}Qo18X1)mz=B$KOPf8HY5nH}5uRpSZO%?qhuS-0}p53DYtu?Be3JH~N|c=T(V90bPHHz0E6({ZA#TJ;CH3%fWdA^6vm5 zybdLcT16$=7(*p~y#UEaflBb_1Q^J3LAtd$AYUh6=a17Zma&F+MtdsHFvtVp*mP=t&OvY^DUUk8iPeY zcdomk)@lnzUEllXy18|~vf6AY;;5}YVCAdJtOQw*lz-j71^>-c%}74wwkttH54{ZvvXDDjOpMDYd=j-@03lUWuG;1npHb1 zXKW9yeW6P^r;N*&xTjH;1zD!uZ0|9)l?GEXY()oFCRbOlWjHJ>QF?1!=fH200Ax$B zZjACw=^)--RXPalF`Yv{9v6IUvFJpRH1}@EG>0MvH`(iaW?CD=+-&xJS8sC}?>4$@ zdeNZWq}6lJpP#*@y zu33JQ4+D3xeZUCA;n?5-Y>>{i16c*>z3oBnxq$p&j!vq)L=g~D?I7f1VO(kz)C>y_ z`L{}N0v;`BW~QLoRsr6qo25g-5f}l8gnxKQh(|-So5kkYp=ewf63Z{wPMrlPiT$*& zWN1`4nOz;Nk7-|gQ5&m|uFjqmupr~QU>z0`#zseDQ}JvTgJF4#Y<&^)aln1a5(9Eh z{$ltj7zz~WHA>1hlKtVTP%u7LA9pKpi3ap81GNapV+O%yM{pPM2-Q!LV1BuFT%#Wk z?Cn>aBK>=Ro0`3Rc1n4BuyuYWGk;q30$e6zsp^%~>}xagTXA{Z-nDTn74Ovr-iwo1 zTa9c%iy+eH5N%br40;=$k>}7Z;NR*xj`LoxbNH97QN&&gQRet|<8vbZ#jYS&v{7cS z3)aZNn}ei(mR)UOV}^cH@bv*@RTdvLQ>@it3kux1T8fB2_siYlWiuzueC9PFGrjln zRiU3_XQh4edYYI2EczdnzfHd`zvnNh{xW5~G+To2W)8q`**3{NNG*g+EU*oUfz7H#j*8f_eAQ3OnO!p6>Mzs%K_!D`qcTekI=+Zfu>k;^?(c9lCbq-v4-p&C9d* zVBeWf6dsOa<=AxWNVJ^o4eW-O0saO|z9RUxm{;=NAsjp6+6fmrV#W6JSM=b0IIVar z+V>ZE#k`46$WeqNTAxEsZ{o##Te?#eJJW4>ZU(l65W7-s9UXGO8A>IR$wXRcpnGxD z(v%V+kr9>+=;7Y!YNM;#x_)HPA%Dy0(DOFr9#QJn8VrT2??g^^Cw*_=V0)_TjxXGS z;ttXR_Q0zi-*oWOCKSDO*VaTzSg`C;9PZqT!WS%C5JF;@hm-4rms}F0zcd(G3R+oR z7;ncC`94ao6w7eItFq~7J^}flZ756<$Foln>NRNKTF`+V1~-gs>|^quN@C#Dmdl_=L#WJ%72m9>N)_?Jpv~9{WdP6N?1a z#3!P^<2JBGX``c+?~lH2a$4bt)LWgV*I#FiasWJUN?rNI^nUT0)Z=ArmI-l)&7jzZ zN!VaXG+3ReK7LeEYtKM2m4BGJa@7};`!V!CJDB|P(yLQXgNGO%WP7!ZV5XI@Gxthx zfwIK|9Ke|QN;+2&dQQqlQtKVt5?_AuR z>u#JZ=+phvIt+bAyJqEbjl4F{Vn4d zsIl@vHD2vCIsJ%iDvwj5?a*YbKfVb5Z8;Zj?qj=ZW34uHZ^VmT&cMGAgnHe-=U=$j z!N17Vo4}udg76-)RB0Ig$aMjyvW4=y*}fx{7mY@hTa8AC!`mEkQiEOqyKSiKLI7HM z(Z6BD_R(VplTTNko#PsHaqq0b0)UekYs&v8Y+Cs?{a3r<4Wi-H{?awz54n42M9GCy zbuYsdZ0#gl@mfOLBH&8I(HU3fS+t;-hohGrgJ-LaDLSbVy9OYQBj0O zb!*4!U|cMq_RS%KflVogkf4bhkvw(4K@lGW`a_IT6n6mn+=}IcC*1g50+kf1vY3?9?WtZ)R?;$UUUKT zCabKlVUq;@bO;Q8J3P!qtP&{XDN+>@G*Kvef%BCSQsxqpF@d2ef>ZFWDaKBLKYGtS zS6?BY5sXMi@Qs8oDa}3e)?fA^QW@Nt#?ouac-uY zu~Y-ThqRxkvu(!sS8vo}f7Qp&4(_pL^w;O{V)EIIw&As8}AM zKl9hSqCqrd5Zo`$WgMf4@Ytd%@)Gw)@qZgU-qcGP>-a0tGF>1bCO3y{h? z-@I?Ilx_XWuFI}jGIM%!veePObh!bSxcQ~Q``+Aj?Pa^Z(wZGBC7Y+uT(Wt5z5Ll9 zDt0+rkB*hYZtN$=A`o_pEF8oju(3di-k+xT|Eo`4?|%~;cii?AJ@k}(+atRXi`WbF zdVl&&lj%(ei#<<2y?eL(M`gY+TkCnWL|^rP!{#b7gbkqttA$1JSr|fP2sS4oID>V? zqb$-6tSuiIMfU3`gx1KrLMi+%7KLL5f3aTwiXnz zY)H(Umqovzs(ElYcpM2YI7r0UR+VTTOMW>yj8V*$gnLIz<$EjHGLqEY%Em7&s~O(z zZk!I6?-fdwCvc}&9u|fW1jU|BYk-EB-d)JQgQiROKE}Lx68?1Ro+=Gq4Ib!KR%p_K> zDa*Pcz$RSBW{1j-u59Bg)|VI1Fw+0A*!yI4_ebnBUBWUA<(!UkMQB2-QKN5{v3UvfjnE?qJ)B!UGFE2u_v|qLIC3xJu-<@d zv>6Rk4A=pHg-#2Ax!4aG^+GIDgX}oCoPbB6#gT`~ww;Y4Cmerqq|dG@QH%wOs!|)PEg0oTzUz zJy?}vXD{KO!1%Bg%rVT4ykB7<=mss@J`HKZQ7p-h@Cla6fbF%FNF?{PC_uwtTe!}q z_XP1p@2}{ypNx&YL<{oko7gTW+zcw-ip3GMQm)$(5`|k!*wn9Xexs@@0s01Hj zODf}V;q$#J3!i&F7JgTs?`IKL1pP2A{*&j^&&#jTJPKzOSTF9KP=Vd0+s{|vopTj9 z?{8psd={8z26*A$rTHqRi2uTqHkJh8Q?|Ke)&~ND>Ka$J)*9haI3$rGK|em9{(Ipb zBy2krWzQ1Ij$*JqI$|-p2-$+zH271~t_T+c%Xh2{bP5NG=QcVycW`dUlS$``d6sSZ zJN`E|qen;=yW47e5udNx9Unl(T*mUVn9qj=^}yPSVnPl!Vrod2RpWk0E>yLy&dU-# zifAR1moSH!#fOw1wvQ)kJ65UTEc?W^XNu7VYZ;w{g+5Ss*lk(qAvT$qFG<~W*`wn= zgi}ecx7F1oW0^!4Pc<3zMqY2!>vRT-&E`SouSM4piPqJau%z2yciLR$q}lE81p){F z8=bYDhPHyoY0!BcUbpD8oApSlqWeC(V9@2P3ve9bs_syvzQOJ9-&@%ZQ!eOsbEmO4 zaMRT3$r(#GE}E84*Z7dWq0{K}Mr4uDMxEYb_XfkUwAsNUMayb(*z|S{Qo+0$ox8@R z*IHZ#tGA&p7HSCi-6n(8WHDxoI}^#KSU6nUY_PlZMw2;`xMA;r{3?5%vb~4mqf@aD zq#)L%j$pLydAI`6IOcs z4PVB{9%po5gEWsZb2#75^uGqU_s$+_y zXa4FnOClNXlEm%F%PU+@?xL2vqU$`ZktIW`=l9tA9Md-J*>`bE7kzu_U~fy#9O_@+ zm73Y^H8)3EOZ{zoHMgG{jNWCqC_AOp*3fMBW@o0m*7w(&vq>yqR^`RL{5z0WK3HLF zO>+d&82}P&2#;$!%UcHX<@GA37PEdY_}R`Gv4sfSnmTZ4UI=x5fH`jq8Gq z@(YEo{G7WM+&N!9TcSjiKPA8M;utnh{^aBF@lxji! zJ3Bp|L-IOt$N@Gv2uVb+F@}&pAc<2z5(-h+NdXT@@c<9xA(bLkp(+%W2Ojc}%Hb+2 z`MP%`*}wzQG4pp%-~IRB$A2_<9MbtWML0zKpv|z(jzb2r4cOU0J5c)mc>f6Gr=aN5 z4y8x*XbkNbx<~(gVfd|W>cVXccl12aM^pQr*$?^3rF%w3LbXe8JounkwH`c3=ihm! zxw(1i4H$97Pkk+4K^~%v;yhg(rQ=_`FSoQQOr%3B5JKP5(wtaVz9!euJz`H2-2e(X z0aA!PvQ+f#6XwpPpfk+YhlRkC_!YSP;GoW*V~aA*>Y;b)lFxHj3jPuw?6eC(I3@g)8dO zoyvD#dMl_0RXk(R%6`{2om6m^BRuekVc4=QCKB9f$ii#{fnGp4O zI|bDMxt4e>?1o-NFJ2{A`t9*;p|SRs5tuYVGY8Uo_b+)YS_4`x!u0i9yV^ywJ+`4GC+TQb|ITRn{B3CwyUSJyR{{>4#DZEUDndM z(W&;_O~x?4m3K7bEy8bpZXptSG&eXjnC*g?a15LWvCe;8+FcCGU4C6_0l2)jzYp>r zo6&waGs2oz3Xj5AANKt)HZ9p4V)+aG+Y7i5VpHdZu8kLgk|Eg1p2|j-XBv zr0|Rg8}!$*ow633IAQIH9uhXQ*TOPa-NYy?4`ZUkxf(|N4(v-oz;J2<3AFxQ^v8+3 zqqxfWCxSQa$-VbpZt3FrmoL2f%F;iDgHo@YzwpX=dhFtO{)n5O_|MA#YzF{+ZgTNA zlM|;-O-#P{+sX0Mr^h8NeH`Oi@N9Dpy^xUFiFW$1{F&H4O5Or+2#X`=EDVh96pOxi zYaMF)fLPl1x;wWi1A~K`^V>SRkN2%t@Uy<}_`0EVdT3oJ2067qwEi6?qL$^%X7G?6WNoC979lMmFj?vB`IcJNrqqE^NxO=7@dKCv74ub}P zAi{put^w?u1dRlneyzO2qaWu55aR=*3&a7(E|A#8LT>V;R%WogW1eK<7|qTK4eo)>;yr^WdwNbTgDC9mD&rV^1A2i1MMJmAxm7M% z(b9qy^^bS+?=JsQ>oNo{M94P$t{xLlte*oo1lpbq;4q+U07n3K25=PlYzW{O{FMMs zVMLDxusDlQfi)BnsWoF~REI-23p)|OVfa53z!AVt2XGX9_fi1I;QwX-r*LcGI{}<- z*i55b^9+q!?)KYR$v0JJ#k~R?V2*2Wt9N8*c*SoIvzViLOz$n!dfmCwcF!yJ79C#g zo#K|qOq2K84xeS3H&pgK`?_u0ih=)-#;dsDQA2GEJUQeSUF>OZ$8C)z+<0iB#?D84 z|8R^0h~XfvA=BsuFJK7zbsrA52jMIkRz;o+x7+r@>PZbx7dPIOkhh25BHTrpv$*+r zN~S47oA~AMvE{c}_=u7Z;l51~%Z8*2E_FjpQIFN|L$YR7Uf?ttM&YQ^@U4GZ=TSU&E8wNhLt02Wpc^%67)p=q&^ zHsLnx0o;bYl?I^^lZOnbFuOWTxN!ytu{*&~9R(ls8oCy@^j(h|vV~OU1WnSXa7XqH zbR+GiDcVDO>C?22Zo;kEx6ppNl|Dna(e3nEx`XbNLeigyOzB;8H*V8DMAI}whe@RZ zX{6)QxgwRQOa{$Tg-oiFMVxFp0!s-ldF0a^1g?%!jgHY5=}UB+zD)PfSFm;Y8hxGa zrTgdvouvEe8}v>37JZu@pzqLw^j*lWexDZTA^HJ038&~ZJwj*bQ94VH(c|<(dV+pL zKc*+?Df$ULP0!Fz>1XtFTxIqP>{p+q=jeI*CH;ziO)tP6=ZmyRFEvC}lQ~{ob+ocE z$5N`}@Oh=cy>bBReBKH`lNG&mJ%D4B%3ih(yHynu+9KQ)9wKz^@(?mk)8#(Cov1r~ zJ62$7g*lM|hDxNsO&t$jNr*>Pbt=h%W3Zy8x(pCkbwFMm(7el>aKSGnG*rXVRVS*I znN~^4r)jueBcM5lTe5sB4pFwu@)udI)UwOB8#TkxOs2S|>XtLY;Ts;BM0NC-W*W9# zi)tpR33QcVyM`NOKpH2?=1{>D ztD#gTcbOgrm@XnWrC?a9Q%g!%G)$9(bi)BTes7bs{ALNL>P^C@w=! zc&U=;Y)7@UvIIph86pIFh*xdZVMzg_*-I=dAlnD_JM4(hTrUHUvR_bC%pu&0mP}q? z@sgt!3e1V(ZI`2EWa`Ds$PhJ;lzEk{DRaj-hS@+xI;d+DDR3`pSOtDGVpv7qXt=Jw z+^T_t+n8|lrur9$)txZ|X&72;784Y!HC0$aEhuvs-Ufz8xWZ}){7cLVo9cYZ6oXhP z_+}v^o0T2)m}9ACM7SEo=ux<%GvGy&bojs#=}Z9qRZ+u;7zfF!YKRs9)(a>t#;a0q zh=hOzWk^<83AN`Ii;H1^sL3k&2aRB{Sk(~t(^%z>r#kh47ODCkOIcj8*gQ(ZA{O^p z0<$eIsv2wLPD!#~IGSkaqDe3T*WsJg)wkIyqFCWeN`q7JjoS_)4t zFyCTpBv|AQ2B_`3<@B<9oLOG zexa6jfuzh*ibx?7z~~l`;Ft@{(#m)_=<b%7 literal 0 HcmV?d00001 diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 5fe9f43d192..357a3488de1 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -46,6 +46,9 @@ enum Settings { PANEL_POSITION = 'workbench.panel.defaultLocation', ZEN_MODE_RESTORE = 'zenMode.restore', + + // TODO @misolori update this when finished + OCTICONS_UPDATE_ENABLED = 'workbench.octiconsUpdate.enabled', } enum Storage { @@ -173,6 +176,11 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi wasSideBarVisible: false, wasPanelVisible: false, transitionDisposables: new DisposableStore() + }, + + // TODO @misolori update this when finished + octiconsUpdate: { + enabled: false } }; @@ -314,6 +322,10 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi const newMenubarVisibility = this.configurationService.getValue(Settings.MENUBAR_VISIBLE); this.setMenubarVisibility(newMenubarVisibility, !!skipLayout); + // TODO @misolori update this when finished + const newOcticonsUpdate = this.configurationService.getValue(Settings.OCTICONS_UPDATE_ENABLED); + this.setOcticonsUpdate(newOcticonsUpdate); + } private setSideBarPosition(position: Position): void { @@ -426,6 +438,10 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi // Zen mode enablement this.state.zenMode.restore = this.storageService.getBoolean(Storage.ZEN_MODE_ENABLED, StorageScope.WORKSPACE, false) && this.configurationService.getValue(Settings.ZEN_MODE_RESTORE); + // TODO @misolori update this when finished + this.state.octiconsUpdate.enabled = this.configurationService.getValue(Settings.OCTICONS_UPDATE_ENABLED); + this.setOcticonsUpdate(this.state.octiconsUpdate.enabled); + } private resolveEditorsToOpen(fileService: IFileService): Promise | IResourceEditor[] { @@ -729,6 +745,19 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi } } + // TODO @misolori update this when finished + private setOcticonsUpdate(enabled: boolean): void { + this.state.octiconsUpdate.enabled = enabled; + + // Update DOM + if (enabled) { + document.body.dataset.octiconsUpdate = 'enabled'; + } else { + document.body.dataset.octiconsUpdate = ''; + } + + } + protected createWorkbenchLayout(instantiationService: IInstantiationService): void { const titleBar = this.getPart(Parts.TITLEBAR_PART); const editorPart = this.getPart(Parts.EDITOR_PART); From d343bb0ca6fad99a06cac83bd68de951a6f118c7 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 15 Aug 2019 09:34:59 -0700 Subject: [PATCH 679/861] Update distro --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 09b59b17c09..77a001fc404 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "a8a3be6f7445a6f3ce736a0ba3cbca717a2372cb", + "distro": "4365d6c41f9a5e75730c78c937b68583cf6f0e4a", "author": { "name": "Microsoft Corporation" }, @@ -158,4 +158,4 @@ "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} \ No newline at end of file +} From af224bcae1660bdceb3276a0200680730646e253 Mon Sep 17 00:00:00 2001 From: gjsjohnmurray Date: Thu, 15 Aug 2019 18:35:07 +0100 Subject: [PATCH 680/861] Fix duplicated '(read-only)' suffix on titlebar name --- .../contrib/files/common/editors/fileEditorInput.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts b/src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts index 2d25923a2c2..3aae29a21be 100644 --- a/src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts +++ b/src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts @@ -203,17 +203,20 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput { switch (verbosity) { case Verbosity.SHORT: title = this.shortTitle; + // already decorated by getName() break; default: case Verbosity.MEDIUM: title = this.mediumTitle; + title = this.decorateLabel(title); break; case Verbosity.LONG: title = this.longTitle; + title = this.decorateLabel(title); break; } - return this.decorateLabel(title); + return title; } private decorateLabel(label: string): string { From 22edad13ff5701fc1d5e07f0a7311881709c55bf Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 15 Aug 2019 11:28:53 -0700 Subject: [PATCH 681/861] Move puppeteer to dev deps --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 77c377f7bde..294df311260 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,6 @@ "node-pty": "0.9.0-beta19", "nsfw": "1.2.5", "onigasm-umd": "^2.2.2", - "puppeteer": "^1.17.0", "semver-umd": "^5.5.3", "spdlog": "^0.9.0", "sudo-prompt": "9.0.0", @@ -125,6 +124,7 @@ "optimist": "0.3.5", "p-all": "^1.0.0", "pump": "^1.0.1", + "puppeteer": "^1.19.0", "queue": "3.0.6", "rcedit": "^1.1.0", "rimraf": "^2.2.8", diff --git a/yarn.lock b/yarn.lock index 0c86a6fc524..7f3c5365e14 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7368,10 +7368,10 @@ punycode@^2.1.0: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -puppeteer@^1.17.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-1.17.0.tgz#371957d227a2f450fa74b78e78a2dadb2be7f14f" - integrity sha512-3EXZSximCzxuVKpIHtyec8Wm2dWZn1fc5tQi34qWfiUgubEVYHjUvr0GOJojqf3mifI6oyKnCdrGxaOI+lWReA== +puppeteer@^1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-1.19.0.tgz#e3b7b448c2c97933517078d7a2c53687361bebea" + integrity sha512-2S6E6ygpoqcECaagDbBopoSOPDv0pAZvTbnBgUY+6hq0/XDFDOLEMNlHF/SKJlzcaZ9ckiKjKDuueWI3FN/WXw== dependencies: debug "^4.1.0" extract-zip "^1.6.6" From 562e4cb004f650e84bca197207acd3a184954abc Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 15 Aug 2019 11:35:39 -0700 Subject: [PATCH 682/861] Run smoke tests for darwin/linux in CI --- build/azure-pipelines/darwin/product-build-darwin.yml | 9 +++++++++ build/azure-pipelines/linux/product-build-linux.yml | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index c088bb8b457..de36023dfe8 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -107,6 +107,15 @@ steps: displayName: Run integration tests condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) +- script: | + set -e + cd test/smoke + yarn compile + cd - + yarn smoketest --web --headless +continueOnError: true +displayName: Smoke tests + - script: | set -e pushd ../VSCode-darwin && zip -r -X -y ../VSCode-darwin.zip * && popd diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index a6cc1c34965..993dec7ce05 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -111,6 +111,15 @@ steps: displayName: Run integration tests condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) +- script: | + set -e + cd test/smoke + yarn compile + cd - + yarn smoketest --web --headless +continueOnError: true +displayName: Smoke tests + - script: | set -e AZURE_DOCUMENTDB_MASTERKEY="$(builds-docdb-key-readwrite)" \ From cfb9c21361737515fe9cbe5df058708f16bb49f3 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 15 Aug 2019 11:36:53 -0700 Subject: [PATCH 683/861] Make display name consistent --- build/azure-pipelines/darwin/product-build-darwin.yml | 3 ++- build/azure-pipelines/linux/product-build-linux.yml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index de36023dfe8..b64b17332ef 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -114,7 +114,8 @@ steps: cd - yarn smoketest --web --headless continueOnError: true -displayName: Smoke tests +displayName: Run smoke tests +condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - script: | set -e diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index 993dec7ce05..0404e905814 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -118,7 +118,8 @@ steps: cd - yarn smoketest --web --headless continueOnError: true -displayName: Smoke tests +displayName: Run smoke tests +condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - script: | set -e From 184f5aaeddd2d04b9a203e41c3e788862ad58e64 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 15 Aug 2019 11:37:40 -0700 Subject: [PATCH 684/861] Fix indent --- .../darwin/product-build-darwin.yml | 16 ++++++++-------- .../linux/product-build-linux.yml | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index b64b17332ef..175e3d0eb08 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -108,14 +108,14 @@ steps: condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - script: | - set -e - cd test/smoke - yarn compile - cd - - yarn smoketest --web --headless -continueOnError: true -displayName: Run smoke tests -condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) + set -e + cd test/smoke + yarn compile + cd - + yarn smoketest --web --headless + continueOnError: true + displayName: Run smoke tests + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - script: | set -e diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index 0404e905814..48261e0020c 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -112,14 +112,14 @@ steps: condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - script: | - set -e - cd test/smoke - yarn compile - cd - - yarn smoketest --web --headless -continueOnError: true -displayName: Run smoke tests -condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) + set -e + cd test/smoke + yarn compile + cd - + yarn smoketest --web --headless + continueOnError: true + displayName: Run smoke tests + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - script: | set -e From c587b3887e943ac6414e3e1e59f199c0e13fbbfc Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 15 Aug 2019 21:40:41 +0200 Subject: [PATCH 685/861] Improve token regex --- .../services/environment/browser/environmentService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts index c8e2227fc0d..318caeb3d77 100644 --- a/src/vs/workbench/services/environment/browser/environmentService.ts +++ b/src/vs/workbench/services/environment/browser/environmentService.ts @@ -203,7 +203,7 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment } private getConnectionToken(str: string): string | undefined { - const m = str.match(/[#&]tkn=([^&]+)/); + const m = str.match(/[#&?]tkn=([^&]+)/); return m ? m[1] : undefined; } } From 08d5f6dcc14d4836b49b02f0b3086f13fb0d1bf9 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 15 Aug 2019 21:57:26 +0200 Subject: [PATCH 686/861] Add connectionToken --- src/vs/platform/remote/common/remoteAgentEnvironment.ts | 3 ++- .../services/remote/common/remoteAgentEnvironmentChannel.ts | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/platform/remote/common/remoteAgentEnvironment.ts b/src/vs/platform/remote/common/remoteAgentEnvironment.ts index c1815d801f3..839a6cb5c19 100644 --- a/src/vs/platform/remote/common/remoteAgentEnvironment.ts +++ b/src/vs/platform/remote/common/remoteAgentEnvironment.ts @@ -9,6 +9,7 @@ import { IExtensionDescription } from 'vs/platform/extensions/common/extensions' export interface IRemoteAgentEnvironment { pid: number; + connectionToken: string; appRoot: URI; appSettingsHome: URI; settingsPath: URI; @@ -24,4 +25,4 @@ export interface IRemoteAgentEnvironment { export interface RemoteAgentConnectionContext { remoteAuthority: string; clientId: string; -} \ No newline at end of file +} diff --git a/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts b/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts index 9f0fb09442e..ee89f26f394 100644 --- a/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts +++ b/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts @@ -18,6 +18,7 @@ export interface IGetEnvironmentDataArguments { export interface IRemoteAgentEnvironmentDTO { pid: number; + connectionToken: string; appRoot: UriComponents; appSettingsHome: UriComponents; settingsPath: UriComponents; @@ -45,6 +46,7 @@ export class RemoteExtensionEnvironmentChannelClient { return { pid: data.pid, + connectionToken: data.connectionToken, appRoot: URI.revive(data.appRoot), appSettingsHome: URI.revive(data.appSettingsHome), settingsPath: URI.revive(data.settingsPath), From bce21c1f5d53e6ea5f438920109a42b61e2b8e1a Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 15 Aug 2019 21:59:56 +0200 Subject: [PATCH 687/861] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 294df311260..339774e76e5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "4365d6c41f9a5e75730c78c937b68583cf6f0e4a", + "distro": "9d5ee3146c410b8afdec64a3a8731eb8ca64f3e7", "author": { "name": "Microsoft Corporation" }, From 3922fe8d604873953cfed6827fe49ad7be35462d Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Thu, 15 Aug 2019 22:48:47 +0200 Subject: [PATCH 688/861] Update search stop icon --- src/vs/workbench/contrib/search/browser/media/stop-dark.svg | 2 +- src/vs/workbench/contrib/search/browser/media/stop-hc.svg | 2 +- src/vs/workbench/contrib/search/browser/media/stop-light.svg | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/search/browser/media/stop-dark.svg b/src/vs/workbench/contrib/search/browser/media/stop-dark.svg index 7e6319104da..890af298354 100644 --- a/src/vs/workbench/contrib/search/browser/media/stop-dark.svg +++ b/src/vs/workbench/contrib/search/browser/media/stop-dark.svg @@ -1,3 +1,3 @@ - + diff --git a/src/vs/workbench/contrib/search/browser/media/stop-hc.svg b/src/vs/workbench/contrib/search/browser/media/stop-hc.svg index a879a194c7a..1c88dfb60a7 100644 --- a/src/vs/workbench/contrib/search/browser/media/stop-hc.svg +++ b/src/vs/workbench/contrib/search/browser/media/stop-hc.svg @@ -1,3 +1,3 @@ - + diff --git a/src/vs/workbench/contrib/search/browser/media/stop-light.svg b/src/vs/workbench/contrib/search/browser/media/stop-light.svg index 10d05f5d8ab..7e41aeff589 100644 --- a/src/vs/workbench/contrib/search/browser/media/stop-light.svg +++ b/src/vs/workbench/contrib/search/browser/media/stop-light.svg @@ -1,3 +1,3 @@ - + From 324da04f350f5cb0ceea7f3173f6c4cd12015ce9 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Thu, 15 Aug 2019 22:52:38 +0200 Subject: [PATCH 689/861] =?UTF-8?q?Update=20checkmark=20so=20they=20look?= =?UTF-8?q?=20more=20like=20a=20=E2=9C=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extensions/git/resources/icons/dark/check.svg | 2 +- extensions/git/resources/icons/light/check.svg | 2 +- src/vs/base/browser/ui/menu/check.svg | 2 +- src/vs/workbench/contrib/files/browser/media/check-dark.svg | 2 +- src/vs/workbench/contrib/files/browser/media/check-light.svg | 2 +- .../workbench/contrib/preferences/browser/media/check-dark.svg | 2 +- .../workbench/contrib/preferences/browser/media/check-light.svg | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/extensions/git/resources/icons/dark/check.svg b/extensions/git/resources/icons/dark/check.svg index 865cc83c347..2d16f390078 100644 --- a/extensions/git/resources/icons/dark/check.svg +++ b/extensions/git/resources/icons/dark/check.svg @@ -1,3 +1,3 @@ - + diff --git a/extensions/git/resources/icons/light/check.svg b/extensions/git/resources/icons/light/check.svg index e1a546660ed..a9f8aa131b5 100644 --- a/extensions/git/resources/icons/light/check.svg +++ b/extensions/git/resources/icons/light/check.svg @@ -1,3 +1,3 @@ - + diff --git a/src/vs/base/browser/ui/menu/check.svg b/src/vs/base/browser/ui/menu/check.svg index 865cc83c347..cea818ef596 100644 --- a/src/vs/base/browser/ui/menu/check.svg +++ b/src/vs/base/browser/ui/menu/check.svg @@ -1,3 +1,3 @@ - + diff --git a/src/vs/workbench/contrib/files/browser/media/check-dark.svg b/src/vs/workbench/contrib/files/browser/media/check-dark.svg index 865cc83c347..51674695e1f 100644 --- a/src/vs/workbench/contrib/files/browser/media/check-dark.svg +++ b/src/vs/workbench/contrib/files/browser/media/check-dark.svg @@ -1,3 +1,3 @@ - + diff --git a/src/vs/workbench/contrib/files/browser/media/check-light.svg b/src/vs/workbench/contrib/files/browser/media/check-light.svg index e1a546660ed..7b1da6d7208 100644 --- a/src/vs/workbench/contrib/files/browser/media/check-light.svg +++ b/src/vs/workbench/contrib/files/browser/media/check-light.svg @@ -1,3 +1,3 @@ - + diff --git a/src/vs/workbench/contrib/preferences/browser/media/check-dark.svg b/src/vs/workbench/contrib/preferences/browser/media/check-dark.svg index 865cc83c347..51674695e1f 100644 --- a/src/vs/workbench/contrib/preferences/browser/media/check-dark.svg +++ b/src/vs/workbench/contrib/preferences/browser/media/check-dark.svg @@ -1,3 +1,3 @@ - + diff --git a/src/vs/workbench/contrib/preferences/browser/media/check-light.svg b/src/vs/workbench/contrib/preferences/browser/media/check-light.svg index e1a546660ed..7b1da6d7208 100644 --- a/src/vs/workbench/contrib/preferences/browser/media/check-light.svg +++ b/src/vs/workbench/contrib/preferences/browser/media/check-light.svg @@ -1,3 +1,3 @@ - + From 6624dbbce9a3f2c2f4d8d294352c3c27bac34255 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 15 Aug 2019 23:11:40 +0200 Subject: [PATCH 690/861] introduce RemoteAuthorities --- src/vs/base/common/network.ts | 23 +++++++++++++++++++ .../remoteAuthorityResolverService.ts | 2 ++ .../common/remoteAgentEnvironmentChannel.ts | 3 +++ 3 files changed, 28 insertions(+) diff --git a/src/vs/base/common/network.ts b/src/vs/base/common/network.ts index 46d2933a05e..f3006bdf3e1 100644 --- a/src/vs/base/common/network.ts +++ b/src/vs/base/common/network.ts @@ -49,3 +49,26 @@ export namespace Schemas { export const userData: string = 'vscode-userdata'; } + +class RemoteAuthoritiesImpl { + private readonly _hosts: { [authority: string]: string; }; + private readonly _ports: { [authority: string]: number; }; + private readonly _connectionTokens: { [authority: string]: string; }; + + constructor() { + this._hosts = Object.create(null); + this._ports = Object.create(null); + this._connectionTokens = Object.create(null); + } + + public set(authority: string, host: string, port: number): void { + this._hosts[authority] = host; + this._ports[authority] = port; + } + + public setConnectionToken(authority: string, connectionToken: string): void { + this._connectionTokens[authority] = connectionToken; + } +} + +export const RemoteAuthorities = new RemoteAuthoritiesImpl(); diff --git a/src/vs/platform/remote/electron-browser/remoteAuthorityResolverService.ts b/src/vs/platform/remote/electron-browser/remoteAuthorityResolverService.ts index 3cd1da3e018..9ab777f67bd 100644 --- a/src/vs/platform/remote/electron-browser/remoteAuthorityResolverService.ts +++ b/src/vs/platform/remote/electron-browser/remoteAuthorityResolverService.ts @@ -6,6 +6,7 @@ import { ResolvedAuthority, IRemoteAuthorityResolverService, ResolverResult, ResolvedOptions } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { ipcRenderer as ipc } from 'electron'; import * as errors from 'vs/base/common/errors'; +import { RemoteAuthorities } from 'vs/base/common/network'; class PendingResolveAuthorityRequest { constructor( @@ -50,6 +51,7 @@ export class RemoteAuthorityResolverService implements IRemoteAuthorityResolverS if (this._resolveAuthorityRequests[resolvedAuthority.authority]) { let request = this._resolveAuthorityRequests[resolvedAuthority.authority]; ipc.send('vscode:remoteAuthorityResolved', resolvedAuthority); + RemoteAuthorities.set(resolvedAuthority.authority, resolvedAuthority.host, resolvedAuthority.port); request.resolve({ authority: resolvedAuthority, options }); } } diff --git a/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts b/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts index ee89f26f394..fe15f2b644e 100644 --- a/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts +++ b/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts @@ -9,6 +9,7 @@ import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment'; import { IDiagnosticInfoOptions, IDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnostics'; +import { RemoteAuthorities } from 'vs/base/common/network'; export interface IGetEnvironmentDataArguments { language: string; @@ -44,6 +45,8 @@ export class RemoteExtensionEnvironmentChannelClient { const data = await this.channel.call('getEnvironmentData', args); + RemoteAuthorities.setConnectionToken(remoteAuthority, data.connectionToken); + return { pid: data.pid, connectionToken: data.connectionToken, From 454d16efd7f6e251347687dc0f74cbf2e3fbfea2 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 15 Aug 2019 14:34:00 -0700 Subject: [PATCH 691/861] remote explorer and contribution under proposed api --- src/vs/workbench/api/browser/viewsExtensionPoint.ts | 7 ++++++- src/vs/workbench/contrib/remote/browser/remote.ts | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/api/browser/viewsExtensionPoint.ts b/src/vs/workbench/api/browser/viewsExtensionPoint.ts index 95a9aff3298..b12e7ec2bf6 100644 --- a/src/vs/workbench/api/browser/viewsExtensionPoint.ts +++ b/src/vs/workbench/api/browser/viewsExtensionPoint.ts @@ -151,7 +151,7 @@ const viewsContribution: IJSONSchema = { default: [] }, 'remote': { - description: localize('views.remote', "Contributes views to Remote container in the Activity bar"), + description: localize('views.remote', "Contributes views to Remote container in the Activity bar. To contribute to this container, enableProposedApi needs to be turned on"), type: 'array', items: nestableViewDescriptor, default: [] @@ -387,6 +387,11 @@ class ViewsExtensionHandler implements IWorkbenchContribution { return; } + if (entry.key === 'remote' && !extension.description.enableProposedApi) { + collector.warn(localize('ViewContainerRequiresProposedAPI', "View container '{0}' requires 'enableProposedApi' turned on to be added to 'Remote'.", entry.key)); + return; + } + const viewContainer = this.getViewContainer(entry.key); if (!viewContainer) { collector.warn(localize('ViewContainerDoesnotExist', "View container '{0}' does not exist and all views registered to it will be added to 'Explorer'.", entry.key)); diff --git a/src/vs/workbench/contrib/remote/browser/remote.ts b/src/vs/workbench/contrib/remote/browser/remote.ts index ea530271414..eb7bc581f9d 100644 --- a/src/vs/workbench/contrib/remote/browser/remote.ts +++ b/src/vs/workbench/contrib/remote/browser/remote.ts @@ -386,6 +386,10 @@ export class RemoteViewlet extends ViewContainerViewlet implements IViewModel { } private _handleRemoteInfoExtensionPoint(extension: IExtensionPointUser, helpInformation: HelpInformation[]) { + if (!extension.description.enableProposedApi) { + return; + } + if (!extension.value.documentation && !extension.value.feedback && !extension.value.getStarted && !extension.value.issues) { return; } From b32052728015c8712819ccc8b28b4bf9880179a7 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 15 Aug 2019 14:38:20 -0700 Subject: [PATCH 692/861] Disable smoke tests on Linux Puppeteer needs special user setup in order to launch --- build/azure-pipelines/linux/product-build-linux.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index 48261e0020c..a6cc1c34965 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -111,16 +111,6 @@ steps: displayName: Run integration tests condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) -- script: | - set -e - cd test/smoke - yarn compile - cd - - yarn smoketest --web --headless - continueOnError: true - displayName: Run smoke tests - condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - script: | set -e AZURE_DOCUMENTDB_MASTERKEY="$(builds-docdb-key-readwrite)" \ From b66f0d96d4c8729cb1fb041ddee2a2edb7203fcc Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 15 Aug 2019 11:47:21 -0700 Subject: [PATCH 693/861] Strict init #78168 --- .../contrib/codeEditor/browser/find/simpleFindWidget.ts | 9 +++++---- .../workbench/contrib/webview/browser/webviewElement.ts | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts b/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts index 1270b142228..8ba218619a2 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget.ts @@ -29,13 +29,14 @@ export abstract class SimpleFindWidget extends Widget { private readonly _findInput: FindInput; private readonly _domNode: HTMLElement; private readonly _innerDomNode: HTMLElement; - private _isVisible: boolean = false; private readonly _focusTracker: dom.IFocusTracker; private readonly _findInputFocusTracker: dom.IFocusTracker; private readonly _updateHistoryDelayer: Delayer; - private prevBtn: SimpleButton; - private nextBtn: SimpleButton; - private foundMatch: boolean; + private readonly prevBtn: SimpleButton; + private readonly nextBtn: SimpleButton; + + private _isVisible: boolean = false; + private foundMatch: boolean = false; constructor( @IContextViewService private readonly _contextViewService: IContextViewService, diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index aa4473313d4..6eb2d99a7b0 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -213,7 +213,7 @@ export class IFrameWebview extends Disposable implements Webview { } } - initialScrollProgress: number; + initialScrollProgress: number = 0; private readonly _onDidFocus = this._register(new Emitter()); public readonly onDidFocus = this._onDidFocus.event; From 3956654054a2cd8c90514769c4461524929dfcc5 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 15 Aug 2019 11:49:09 -0700 Subject: [PATCH 694/861] Strict init and mark events readonly #78168 --- src/vs/platform/windows/common/windows.ts | 12 ++++++------ src/vs/platform/windows/common/windowsIpc.ts | 16 ++++++++-------- src/vs/workbench/test/workbenchTestServices.ts | 12 ++++++------ 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index a1f50a5a715..7ac04663081 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -96,12 +96,12 @@ export interface IWindowsService { _serviceBrand: any; - onWindowOpen: Event; - onWindowFocus: Event; - onWindowBlur: Event; - onWindowMaximize: Event; - onWindowUnmaximize: Event; - onRecentlyOpenedChange: Event; + readonly onWindowOpen: Event; + readonly onWindowFocus: Event; + readonly onWindowBlur: Event; + readonly onWindowMaximize: Event; + readonly onWindowUnmaximize: Event; + readonly onRecentlyOpenedChange: Event; // Dialogs pickFileFolderAndOpen(options: INativeOpenDialogOptions): Promise; diff --git a/src/vs/platform/windows/common/windowsIpc.ts b/src/vs/platform/windows/common/windowsIpc.ts index 6fbad27a549..3cdf71e2f4a 100644 --- a/src/vs/platform/windows/common/windowsIpc.ts +++ b/src/vs/platform/windows/common/windowsIpc.ts @@ -12,14 +12,14 @@ import { IRecent, isRecentFile, isRecentFolder } from 'vs/platform/history/commo export class WindowsChannel implements IServerChannel { - private onWindowOpen: Event; - private onWindowFocus: Event; - private onWindowBlur: Event; - private onWindowMaximize: Event; - private onWindowUnmaximize: Event; - private onRecentlyOpenedChange: Event; + private readonly onWindowOpen: Event; + private readonly onWindowFocus: Event; + private readonly onWindowBlur: Event; + private readonly onWindowMaximize: Event; + private readonly onWindowUnmaximize: Event; + private readonly onRecentlyOpenedChange: Event; - constructor(private service: IWindowsService) { + constructor(private readonly service: IWindowsService) { this.onWindowOpen = Event.buffer(service.onWindowOpen, true); this.onWindowFocus = Event.buffer(service.onWindowFocus, true); this.onWindowBlur = Event.buffer(service.onWindowBlur, true); @@ -120,4 +120,4 @@ export class WindowsChannel implements IServerChannel { throw new Error(`Call not found: ${command}`); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 576df9cb63c..d182e4ca73c 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -1340,12 +1340,12 @@ export class TestWindowsService implements IWindowsService { public windowCount = 1; - onWindowOpen: Event; - onWindowFocus: Event; - onWindowBlur: Event; - onWindowMaximize: Event; - onWindowUnmaximize: Event; - onRecentlyOpenedChange: Event; + readonly onWindowOpen: Event = Event.None; + readonly onWindowFocus: Event = Event.None; + readonly onWindowBlur: Event = Event.None; + readonly onWindowMaximize: Event = Event.None; + readonly onWindowUnmaximize: Event = Event.None; + readonly onRecentlyOpenedChange: Event = Event.None; isFocused(_windowId: number): Promise { return Promise.resolve(false); From 883ae9069a23b9125d3afc47f51da407fa7baf2f Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 15 Aug 2019 11:55:29 -0700 Subject: [PATCH 695/861] Remove extra null checks in coalesce The type system should catch these now --- src/vs/base/common/arrays.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/vs/base/common/arrays.ts b/src/vs/base/common/arrays.ts index 7aa42597714..cb3c94b3d15 100644 --- a/src/vs/base/common/arrays.ts +++ b/src/vs/base/common/arrays.ts @@ -293,12 +293,9 @@ function topStep(array: ReadonlyArray, compare: (a: T, b: T) => number, re } /** - * @returns a new array with all falsy values removed. The original array IS NOT modified. + * @returns New array with all falsy values removed. The original array IS NOT modified. */ export function coalesce(array: ReadonlyArray): T[] { - if (!array) { - return array; - } return array.filter(e => !!e); } @@ -306,9 +303,6 @@ export function coalesce(array: ReadonlyArray): T[] { * Remove all falsey values from `array`. The original array IS modified. */ export function coalesceInPlace(array: Array): void { - if (!array) { - return; - } let to = 0; for (let i = 0; i < array.length; i++) { if (!!array[i]) { From 1bbf3b3fa693afa1ae69adff22ea65317396aeda Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 15 Aug 2019 15:15:36 -0700 Subject: [PATCH 696/861] Add telemetry+warning for webviews that don't have a content security policy Fixes #79248 --- .../src/features/previewContentProvider.ts | 2 +- .../contrib/webview/browser/pre/main.js | 6 ++++ .../electron-browser/webviewElement.ts | 34 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/extensions/markdown-language-features/src/features/previewContentProvider.ts b/extensions/markdown-language-features/src/features/previewContentProvider.ts index 17b6d4f4ebb..9b70fe3beb3 100644 --- a/extensions/markdown-language-features/src/features/previewContentProvider.ts +++ b/extensions/markdown-language-features/src/features/previewContentProvider.ts @@ -209,7 +209,7 @@ export class MarkdownContentProvider { return ``; case MarkdownPreviewSecurityLevel.AllowScriptsAndAllContent: - return ''; + return ''; case MarkdownPreviewSecurityLevel.Strict: default: diff --git a/src/vs/workbench/contrib/webview/browser/pre/main.js b/src/vs/workbench/contrib/webview/browser/pre/main.js index 6568b02f011..0b25585c611 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/main.js +++ b/src/vs/workbench/contrib/webview/browser/pre/main.js @@ -285,6 +285,12 @@ applyStyles(newDocument, newDocument.body); + // Check for CSP + const csp = newDocument.querySelector('meta[http-equiv="Content-Security-Policy"]'); + if (!csp) { + host.postMessage('no-csp-found'); + } + // set DOCTYPE for newDocument explicitly as DOMParser.parseFromString strips it off // and DOCTYPE is needed in the iframe to ensure that the user agent stylesheet is correctly overridden return '\n' + newDocument.documentElement.outerHTML; diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts index 20daf1ec4bc..4b06dd21bb1 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts @@ -13,9 +13,11 @@ import { endsWith } from 'vs/base/common/strings'; import { URI } from 'vs/base/common/uri'; import * as modes from 'vs/editor/common/modes'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ITunnelService } from 'vs/platform/remote/common/tunnel'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITheme, IThemeService } from 'vs/platform/theme/common/themeService'; import { WebviewPortMappingManager } from 'vs/workbench/contrib/webview/common/portMapping'; import { getWebviewThemeData } from 'vs/workbench/contrib/webview/common/themeing'; @@ -284,6 +286,8 @@ export class ElectronWebviewBasedWebview extends Disposable implements Webview { @IFileService fileService: IFileService, @ITunnelService tunnelService: ITunnelService, @IConfigurationService private readonly _configurationService: IConfigurationService, + @ITelemetryService private readonly _telemetryService: ITelemetryService, + @IEnvironmentService private readonly _environementService: IEnvironmentService, ) { super(); this.content = { @@ -412,6 +416,10 @@ export class ElectronWebviewBasedWebview extends Disposable implements Webview { case 'did-blur': this.handleFocusChange(false); return; + + case 'no-csp-found': + this.handleNoCspFound(); + return; } })); this._register(addDisposableListener(this._webview, 'devtools-opened', () => { @@ -546,6 +554,32 @@ export class ElectronWebviewBasedWebview extends Disposable implements Webview { } } + private _hasAlertedAboutMissingCsp = false; + + private handleNoCspFound(): void { + if (this._hasAlertedAboutMissingCsp) { + return; + } + this._hasAlertedAboutMissingCsp = true; + + if (this._options.extension && this._options.extension.id) { + if (this._environementService.isExtensionDevelopment) { + console.warn(`${this._options.extension.id.value} created a webview without a content security policy: https://aka.ms/vscode-webview-missing-csp`); + } + + type TelemetryClassification = { + extension?: { classification: 'SystemMetaData', purpose: 'FeatureInsight' } + }; + type TelemetryData = { + extension?: string, + }; + + this._telemetryService.publicLog2('webviewMissingCsp', { + extension: this._options.extension.id.value + }); + } + } + public sendMessage(data: any): void { this._send('message', data); } From 8eb0097c39a7bc8a216e87d4075e67959606c2bb Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 15 Aug 2019 15:15:50 -0700 Subject: [PATCH 697/861] Fixing comment --- src/vs/vscode.proposed.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 328fcae5896..5284711d6e1 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1161,11 +1161,11 @@ declare module 'vscode' { /** * Content security policy source for webview resources. * - * This is origin used in a content security policy rule: + * This is the origin that should be used in a content security policy rule: * * ``` * img-src https: ${webview.cspSource} ...; - * ```` + * ``` */ readonly cspSource: string; } From 86819a886c540c45a97d1a67cdc2fc31ee899a72 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 15 Aug 2019 16:35:13 -0700 Subject: [PATCH 698/861] Update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 339774e76e5..293e9648933 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "9d5ee3146c410b8afdec64a3a8731eb8ca64f3e7", + "distro": "294c6a19b85a4ec824a66dbe70c51a2858961b12", "author": { "name": "Microsoft Corporation" }, From c44c802a1dadb05f2ed7d315e05ba352185c2954 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 15 Aug 2019 17:07:40 -0700 Subject: [PATCH 699/861] Update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 293e9648933..ee393d1aaf3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "294c6a19b85a4ec824a66dbe70c51a2858961b12", + "distro": "13f407368a517ace39c2721a66a951ba4eebce20", "author": { "name": "Microsoft Corporation" }, From 55c5bbfddd6ab1974c92fcefc24b980b85b50a10 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 15 Aug 2019 17:59:38 -0700 Subject: [PATCH 700/861] Don't dispose of added object in already disposed of case Fixes #77192 See #77192 for discussion --- src/vs/base/common/lifecycle.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/base/common/lifecycle.ts b/src/vs/base/common/lifecycle.ts index 6be438cee41..44cfdada8ab 100644 --- a/src/vs/base/common/lifecycle.ts +++ b/src/vs/base/common/lifecycle.ts @@ -127,8 +127,7 @@ export class DisposableStore implements IDisposable { markTracked(t); if (this._isDisposed) { - console.warn(new Error('Registering disposable on object that has already been disposed of').stack); - t.dispose(); + console.warn(new Error('Trying to add a disposable to a DisposableStore that has already been disposed of. The added object will be leaked!').stack); } else { this._toDispose.add(t); } From 35c97ea91de2bd339d907f1f01ff4713c235fd52 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 15 Aug 2019 18:02:28 -0700 Subject: [PATCH 701/861] Mark readonly --- .../src/features/updatePathsOnRename.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/typescript-language-features/src/features/updatePathsOnRename.ts b/extensions/typescript-language-features/src/features/updatePathsOnRename.ts index c4c2e9ca135..cbb0d251adf 100644 --- a/extensions/typescript-language-features/src/features/updatePathsOnRename.ts +++ b/extensions/typescript-language-features/src/features/updatePathsOnRename.ts @@ -40,7 +40,7 @@ enum UpdateImportsOnFileMoveSetting { } class UpdateImportsOnFileRenameHandler extends Disposable { - public static minVersion = API.v300; + public static readonly minVersion = API.v300; public constructor( private readonly client: ITypeScriptServiceClient, @@ -237,4 +237,4 @@ export function register( ) { return new VersionDependentRegistration(client, UpdateImportsOnFileRenameHandler.minVersion, () => new UpdateImportsOnFileRenameHandler(client, fileConfigurationManager, handles)); -} \ No newline at end of file +} From d9aba4fa7f4e3ab0039458c829bd7d8ade38b11c Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 15 Aug 2019 18:03:55 -0700 Subject: [PATCH 702/861] Use const enums --- .../src/features/updatePathsOnRename.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/typescript-language-features/src/features/updatePathsOnRename.ts b/extensions/typescript-language-features/src/features/updatePathsOnRename.ts index cbb0d251adf..102658ecf01 100644 --- a/extensions/typescript-language-features/src/features/updatePathsOnRename.ts +++ b/extensions/typescript-language-features/src/features/updatePathsOnRename.ts @@ -33,7 +33,7 @@ function isDirectory(path: string): Promise { }); } -enum UpdateImportsOnFileMoveSetting { +const enum UpdateImportsOnFileMoveSetting { Prompt = 'prompt', Always = 'always', Never = 'never', @@ -127,7 +127,7 @@ class UpdateImportsOnFileRenameHandler extends Disposable { newResource: vscode.Uri, newDocument: vscode.TextDocument ): Promise { - enum Choice { + const enum Choice { None = 0, Accept = 1, Reject = 2, From 967b43392e2afb55659c062230f16ce15db2926d Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 15 Aug 2019 18:10:07 -0700 Subject: [PATCH 703/861] Marking fields readonly --- src/vs/platform/files/common/files.ts | 24 +++++++++---------- .../contrib/files/common/explorerModel.ts | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/vs/platform/files/common/files.ts b/src/vs/platform/files/common/files.ts index ad600a2a430..40d21fce9de 100644 --- a/src/vs/platform/files/common/files.ts +++ b/src/vs/platform/files/common/files.ts @@ -620,26 +620,26 @@ export interface IReadFileOptions { * that have been read already with the same etag. * It is the task of the caller to makes sure to handle this error case from the promise. */ - etag?: string; + readonly etag?: string; /** * Is an integer specifying where to begin reading from in the file. If position is null, * data will be read from the current file position. */ - position?: number; + readonly position?: number; /** * Is an integer specifying how many bytes to read from the file. By default, all bytes * will be read. */ - length?: number; + readonly length?: number; /** * If provided, the size of the file will be checked against the limits. */ limits?: { - size?: number; - memory?: number; + readonly size?: number; + readonly memory?: number; }; } @@ -648,12 +648,12 @@ export interface IWriteFileOptions { /** * The last known modification time of the file. This can be used to prevent dirty writes. */ - mtime?: number; + readonly mtime?: number; /** * The etag of the file. This can be used to prevent dirty writes. */ - etag?: string; + readonly etag?: string; } export interface IResolveFileOptions { @@ -662,22 +662,22 @@ export interface IResolveFileOptions { * Automatically continue resolving children of a directory until the provided resources * are found. */ - resolveTo?: URI[]; + readonly resolveTo?: readonly URI[]; /** * Automatically continue resolving children of a directory if the number of children is 1. */ - resolveSingleChildDescendants?: boolean; + readonly resolveSingleChildDescendants?: boolean; /** * Will resolve mtime, size and etag of files if enabled. This can have a negative impact * on performance and thus should only be used when these values are required. */ - resolveMetadata?: boolean; + readonly resolveMetadata?: boolean; } export interface IResolveMetadataFileOptions extends IResolveFileOptions { - resolveMetadata: true; + readonly resolveMetadata: true; } export interface ICreateFileOptions { @@ -686,7 +686,7 @@ 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; + readonly overwrite?: boolean; } export class FileOperationError extends Error { diff --git a/src/vs/workbench/contrib/files/common/explorerModel.ts b/src/vs/workbench/contrib/files/common/explorerModel.ts index aefd67e415d..cf0172fd317 100644 --- a/src/vs/workbench/contrib/files/common/explorerModel.ts +++ b/src/vs/workbench/contrib/files/common/explorerModel.ts @@ -148,7 +148,7 @@ export class ExplorerItem { return this === this.root; } - static create(raw: IFileStat, parent: ExplorerItem | undefined, resolveTo?: URI[]): ExplorerItem { + static create(raw: IFileStat, parent: ExplorerItem | undefined, resolveTo?: readonly URI[]): ExplorerItem { const stat = new ExplorerItem(raw.resource, parent, raw.isDirectory, raw.isSymbolicLink, raw.isReadonly, raw.name, raw.mtime); // Recursively add children if present From 99912f5866092ff906e69b8e66771c8124922ee2 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 15 Aug 2019 18:18:42 -0700 Subject: [PATCH 704/861] Remove webview svg whitelist This is no longer required --- src/vs/platform/product/common/product.ts | 1 - .../api/browser/mainThreadCodeInsets.ts | 1 - .../extensions/browser/extensionEditor.ts | 4 +- .../browser/extensionsWorkbenchService.ts | 8 --- .../contrib/extensions/common/extensions.ts | 1 - .../webview/browser/webviewEditorService.ts | 1 - .../contrib/webview/common/webview.ts | 2 - .../electron-browser/webviewElement.ts | 57 ------------------- 8 files changed, 1 insertion(+), 74 deletions(-) diff --git a/src/vs/platform/product/common/product.ts b/src/vs/platform/product/common/product.ts index 3797e18a25e..0a3b1f75c89 100644 --- a/src/vs/platform/product/common/product.ts +++ b/src/vs/platform/product/common/product.ts @@ -46,7 +46,6 @@ export interface IProductConfiguration { readonly extensionImportantTips: { [id: string]: { name: string; pattern: string; isExtensionPack?: boolean }; }; readonly exeBasedExtensionTips: { [id: string]: IExeBasedExtensionTip; }; readonly extensionKeywords: { [extension: string]: readonly string[]; }; - readonly extensionAllowedBadgeProviders: readonly string[]; readonly extensionAllowedProposedApi: readonly string[]; readonly keymapExtensionTips: readonly string[]; readonly crashReporter: { diff --git a/src/vs/workbench/api/browser/mainThreadCodeInsets.ts b/src/vs/workbench/api/browser/mainThreadCodeInsets.ts index 2e9ea44a233..bb42627961d 100644 --- a/src/vs/workbench/api/browser/mainThreadCodeInsets.ts +++ b/src/vs/workbench/api/browser/mainThreadCodeInsets.ts @@ -90,7 +90,6 @@ export class MainThreadEditorInsets implements MainThreadEditorInsetsShape { const webview = this._webviewService.createWebview('' + handle, { enableFindWidget: false, - allowSvgs: false, extension: { id: extensionId, location: URI.revive(extensionLocation) } }, { allowScripts: options.enableScripts, diff --git a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index e31c90cb95b..d4a6e6f60ac 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -572,9 +572,7 @@ export class ExtensionEditor extends BaseEditor { { enableFindWidget: true, }, - { - svgWhiteList: this.extensionsWorkbenchService.allowedBadgeProviders, - }); + {}); webviewElement.mountTo(template.content); this.contentDisposables.add(webviewElement.onDidFocus(() => this.fireOnDidFocus())); const removeLayoutParticipant = arrays.insert(this.layoutParticipants, webviewElement); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index b64689e02c6..e82544c68e3 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -484,7 +484,6 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension private readonly _onChange: Emitter = new Emitter(); get onChange(): Event { return this._onChange.event; } - private _extensionAllowedBadgeProviders: string[] | undefined; private installing: IExtension[] = []; constructor( @@ -1020,13 +1019,6 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension return changed; } - get allowedBadgeProviders(): string[] { - if (!this._extensionAllowedBadgeProviders) { - this._extensionAllowedBadgeProviders = (this.productService.extensionAllowedBadgeProviders || []).map(s => s.toLowerCase()); - } - return this._extensionAllowedBadgeProviders; - } - private _activityCallBack: (() => void) | null = null; private updateActivity(): void { if ((this.localExtensions && this.localExtensions.local.some(e => e.state === ExtensionState.Installing || e.state === ExtensionState.Uninstalling)) diff --git a/src/vs/workbench/contrib/extensions/common/extensions.ts b/src/vs/workbench/contrib/extensions/common/extensions.ts index 33e46eecf82..47b8e916d88 100644 --- a/src/vs/workbench/contrib/extensions/common/extensions.ts +++ b/src/vs/workbench/contrib/extensions/common/extensions.ts @@ -91,7 +91,6 @@ export interface IExtensionsWorkbenchService { setEnablement(extensions: IExtension | IExtension[], enablementState: EnablementState): Promise; open(extension: IExtension, sideByside?: boolean): Promise; checkForUpdates(): Promise; - allowedBadgeProviders: string[]; } export const ConfigurationKey = 'extensions'; diff --git a/src/vs/workbench/contrib/webview/browser/webviewEditorService.ts b/src/vs/workbench/contrib/webview/browser/webviewEditorService.ts index fb0354fab1a..c17d203aed3 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewEditorService.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewEditorService.ts @@ -244,7 +244,6 @@ export class WebviewEditorService implements IWebviewEditorService { private createWebiew(id: string, extension: { location: URI; id: ExtensionIdentifier; } | undefined, options: WebviewInputOptions) { return this._webviewService.createWebviewEditorOverlay(id, { - allowSvgs: true, extension: extension, enableFindWidget: options.enableFindWidget, retainContextWhenHidden: options.retainContextWhenHidden diff --git a/src/vs/workbench/contrib/webview/common/webview.ts b/src/vs/workbench/contrib/webview/common/webview.ts index d6a73ff5d61..ea7ecb5a720 100644 --- a/src/vs/workbench/contrib/webview/common/webview.ts +++ b/src/vs/workbench/contrib/webview/common/webview.ts @@ -41,7 +41,6 @@ export interface IWebviewService { export const WebviewResourceScheme = 'vscode-resource'; export interface WebviewOptions { - readonly allowSvgs?: boolean; readonly extension?: { readonly location: URI; readonly id?: ExtensionIdentifier; @@ -53,7 +52,6 @@ export interface WebviewOptions { export interface WebviewContentOptions { readonly allowScripts?: boolean; - readonly svgWhiteList?: string[]; readonly localResourceRoots?: ReadonlyArray; readonly portMapping?: ReadonlyArray; readonly enableCommandUris?: boolean; diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts index 4b06dd21bb1..4002461cae2 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts @@ -9,7 +9,6 @@ import { Emitter, Event } from 'vs/base/common/event'; import { once } from 'vs/base/common/functional'; import { Disposable } from 'vs/base/common/lifecycle'; import { isMacintosh } from 'vs/base/common/platform'; -import { endsWith } from 'vs/base/common/strings'; import { URI } from 'vs/base/common/uri'; import * as modes from 'vs/editor/common/modes'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -137,51 +136,6 @@ class WebviewPortMappingProvider extends Disposable { } } -class SvgBlocker extends Disposable { - - private readonly _onDidBlockSvg = this._register(new Emitter()); - public readonly onDidBlockSvg = this._onDidBlockSvg.event; - - constructor( - session: WebviewSession, - private readonly _options: WebviewContentOptions, - ) { - super(); - - session.onBeforeRequest(async (details) => { - if (details.url.indexOf('.svg') > 0) { - const uri = URI.parse(details.url); - if (uri && !uri.scheme.match(/file/i) && endsWith(uri.path, '.svg') && !this.isAllowedSvg(uri)) { - this._onDidBlockSvg.fire(); - return { cancel: true }; - } - } - - return undefined; - }); - - session.onHeadersReceived((details) => { - const headers: any = details.responseHeaders; - const contentType: string[] = headers['content-type'] || headers['Content-Type']; - if (contentType && Array.isArray(contentType) && contentType.some(x => x.toLowerCase().indexOf('image/svg') >= 0)) { - const uri = URI.parse(details.url); - if (uri && !this.isAllowedSvg(uri)) { - this._onDidBlockSvg.fire(); - return { cancel: true }; - } - } - return undefined; - }); - } - - private isAllowedSvg(uri: URI): boolean { - if (this._options.svgWhiteList) { - return this._options.svgWhiteList.indexOf(uri.authority.toLowerCase()) >= 0; - } - return false; - } -} - class WebviewKeyboardHandler extends Disposable { private _ignoreMenuShortcut = false; @@ -335,11 +289,6 @@ export class ElectronWebviewBasedWebview extends Disposable implements Webview { tunnelService, )); - if (!this._options.allowSvgs) { - const svgBlocker = this._register(new SvgBlocker(session, this.content.options)); - svgBlocker.onDidBlockSvg(() => this.onDidBlockSvg()); - } - this._register(new WebviewKeyboardHandler(this._webview)); this._register(addDisposableListener(this._webview, 'console-message', function (e: { level: number; message: string; line: number; sourceId: string; }) { @@ -584,12 +533,6 @@ export class ElectronWebviewBasedWebview extends Disposable implements Webview { this._send('message', data); } - private onDidBlockSvg() { - this.sendMessage({ - name: 'vscode-did-block-svg' - }); - } - private style(theme: ITheme): void { const { styles, activeTheme } = getWebviewThemeData(theme, this._configurationService); this._send('styles', { styles, activeTheme }); From 1ce89e2cb720d69c496c2815c4696ee4fd4429a6 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 15 Aug 2019 18:20:21 -0700 Subject: [PATCH 705/861] Removing test for disposable store We have disabled this behavior --- src/vs/base/test/common/lifecycle.test.ts | 36 ++--------------------- 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/src/vs/base/test/common/lifecycle.test.ts b/src/vs/base/test/common/lifecycle.test.ts index 46d8a254b5b..4d15ad2046c 100644 --- a/src/vs/base/test/common/lifecycle.test.ts +++ b/src/vs/base/test/common/lifecycle.test.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { IDisposable, dispose, ReferenceCollection, Disposable as DisposableBase, toDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, ReferenceCollection } from 'vs/base/common/lifecycle'; class Disposable implements IDisposable { isDisposed = false; @@ -50,38 +50,6 @@ suite('Lifecycle', () => { }); }); -suite('DisposableBase', () => { - test('register should not leak if object has already been disposed', () => { - let aCount = 0; - let bCount = 0; - - const disposable = new class extends DisposableBase { - register(other: IDisposable) { - this._register(other); - } - }; - - disposable.register(toDisposable(() => ++aCount)); - - assert.strictEqual(aCount, 0); - assert.strictEqual(bCount, 0); - - disposable.dispose(); - assert.strictEqual(aCount, 1); - assert.strictEqual(bCount, 0); - - // Any newly added disposables should be disposed of immediately - disposable.register(toDisposable(() => ++bCount)); - assert.strictEqual(aCount, 1); - assert.strictEqual(bCount, 1); - - // Further dispose calls should have no effect - disposable.dispose(); - assert.strictEqual(aCount, 1); - assert.strictEqual(bCount, 1); - }); -}); - suite('Reference Collection', () => { class Collection extends ReferenceCollection { private _count = 0; @@ -118,4 +86,4 @@ suite('Reference Collection', () => { ref4.dispose(); assert.equal(collection.count, 0); }); -}); \ No newline at end of file +}); From c23cacdc97b54e6056400599dad329cabc7facfb Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 16 Aug 2019 08:08:25 +0200 Subject: [PATCH 706/861] build - disable smoketest --- .../darwin/product-build-darwin.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index 175e3d0eb08..5718cfa56bd 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -107,15 +107,15 @@ steps: displayName: Run integration tests condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) -- script: | - set -e - cd test/smoke - yarn compile - cd - - yarn smoketest --web --headless - continueOnError: true - displayName: Run smoke tests - condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) +# - script: | +# set -e +# cd test/smoke +# yarn compile +# cd - +# yarn smoketest --web --headless +# continueOnError: true +# displayName: Run smoke tests +# condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - script: | set -e From 0a7d4edb20715ddb7ad124936a7dcb0ca8940e65 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Fri, 16 Aug 2019 09:14:14 +0200 Subject: [PATCH 707/861] Enable new Octicons style by default --- src/vs/workbench/browser/workbench.contribution.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index 22ca16ef487..5504ef50307 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -239,6 +239,11 @@ import { isMacintosh, isWindows, isLinux, isWeb } from 'vs/base/common/platform' 'description': nls.localize('workbench.useExperimentalGridLayout', "Enables the grid layout for the workbench. This setting may enable additional layout options for workbench components."), 'default': true, 'scope': ConfigurationScope.APPLICATION + }, + 'workbench.octiconsUpdate.enabled': { + 'type': 'boolean', + 'default': true, + 'description': nls.localize('workbench.octiconsUpdate.enabled', "Controls the visibility of the new Octicons style in the workbench.") } } }); From 54520f5f4437565b2bd68524d0b9586ca86712f1 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 16 Aug 2019 09:27:34 +0200 Subject: [PATCH 708/861] fix web platform check --- .../contrib/extensions/browser/extensionTipsService.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts b/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts index ec9b7e82c0f..ebf0b5ba336 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts @@ -40,7 +40,7 @@ import { extname } from 'vs/base/common/resources'; import { IExeBasedExtensionTip, IProductService } from 'vs/platform/product/common/product'; import { timeout } from 'vs/base/common/async'; import { IWorkspaceStatsService } from 'vs/workbench/contrib/stats/common/workspaceStats'; -import { Platform, setImmediate } from 'vs/base/common/platform'; +import { setImmediate, isWeb } from 'vs/base/common/platform'; import { platform, env as processEnv } from 'vs/base/common/process'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; @@ -984,7 +984,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe * If user has any of the tools listed in this.productService.exeBasedExtensionTips, fetch corresponding recommendations */ private async fetchExecutableRecommendations(important: boolean): Promise { - if (Platform.Web) { + if (isWeb) { return; } From e741e07929e45157761d4deb976fcb156b886f87 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 16 Aug 2019 09:11:24 +0200 Subject: [PATCH 709/861] better worker error logging --- .../extensions/browser/webWorkerExtensionHostStarter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts index 5794b259061..ef8569f5252 100644 --- a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts +++ b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts @@ -65,8 +65,8 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { }; worker.onerror = (event) => { - console.error(event.error); - this._onDidExit.fire([81, event.error]); + console.error(event.message, event.error); + this._onDidExit.fire([81, event.message || event.error]); }; // keep for cleanup From 81b873bb6e5ac65f78e49e788c1c0b8749028d50 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 16 Aug 2019 09:35:51 +0200 Subject: [PATCH 710/861] make sure to prepend vs/nls --- src/buildfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/buildfile.js b/src/buildfile.js index 43fcfa807c3..27928e946eb 100644 --- a/src/buildfile.js +++ b/src/buildfile.js @@ -26,7 +26,7 @@ exports.serviceWorker = [{ exports.workerExtensionHost = [{ name: 'vs/workbench/services/extensions/worker/extensionHostWorker', // include: [], - prepend: ['vs/loader.js'], + prepend: ['vs/loader.js', 'vs/nls.js'], append: ['vs/workbench/services/extensions/worker/extensionHostWorkerMain'], dest: 'vs/workbench/services/extensions/worker/extensionHostWorkerMain.js' }]; From bd9d98bb41b10bea4f5d8cc331e193b07e01bdaf Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 16 Aug 2019 10:50:21 +0200 Subject: [PATCH 711/861] :lipstick: --- src/vs/code/electron-main/app.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 159eb32b49c..c17c592775f 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -167,11 +167,13 @@ export class CodeApplication extends Disposable { event.preventDefault(); }); app.on('remote-get-current-web-contents', event => { - // The driver needs access to web contents - if (!this.environmentService.args.driver) { - this.logService.trace(`App#on(remote-get-current-web-contents): prevented`); - event.preventDefault(); + if (this.environmentService.args.driver) { + return; // the driver needs access to web contents } + + this.logService.trace(`App#on(remote-get-current-web-contents): prevented`); + + event.preventDefault(); }); app.on('web-contents-created', (_event: Electron.Event, contents) => { contents.on('will-attach-webview', (event: Electron.Event, webPreferences, params) => { From 92399b7867e4503806b916db357fd7a0451dbf8d Mon Sep 17 00:00:00 2001 From: weijiaxun Date: Fri, 16 Aug 2019 17:19:45 +0800 Subject: [PATCH 712/861] fix: keep the two "Copy Path" behavior consistent When using remote, this "Copy Path" function of SearchAction will keep the remote prefix while the FileCommand will not. Change-Id: Ide00d2da5a695d0adbe87622643c7a600dd46432 --- .../contrib/search/browser/searchActions.ts | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/contrib/search/browser/searchActions.ts b/src/vs/workbench/contrib/search/browser/searchActions.ts index ca96a4cd1ee..9eac783512a 100644 --- a/src/vs/workbench/contrib/search/browser/searchActions.ts +++ b/src/vs/workbench/contrib/search/browser/searchActions.ts @@ -7,14 +7,11 @@ import * as DOM from 'vs/base/browser/dom'; import { Action } from 'vs/base/common/actions'; import { INavigator } from 'vs/base/common/iterator'; import { createKeybinding, ResolvedKeybinding } from 'vs/base/common/keyCodes'; -import { normalizeDriveLetter } from 'vs/base/common/labels'; -import { Schemas } from 'vs/base/common/network'; -import { normalize } from 'vs/base/common/path'; import { isWindows, OS } from 'vs/base/common/platform'; import { repeat } from 'vs/base/common/strings'; -import { URI } from 'vs/base/common/uri'; import * as nls from 'vs/nls'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; +import { ILabelService } from 'vs/platform/label/common/label'; import { ICommandHandler } from 'vs/platform/commands/common/commands'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; @@ -667,14 +664,11 @@ export class ReplaceAction extends AbstractSearchAndReplaceAction { } } -function uriToClipboardString(resource: URI): string { - return resource.scheme === Schemas.file ? normalize(normalizeDriveLetter(resource.fsPath)) : resource.toString(); -} - export const copyPathCommand: ICommandHandler = async (accessor, fileMatch: FileMatch | FolderMatch) => { const clipboardService = accessor.get(IClipboardService); + const labelService = accessor.get(ILabelService); - const text = uriToClipboardString(fileMatch.resource); + const text = labelService.getUriLabel(fileMatch.resource, { noPrefix: true }); await clipboardService.writeText(text); }; @@ -706,25 +700,26 @@ function matchToString(match: Match, indent = 0): string { } const lineDelimiter = isWindows ? '\r\n' : '\n'; -function fileMatchToString(fileMatch: FileMatch, maxMatches: number): { text: string, count: number } { +function fileMatchToString(fileMatch: FileMatch, maxMatches: number, labelService: ILabelService): { text: string, count: number } { const matchTextRows = fileMatch.matches() .sort(searchMatchComparer) .slice(0, maxMatches) .map(match => matchToString(match, 2)); + const uriString = labelService.getUriLabel(fileMatch.resource, { noPrefix: true }); return { - text: `${uriToClipboardString(fileMatch.resource)}${lineDelimiter}${matchTextRows.join(lineDelimiter)}`, + text: `${uriString}${lineDelimiter}${matchTextRows.join(lineDelimiter)}`, count: matchTextRows.length }; } -function folderMatchToString(folderMatch: FolderMatch | BaseFolderMatch, maxMatches: number): { text: string, count: number } { +function folderMatchToString(folderMatch: FolderMatch | BaseFolderMatch, maxMatches: number, labelService: ILabelService): { text: string, count: number } { const fileResults: string[] = []; let numMatches = 0; const matches = folderMatch.matches().sort(searchMatchComparer); for (let i = 0; i < folderMatch.fileCount() && numMatches < maxMatches; i++) { - const fileResult = fileMatchToString(matches[i], maxMatches - numMatches); + const fileResult = fileMatchToString(matches[i], maxMatches - numMatches, labelService); numMatches += fileResult.count; fileResults.push(fileResult.text); } @@ -738,14 +733,15 @@ function folderMatchToString(folderMatch: FolderMatch | BaseFolderMatch, maxMatc const maxClipboardMatches = 1e4; export const copyMatchCommand: ICommandHandler = async (accessor, match: RenderableMatch) => { const clipboardService = accessor.get(IClipboardService); + const labelService = accessor.get(ILabelService); let text: string | undefined; if (match instanceof Match) { text = matchToString(match); } else if (match instanceof FileMatch) { - text = fileMatchToString(match, maxClipboardMatches).text; + text = fileMatchToString(match, maxClipboardMatches, labelService).text; } else if (match instanceof BaseFolderMatch) { - text = folderMatchToString(match, maxClipboardMatches).text; + text = folderMatchToString(match, maxClipboardMatches, labelService).text; } if (text) { @@ -753,12 +749,12 @@ export const copyMatchCommand: ICommandHandler = async (accessor, match: Rendera } }; -function allFolderMatchesToString(folderMatches: Array, maxMatches: number): string { +function allFolderMatchesToString(folderMatches: Array, maxMatches: number, labelService: ILabelService): string { const folderResults: string[] = []; let numMatches = 0; folderMatches = folderMatches.sort(searchMatchComparer); for (let i = 0; i < folderMatches.length && numMatches < maxMatches; i++) { - const folderResult = folderMatchToString(folderMatches[i], maxMatches - numMatches); + const folderResult = folderMatchToString(folderMatches[i], maxMatches - numMatches, labelService); if (folderResult.count) { numMatches += folderResult.count; folderResults.push(folderResult.text); @@ -772,12 +768,13 @@ export const copyAllCommand: ICommandHandler = async (accessor) => { const viewletService = accessor.get(IViewletService); const panelService = accessor.get(IPanelService); const clipboardService = accessor.get(IClipboardService); + const labelService = accessor.get(ILabelService); const searchView = getSearchView(viewletService, panelService); if (searchView) { const root = searchView.searchResult; - const text = allFolderMatchesToString(root.folderMatches(), maxClipboardMatches); + const text = allFolderMatchesToString(root.folderMatches(), maxClipboardMatches, labelService); await clipboardService.writeText(text); } }; From 1c6e25b87e05a8429c986c59431be77467af9449 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Fri, 16 Aug 2019 11:20:09 +0200 Subject: [PATCH 713/861] Load Octicons through ts instead of css import --- src/vs/base/browser/ui/octiconLabel/octiconLabel.ts | 2 ++ src/vs/base/browser/ui/octiconLabel/octicons/octicons-main.css | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/vs/base/browser/ui/octiconLabel/octiconLabel.ts b/src/vs/base/browser/ui/octiconLabel/octiconLabel.ts index 70c4a9e8cd2..75b3ba027dd 100644 --- a/src/vs/base/browser/ui/octiconLabel/octiconLabel.ts +++ b/src/vs/base/browser/ui/octiconLabel/octiconLabel.ts @@ -3,6 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import 'vs/css!./octicons/octicons'; +import 'vs/css!./octicons/octicons2'; import 'vs/css!./octicons/octicons-main'; import 'vs/css!./octicons/octicons-animations'; import { escape } from 'vs/base/common/strings'; diff --git a/src/vs/base/browser/ui/octiconLabel/octicons/octicons-main.css b/src/vs/base/browser/ui/octiconLabel/octicons/octicons-main.css index d06eca484d1..8a387b335ba 100644 --- a/src/vs/base/browser/ui/octiconLabel/octicons/octicons-main.css +++ b/src/vs/base/browser/ui/octiconLabel/octicons/octicons-main.css @@ -1,6 +1,3 @@ -@import 'octicons.css'; -@import 'octicons2.css'; - body[data-octicons-update="enabled"] { --version: octicons2; } From c9c42e4f7f37992d9e178a007a097ae9d319e9ec Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 16 Aug 2019 11:21:00 +0200 Subject: [PATCH 714/861] update distro --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index ee393d1aaf3..f8a973d504e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "13f407368a517ace39c2721a66a951ba4eebce20", + "distro": "32d06dfa691431ba32bbe11ac39ab4b30663b342", "author": { "name": "Microsoft Corporation" }, @@ -159,4 +159,4 @@ "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} +} \ No newline at end of file From 73f852d270893e4208577de5b352076338a87083 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 16 Aug 2019 11:22:25 +0200 Subject: [PATCH 715/861] Fixes #79166 --- src/vs/editor/contrib/zoneWidget/zoneWidget.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/contrib/zoneWidget/zoneWidget.ts b/src/vs/editor/contrib/zoneWidget/zoneWidget.ts index 3e0fe0a7d66..703706bf238 100644 --- a/src/vs/editor/contrib/zoneWidget/zoneWidget.ts +++ b/src/vs/editor/contrib/zoneWidget/zoneWidget.ts @@ -192,9 +192,6 @@ export abstract class ZoneWidget implements IHorizontalSashLayoutProvider { } public dispose(): void { - - this._disposables.dispose(); - if (this._overlayWidget) { this.editor.removeOverlayWidget(this._overlayWidget); this._overlayWidget = null; @@ -211,6 +208,8 @@ export abstract class ZoneWidget implements IHorizontalSashLayoutProvider { this.editor.deltaDecorations(this._positionMarkerId, []); this._positionMarkerId = []; + + this._disposables.dispose(); } public create(): void { From 5352ba33be8dde00a0cb1354711174ee5c1fcf0d Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 16 Aug 2019 12:10:43 +0200 Subject: [PATCH 716/861] web - synchronise global state changes --- .../storage/browser/storageService.ts | 159 +++++++++++++++--- src/vs/platform/storage/common/storage.ts | 74 -------- .../storage.test.ts | 10 +- 3 files changed, 143 insertions(+), 100 deletions(-) rename src/vs/platform/storage/test/{node => electron-browser}/storage.test.ts (92%) diff --git a/src/vs/platform/storage/browser/storageService.ts b/src/vs/platform/storage/browser/storageService.ts index a11505e32ac..cec2d7dc9c7 100644 --- a/src/vs/platform/storage/browser/storageService.ts +++ b/src/vs/platform/storage/browser/storageService.ts @@ -5,15 +5,17 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { Event, Emitter } from 'vs/base/common/event'; -import { IWorkspaceStorageChangeEvent, IStorageService, StorageScope, IWillSaveStateEvent, WillSaveStateReason, logStorage, FileStorageDatabase } from 'vs/platform/storage/common/storage'; +import { IWorkspaceStorageChangeEvent, IStorageService, StorageScope, IWillSaveStateEvent, WillSaveStateReason, logStorage } from 'vs/platform/storage/common/storage'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IWorkspaceInitializationPayload } from 'vs/platform/workspaces/common/workspaces'; import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; -import { IFileService } from 'vs/platform/files/common/files'; -import { IStorage, Storage } from 'vs/base/parts/storage/common/storage'; +import { IFileService, FileChangeType } from 'vs/platform/files/common/files'; +import { IStorage, Storage, IStorageDatabase, IStorageItemsChangeEvent, IUpdateRequest } from 'vs/base/parts/storage/common/storage'; import { URI } from 'vs/base/common/uri'; import { joinPath } from 'vs/base/common/resources'; -import { runWhenIdle } from 'vs/base/common/async'; +import { runWhenIdle, RunOnceScheduler } from 'vs/base/common/async'; +import { serializableToMap, mapToSerializable } from 'vs/base/common/map'; +import { VSBuffer } from 'vs/base/common/buffer'; export class BrowserStorageService extends Disposable implements IStorageService { @@ -35,6 +37,7 @@ export class BrowserStorageService extends Disposable implements IStorageService private workspaceStorageFile: URI; private initializePromise: Promise; + private periodicSaveScheduler = this._register(new RunOnceScheduler(() => this.saveState(), 5000)); get hasPendingUpdate(): boolean { return this.globalStorageDatabase.hasPendingUpdate || this.workspaceStorageDatabase.hasPendingUpdate; @@ -51,20 +54,23 @@ export class BrowserStorageService extends Disposable implements IStorageService // long running operation. // Instead, periodically ask customers to save save. The library will be clever enough // to only save state that has actually changed. - this.saveStatePeriodically(); + this.periodicSaveScheduler.schedule(); } - private saveStatePeriodically(): void { - setTimeout(() => { - runWhenIdle(() => { + private saveState(): void { + runWhenIdle(() => { - // this event will potentially cause new state to be stored + // this event will potentially cause new state to be stored + // since new state will only be created while the document + // has focus, one optimization is to not run this when the + // document has no focus, assuming that state has not changed + if (document.hasFocus()) { this._onWillSaveState.fire({ reason: WillSaveStateReason.NONE }); + } - // repeat - this.saveStatePeriodically(); - }); - }, 5000); + // repeat + this.periodicSaveScheduler.schedule(); + }); } initialize(payload: IWorkspaceInitializationPayload): Promise { @@ -83,14 +89,14 @@ export class BrowserStorageService extends Disposable implements IStorageService // Workspace Storage this.workspaceStorageFile = joinPath(stateRoot, `${payload.id}.json`); - this.workspaceStorageDatabase = this._register(new FileStorageDatabase(this.workspaceStorageFile, this.fileService)); - this.workspaceStorage = new Storage(this.workspaceStorageDatabase); + this.workspaceStorageDatabase = this._register(new FileStorageDatabase(this.workspaceStorageFile, false /* do not watch for external changes */, this.fileService)); + this.workspaceStorage = this._register(new Storage(this.workspaceStorageDatabase)); this._register(this.workspaceStorage.onDidChangeStorage(key => this._onDidChangeStorage.fire({ key, scope: StorageScope.WORKSPACE }))); // Global Storage this.globalStorageFile = joinPath(stateRoot, 'global.json'); - this.globalStorageDatabase = this._register(new FileStorageDatabase(this.globalStorageFile, this.fileService)); - this.globalStorage = new Storage(this.globalStorageDatabase); + this.globalStorageDatabase = this._register(new FileStorageDatabase(this.globalStorageFile, true /* watch for external changes */, this.fileService)); + this.globalStorage = this._register(new Storage(this.globalStorageDatabase)); this._register(this.globalStorage.onDidChangeStorage(key => this._onDidChangeStorage.fire({ key, scope: StorageScope.GLOBAL }))); // Init both @@ -140,14 +146,125 @@ export class BrowserStorageService extends Disposable implements IStorageService } close(): void { - - // Signal as event so that clients can still store data - this._onWillSaveState.fire({ reason: WillSaveStateReason.SHUTDOWN }); - // We explicitly do not close our DBs because writing data onBeforeUnload() // can result in unexpected results. Namely, it seems that - even though this // operation is async - sometimes it is being triggered on unload and // succeeds. Often though, the DBs turn out to be empty because the write // never had a chance to complete. + // + // Instead we trigger dispose() to ensure that no timeouts or callbacks + // get triggered in this phase. + this.dispose(); + } +} + +export class FileStorageDatabase extends Disposable implements IStorageDatabase { + + private readonly _onDidChangeItemsExternal: Emitter = this._register(new Emitter()); + readonly onDidChangeItemsExternal: Event = this._onDidChangeItemsExternal.event; + + private cache: Map | undefined; + + private pendingUpdate: Promise = Promise.resolve(); + + private _hasPendingUpdate = false; + get hasPendingUpdate(): boolean { + return this._hasPendingUpdate; + } + + private isWatching = false; + + constructor( + private readonly file: URI, + private readonly watchForExternalChanges: boolean, + @IFileService private readonly fileService: IFileService + ) { + super(); + } + + private async ensureWatching(): Promise { + if (this.isWatching || !this.watchForExternalChanges) { + return; + } + + const exists = await this.fileService.exists(this.file); + if (this.isWatching || !exists) { + return; // file must exist to be watched + } + + this.isWatching = true; + + this._register(this.fileService.watch(this.file)); + this._register(this.fileService.onFileChanges(e => { + if (document.hasFocus()) { + return; // ignore changes from ourselves by checking for focus + } + + if (!e.contains(this.file, FileChangeType.UPDATED)) { + return; // not our file + } + + this.onDidStorageChangeExternal(); + })); + } + + private async onDidStorageChangeExternal(): Promise { + const items = await this.doGetItemsFromFile(); + + this.cache = items; + + this._onDidChangeItemsExternal.fire({ items }); + } + + async getItems(): Promise> { + if (!this.cache) { + try { + this.cache = await this.doGetItemsFromFile(); + } catch (error) { + this.cache = new Map(); + } + } + + return this.cache; + } + + private async doGetItemsFromFile(): Promise> { + await this.pendingUpdate; + + const itemsRaw = await this.fileService.readFile(this.file); + + this.ensureWatching(); // now that the file must exist, ensure we watch it for changes + + return serializableToMap(JSON.parse(itemsRaw.value.toString())); + } + + async updateItems(request: IUpdateRequest): Promise { + const items = await this.getItems(); + + if (request.insert) { + request.insert.forEach((value, key) => items.set(key, value)); + } + + if (request.delete) { + request.delete.forEach(key => items.delete(key)); + } + + await this.pendingUpdate; + + this._hasPendingUpdate = true; + + this.pendingUpdate = this.fileService.writeFile(this.file, VSBuffer.fromString(JSON.stringify(mapToSerializable(items)))) + .then(() => { + this.ensureWatching(); // now that the file must exist, ensure we watch it for changes + }) + .finally(() => { + this._hasPendingUpdate = false; + }); + + return this.pendingUpdate; + } + + close(): Promise { + return this.pendingUpdate; } } diff --git a/src/vs/platform/storage/common/storage.ts b/src/vs/platform/storage/common/storage.ts index 46fdd613d11..8860535a54a 100644 --- a/src/vs/platform/storage/common/storage.ts +++ b/src/vs/platform/storage/common/storage.ts @@ -7,11 +7,6 @@ import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/co import { Event, Emitter } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; import { isUndefinedOrNull } from 'vs/base/common/types'; -import { IUpdateRequest, IStorageDatabase } from 'vs/base/parts/storage/common/storage'; -import { serializableToMap, mapToSerializable } from 'vs/base/common/map'; -import { VSBuffer } from 'vs/base/common/buffer'; -import { URI } from 'vs/base/common/uri'; -import { IFileService } from 'vs/platform/files/common/files'; export const IStorageService = createDecorator('storageService'); @@ -212,75 +207,6 @@ export class InMemoryStorageService extends Disposable implements IStorageServic } } -export class FileStorageDatabase extends Disposable implements IStorageDatabase { - - readonly onDidChangeItemsExternal = Event.None; // TODO@Ben implement global UI storage events - - private cache: Map | undefined; - - private pendingUpdate: Promise = Promise.resolve(); - - private _hasPendingUpdate = false; - get hasPendingUpdate(): boolean { - return this._hasPendingUpdate; - } - - constructor( - private readonly file: URI, - private readonly fileService: IFileService - ) { - super(); - } - - async getItems(): Promise> { - if (!this.cache) { - try { - this.cache = await this.doGetItemsFromFile(); - } catch (error) { - this.cache = new Map(); - } - } - - return this.cache; - } - - private async doGetItemsFromFile(): Promise> { - await this.pendingUpdate; - - const itemsRaw = await this.fileService.readFile(this.file); - - return serializableToMap(JSON.parse(itemsRaw.value.toString())); - } - - async updateItems(request: IUpdateRequest): Promise { - const items = await this.getItems(); - - if (request.insert) { - request.insert.forEach((value, key) => items.set(key, value)); - } - - if (request.delete) { - request.delete.forEach(key => items.delete(key)); - } - - await this.pendingUpdate; - - this._hasPendingUpdate = true; - - this.pendingUpdate = this.fileService.writeFile(this.file, VSBuffer.fromString(JSON.stringify(mapToSerializable(items)))) - .then(() => undefined) - .finally(() => { - this._hasPendingUpdate = false; - }); - - return this.pendingUpdate; - } - - close(): Promise { - return this.pendingUpdate; - } -} - export async function logStorage(global: Map, workspace: Map, globalPath: string, workspacePath: string): Promise { const safeParse = (value: string) => { try { diff --git a/src/vs/platform/storage/test/node/storage.test.ts b/src/vs/platform/storage/test/electron-browser/storage.test.ts similarity index 92% rename from src/vs/platform/storage/test/node/storage.test.ts rename to src/vs/platform/storage/test/electron-browser/storage.test.ts index 7c77b9e1c08..4e5e10a4e13 100644 --- a/src/vs/platform/storage/test/node/storage.test.ts +++ b/src/vs/platform/storage/test/electron-browser/storage.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { equal } from 'assert'; -import { FileStorageDatabase } from 'vs/platform/storage/common/storage'; +import { FileStorageDatabase } from 'vs/platform/storage/browser/storageService'; import { generateUuid } from 'vs/base/common/uuid'; import { join } from 'vs/base/common/path'; import { tmpdir } from 'os'; @@ -49,7 +49,7 @@ suite('Storage', () => { }); test('File Based Storage', async () => { - let storage = new Storage(new FileStorageDatabase(URI.file(join(testDir, 'storage.json')), fileService)); + let storage = new Storage(new FileStorageDatabase(URI.file(join(testDir, 'storage.json')), false, fileService)); await storage.init(); @@ -63,7 +63,7 @@ suite('Storage', () => { await storage.close(); - storage = new Storage(new FileStorageDatabase(URI.file(join(testDir, 'storage.json')), fileService)); + storage = new Storage(new FileStorageDatabase(URI.file(join(testDir, 'storage.json')), false, fileService)); await storage.init(); @@ -81,7 +81,7 @@ suite('Storage', () => { await storage.close(); - storage = new Storage(new FileStorageDatabase(URI.file(join(testDir, 'storage.json')), fileService)); + storage = new Storage(new FileStorageDatabase(URI.file(join(testDir, 'storage.json')), false, fileService)); await storage.init(); @@ -89,4 +89,4 @@ suite('Storage', () => { equal(storage.get('barNumber', 'undefinedNumber'), 'undefinedNumber'); equal(storage.get('barBoolean', 'undefinedBoolean'), 'undefinedBoolean'); }); -}); \ No newline at end of file +}); From b8974b05a62c83fd92deb787162cf507e10bfd46 Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 16 Aug 2019 12:26:32 +0200 Subject: [PATCH 717/861] explorer input black magic fixes #78153 --- .../files/browser/views/explorerViewer.ts | 50 ++++++++----------- 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 75aae73d144..d8d9f52f320 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -218,56 +218,46 @@ export class FilesRenderer implements ITreeRenderer 0 && !stat.isDirectory ? lastDot : value.length }); - let isFinishableDisposeEvent = false; - setTimeout(() => { - // Check if disposed - if (!inputBox.inputElement) { - return; - } - inputBox.focus(); - inputBox.select({ start: 0, end: lastDot > 0 && !stat.isDirectory ? lastDot : value.length }); - isFinishableDisposeEvent = true; - }, 0); - - const done = once(async (success: boolean) => { + const done = once(async (success: boolean, blur: boolean) => { label.element.style.display = 'none'; const value = inputBox.value; dispose(toDispose); - label.element.remove(); - // Timeout: once done rendering only then re-render #70902 - setTimeout(() => editableData.onFinish(value, success), 0); + container.removeChild(label.element); + editableData.onFinish(value, success); }); - const blurDisposable = DOM.addDisposableListener(inputBox.inputElement, DOM.EventType.BLUR, () => { - done(inputBox.isInputValid()); - }); + // It can happen that the tree re-renders this node. When that happens, + // we're gonna get a blur event first and only after an element disposable. + // Because of that, we should setTimeout the blur handler to differentiate + // between the blur happening because of a unrender or because of a user action. + let ignoreBlur = false; const toDispose = [ inputBox, DOM.addStandardDisposableListener(inputBox.inputElement, DOM.EventType.KEY_DOWN, (e: IKeyboardEvent) => { if (e.equals(KeyCode.Enter)) { if (inputBox.validate()) { - done(true); + done(true, false); } } else if (e.equals(KeyCode.Escape)) { - done(false); + done(false, false); } }), - blurDisposable, + DOM.addDisposableListener(inputBox.inputElement, DOM.EventType.BLUR, () => { + setTimeout(() => { + if (!ignoreBlur) { + done(inputBox.isInputValid(), true); + } + }, 0); + }), label, styler ]; - return toDisposable(() => { - if (isFinishableDisposeEvent) { - done(false); - } - else { - dispose(toDispose); - label.element.remove(); - } - }); + return toDisposable(() => ignoreBlur = true); } disposeElement?(element: ITreeNode, index: number, templateData: IFileTemplateData): void { From 4f9f4c3c13ce178e65e2cf5dc8deedbe647b1f2e Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 16 Aug 2019 15:27:59 +0200 Subject: [PATCH 718/861] fix #72417 --- .../notification/common/notification.ts | 19 ++++++ .../contrib/files/browser/saveErrorHandler.ts | 23 +++---- .../browser/localizations.contribution.ts | 14 ++-- .../electron-browser/workspaceStatsService.ts | 20 ++---- .../terminal/browser/terminalConfigHelper.ts | 19 ++---- .../contrib/update/electron-browser/update.ts | 68 ++++--------------- .../services/files/common/workspaceWatcher.ts | 32 ++++----- .../common/notificationService.ts | 12 ++-- 8 files changed, 73 insertions(+), 134 deletions(-) diff --git a/src/vs/platform/notification/common/notification.ts b/src/vs/platform/notification/common/notification.ts index 2582047934e..23b14135edb 100644 --- a/src/vs/platform/notification/common/notification.ts +++ b/src/vs/platform/notification/common/notification.ts @@ -37,6 +37,19 @@ export interface INotificationProperties { neverShowAgain?: INeverShowAgainOptions; } +export enum NeverShowAgainScope { + + /** + * Will never show this notification on the current workspace again. + */ + WORKSPACE, + + /** + * Will never show this notification on any workspace again. + */ + GLOBAL +} + export interface INeverShowAgainOptions { /** @@ -49,6 +62,12 @@ export interface INeverShowAgainOptions { * make it a secondary action instead. */ isSecondary?: boolean; + + /** + * Wether to persist the choice in the current workspace or for all workspaces. By + * default it will be persisted for all workspaces. + */ + scope?: NeverShowAgainScope; } export interface INotification extends INotificationProperties { diff --git a/src/vs/workbench/contrib/files/browser/saveErrorHandler.ts b/src/vs/workbench/contrib/files/browser/saveErrorHandler.ts index ac09186d046..608638b5178 100644 --- a/src/vs/workbench/contrib/files/browser/saveErrorHandler.ts +++ b/src/vs/workbench/contrib/files/browser/saveErrorHandler.ts @@ -236,7 +236,6 @@ class ResolveSaveConflictAction extends Action { @IEditorService private readonly editorService: IEditorService, @INotificationService private readonly notificationService: INotificationService, @IInstantiationService private readonly instantiationService: IInstantiationService, - @IStorageService private readonly storageService: IStorageService, @IEnvironmentService private readonly environmentService: IEnvironmentService ) { super('workbench.files.action.resolveConflict', nls.localize('compareChanges', "Compare")); @@ -250,21 +249,15 @@ class ResolveSaveConflictAction extends Action { await TextFileContentProvider.open(resource, CONFLICT_RESOLUTION_SCHEME, editorLabel, this.editorService, { pinned: true }); - if (this.storageService.getBoolean(LEARN_MORE_DIRTY_WRITE_IGNORE_KEY, StorageScope.GLOBAL)) { - return; // return if this message is ignored - } - // Show additional help how to resolve the save conflict - const primaryActions: IAction[] = [ - this.instantiationService.createInstance(ResolveConflictLearnMoreAction) - ]; - const secondaryActions: IAction[] = [ - this.instantiationService.createInstance(DoNotShowResolveConflictLearnMoreAction) - ]; - - const actions: INotificationActions = { primary: primaryActions, secondary: secondaryActions }; - const handle = this.notificationService.notify({ severity: Severity.Info, message: conflictEditorHelp, actions }); - Event.once(handle.onDidClose)(() => { dispose(primaryActions); dispose(secondaryActions); }); + const actions: INotificationActions = { primary: [this.instantiationService.createInstance(ResolveConflictLearnMoreAction)] }; + const handle = this.notificationService.notify({ + severity: Severity.Info, + message: conflictEditorHelp, + actions, + neverShowAgain: { id: LEARN_MORE_DIRTY_WRITE_IGNORE_KEY, isSecondary: true } + }); + Event.once(handle.onDidClose)(() => dispose(actions.primary!)); pendingResolveSaveConflictMessages.push(handle); } diff --git a/src/vs/workbench/contrib/localizations/browser/localizations.contribution.ts b/src/vs/workbench/contrib/localizations/browser/localizations.contribution.ts index 0ab7785ff31..1982d8aebc0 100644 --- a/src/vs/workbench/contrib/localizations/browser/localizations.contribution.ts +++ b/src/vs/workbench/contrib/localizations/browser/localizations.contribution.ts @@ -68,8 +68,7 @@ export class LocalizationWorkbenchContribution extends Disposable implements IWo } private onDidInstallExtension(e: DidInstallExtensionEvent): void { - const donotAskUpdateKey = 'langugage.update.donotask'; - if (!this.storageService.getBoolean(donotAskUpdateKey, StorageScope.GLOBAL) && e.local && e.operation === InstallOperation.Install && e.local.manifest.contributes && e.local.manifest.contributes.localizations && e.local.manifest.contributes.localizations.length) { + if (e.local && e.operation === InstallOperation.Install && e.local.manifest.contributes && e.local.manifest.contributes.localizations && e.local.manifest.contributes.localizations.length) { const locale = e.local.manifest.contributes.localizations[0].languageId; if (platform.language !== locale) { const updateAndRestart = platform.locale !== locale; @@ -83,12 +82,11 @@ export class LocalizationWorkbenchContribution extends Disposable implements IWo const updatePromise = updateAndRestart ? this.jsonEditingService.write(this.environmentService.localeResource, { key: 'locale', value: locale }, true) : Promise.resolve(undefined); updatePromise.then(() => this.windowsService.relaunch({}), e => this.notificationService.error(e)); } - }, { - label: localize('neverAgain', "Don't Show Again"), - isSecondary: true, - run: () => this.storageService.store(donotAskUpdateKey, true, StorageScope.GLOBAL) }], - { sticky: true } + { + sticky: true, + neverShowAgain: { id: 'langugage.update.donotask', isSecondary: true } + } ); } } @@ -302,4 +300,4 @@ ExtensionsRegistry.registerExtensionPoint({ } } } -}); \ No newline at end of file +}); diff --git a/src/vs/workbench/contrib/stats/electron-browser/workspaceStatsService.ts b/src/vs/workbench/contrib/stats/electron-browser/workspaceStatsService.ts index 9c1c1d57180..2cb249cba47 100644 --- a/src/vs/workbench/contrib/stats/electron-browser/workspaceStatsService.ts +++ b/src/vs/workbench/contrib/stats/electron-browser/workspaceStatsService.ts @@ -8,9 +8,8 @@ import { IFileService, IResolveFileResult, IFileStat } from 'vs/platform/files/c import { IWorkspaceContextService, WorkbenchState, IWorkspace } from 'vs/platform/workspace/common/workspace'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IWindowService, IWindowConfiguration } from 'vs/platform/windows/common/windows'; -import { INotificationService, IPromptChoice } from 'vs/platform/notification/common/notification'; +import { INotificationService, NeverShowAgainScope, INeverShowAgainOptions } from 'vs/platform/notification/common/notification'; import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; -import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { ITextFileService, ITextFileContent } from 'vs/workbench/services/textfile/common/textfiles'; import { URI } from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; @@ -22,8 +21,6 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IWorkspaceStatsService, Tags } from 'vs/workbench/contrib/stats/common/workspaceStats'; import { getHashedRemotesFromConfig } from 'vs/workbench/contrib/stats/electron-browser/workspaceStats'; -const DISABLE_WORKSPACE_PROMPT_KEY = 'workspaces.dontPromptToOpen'; - const ModulesToLookFor = [ // Packages that suggest a node server 'express', @@ -103,7 +100,6 @@ export class WorkspaceStatsService implements IWorkspaceStatsService { @IWindowService private readonly windowService: IWindowService, @INotificationService private readonly notificationService: INotificationService, @IQuickInputService private readonly quickInputService: IQuickInputService, - @IStorageService private readonly storageService: IStorageService, @ITextFileService private readonly textFileService: ITextFileService ) { } @@ -449,15 +445,7 @@ export class WorkspaceStatsService implements IWorkspaceStatsService { } private doHandleWorkspaceFiles(folder: URI, workspaces: string[]): void { - if (this.storageService.getBoolean(DISABLE_WORKSPACE_PROMPT_KEY, StorageScope.WORKSPACE)) { - return; // prompt disabled by user - } - - const doNotShowAgain: IPromptChoice = { - label: localize('never again', "Don't Show Again"), - isSecondary: true, - run: () => this.storageService.store(DISABLE_WORKSPACE_PROMPT_KEY, true, StorageScope.WORKSPACE) - }; + const neverShowAgain: INeverShowAgainOptions = { id: 'workspaces.dontPromptToOpen', scope: NeverShowAgainScope.WORKSPACE, isSecondary: true }; // Prompt to open one workspace if (workspaces.length === 1) { @@ -466,7 +454,7 @@ export class WorkspaceStatsService implements IWorkspaceStatsService { this.notificationService.prompt(Severity.Info, localize('workspaceFound', "This folder contains a workspace file '{0}'. Do you want to open it? [Learn more]({1}) about workspace files.", workspaceFile, 'https://go.microsoft.com/fwlink/?linkid=2025315'), [{ label: localize('openWorkspace', "Open Workspace"), run: () => this.windowService.openWindow([{ workspaceUri: joinPath(folder, workspaceFile) }]) - }, doNotShowAgain]); + }], { neverShowAgain }); } // Prompt to select a workspace from many @@ -482,7 +470,7 @@ export class WorkspaceStatsService implements IWorkspaceStatsService { } }); } - }, doNotShowAgain]); + }], { neverShowAgain }); } } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts b/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts index 7d7aafdb6b3..e4a307e4059 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts @@ -11,7 +11,7 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag import { ITerminalConfiguration, ITerminalFont, IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, TERMINAL_CONFIG_SECTION, DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, MINIMUM_LETTER_SPACING, LinuxDistro, IShellLaunchConfig } from 'vs/workbench/contrib/terminal/common/terminal'; import Severity from 'vs/base/common/severity'; import { Terminal as XTermTerminal } from 'xterm'; -import { INotificationService } from 'vs/platform/notification/common/notification'; +import { INotificationService, NeverShowAgainScope } from 'vs/platform/notification/common/notification'; import { IBrowserTerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminal'; import { Emitter, Event } from 'vs/base/common/event'; import { basename } from 'vs/base/common/path'; @@ -254,7 +254,6 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper { return r; } - private readonly NO_RECOMMENDATIONS_KEY = 'terminalConfigHelper/launchRecommendationsIgnore'; private recommendationsShown = false; public async showRecommendations(shellLaunchConfig: IShellLaunchConfig): Promise { @@ -264,10 +263,6 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper { this.recommendationsShown = true; if (platform.isWindows && shellLaunchConfig.executable && basename(shellLaunchConfig.executable).toLowerCase() === 'wsl.exe') { - if (this._storageService.getBoolean(this.NO_RECOMMENDATIONS_KEY, StorageScope.WORKSPACE, false)) { - return; - } - if (! await this.isExtensionInstalled('ms-vscode-remote.remote-wsl')) { this._notificationService.prompt( Severity.Info, @@ -276,16 +271,10 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper { "Check out the 'Visual Studio Code Remote - WSL' extension for a great development experience in WSL. Click [here]({0}) to learn more.", 'https://go.microsoft.com/fwlink/?linkid=2097212' ), - [ - { - label: nls.localize('doNotShowAgain', "Don't Show Again"), - run: () => { - this._storageService.store(this.NO_RECOMMENDATIONS_KEY, true, StorageScope.WORKSPACE); - } - } - ], + [], { - sticky: true + sticky: true, + neverShowAgain: { id: 'terminalConfigHelper/launchRecommendationsIgnore', scope: NeverShowAgainScope.WORKSPACE } } ); } diff --git a/src/vs/workbench/contrib/update/electron-browser/update.ts b/src/vs/workbench/contrib/update/electron-browser/update.ts index 0d2d53003b7..64d43209612 100644 --- a/src/vs/workbench/contrib/update/electron-browser/update.ts +++ b/src/vs/workbench/contrib/update/electron-browser/update.ts @@ -19,7 +19,7 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag import { IUpdateService, State as UpdateState, StateType, IUpdate } from 'vs/platform/update/common/update'; import * as semver from 'semver-umd'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { INotificationService, INotificationHandle, Severity } from 'vs/platform/notification/common/notification'; +import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { ReleaseNotesManager } from './releaseNotesEditor'; @@ -162,32 +162,8 @@ export class ProductContribution implements IWorkbenchContribution { } } -class NeverShowAgain { - - private readonly key: string; - - readonly action = new Action(`neverShowAgain:${this.key}`, nls.localize('neveragain', "Don't Show Again"), undefined, true, (notification: INotificationHandle) => { - - // Hide notification - notification.close(); - - this.storageService.store(this.key, true, StorageScope.GLOBAL); - - return Promise.resolve(true); - }); - - constructor(key: string, @IStorageService private readonly storageService: IStorageService) { - this.key = `neverShowAgain:${key}`; - } - - shouldShow(): boolean { - return !this.storageService.getBoolean(this.key, StorageScope.GLOBAL, false); - } -} - export class Win3264BitContribution implements IWorkbenchContribution { - private static readonly KEY = 'update/win32-64bits'; private static readonly URL = 'https://code.visualstudio.com/updates/v1_15#_windows-64-bit'; private static readonly INSIDER_URL = 'https://github.com/Microsoft/vscode-docs/blob/vnext/release-notes/v1_15.md#windows-64-bit'; @@ -200,28 +176,18 @@ export class Win3264BitContribution implements IWorkbenchContribution { return; } - const neverShowAgain = new NeverShowAgain(Win3264BitContribution.KEY, storageService); - - if (!neverShowAgain.shouldShow()) { - return; - } - const url = product.quality === 'insider' ? Win3264BitContribution.INSIDER_URL : Win3264BitContribution.URL; - const handle = notificationService.prompt( + notificationService.prompt( severity.Info, nls.localize('64bitisavailable', "{0} for 64-bit Windows is now available! Click [here]({1}) to learn more.", product.nameShort, url), - [{ - label: nls.localize('neveragain', "Don't Show Again"), - isSecondary: true, - run: () => { - neverShowAgain.action.run(handle); - neverShowAgain.action.dispose(); - } - }], - { sticky: true } + [], + { + sticky: true, + neverShowAgain: { id: 'neverShowAgain:update/win32-64bits', isSecondary: true } + } ); } } @@ -396,23 +362,13 @@ export class UpdateContribution extends Disposable implements IWorkbenchContribu } // windows fast updates (target === system) - const neverShowAgain = new NeverShowAgain('update/win32-fast-updates', this.storageService); - - if (!neverShowAgain.shouldShow()) { - return; - } - - const handle = this.notificationService.prompt( + this.notificationService.prompt( severity.Info, nls.localize('updateInstalling', "{0} {1} is being installed in the background; we'll let you know when it's done.", product.nameLong, update.productVersion), - [{ - label: nls.localize('neveragain', "Don't Show Again"), - isSecondary: true, - run: () => { - neverShowAgain.action.run(handle); - neverShowAgain.action.dispose(); - } - }] + [], + { + neverShowAgain: { id: 'neverShowAgain:update/win32-fast-updates', isSecondary: true } + } ); } diff --git a/src/vs/workbench/services/files/common/workspaceWatcher.ts b/src/vs/workbench/services/files/common/workspaceWatcher.ts index 7aa7ef157f6..46badeabf80 100644 --- a/src/vs/workbench/services/files/common/workspaceWatcher.ts +++ b/src/vs/workbench/services/files/common/workspaceWatcher.ts @@ -13,8 +13,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { ResourceMap } from 'vs/base/common/map'; import { onUnexpectedError } from 'vs/base/common/errors'; -import { StorageScope, IStorageService } from 'vs/platform/storage/common/storage'; -import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; +import { INotificationService, Severity, NeverShowAgainScope } from 'vs/platform/notification/common/notification'; import { localize } from 'vs/nls'; import { FileService } from 'vs/platform/files/common/fileService'; @@ -26,8 +25,7 @@ export class WorkspaceWatcher extends Disposable { @IFileService private readonly fileService: FileService, @IConfigurationService private readonly configurationService: IConfigurationService, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, - @INotificationService private readonly notificationService: INotificationService, - @IStorageService private readonly storageService: IStorageService + @INotificationService private readonly notificationService: INotificationService ) { super(); @@ -73,38 +71,34 @@ export class WorkspaceWatcher extends Disposable { onUnexpectedError(msg); // Detect if we run < .NET Framework 4.5 - if (msg.indexOf('System.MissingMethodException') >= 0 && !this.storageService.getBoolean('ignoreNetVersionError', StorageScope.WORKSPACE)) { + if (msg.indexOf('System.MissingMethodException') >= 0) { this.notificationService.prompt( Severity.Warning, localize('netVersionError', "The Microsoft .NET Framework 4.5 is required. Please follow the link to install it."), [{ label: localize('installNet', "Download .NET Framework 4.5"), run: () => window.open('https://go.microsoft.com/fwlink/?LinkId=786533') - }, - { - label: localize('neverShowAgain', "Don't Show Again"), - isSecondary: true, - run: () => this.storageService.store('ignoreNetVersionError', true, StorageScope.WORKSPACE) }], - { sticky: true } + { + sticky: true, + neverShowAgain: { id: 'ignoreNetVersionError', isSecondary: true, scope: NeverShowAgainScope.WORKSPACE } + } ); } // Detect if we run into ENOSPC issues - if (msg.indexOf('ENOSPC') >= 0 && !this.storageService.getBoolean('ignoreEnospcError', StorageScope.WORKSPACE)) { + if (msg.indexOf('ENOSPC') >= 0) { this.notificationService.prompt( Severity.Warning, localize('enospcError', "Unable to watch for file changes in this large workspace. Please follow the instructions link to resolve this issue."), [{ label: localize('learnMore', "Instructions"), run: () => window.open('https://go.microsoft.com/fwlink/?linkid=867693') - }, - { - label: localize('neverShowAgain', "Don't Show Again"), - isSecondary: true, - run: () => this.storageService.store('ignoreEnospcError', true, StorageScope.WORKSPACE) }], - { sticky: true } + { + sticky: true, + neverShowAgain: { id: 'ignoreEnospcError', isSecondary: true, scope: NeverShowAgainScope.WORKSPACE } + } ); } } @@ -157,4 +151,4 @@ export class WorkspaceWatcher extends Disposable { } } -Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(WorkspaceWatcher, LifecyclePhase.Restored); \ No newline at end of file +Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(WorkspaceWatcher, LifecyclePhase.Restored); diff --git a/src/vs/workbench/services/notification/common/notificationService.ts b/src/vs/workbench/services/notification/common/notificationService.ts index 81ba282a7c3..e701a079c29 100644 --- a/src/vs/workbench/services/notification/common/notificationService.ts +++ b/src/vs/workbench/services/notification/common/notificationService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; -import { INotificationService, INotification, INotificationHandle, Severity, NotificationMessage, INotificationActions, IPromptChoice, IPromptOptions, IStatusMessageOptions, NoOpNotification } from 'vs/platform/notification/common/notification'; +import { INotificationService, INotification, INotificationHandle, Severity, NotificationMessage, INotificationActions, IPromptChoice, IPromptOptions, IStatusMessageOptions, NoOpNotification, NeverShowAgainScope } from 'vs/platform/notification/common/notification'; import { INotificationsModel, NotificationsModel, ChoiceAction } from 'vs/workbench/common/notifications'; import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; import { Event } from 'vs/base/common/event'; @@ -63,11 +63,12 @@ export class NotificationService extends Disposable implements INotificationServ // Handle neverShowAgain option accordingly let handle: INotificationHandle; if (notification.neverShowAgain) { + const scope = notification.neverShowAgain.scope === NeverShowAgainScope.WORKSPACE ? StorageScope.WORKSPACE : StorageScope.GLOBAL; // If the user already picked to not show the notification // again, we return with a no-op notification here const id = notification.neverShowAgain.id; - if (this.storageService.getBoolean(id, StorageScope.GLOBAL)) { + if (this.storageService.getBoolean(id, scope)) { return new NoOpNotification(); } @@ -80,7 +81,7 @@ export class NotificationService extends Disposable implements INotificationServ handle.close(); // Remember choice - this.storageService.store(id, true, StorageScope.GLOBAL); + this.storageService.store(id, true, scope); return Promise.resolve(); })); @@ -110,17 +111,18 @@ export class NotificationService extends Disposable implements INotificationServ // Handle neverShowAgain option accordingly if (options && options.neverShowAgain) { + const scope = options.neverShowAgain.scope === NeverShowAgainScope.WORKSPACE ? StorageScope.WORKSPACE : StorageScope.GLOBAL; // If the user already picked to not show the notification // again, we return with a no-op notification here const id = options.neverShowAgain.id; - if (this.storageService.getBoolean(id, StorageScope.GLOBAL)) { + if (this.storageService.getBoolean(id, scope)) { return new NoOpNotification(); } const neverShowAgainChoice = { label: nls.localize('neverShowAgain', "Don't Show Again"), - run: () => this.storageService.store(id, true, StorageScope.GLOBAL), + run: () => this.storageService.store(id, true, scope), isSecondary: options.neverShowAgain.isSecondary }; From 329f2fe76b86f244ca310dc77464fa623ead3baa Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 16 Aug 2019 06:39:38 -0700 Subject: [PATCH 719/861] Fix smoke tests --- test/smoke/src/vscode/puppeteerDriver.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/smoke/src/vscode/puppeteerDriver.ts b/test/smoke/src/vscode/puppeteerDriver.ts index 6b1f51d8ce8..955460f9d0a 100644 --- a/test/smoke/src/vscode/puppeteerDriver.ts +++ b/test/smoke/src/vscode/puppeteerDriver.ts @@ -95,6 +95,7 @@ export async function launch(_args: string[]): Promise { await promisify(mkdir)(webUserDataDir); server = spawn(join(args[0], `resources/server/web.${process.platform === 'win32' ? 'bat' : 'sh'}`), ['--browser', 'none', '--driver', 'web', '--web-user-data-dir', webUserDataDir]); server.stderr.on('data', e => console.log('Server stderr: ' + e)); + server.stdout.on('data', e => console.log('Server stdout: ' + e)); process.on('exit', teardown); process.on('SIGINT', teardown); endpoint = await waitForEndpoint(); @@ -129,8 +130,7 @@ export function connect(headless: boolean, outPath: string, handle: string): Pro }); const page = (await browser.pages())[0]; await page.setViewport({ width, height }); - const endpointSplit = endpoint!.split('#'); - await page.goto(`${endpointSplit[0]}?folder=${args![1]}#${endpointSplit[1]}`); + await page.goto(`${endpoint}&folder=${args![1]}`); const result = { client: { dispose: () => teardown }, driver: buildDriver(browser, page) From db8368395f65b584eec79e74e8d4a47aa0c60349 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 16 Aug 2019 06:41:28 -0700 Subject: [PATCH 720/861] Revert "build - disable smoketest" This reverts commit c23cacdc97b54e6056400599dad329cabc7facfb. --- .../darwin/product-build-darwin.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index 5718cfa56bd..175e3d0eb08 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -107,15 +107,15 @@ steps: displayName: Run integration tests condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) -# - script: | -# set -e -# cd test/smoke -# yarn compile -# cd - -# yarn smoketest --web --headless -# continueOnError: true -# displayName: Run smoke tests -# condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) +- script: | + set -e + cd test/smoke + yarn compile + cd - + yarn smoketest --web --headless + continueOnError: true + displayName: Run smoke tests + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - script: | set -e From f411f6672c51126a55a3948ede98593467b38c46 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 16 Aug 2019 07:24:16 -0700 Subject: [PATCH 721/861] Scope new variable to a string --- .../terminal/common/terminalEnvironment.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index 9d6215af30c..ab99f2cf048 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -208,33 +208,33 @@ export function getDefaultShell( if (!maybeExecutable) { maybeExecutable = getShellSetting(fetchSetting, isWorkspaceShellAllowed, 'shell', platformOverride); } - maybeExecutable = maybeExecutable || defaultShell; + let executable: string = maybeExecutable || defaultShell; // Change Sysnative to System32 if the OS is Windows but NOT WoW64. It's // safe to assume that this was used by accident as Sysnative does not // exist and will break the terminal in non-WoW64 environments. if ((platformOverride === platform.Platform.Windows) && !isWoW64 && windir) { const sysnativePath = path.join(windir, 'Sysnative').replace(/\//g, '\\').toLowerCase(); - if (maybeExecutable && maybeExecutable.toLowerCase().indexOf(sysnativePath) === 0) { - maybeExecutable = path.join(windir, 'System32', maybeExecutable.substr(sysnativePath.length + 1)); + if (executable && executable.toLowerCase().indexOf(sysnativePath) === 0) { + executable = path.join(windir, 'System32', executable.substr(sysnativePath.length + 1)); } } // Convert / to \ on Windows for convenience - if (maybeExecutable && platformOverride === platform.Platform.Windows) { - maybeExecutable = maybeExecutable.replace(/\//g, '\\'); + if (executable && platformOverride === platform.Platform.Windows) { + executable = executable.replace(/\//g, '\\'); } if (configurationResolverService) { try { - maybeExecutable = configurationResolverService.resolve(lastActiveWorkspace, maybeExecutable); + executable = configurationResolverService.resolve(lastActiveWorkspace, executable); } catch (e) { logService.error(`Could not resolve shell`, e); - maybeExecutable = maybeExecutable; + executable = executable; } } - return maybeExecutable; + return executable; } export function getDefaultShellArgs( From 90b64a2f17ff19da19906b3fd422d7a8c8d4a1fd Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 16 Aug 2019 07:27:40 -0700 Subject: [PATCH 722/861] Fallback to default when cwd var cannot be resolved Fixes #79281 --- .../terminal/common/terminalEnvironment.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index ab99f2cf048..e6936280a46 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -144,18 +144,20 @@ export function getCwd( try { customCwd = configurationResolverService.resolve(lastActiveWorkspace, customCwd); } catch (e) { - // There was an issue resolving a variable, just use the unresolved customCwd which - // which will fail, and log the error in the console. + // There was an issue resolving a variable, log the error in the console and + // fallback to the default. if (logService) { logService.error('Could not resolve terminal.integrated.cwd', e); } - return customCwd; + customCwd = undefined; } } - if (path.isAbsolute(customCwd)) { - cwd = customCwd; - } else if (root) { - cwd = path.join(root.fsPath, customCwd); + if (customCwd) { + if (path.isAbsolute(customCwd)) { + cwd = customCwd; + } else if (root) { + cwd = path.join(root.fsPath, customCwd); + } } } From 5f593c7a797acb59449de8b38281aa461340fbb5 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 16 Aug 2019 11:53:56 +0200 Subject: [PATCH 723/861] fix error when dismissing snippets picker --- src/vs/workbench/contrib/snippets/browser/insertSnippet.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/snippets/browser/insertSnippet.ts b/src/vs/workbench/contrib/snippets/browser/insertSnippet.ts index 5c84fba2775..e15578264ec 100644 --- a/src/vs/workbench/contrib/snippets/browser/insertSnippet.ts +++ b/src/vs/workbench/contrib/snippets/browser/insertSnippet.ts @@ -168,13 +168,14 @@ class InsertSnippetAction extends EditorAction { return quickInputService.pick(picks, { matchOnDetail: true }).then(pick => resolve(pick && pick.snippet), reject); } }).then(async snippet => { + if (!snippet) { + return; + } let clipboardText: string | undefined; if (snippet.needsClipboard) { clipboardText = await clipboardService.readText(); } - if (snippet) { - SnippetController2.get(editor).insert(snippet.codeSnippet, { clipboardText }); - } + SnippetController2.get(editor).insert(snippet.codeSnippet, { clipboardText }); }); } } From dc5fdf7b625311d12bf81bd676e368ad725b2041 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 16 Aug 2019 16:03:36 +0200 Subject: [PATCH 724/861] add fetch file system provider --- src/vs/base/common/errors.ts | 10 +++ .../browser/webWorkerFileSystemProvider.ts | 62 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 src/vs/workbench/services/extensions/browser/webWorkerFileSystemProvider.ts diff --git a/src/vs/base/common/errors.ts b/src/vs/base/common/errors.ts index da6f814332f..b8077dd5376 100644 --- a/src/vs/base/common/errors.ts +++ b/src/vs/base/common/errors.ts @@ -194,3 +194,13 @@ export function getErrorMessage(err: any): string { return String(err); } + + +export class NotImplementedError extends Error { + constructor(message?: string) { + super('NotImplemented'); + if (message) { + this.message = message; + } + } +} diff --git a/src/vs/workbench/services/extensions/browser/webWorkerFileSystemProvider.ts b/src/vs/workbench/services/extensions/browser/webWorkerFileSystemProvider.ts new file mode 100644 index 00000000000..13afbbcce1f --- /dev/null +++ b/src/vs/workbench/services/extensions/browser/webWorkerFileSystemProvider.ts @@ -0,0 +1,62 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IFileSystemProvider, FileSystemProviderCapabilities, IStat, FileType, FileDeleteOptions, FileOverwriteOptions, FileWriteOptions, FileSystemProviderError, FileSystemProviderErrorCode } from 'vs/platform/files/common/files'; + +import { Event } from 'vs/base/common/event'; +import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; +import { URI } from 'vs/base/common/uri'; +import { NotImplementedError } from 'vs/base/common/errors'; + +export class FetchFileSystemProvider implements IFileSystemProvider { + + readonly capabilities = FileSystemProviderCapabilities.Readonly + FileSystemProviderCapabilities.FileReadWrite + FileSystemProviderCapabilities.PathCaseSensitive; + readonly onDidChangeCapabilities = Event.None; + readonly onDidChangeFile = Event.None; + + // working implementations + async readFile(resource: URI): Promise { + try { + const res = await fetch(resource.toString(true)); + if (res.status === 200) { + return new Uint8Array(await res.arrayBuffer()); + } + throw new FileSystemProviderError(res.statusText, FileSystemProviderErrorCode.Unknown); + } catch (err) { + throw new FileSystemProviderError(err, FileSystemProviderErrorCode.Unknown); + } + } + + // fake implementations + async stat(_resource: URI): Promise { + return { + type: FileType.File, + size: 0, + mtime: 0, + ctime: 0 + }; + } + + watch(): IDisposable { + return Disposable.None; + } + + // error implementations + writeFile(_resource: URI, _content: Uint8Array, _opts: FileWriteOptions): Promise { + throw new NotImplementedError(); + } + readdir(_resource: URI): Promise<[string, FileType][]> { + throw new NotImplementedError(); + } + mkdir(_resource: URI): Promise { + throw new NotImplementedError(); + } + delete(_resource: URI, _opts: FileDeleteOptions): Promise { + throw new NotImplementedError(); + } + rename(_from: URI, _to: URI, _opts: FileOverwriteOptions): Promise { + throw new NotImplementedError(); + } +} From 811dea422e334fcee3c7459924669c57e8f7335d Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 16 Aug 2019 16:35:19 +0200 Subject: [PATCH 725/861] add IStaticExtensionsService, add `staticExtensions` to embedder API --- src/vs/workbench/browser/web.main.ts | 5 +++ .../extensions/browser/extensionService.ts | 44 +++++++++++++++---- .../extensions/common/staticExtensions.ts | 34 ++++++++++++++ .../electron-browser/extensionService.ts | 23 +++++----- src/vs/workbench/workbench.desktop.main.ts | 2 + src/vs/workbench/workbench.web.api.ts | 6 +++ 6 files changed, 94 insertions(+), 20 deletions(-) create mode 100644 src/vs/workbench/services/extensions/common/staticExtensions.ts diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index 7ee10dddb41..e882484c10b 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -41,6 +41,7 @@ import { IStorageService } from 'vs/platform/storage/common/storage'; import { getThemeTypeSelector, DARK, HIGH_CONTRAST, LIGHT } from 'vs/platform/theme/common/themeService'; import { InMemoryUserDataProvider } from 'vs/workbench/services/userData/common/inMemoryUserDataProvider'; import { registerWindowDriver } from 'vs/platform/driver/browser/driver'; +import { StaticExtensionsService, IStaticExtensionsService } from 'vs/workbench/services/extensions/common/staticExtensions'; class CodeRendererMain extends Disposable { @@ -145,6 +146,10 @@ class CodeRendererMain extends Disposable { const fileService = this._register(new FileService(logService)); serviceCollection.set(IFileService, fileService); + // Static Extensions + const staticExtensions = new StaticExtensionsService(this.configuration.staticExtensions || []); + serviceCollection.set(IStaticExtensionsService, staticExtensions); + let userDataProvider: IFileSystemProvider | undefined = this.configuration.userDataProvider; const connection = remoteAgentService.getConnection(); if (connection) { diff --git a/src/vs/workbench/services/extensions/browser/extensionService.ts b/src/vs/workbench/services/extensions/browser/extensionService.ts index 80e9fe37c3f..59e7baf1a17 100644 --- a/src/vs/workbench/services/extensions/browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/browser/extensionService.ts @@ -22,10 +22,16 @@ import { WebWorkerExtensionHostStarter } from 'vs/workbench/services/extensions/ import { URI } from 'vs/base/common/uri'; import { isWebExtension } from 'vs/workbench/services/extensions/common/extensionsUtil'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { FetchFileSystemProvider } from 'vs/workbench/services/extensions/browser/webWorkerFileSystemProvider'; +import { Schemas } from 'vs/base/common/network'; +import { DisposableStore } from 'vs/base/common/lifecycle'; +import { IStaticExtensionsService } from 'vs/workbench/services/extensions/common/staticExtensions'; export class ExtensionService extends AbstractExtensionService implements IExtensionService { - private _remoteExtensionsEnvironmentData: IRemoteAgentEnvironment | null; + private _disposables = new DisposableStore(); + private _remoteExtensionsEnvironmentData: IRemoteAgentEnvironment | null = null; constructor( @IInstantiationService instantiationService: IInstantiationService, @@ -37,6 +43,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten @IProductService productService: IProductService, @IRemoteAgentService private readonly _remoteAgentService: IRemoteAgentService, @IConfigurationService private readonly _configService: IConfigurationService, + @IStaticExtensionsService private readonly _staticExtensions: IStaticExtensionsService, ) { super( instantiationService, @@ -48,8 +55,19 @@ export class ExtensionService extends AbstractExtensionService implements IExten productService, ); - this._remoteExtensionsEnvironmentData = null; this._initialize(); + this._initFetchFileSystem(); + } + + dispose(): void { + this._disposables.dispose(); + super.dispose(); + } + + private _initFetchFileSystem(): void { + const provider = new FetchFileSystemProvider(); + this._disposables.add(this._fileService.registerProvider(Schemas.http, provider)); + this._disposables.add(this._fileService.registerProvider(Schemas.https, provider)); } private _createProvider(remoteAuthority: string): IInitDataProvider { @@ -84,23 +102,31 @@ export class ExtensionService extends AbstractExtensionService implements IExten protected async _scanAndHandleExtensions(): Promise { // fetch the remote environment - const remoteEnv = (await this._remoteAgentService.getEnvironment())!; + let [remoteEnv, localExtensions] = await Promise.all([ + >this._remoteAgentService.getEnvironment(), + this._staticExtensions.getExtensions() + ]); - // enable or disable proposed API per extension + // local: only enabled and web'ish extension + localExtensions = localExtensions.filter(ext => this._isEnabled(ext) && isWebExtension(ext, this._configService)); + this._checkEnableProposedApi(localExtensions); + + // remote: only enabled and none-web'ish extension + remoteEnv.extensions = remoteEnv.extensions.filter(extension => this._isEnabled(extension) && !isWebExtension(extension, this._configService)); this._checkEnableProposedApi(remoteEnv.extensions); - // remove disabled extensions - remoteEnv.extensions = remoteEnv.extensions.filter(extension => this._isEnabled(extension)); + // in case of overlap, the remote wins + const isRemoteExtension = new Set(); + remoteEnv.extensions.forEach(extension => isRemoteExtension.add(ExtensionIdentifier.toKey(extension.identifier))); + localExtensions = localExtensions.filter(extension => !isRemoteExtension.has(ExtensionIdentifier.toKey(extension.identifier))); // save for remote extension's init data this._remoteExtensionsEnvironmentData = remoteEnv; - // this._handleExtensionPoints(([]).concat(remoteEnv.extensions).concat(localExtensions)); - const result = this._registry.deltaExtensions(remoteEnv.extensions, []); + const result = this._registry.deltaExtensions(remoteEnv.extensions.concat(localExtensions), []); if (result.removedDueToLooping.length > 0) { this._logOrShowMessage(Severity.Error, nls.localize('looping', "The following extensions contain dependency loops and have been disabled: {0}", result.removedDueToLooping.map(e => `'${e.identifier.value}'`).join(', '))); } - this._doHandleExtensionPoints(this._registry.getAllExtensionDescriptions()); } diff --git a/src/vs/workbench/services/extensions/common/staticExtensions.ts b/src/vs/workbench/services/extensions/common/staticExtensions.ts new file mode 100644 index 00000000000..06f102534d1 --- /dev/null +++ b/src/vs/workbench/services/extensions/common/staticExtensions.ts @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { IExtensionDescription, IExtensionManifest, ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { UriComponents, URI } from 'vs/base/common/uri'; + +export const IStaticExtensionsService = createDecorator('IStaticExtensionsService'); + +export interface IStaticExtensionsService { + _serviceBrand: any; + getExtensions(): Promise; +} + +export class StaticExtensionsService implements IStaticExtensionsService { + + _serviceBrand: any; + + private readonly _descriptions: IExtensionDescription[] = []; + + constructor(staticExtensions: { packageJSON: IExtensionManifest, extensionLocation: UriComponents }[]) { + this._descriptions = staticExtensions.map(data => { + identifier: new ExtensionIdentifier(`${data.packageJSON.publisher}.${data.packageJSON.name}`), + extensionLocation: URI.revive(data.extensionLocation), + ...data.packageJSON, + }); + } + + async getExtensions(): Promise { + return this._descriptions; + } +} diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index 272f399268f..b8c267ab590 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -34,6 +34,8 @@ import { IFileService } from 'vs/platform/files/common/files'; import { PersistentConnectionEventType } from 'vs/platform/remote/common/remoteAgentConnection'; import { IProductService } from 'vs/platform/product/common/product'; import { Logger } from 'vs/workbench/services/extensions/common/extensionPoints'; +import { flatten } from 'vs/base/common/arrays'; +import { IStaticExtensionsService } from 'vs/workbench/services/extensions/common/staticExtensions'; class DeltaExtensionsQueueItem { constructor( @@ -64,6 +66,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten @IConfigurationService private readonly _configurationService: IConfigurationService, @ILifecycleService private readonly _lifecycleService: ILifecycleService, @IWindowService protected readonly _windowService: IWindowService, + @IStaticExtensionsService private readonly _staticExtensions: IStaticExtensionsService, ) { super( instantiationService, @@ -72,7 +75,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten telemetryService, extensionEnablementService, fileService, - productService, + productService ); if (this._extensionEnablementService.allUserExtensionsDisabled) { @@ -432,7 +435,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten const remoteAuthority = this._environmentService.configuration.remoteAuthority; const extensionHost = this._extensionHostProcessManagers[0]; - let localExtensions = await this._extensionScanner.scannedExtensions; + let localExtensions = flatten(await Promise.all([this._extensionScanner.scannedExtensions, this._staticExtensions.getExtensions()])); // enable or disable proposed API per extension this._checkEnableProposedApi(localExtensions); @@ -458,7 +461,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten this._remoteAuthorityResolverService.setResolvedAuthorityError(remoteAuthority, err); // Proceed with the local extension host - await this._startLocalExtensionHost(extensionHost, localExtensions); + await this._startLocalExtensionHost(extensionHost, localExtensions, localExtensions.map(extension => extension.identifier)); return; } @@ -503,20 +506,18 @@ export class ExtensionService extends AbstractExtensionService implements IExten // save for remote extension's init data this._remoteExtensionsEnvironmentData.set(remoteAuthority, remoteEnv); - this._handleExtensionPoints(([]).concat(remoteEnv.extensions).concat(localExtensions)); - extensionHost.start(localExtensions.map(extension => extension.identifier)); - + await this._startLocalExtensionHost(extensionHost, remoteEnv.extensions.concat(localExtensions), localExtensions.map(extension => extension.identifier)); } else { - await this._startLocalExtensionHost(extensionHost, localExtensions); + await this._startLocalExtensionHost(extensionHost, localExtensions, localExtensions.map(extension => extension.identifier)); } } - private async _startLocalExtensionHost(extensionHost: ExtensionHostProcessManager, localExtensions: IExtensionDescription[]): Promise { - this._handleExtensionPoints(localExtensions); - extensionHost.start(localExtensions.map(extension => extension.identifier).filter(id => this._registry.containsExtension(id))); + private async _startLocalExtensionHost(extensionHost: ExtensionHostProcessManager, allExtensions: IExtensionDescription[], localExtensions: ExtensionIdentifier[]): Promise { + this._registerAndHandleExtensions(allExtensions); + extensionHost.start(localExtensions.filter(id => this._registry.containsExtension(id))); } - private _handleExtensionPoints(allExtensions: IExtensionDescription[]): void { + private _registerAndHandleExtensions(allExtensions: IExtensionDescription[]): void { const result = this._registry.deltaExtensions(allExtensions, []); if (result.removedDueToLooping.length > 0) { this._logOrShowMessage(Severity.Error, nls.localize('looping', "The following extensions contain dependency loops and have been disabled: {0}", result.removedDueToLooping.map(e => `'${e.identifier.value}'`).join(', '))); diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index 90f3e4c63d1..04981fd3a82 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -73,6 +73,7 @@ import { IMenubarService } from 'vs/platform/menubar/common/menubar'; import { MenubarService } from 'vs/platform/menubar/electron-browser/menubarService'; import { IURLService } from 'vs/platform/url/common/url'; import { RelayURLService } from 'vs/platform/url/electron-browser/urlService'; +import { StaticExtensionsService, IStaticExtensionsService } from 'vs/workbench/services/extensions/common/staticExtensions'; registerSingleton(IClipboardService, ClipboardService, true); registerSingleton(IRequestService, RequestService, true); @@ -85,6 +86,7 @@ registerSingleton(IIssueService, IssueService); registerSingleton(IWorkspacesService, WorkspacesService); registerSingleton(IMenubarService, MenubarService); registerSingleton(IURLService, RelayURLService); +registerSingleton(IStaticExtensionsService, class extends StaticExtensionsService { constructor() { super([]); } }); //#endregion diff --git a/src/vs/workbench/workbench.web.api.ts b/src/vs/workbench/workbench.web.api.ts index 2727fa5eb5d..69c2fa84a65 100644 --- a/src/vs/workbench/workbench.web.api.ts +++ b/src/vs/workbench/workbench.web.api.ts @@ -9,6 +9,7 @@ import { UriComponents } from 'vs/base/common/uri'; import { IFileSystemProvider } from 'vs/platform/files/common/files'; import { IWebSocketFactory } from 'vs/platform/remote/browser/browserSocketFactory'; import { ICredentialsProvider } from 'vs/workbench/services/credentials/browser/credentialsService'; +import { IExtensionManifest } from 'vs/platform/extensions/common/extensions'; export interface IWorkbenchConstructionOptions { @@ -59,6 +60,11 @@ export interface IWorkbenchConstructionOptions { * Experimental: The credentials provider to store and retrieve secrets. */ credentialsProvider?: ICredentialsProvider; + + /** + * Experimental: Add static extensions that cannot be uninstalled but only be disabled. + */ + staticExtensions: { packageJSON: IExtensionManifest, extensionLocation: UriComponents }[]; } /** From bcca36044bfaaedeb9182114ed812ca7def4a671 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 16 Aug 2019 16:41:32 +0200 Subject: [PATCH 726/861] make staticExtensions optional --- src/vs/workbench/workbench.web.api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/workbench.web.api.ts b/src/vs/workbench/workbench.web.api.ts index 69c2fa84a65..dd84853e87a 100644 --- a/src/vs/workbench/workbench.web.api.ts +++ b/src/vs/workbench/workbench.web.api.ts @@ -64,7 +64,7 @@ export interface IWorkbenchConstructionOptions { /** * Experimental: Add static extensions that cannot be uninstalled but only be disabled. */ - staticExtensions: { packageJSON: IExtensionManifest, extensionLocation: UriComponents }[]; + staticExtensions?: { packageJSON: IExtensionManifest, extensionLocation: UriComponents }[]; } /** From 2821335cb5aaafde1c4f3bfe337e009e94575e89 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 16 Aug 2019 07:45:07 -0700 Subject: [PATCH 727/861] Indicate web in smoke test step --- build/azure-pipelines/darwin/product-build-darwin.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index 175e3d0eb08..84764519f53 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -114,7 +114,7 @@ steps: cd - yarn smoketest --web --headless continueOnError: true - displayName: Run smoke tests + displayName: Run web smoke tests condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - script: | From a90999e63537a24c7f1d3cce24db490066dd14f5 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Fri, 16 Aug 2019 16:54:15 +0200 Subject: [PATCH 728/861] Update octicon css logic --- src/vs/base/browser/ui/octiconLabel/octicons/octicons-main.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/octiconLabel/octicons/octicons-main.css b/src/vs/base/browser/ui/octiconLabel/octicons/octicons-main.css index 8a387b335ba..841e5e575cd 100644 --- a/src/vs/base/browser/ui/octiconLabel/octicons/octicons-main.css +++ b/src/vs/base/browser/ui/octiconLabel/octicons/octicons-main.css @@ -7,7 +7,7 @@ body { } .octicon, .mega-octicon { - font-family: var(--version); + font-family: var(--version) !important; } body[data-octicons-update="enabled"] .monaco-workbench .part.statusbar > .items-container > .statusbar-item span.octicon { From d71800cbc594b20606b58347e34eecc23aa235cb Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Fri, 16 Aug 2019 16:55:38 +0200 Subject: [PATCH 729/861] Fix Octicon icons on Linux --- .../ui/octiconLabel/octicons/octicons2.css | 4 ++-- .../ui/octiconLabel/octicons/octicons2.svg | 14 +++++++------- .../ui/octiconLabel/octicons/octicons2.ttf | Bin 35152 -> 35276 bytes 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.css b/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.css index 1b262b5defa..6da9003b49a 100644 --- a/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.css +++ b/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.css @@ -1,7 +1,7 @@ @font-face { font-family: "octicons2"; - src: url("./octicons2.ttf?be4194a3b16397b3f3d1c63861eae9a2") format("truetype"), -url("./octicons2.svg?be4194a3b16397b3f3d1c63861eae9a2#octicons2") format("svg"); + src: url("./octicons2.ttf?064476e75412ccad4ae99d4bf24539b4") format("truetype"), +url("./octicons2.svg?064476e75412ccad4ae99d4bf24539b4#octicons2") format("svg"); } .octicon, .mega-octicon { diff --git a/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.svg b/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.svg index f12b9fef301..e7d0d05d458 100644 --- a/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.svg +++ b/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.svg @@ -45,13 +45,13 @@ horiz-adv-x="1000" d=" M868.30625 -27.375L624.99625 444.625V694.625H687.49375V757.125H624.62125V757.5L596.12125 757.1875H312.49625V695H374.99625V448L131.62125 -27.5625C126.889375 -37.0812500000001 124.665625 -47.65625 125.15875 -58.275C125.6525 -68.9 128.8475 -79.21875 134.44125 -88.25625C140.035625 -97.2999999999999 147.84375 -104.7625 157.1275 -109.95C166.41125 -115.13125 176.86375 -117.8562499999999 187.49625 -117.875H812.49375C823.1500000000001 -117.8625000000001 833.61875 -115.13125 842.91875 -109.93125C852.21875 -104.7374999999999 860.0375 -97.25 865.6312499999999 -88.1812500000001C871.21875 -79.1124999999999 874.4 -68.7687499999999 874.86875 -58.125C875.3375 -47.4875 873.0812500000001 -36.9 868.30625 -27.375zM430.8087500000001 419.5L437.49625 432.9375V692.75L562.49625 694.25V444.5625V429.4375L569.4337499999999 416L683.55625 194.625H315.55875L430.8087500000001 419.5zM187.49625 -56.0625L283.80875 132.125H715.99375L812.68125 -55.375L187.49625 -56.0625z" /> + horiz-adv-x="1000" d=" M837.5 157.5C818.75 207.5018750000001 812.5 257.5018750000001 812.5 307.501875V432.501875C812.5 513.751875 787.5 588.751875 731.25 645.0018749999999C681.25 707.501875 606.25 745.001875 531.25 751.251875C487.5 757.5019374999999 443.75 757.5019374999999 400 738.751875C356.25 720.001875 318.75 707.501875 287.5 676.2518749999999C256.25 645.0018749999999 231.25 613.7518749999999 212.5 570.001875C193.75 532.5018749999999 187.5 488.751875 187.5 445.001875V307.501875C187.5 257.5018750000001 175 207.5018750000001 162.5 157.5L125 51.25L156.25 7.5H375C375 -23.75 387.5 -55 412.5 -80C431.25 -105 462.5 -117.5 500 -117.5C537.5 -117.5 562.5 -105 587.5 -80C612.5 -55 625 -23.75 625 7.5H843.75L875 51.25L837.5 157.5zM543.75 -36.25C531.25 -48.75 512.5 -55 500 -55C487.5 -55 468.75 -48.75 456.25 -36.25C443.75 -23.75 437.5 -11.25 437.5 7.5H500H562.5C562.5 -11.25 556.25 -23.75 543.75 -36.25zM587.5 70H562.5H437.5H412.5H200L225 138.75C237.5 195.0018750000001 250 251.251875 250 307.501875V445.001875C250 482.501875 256.25 513.751875 268.75 545.001875C281.25 576.2518749999999 306.25 607.5018749999999 331.25 626.251875C356.25 651.251875 387.5 670.0018749999999 418.75 676.2518749999999C456.25 695.001875 487.5 695.001875 525 695.001875C587.5 688.751875 643.75 657.501875 687.5 607.5018749999999C731.25 557.5018749999999 750 495.001875 750 432.501875V307.501875C750 251.251875 756.25 195.0018750000001 775 138.75L800 70H587.5V70z" /> + horiz-adv-x="1000" d=" M906.25 695H562.5L537.5 688.75L500 645L462.5 688.75L437.5 695H93.75L62.5 663.75V38.75L93.75 7.5H425L481.25 -48.75H525L575 7.5H906.25L937.5 38.75V663.75L906.25 695zM456.25 63.75L437.5 70H125V632.5H425L468.75 588.75V51.25L456.25 63.75zM875 70H562.5L537.5 63.75L531.25 57.5V588.75L575 632.5H875V70zM375 507.5H187.5V445H375V507.5zM375 382.5H187.5V320H375V382.5zM187.5 257.5H375V195H187.5V257.5zM812.5 507.5H625V445H812.5V507.5zM625 382.5H812.5V320H625V382.5zM625 257.5H812.5V195H625V257.5z" /> @@ -162,22 +162,22 @@ horiz-adv-x="1000" d=" M93.75 757.5H906.25L937.5 726.25V-86.25L906.25 -117.5H93.75L62.5 -86.25V726.25L93.75 757.5zM125 -55H875V695H125V-55zM250 257.5H437.5V70L750 320L437.5 570V382.5H250V257.5z" /> + horiz-adv-x="1000" d=" M125 601.25L156.25 632.5H468.75L500 601.25V38.75L468.75 7.5H156.25L125 38.75V601.25zM187.5 70H437.5V445H187.5V70zM187.5 507.5H437.5V570H187.5V507.5zM593.75 632.5H906.25L937.5 601.25V38.75L906.25 7.5H593.75L562.5 38.75V601.25L593.75 632.5zM625 70H875V195H625V70zM625 320H875V570H625V320z" /> + horiz-adv-x="1000" d=" M537.5 757.5009375C637.5 751.250625 731.25 701.250625 800 632.500625C881.25 545.000625 925 438.750625 925 313.750625C925 213.750625 887.5 120 825 38.75C762.5 -36.25 675 -92.5 575 -111.25C475 -130 375 -117.5 287.5 -67.5C200 -17.5 131.25 57.5 93.75 151.25C56.2498125 245.000625 49.9998125 351.250625 81.25 445.000625C112.5 545.000625 168.75 626.250625 256.25 682.500625C337.5 738.750625 437.5 763.7509375 537.5 757.5009375zM568.75 -48.75C650 -30 725 13.75 781.25 82.5C831.25 151.25 862.5 232.5006249999999 856.25 320.000625C856.25 420.000625 818.75 520.000625 750 588.750625C687.5 651.250625 612.5 688.750625 525 695.000625C443.75 701.250625 356.25 682.500625 287.5 632.500625C218.75 582.500625 168.75 513.750625 143.75 426.250625C118.75 345.000625 118.75 257.500625 156.25 176.25C193.75 95 250 32.5 325 -11.25C400 -55 487.5 -67.5 568.75 -48.75zM493.749375 351.25L643.75 507.5L687.5 463.75L537.499375 307.5L687.5 151.25L643.75 107.5L493.749375 263.75L343.7493750000001 107.5L299.999375 151.25L449.999375 307.5L299.999375 463.75L343.7493750000001 507.5L493.749375 351.25z" /> + horiz-adv-x="1000" d=" M500 695C406.25 695 325 670 256.25 620L306.25 576.25C362.5 613.75 425 632.5 500 632.5C706.25 632.5 875 463.75 875 257.5H937.5C937.5 501.25 743.75 695 500 695zM62.5 632.496875L162.5 538.746875C100 463.746875 62.5 363.7468750000001 62.5 257.4968750000001H125C125 351.246875 156.25 432.496875 212.5 494.996875L350 369.996875C325 338.746875 312.5 301.246875 312.5 257.4968750000001C312.5 151.25 393.75 70 500 70C550 70 593.75 88.75 625 120L812.5 -55L856.25 -11.25L106.25 676.246875L62.5 632.496875zM393.75 326.246875L575 157.5C556.25 145 531.25 132.5 500 132.5C431.25 132.5 375 188.75 375 257.4968750000001C375 282.4968750000001 381.25 307.4968750000001 393.75 326.246875zM687.5 226.25L625 282.5C612.5 332.5 568.75 376.25 512.5 382.5L450 438.75C468.75 445 481.25 445 500 445C606.25 445 687.5 363.75 687.5 257.5V226.25z" /> + horiz-adv-x="1000" d=" M62.5 195C62.5 438.75 256.25 632.5 500 632.5C743.75 632.5 937.5 438.75 937.5 195H875C875 401.25 706.25 570 500 570C293.75 570 125 401.25 125 195H62.5zM312.5 195C312.5 301.25 393.75 382.5 500 382.5C606.25 382.5 687.5 301.25 687.5 195C687.5 88.75 606.25 7.5 500 7.5C393.75 7.5 312.5 88.75 312.5 195zM375 195C375 126.25 431.25 70 500 70C568.75 70 625 126.25 625 195C625 263.75 568.75 320 500 320C431.25 320 375 263.75 375 195z" /> @@ -186,7 +186,7 @@ horiz-adv-x="1000" d=" M660.625 748.75L865.625 542.5L875 520V-86.25L843.75 -117.5H156.25L125 -86.25V726.25L156.25 757.5H638.75L660.625 748.75zM625 507.5H812.5L625 695V507.5zM187.5 695V-55H812.5V445H593.75L562.5 476.25V695H187.5zM316.375 224.1875L429.9375 338.4375L385.625 382.5L250 246.3125V202.125L385.6875 66.25L429.875 110.4375L316.375 224.1875zM550 337.875L593.75 382.1875L730.5625 246.25V201.9375L593.75 66.125L549.6875 110.4375L664.125 224.1875L550 337.875z" /> + horiz-adv-x="1000" d=" M906.25 632.5H481.25L431.25 688.75L406.25 695H93.75L62.5 663.75V413.75V-23.75L93.75 -55H906.25L937.5 -23.75V257.5V601.25L906.25 632.5zM875 101.25V7.5H125V101.25V351.25V382.5H406.25L431.25 388.75L481.25 445H875V351.25V101.25zM875 507.5H468.75L443.75 501.25L393.75 445H125V632.5H393.75L450 576.25L468.75 570H875V507.5z" /> diff --git a/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.ttf b/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.ttf index 97d221792967c3dc9182078b5514358637c80843..654cfe91291a4b391122cf0b76277f89e8723e80 100644 GIT binary patch delta 1648 zcmXw2Yi!e26u#GqokyFbj*~b}+c{`XjsQT_0@0UD2oY zqxuQlg^PGSz8desCx{F&NZd0lH;fu4jb>w`ai{ULan!WTbjdVj_LzIjXUr4kM`iA^ zWo4aZePt8nMEUOWlNQXf!t#aXUn_6zvc9k_x1F&~RkT(Nkga4ld5XMl&)P>Qj5<#J zS#WeXo;r^^CtbT;y{_NrEPar^L>Jv1?m_q8Oe539OnS;an>?p0U6nnR533SY8>;@Q z?ybJ&6};=bz25WePIic$^fmhS`>t{Xm*Ea_U-1n!*8?EX8R!%ALcOp?7!*c@`#~a@ z3bqDs*E(uPYH!s(4($rvn$x^;&h;=K?hcQJr^HsVPrNKXs*BZi*G)y{My^DP(QNd5 zY-{XL>{{Fv-xWU@pOUQ70%?tORj!eD%3sRg%aihb`9-23F_h$!yOJZxhbi+|E%gsp z*n&L)bs!B|00;>4VIn95BQPi!2pc2}vsSHzHb~137wv^o7E8(sZiRdV1r9>-b4p4{ zp>LHe)FLG%dokKo4IM1hEnytaP@q$-srIuJU*RD=BxPZs0WTNWI}}y0)TKiLb%!lp zFfk6sZpxeeOz|_uqBl||o(e^oDzYZ>*1`%K!zWn=9U@u( z*RBrubHA5%7a(VYQOFrcnxkcfQ%D%(NRB20XrEL#-0zf~=rte@XJ>6k*IWFY5duu{ zEX%^Cv?#$QU(stX-hiSA2Z|GnL4;zl{F|A9?HHdK*hNAV33mDjtEw!vWBROzz+`dy zE=3R+CFXNkWKbIQ#qTyBFQ?R8ZuzHjn+dm7)T}s=%hu1^zmTKg$zgG5 zI6O2I9v%|4PWOc0DUcutVjzpa@di32OC^M|MtT9Kt%%`?ltL4Fx>=HQ8MS@W^sgPUB+S-@4+}8fk_aqtkB6u2(03sq z@G6fQX`Ua-SqkMwGSMPo7n?*iAvLesxMx%Q+ao|B?2G23^@*0a$9+!3&J|Cc zWw^OqXqhUgcv=s&LqUnLKsSQz12m`saR8KrCbtxENJWFe~4p@|eK2#%D6 zi3nW9TVZYj$udIZ65?K698C40PGmsw)Mp=_Qg-`A6?6%e>H#<~fAm7LXN!6F;}^_re*%MQ0id|^dV2MLr>IJo;v1uZjE=^Ty(hg`Z;uK!SPvJl4Jh~3uZe5vh6Qjf|@teL|zeiuy zU)KL(a2whTn+=nOyGGu))_Ac_U-weoiMn}H&UDFaGH)|a)qCpKSv;0@%NEO_2GB6j zaM@b4PL9}E+XZ{kUUjrMIvwwlfGm)&k+V+LxzYKd%jn9vs;=wqkh|o*-MFIhOydI& z<9WZSv#H#)KzXT7Y8RcN`{=6I=xy^J^v-z|U%|JB(FP6$z6$ce?%)+x%~I?}c8ERA z&an?U4|k0FE;JB296A@4!-pe1j>w_Ne6&3}6rJKdd^i6F|0#bz)*hRR{T)9LpG|rdSnEily zdY1}1rOo?SWVd&Pp)z=jY>akom73S)ywF1`#{;P#6gvxpVOK0*wFY9Y$j(CN=n7`< z^AQ|xSwEOnj<4!2j!K&fJ`El#tWWGOcCX620|9r%NN#VrsXB$72laqNunb^91jG@v z3_y?+)4sHY^O<1+`fv*w^jUnQg(LG2-IyysHah#@Nr{)>GhVN9k_?3$$_bi=>y)dI zj~fa)61FI}qVIja9FJy}Lnq5L_6kje!vwwfHl4%7#NvX1AP7w4pUdaa1v5*-H0Kl= zHd_%Ije1x^Ks+kHMda+Fr149l#cvlOV#0l#1%9hsMPJX*xko7A*;-ca!4||eM`L@v zi`Quy6Bd7m!~1ebqP(>a6PFh&=OYIVWz{4)FdGO1sj{x;`G@}kclH3LsTP)tQ{Yzc^cKLI+d?sTP#{}c;C!`zacYg@j`&19fr5d0K2MiUaUC{*qthn$6zc|w|zi5W`y2%eLtw Date: Fri, 16 Aug 2019 17:16:41 +0200 Subject: [PATCH 730/861] debug: introduce data breakpoints --- .../api/browser/mainThreadDebugService.ts | 29 ++++-- .../workbench/api/common/extHost.protocol.ts | 15 +++- src/vs/workbench/api/common/extHostTypes.ts | 18 ++++ .../workbench/api/node/extHostDebugService.ts | 7 +- .../contrib/debug/browser/breakpointsView.ts | 90 +++++++++++++++++-- .../contrib/debug/browser/debugActions.ts | 6 +- .../contrib/debug/browser/debugCommands.ts | 4 +- .../contrib/debug/browser/debugService.ts | 46 +++++++++- .../contrib/debug/browser/debugSession.ts | 30 ++++++- .../contrib/debug/browser/rawDebugSession.ts | 14 +++ .../contrib/debug/browser/variablesView.ts | 24 +++-- .../workbench/contrib/debug/common/debug.ts | 27 +++++- .../contrib/debug/common/debugModel.ts | 71 ++++++++++++++- .../debug/test/browser/debugModel.test.ts | 2 +- .../contrib/debug/test/common/mockDebug.ts | 16 +++- 15 files changed, 356 insertions(+), 43 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadDebugService.ts b/src/vs/workbench/api/browser/mainThreadDebugService.ts index 20572fa7783..2f0f5283bfd 100644 --- a/src/vs/workbench/api/browser/mainThreadDebugService.ts +++ b/src/vs/workbench/api/browser/mainThreadDebugService.ts @@ -5,10 +5,10 @@ import { DisposableStore } from 'vs/base/common/lifecycle'; import { URI as uri } from 'vs/base/common/uri'; -import { IDebugService, IConfig, IDebugConfigurationProvider, IBreakpoint, IFunctionBreakpoint, IBreakpointData, IDebugAdapter, IDebugAdapterDescriptorFactory, IDebugSession, IDebugAdapterFactory } from 'vs/workbench/contrib/debug/common/debug'; +import { IDebugService, IConfig, IDebugConfigurationProvider, IBreakpoint, IFunctionBreakpoint, IBreakpointData, IDebugAdapter, IDebugAdapterDescriptorFactory, IDebugSession, IDebugAdapterFactory, IDataBreakpoint } from 'vs/workbench/contrib/debug/common/debug'; import { ExtHostContext, ExtHostDebugServiceShape, MainThreadDebugServiceShape, DebugSessionUUID, MainContext, - IExtHostContext, IBreakpointsDeltaDto, ISourceMultiBreakpointDto, ISourceBreakpointDto, IFunctionBreakpointDto, IDebugSessionDto + IExtHostContext, IBreakpointsDeltaDto, ISourceMultiBreakpointDto, ISourceBreakpointDto, IFunctionBreakpointDto, IDebugSessionDto, IDataBreakpointDto } from 'vs/workbench/api/common/extHost.protocol'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import severity from 'vs/base/common/severity'; @@ -110,15 +110,16 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb // send all breakpoints const bps = this.debugService.getModel().getBreakpoints(); const fbps = this.debugService.getModel().getFunctionBreakpoints(); + const dbps = this.debugService.getModel().getDataBreakpoints(); if (bps.length > 0 || fbps.length > 0) { this._proxy.$acceptBreakpointsDelta({ - added: this.convertToDto(bps).concat(this.convertToDto(fbps)) + added: this.convertToDto(bps).concat(this.convertToDto(fbps)).concat(this.convertToDto(dbps)) }); } } } - public $registerBreakpoints(DTOs: Array): Promise { + public $registerBreakpoints(DTOs: Array): Promise { for (let dto of DTOs) { if (dto.type === 'sourceMulti') { @@ -136,14 +137,17 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb this.debugService.addBreakpoints(uri.revive(dto.uri), rawbps, 'extension'); } else if (dto.type === 'function') { this.debugService.addFunctionBreakpoint(dto.functionName, dto.id); + } else if (dto.type === 'data') { + this.debugService.addDataBreakpoint(dto.label, dto.dataId, dto.canPersist); } } return Promise.resolve(); } - public $unregisterBreakpoints(breakpointIds: string[], functionBreakpointIds: string[]): Promise { + public $unregisterBreakpoints(breakpointIds: string[], functionBreakpointIds: string[], dataBreakpointIds: string[]): Promise { breakpointIds.forEach(id => this.debugService.removeBreakpoints(id)); functionBreakpointIds.forEach(id => this.debugService.removeFunctionBreakpoints(id)); + dataBreakpointIds.forEach(id => this.debugService.removeDataBreakpoints(id)); return Promise.resolve(); } @@ -294,7 +298,7 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb return undefined; } - private convertToDto(bps: (ReadonlyArray)): Array { + private convertToDto(bps: (ReadonlyArray)): Array { return bps.map(bp => { if ('name' in bp) { const fbp = bp; @@ -307,6 +311,19 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb logMessage: fbp.logMessage, functionName: fbp.name }; + } else if ('dataId' in bp) { + const dbp = bp; + return { + type: 'data', + id: dbp.getId(), + dataId: dbp.dataId, + enabled: dbp.enabled, + condition: dbp.condition, + hitCondition: dbp.hitCondition, + logMessage: dbp.logMessage, + label: dbp.label, + canPersist: dbp.canPersist + }; } else { const sbp = bp; return { diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 1cc498a9ca4..2b1f57a09d6 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -715,8 +715,8 @@ export interface MainThreadDebugServiceShape extends IDisposable { $customDebugAdapterRequest(id: DebugSessionUUID, command: string, args: any): Promise; $appendDebugConsole(value: string): void; $startBreakpointEvents(): void; - $registerBreakpoints(breakpoints: Array): Promise; - $unregisterBreakpoints(breakpointIds: string[], functionBreakpointIds: string[]): Promise; + $registerBreakpoints(breakpoints: Array): Promise; + $unregisterBreakpoints(breakpointIds: string[], functionBreakpointIds: string[], dataBreakpointIds: string[]): Promise; } export interface IOpenUriOptions { @@ -1198,6 +1198,13 @@ export interface IFunctionBreakpointDto extends IBreakpointDto { functionName: string; } +export interface IDataBreakpointDto extends IBreakpointDto { + type: 'data'; + dataId: string; + canPersist: boolean; + label: string; +} + export interface ISourceBreakpointDto extends IBreakpointDto { type: 'source'; uri: UriComponents; @@ -1206,9 +1213,9 @@ export interface ISourceBreakpointDto extends IBreakpointDto { } export interface IBreakpointsDeltaDto { - added?: Array; + added?: Array; removed?: string[]; - changed?: Array; + changed?: Array; } export interface ISourceMultiBreakpointDto { diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index e3c30b6e3a0..9084c617057 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -2166,6 +2166,24 @@ export class FunctionBreakpoint extends Breakpoint { } } +@es5ClassCompat +export class DataBreakpoint extends Breakpoint { + readonly label: string; + readonly dataId: string; + readonly canPersist: boolean; + + constructor(label: string, dataId: string, canPersist: boolean, enabled?: boolean, condition?: string, hitCondition?: string, logMessage?: string) { + super(enabled, condition, hitCondition, logMessage); + if (!dataId) { + throw illegalArgument('dataId'); + } + this.label = label; + this.dataId = dataId; + this.canPersist = canPersist; + } +} + + @es5ClassCompat export class DebugAdapterExecutable implements vscode.DebugAdapterExecutable { readonly command: string; diff --git a/src/vs/workbench/api/node/extHostDebugService.ts b/src/vs/workbench/api/node/extHostDebugService.ts index 87adb02d748..c82f788a370 100644 --- a/src/vs/workbench/api/node/extHostDebugService.ts +++ b/src/vs/workbench/api/node/extHostDebugService.ts @@ -14,7 +14,7 @@ import { IBreakpointsDeltaDto, ISourceMultiBreakpointDto, IFunctionBreakpointDto, IDebugSessionDto } from 'vs/workbench/api/common/extHost.protocol'; import * as vscode from 'vscode'; -import { Disposable, Position, Location, SourceBreakpoint, FunctionBreakpoint, DebugAdapterServer, DebugAdapterExecutable } from 'vs/workbench/api/common/extHostTypes'; +import { Disposable, Position, Location, SourceBreakpoint, FunctionBreakpoint, DebugAdapterServer, DebugAdapterExecutable, DataBreakpoint } from 'vs/workbench/api/common/extHostTypes'; import { ExecutableDebugAdapter, SocketDebugAdapter } from 'vs/workbench/contrib/debug/node/debugAdapter'; import { AbstractDebugAdapter } from 'vs/workbench/contrib/debug/common/abstractDebugAdapter'; import { IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; @@ -248,7 +248,8 @@ export class ExtHostDebugService implements IExtHostDebugService, ExtHostDebugSe // unregister with VS Code const ids = breakpoints.filter(bp => bp instanceof SourceBreakpoint).map(bp => bp.id); const fids = breakpoints.filter(bp => bp instanceof FunctionBreakpoint).map(bp => bp.id); - return this._debugServiceProxy.$unregisterBreakpoints(ids, fids); + const dids = breakpoints.filter(bp => bp instanceof DataBreakpoint).map(bp => bp.id); + return this._debugServiceProxy.$unregisterBreakpoints(ids, fids, dids); } public startDebugging(folder: vscode.WorkspaceFolder | undefined, nameOrConfig: string | vscode.DebugConfiguration, parentSession?: vscode.DebugSession): Promise { @@ -554,6 +555,8 @@ export class ExtHostDebugService implements IExtHostDebugService, ExtHostDebugSe let bp: vscode.Breakpoint; if (bpd.type === 'function') { bp = new FunctionBreakpoint(bpd.functionName, bpd.enabled, bpd.condition, bpd.hitCondition, bpd.logMessage); + } else if (bpd.type === 'data') { + bp = new DataBreakpoint(bpd.label, bpd.dataId, bpd.canPersist, bpd.enabled, bpd.hitCondition, bpd.condition, bpd.logMessage); } else { const uri = URI.revive(bpd.uri); bp = new SourceBreakpoint(new Location(uri, new Position(bpd.line, bpd.character)), bpd.enabled, bpd.condition, bpd.hitCondition, bpd.logMessage); diff --git a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts index 4c8f5b36ee8..e1f0c4496a0 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts @@ -8,7 +8,7 @@ import * as resources from 'vs/base/common/resources'; import * as dom from 'vs/base/browser/dom'; import { IAction, Action } from 'vs/base/common/actions'; import { IDebugService, IBreakpoint, CONTEXT_BREAKPOINTS_FOCUSED, EDITOR_CONTRIBUTION_ID, State, DEBUG_SCHEME, IFunctionBreakpoint, IExceptionBreakpoint, IEnablement, IDebugEditorContribution } from 'vs/workbench/contrib/debug/common/debug'; -import { ExceptionBreakpoint, FunctionBreakpoint, Breakpoint } from 'vs/workbench/contrib/debug/common/debugModel'; +import { ExceptionBreakpoint, FunctionBreakpoint, Breakpoint, DataBreakpoint } from 'vs/workbench/contrib/debug/common/debugModel'; import { AddFunctionBreakpointAction, ToggleBreakpointsActivatedAction, RemoveAllBreakpointsAction, RemoveBreakpointAction, EnableAllBreakpointsAction, DisableAllBreakpointsAction, ReapplyBreakpointsAction } from 'vs/workbench/contrib/debug/browser/debugActions'; import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -74,6 +74,7 @@ export class BreakpointsView extends ViewletPanel { this.instantiationService.createInstance(BreakpointsRenderer), new ExceptionBreakpointsRenderer(this.debugService), this.instantiationService.createInstance(FunctionBreakpointsRenderer), + this.instantiationService.createInstance(DataBreakpointsRenderer), new FunctionBreakpointInputRenderer(this.debugService, this.contextViewService, this.themeService) ], { identityProvider: { getId: (element: IEnablement) => element.getId() }, @@ -91,7 +92,7 @@ export class BreakpointsView extends ViewletPanel { this._register(this.list.onContextMenu(this.onListContextMenu, this)); - this._register(this.list.onDidOpen(e => { + this._register(this.list.onDidOpen(async e => { let isSingleClick = false; let isDoubleClick = false; let isMiddleClick = false; @@ -110,9 +111,11 @@ export class BreakpointsView extends ViewletPanel { if (isMiddleClick) { if (element instanceof Breakpoint) { - this.debugService.removeBreakpoints(element.getId()); + await this.debugService.removeBreakpoints(element.getId()); } else if (element instanceof FunctionBreakpoint) { - this.debugService.removeFunctionBreakpoints(element.getId()); + await this.debugService.removeFunctionBreakpoints(element.getId()); + } else if (element instanceof DataBreakpoint) { + await this.debugService.removeDataBreakpoints(element.getId()); } return; } @@ -222,14 +225,14 @@ export class BreakpointsView extends ViewletPanel { private get elements(): IEnablement[] { const model = this.debugService.getModel(); - const elements = (>model.getExceptionBreakpoints()).concat(model.getFunctionBreakpoints()).concat(model.getBreakpoints()); + const elements = (>model.getExceptionBreakpoints()).concat(model.getFunctionBreakpoints()).concat(model.getDataBreakpoints()).concat(model.getBreakpoints()); return elements; } private getExpandedBodySize(): number { const model = this.debugService.getModel(); - const length = model.getBreakpoints().length + model.getExceptionBreakpoints().length + model.getFunctionBreakpoints().length; + const length = model.getBreakpoints().length + model.getExceptionBreakpoints().length + model.getFunctionBreakpoints().length + model.getDataBreakpoints().length; return Math.min(BreakpointsView.MAX_VISIBLE_FILES, length) * 22; } } @@ -259,6 +262,9 @@ class BreakpointsDelegate implements IListVirtualDelegate { if (element instanceof ExceptionBreakpoint) { return ExceptionBreakpointsRenderer.ID; } + if (element instanceof DataBreakpoint) { + return DataBreakpointsRenderer.ID; + } return ''; } @@ -454,6 +460,61 @@ class FunctionBreakpointsRenderer implements IListRenderer { + + constructor( + @IDebugService private readonly debugService: IDebugService + ) { + // noop + } + + static readonly ID = 'databreakpoints'; + + get templateId() { + return DataBreakpointsRenderer.ID; + } + + renderTemplate(container: HTMLElement): IBaseBreakpointWithIconTemplateData { + const data: IBreakpointTemplateData = Object.create(null); + data.breakpoint = dom.append(container, $('.breakpoint')); + + data.icon = $('.icon'); + data.checkbox = createCheckbox(); + data.toDispose = []; + data.toDispose.push(dom.addStandardDisposableListener(data.checkbox, 'change', (e) => { + this.debugService.enableOrDisableBreakpoints(!data.context.enabled, data.context); + })); + + dom.append(data.breakpoint, data.icon); + dom.append(data.breakpoint, data.checkbox); + + data.name = dom.append(data.breakpoint, $('span.name')); + + return data; + } + + renderElement(dataBreakpoint: DataBreakpoint, index: number, data: IBaseBreakpointWithIconTemplateData): void { + data.context = dataBreakpoint; + data.name.textContent = dataBreakpoint.label; + const { className, message } = getBreakpointMessageAndClassName(this.debugService, dataBreakpoint); + data.icon.className = className + ' icon'; + data.icon.title = message ? message : ''; + data.checkbox.checked = dataBreakpoint.enabled; + data.breakpoint.title = dataBreakpoint.label; + + // Mark function breakpoints as disabled if deactivated or if debug type does not support them #9099 + const session = this.debugService.getViewModel().focusedSession; + dom.toggleClass(data.breakpoint, 'disabled', (session && !session.capabilities.supportsDataBreakpoints) || !this.debugService.getModel().areBreakpointsActivated()); + if (session && !session.capabilities.supportsDataBreakpoints) { + data.breakpoint.title = nls.localize('dataBreakpointsNotSupported', "Data breakpoints are not supported by this debug type"); + } + } + + disposeTemplate(templateData: IBaseBreakpointWithIconTemplateData): void { + dispose(templateData.toDispose); + } +} + class FunctionBreakpointInputRenderer implements IListRenderer { constructor( @@ -572,7 +633,7 @@ export function openBreakpointSource(breakpoint: IBreakpoint, sideBySide: boolea }, sideBySide ? SIDE_GROUP : ACTIVE_GROUP); } -export function getBreakpointMessageAndClassName(debugService: IDebugService, breakpoint: IBreakpoint | FunctionBreakpoint): { message?: string, className: string } { +export function getBreakpointMessageAndClassName(debugService: IDebugService, breakpoint: IBreakpoint | FunctionBreakpoint | DataBreakpoint): { message?: string, className: string } { const state = debugService.state; const debugActive = state === State.Running || state === State.Stopped; @@ -584,7 +645,7 @@ export function getBreakpointMessageAndClassName(debugService: IDebugService, br } const appendMessage = (text: string): string => { - return !(breakpoint instanceof FunctionBreakpoint) && breakpoint.message ? text.concat(', ' + breakpoint.message) : text; + return !(breakpoint instanceof FunctionBreakpoint) && !(breakpoint instanceof DataBreakpoint) && breakpoint.message ? text.concat(', ' + breakpoint.message) : text; }; if (debugActive && !breakpoint.verified) { return { @@ -607,6 +668,19 @@ export function getBreakpointMessageAndClassName(debugService: IDebugService, br }; } + if (breakpoint instanceof DataBreakpoint) { + if (session && !session.capabilities.supportsDataBreakpoints) { + return { + className: 'debug-data-breakpoint-unverified', + message: nls.localize('dataBreakpointUnsupported', "Data breakpoints not supported by this debug type"), + }; + } + + return { + className: 'debug-data-breakpoint', + }; + } + if (breakpoint.logMessage || breakpoint.condition || breakpoint.hitCondition) { const messages: string[] = []; if (breakpoint.logMessage) { diff --git a/src/vs/workbench/contrib/debug/browser/debugActions.ts b/src/vs/workbench/contrib/debug/browser/debugActions.ts index f2ed8a479ac..8f926b2a35a 100644 --- a/src/vs/workbench/contrib/debug/browser/debugActions.ts +++ b/src/vs/workbench/contrib/debug/browser/debugActions.ts @@ -9,7 +9,7 @@ import * as lifecycle from 'vs/base/common/lifecycle'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IDebugService, State, IEnablement, IBreakpoint, IDebugSession } from 'vs/workbench/contrib/debug/common/debug'; -import { Variable, Breakpoint } from 'vs/workbench/contrib/debug/common/debugModel'; +import { Variable, Breakpoint, FunctionBreakpoint } from 'vs/workbench/contrib/debug/common/debugModel'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; import { INotificationService } from 'vs/platform/notification/common/notification'; @@ -191,7 +191,7 @@ export class RemoveBreakpointAction extends AbstractDebugAction { public run(breakpoint: IBreakpoint): Promise { return breakpoint instanceof Breakpoint ? this.debugService.removeBreakpoints(breakpoint.getId()) - : this.debugService.removeFunctionBreakpoints(breakpoint.getId()); + : breakpoint instanceof FunctionBreakpoint ? this.debugService.removeFunctionBreakpoints(breakpoint.getId()) : this.debugService.removeDataBreakpoints(breakpoint.getId()); } } @@ -205,7 +205,7 @@ export class RemoveAllBreakpointsAction extends AbstractDebugAction { } public run(): Promise { - return Promise.all([this.debugService.removeBreakpoints(), this.debugService.removeFunctionBreakpoints()]); + return Promise.all([this.debugService.removeBreakpoints(), this.debugService.removeFunctionBreakpoints(), this.debugService.removeDataBreakpoints()]); } protected isEnabled(state: State): boolean { diff --git a/src/vs/workbench/contrib/debug/browser/debugCommands.ts b/src/vs/workbench/contrib/debug/browser/debugCommands.ts index 67bcdb80de9..7acca069182 100644 --- a/src/vs/workbench/contrib/debug/browser/debugCommands.ts +++ b/src/vs/workbench/contrib/debug/browser/debugCommands.ts @@ -10,7 +10,7 @@ import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/co import { IListService } from 'vs/platform/list/browser/listService'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IDebugService, IEnablement, CONTEXT_BREAKPOINTS_FOCUSED, CONTEXT_WATCH_EXPRESSIONS_FOCUSED, CONTEXT_VARIABLES_FOCUSED, EDITOR_CONTRIBUTION_ID, IDebugEditorContribution, CONTEXT_IN_DEBUG_MODE, CONTEXT_EXPRESSION_SELECTED, CONTEXT_BREAKPOINT_SELECTED, IConfig, IStackFrame, IThread, IDebugSession, CONTEXT_DEBUG_STATE, REPL_ID, IDebugConfiguration, CONTEXT_JUMP_TO_CURSOR_SUPPORTED } from 'vs/workbench/contrib/debug/common/debug'; -import { Expression, Variable, Breakpoint, FunctionBreakpoint, Thread } from 'vs/workbench/contrib/debug/common/debugModel'; +import { Expression, Variable, Breakpoint, FunctionBreakpoint, Thread, DataBreakpoint } from 'vs/workbench/contrib/debug/common/debugModel'; import { IExtensionsViewlet, VIEWLET_ID as EXTENSIONS_VIEWLET_ID } from 'vs/workbench/contrib/extensions/common/extensions'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { ICodeEditor, isCodeEditor } from 'vs/editor/browser/editorBrowser'; @@ -410,6 +410,8 @@ export function registerCommands(): void { debugService.removeBreakpoints(element.getId()); } else if (element instanceof FunctionBreakpoint) { debugService.removeFunctionBreakpoints(element.getId()); + } else if (element instanceof DataBreakpoint) { + debugService.removeDataBreakpoints(element.getId()); } } } diff --git a/src/vs/workbench/contrib/debug/browser/debugService.ts b/src/vs/workbench/contrib/debug/browser/debugService.ts index eddc8876af7..8b139d2a3e3 100644 --- a/src/vs/workbench/contrib/debug/browser/debugService.ts +++ b/src/vs/workbench/contrib/debug/browser/debugService.ts @@ -18,7 +18,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { FileChangesEvent, FileChangeType, IFileService } from 'vs/platform/files/common/files'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; -import { DebugModel, ExceptionBreakpoint, FunctionBreakpoint, Breakpoint, Expression } from 'vs/workbench/contrib/debug/common/debugModel'; +import { DebugModel, ExceptionBreakpoint, FunctionBreakpoint, Breakpoint, Expression, DataBreakpoint } from 'vs/workbench/contrib/debug/common/debugModel'; import { ViewModel } from 'vs/workbench/contrib/debug/common/debugViewModel'; import * as debugactions from 'vs/workbench/contrib/debug/browser/debugActions'; import { ConfigurationManager } from 'vs/workbench/contrib/debug/browser/debugConfigurationManager'; @@ -52,6 +52,7 @@ import { CancellationTokenSource } from 'vs/base/common/cancellation'; const DEBUG_BREAKPOINTS_KEY = 'debug.breakpoint'; const DEBUG_BREAKPOINTS_ACTIVATED_KEY = 'debug.breakpointactivated'; const DEBUG_FUNCTION_BREAKPOINTS_KEY = 'debug.functionbreakpoint'; +const DEBUG_DATA_BREAKPOINTS_KEY = 'debug.databreakpoint'; const DEBUG_EXCEPTION_BREAKPOINTS_KEY = 'debug.exceptionbreakpoint'; const DEBUG_WATCH_EXPRESSIONS_KEY = 'debug.watchexpressions'; @@ -129,7 +130,7 @@ export class DebugService implements IDebugService { this.inDebugMode = CONTEXT_IN_DEBUG_MODE.bindTo(contextKeyService); this.model = new DebugModel(this.loadBreakpoints(), this.storageService.getBoolean(DEBUG_BREAKPOINTS_ACTIVATED_KEY, StorageScope.WORKSPACE, true), this.loadFunctionBreakpoints(), - this.loadExceptionBreakpoints(), this.loadWatchExpressions(), this.textFileService); + this.loadExceptionBreakpoints(), this.loadDataBreakpoints(), this.loadWatchExpressions(), this.textFileService); this.toDispose.push(this.model); this.viewModel = new ViewModel(contextKeyService); @@ -851,6 +852,8 @@ export class DebugService implements IDebugService { await this.sendBreakpoints(breakpoint.uri); } else if (breakpoint instanceof FunctionBreakpoint) { await this.sendFunctionBreakpoints(); + } else if (breakpoint instanceof DataBreakpoint) { + await this.sendDataBreakpoints(); } else { await this.sendExceptionBreakpoints(); } @@ -920,6 +923,19 @@ export class DebugService implements IDebugService { this.storeBreakpoints(); } + async addDataBreakpoint(label: string, dataId: string, canPersist: boolean): Promise { + this.model.addDataBreakpoint(label, dataId, canPersist); + await this.sendDataBreakpoints(); + + this.storeBreakpoints(); + } + + async removeDataBreakpoints(id?: string): Promise { + this.model.removeDataBreakpoints(id); + await this.sendDataBreakpoints(); + this.storeBreakpoints(); + } + sendAllBreakpoints(session?: IDebugSession): Promise { return Promise.all(distinct(this.model.getBreakpoints(), bp => bp.uri.toString()).map(bp => this.sendBreakpoints(bp.uri, false, session))) .then(() => this.sendFunctionBreakpoints(session)) @@ -943,6 +959,14 @@ export class DebugService implements IDebugService { }); } + private sendDataBreakpoints(session?: IDebugSession): Promise { + const breakpointsToSend = this.model.getDataBreakpoints().filter(fbp => fbp.enabled && this.model.areBreakpointsActivated()); + + return this.sendToOneOrAllSessions(session, s => { + return s.capabilities.supportsDataBreakpoints ? s.sendDataBreakpoints(breakpointsToSend) : Promise.resolve(undefined); + }); + } + private sendExceptionBreakpoints(session?: IDebugSession): Promise { const enabledExceptionBps = this.model.getExceptionBreakpoints().filter(exb => exb.enabled); @@ -1006,6 +1030,17 @@ export class DebugService implements IDebugService { return result || []; } + private loadDataBreakpoints(): DataBreakpoint[] { + let result: DataBreakpoint[] | undefined; + try { + result = JSON.parse(this.storageService.get(DEBUG_DATA_BREAKPOINTS_KEY, StorageScope.WORKSPACE, '[]')).map((dbp: any) => { + return new DataBreakpoint(dbp.label, dbp.dataId, true, dbp.enabled, dbp.hitCondition, dbp.condition, dbp.logMessage); + }); + } catch (e) { } + + return result || []; + } + private loadWatchExpressions(): Expression[] { let result: Expression[] | undefined; try { @@ -1041,6 +1076,13 @@ export class DebugService implements IDebugService { this.storageService.remove(DEBUG_FUNCTION_BREAKPOINTS_KEY, StorageScope.WORKSPACE); } + const dataBreakpoints = this.model.getDataBreakpoints().filter(dbp => dbp.canPersist); + if (dataBreakpoints.length) { + this.storageService.store(DEBUG_DATA_BREAKPOINTS_KEY, JSON.stringify(dataBreakpoints), StorageScope.WORKSPACE); + } else { + this.storageService.remove(DEBUG_DATA_BREAKPOINTS_KEY, StorageScope.WORKSPACE); + } + const exceptionBreakpoints = this.model.getExceptionBreakpoints(); if (exceptionBreakpoints.length) { this.storageService.store(DEBUG_EXCEPTION_BREAKPOINTS_KEY, JSON.stringify(exceptionBreakpoints), StorageScope.WORKSPACE); diff --git a/src/vs/workbench/contrib/debug/browser/debugSession.ts b/src/vs/workbench/contrib/debug/browser/debugSession.ts index d4548944019..b0f361a4872 100644 --- a/src/vs/workbench/contrib/debug/browser/debugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/debugSession.ts @@ -12,7 +12,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { CompletionItem, completionKindFromString } from 'vs/editor/common/modes'; import { Position } from 'vs/editor/common/core/position'; import * as aria from 'vs/base/browser/ui/aria/aria'; -import { IDebugSession, IConfig, IThread, IRawModelUpdate, IDebugService, IRawStoppedDetails, State, LoadedSourceEvent, IFunctionBreakpoint, IExceptionBreakpoint, IBreakpoint, IExceptionInfo, AdapterEndEvent, IDebugger, VIEWLET_ID, IDebugConfiguration, IReplElement, IStackFrame, IExpression, IReplElementSource } from 'vs/workbench/contrib/debug/common/debug'; +import { IDebugSession, IConfig, IThread, IRawModelUpdate, IDebugService, IRawStoppedDetails, State, LoadedSourceEvent, IFunctionBreakpoint, IExceptionBreakpoint, IBreakpoint, IExceptionInfo, AdapterEndEvent, IDebugger, VIEWLET_ID, IDebugConfiguration, IReplElement, IStackFrame, IExpression, IReplElementSource, IDataBreakpoint } from 'vs/workbench/contrib/debug/common/debug'; import { Source } from 'vs/workbench/contrib/debug/common/debugSource'; import { mixin } from 'vs/base/common/objects'; import { Thread, ExpressionContainer, DebugModel } from 'vs/workbench/contrib/debug/common/debugModel'; @@ -327,6 +327,34 @@ export class DebugSession implements IDebugSession { return Promise.reject(new Error('no debug adapter')); } + dataBreakpointInfo(name: string, variablesReference?: number): Promise<{ dataId: string | null, description: string, canPersist?: boolean }> { + if (this.raw) { + if (this.raw.readyForBreakpoints) { + return this.raw.dataBreakpointInfo({ name, variablesReference }).then(response => response.body); + } + return Promise.reject(new Error(nls.localize('sessionNotReadyForBreakpoints', "Session is not ready for breakpoints"))); + } + return Promise.reject(new Error('no debug adapter')); + } + + sendDataBreakpoints(dataBreakpoints: IDataBreakpoint[]): Promise { + if (this.raw) { + if (this.raw.readyForBreakpoints) { + return this.raw.setDataBreakpoints({ breakpoints: dataBreakpoints }).then(response => { + if (response && response.body) { + const data = new Map(); + for (let i = 0; i < dataBreakpoints.length; i++) { + data.set(dataBreakpoints[i].getId(), response.body.breakpoints[i]); + } + this.model.setBreakpointSessionData(this.getId(), data); + } + }); + } + return Promise.resolve(undefined); + } + return Promise.reject(new Error('no debug adapter')); + } + customRequest(request: string, args: any): Promise { if (this.raw) { return this.raw.custom(request, args); diff --git a/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts b/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts index 0d1772ff111..fe5e98b83dd 100644 --- a/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts @@ -357,6 +357,20 @@ export class RawDebugSession { return Promise.reject(new Error('setFunctionBreakpoints not supported')); } + dataBreakpointInfo(args: DebugProtocol.DataBreakpointInfoArguments): Promise { + if (this.capabilities.supportsDataBreakpoints) { + return this.send('dataBreakpointInfo', args); + } + return Promise.reject(new Error('dataBreakpointInfo not supported')); + } + + setDataBreakpoints(args: DebugProtocol.SetDataBreakpointsArguments): Promise { + if (this.capabilities.supportsDataBreakpoints) { + return this.send('setDataBreakpoints', args); + } + return Promise.reject(new Error('setDataBreakpoints not supported')); + } + setExceptionBreakpoints(args: DebugProtocol.SetExceptionBreakpointsArguments): Promise { return this.send('setExceptionBreakpoints', args); } diff --git a/src/vs/workbench/contrib/debug/browser/variablesView.ts b/src/vs/workbench/contrib/debug/browser/variablesView.ts index 45eb8037c71..3c3890b574d 100644 --- a/src/vs/workbench/contrib/debug/browser/variablesView.ts +++ b/src/vs/workbench/contrib/debug/browser/variablesView.ts @@ -89,11 +89,11 @@ export class VariablesView extends ViewletPanel { this.tree = this.instantiationService.createInstance(WorkbenchAsyncDataTree, treeContainer, new VariablesDelegate(), [this.instantiationService.createInstance(VariablesRenderer), new ScopesRenderer()], new VariablesDataSource(), { - ariaLabel: nls.localize('variablesAriaTreeLabel', "Debug Variables"), - accessibilityProvider: new VariablesAccessibilityProvider(), - identityProvider: { getId: (element: IExpression | IScope) => element.getId() }, - keyboardNavigationLabelProvider: { getKeyboardNavigationLabel: (e: IExpression | IScope) => e } - }); + ariaLabel: nls.localize('variablesAriaTreeLabel', "Debug Variables"), + accessibilityProvider: new VariablesAccessibilityProvider(), + identityProvider: { getId: (element: IExpression | IScope) => element.getId() }, + keyboardNavigationLabelProvider: { getKeyboardNavigationLabel: (e: IExpression | IScope) => e } + }); this.tree.setInput(this.debugService.getViewModel()).then(null, onUnexpectedError); @@ -123,7 +123,7 @@ export class VariablesView extends ViewletPanel { this.tree.updateChildren(); })); this._register(this.tree.onMouseDblClick(e => this.onMouseDblClick(e))); - this._register(this.tree.onContextMenu(e => this.onContextMenu(e))); + this._register(this.tree.onContextMenu(async e => await this.onContextMenu(e))); this._register(this.onDidChangeBodyVisibility(visible => { if (visible && this.needsRefresh) { @@ -152,7 +152,7 @@ export class VariablesView extends ViewletPanel { } } - private onContextMenu(e: ITreeContextMenuEvent): void { + private async onContextMenu(e: ITreeContextMenuEvent): Promise { const variable = e.element; if (variable instanceof Variable && !!variable.value) { const actions: IAction[] = []; @@ -174,6 +174,16 @@ export class VariablesView extends ViewletPanel { return Promise.resolve(undefined); })); } + if (session && session.capabilities.supportsDataBreakpoints) { + const response = await session.dataBreakpointInfo(variable.name, variable.parent.reference); + const dataid = response.dataId; + if (dataid) { + actions.push(new Separator()); + actions.push(new Action('debug.addDataBreakpoint', nls.localize('setDataBreakpoint', "Set Data Breakpoint"), undefined, true, () => { + return this.debugService.addDataBreakpoint(response.description, dataid, !!response.canPersist); + })); + } + } this.contextMenuService.showContextMenu({ getAnchor: () => e.anchor, diff --git a/src/vs/workbench/contrib/debug/common/debug.ts b/src/vs/workbench/contrib/debug/common/debug.ts index 65e28660dc9..42a35769797 100644 --- a/src/vs/workbench/contrib/debug/common/debug.ts +++ b/src/vs/workbench/contrib/debug/common/debug.ts @@ -103,6 +103,7 @@ export interface IReplElementSource { export interface IExpressionContainer extends ITreeElement { readonly hasChildren: boolean; getChildren(): Promise; + readonly reference?: number; } export interface IExpression extends IReplElement, IExpressionContainer { @@ -201,6 +202,8 @@ export interface IDebugSession extends ITreeElement { sendBreakpoints(modelUri: uri, bpts: IBreakpoint[], sourceModified: boolean): Promise; sendFunctionBreakpoints(fbps: IFunctionBreakpoint[]): Promise; + dataBreakpointInfo(name: string, variablesReference?: number): Promise<{ dataId: string | null, description: string, canPersist?: boolean }>; + sendDataBreakpoints(dbps: IDataBreakpoint[]): Promise; sendExceptionBreakpoints(exbpts: IExceptionBreakpoint[]): Promise; stackTrace(threadId: number, startFrame: number, levels: number): Promise; @@ -357,6 +360,12 @@ export interface IExceptionBreakpoint extends IEnablement { readonly label: string; } +export interface IDataBreakpoint extends IBaseBreakpoint { + readonly label: string; + readonly dataId: string; + readonly canPersist: boolean; +} + export interface IExceptionInfo { readonly id?: string; readonly description?: string; @@ -404,6 +413,7 @@ export interface IDebugModel extends ITreeElement { getBreakpoints(filter?: { uri?: uri, lineNumber?: number, column?: number, enabledOnly?: boolean }): ReadonlyArray; areBreakpointsActivated(): boolean; getFunctionBreakpoints(): ReadonlyArray; + getDataBreakpoints(): ReadonlyArray; getExceptionBreakpoints(): ReadonlyArray; getWatchExpressions(): ReadonlyArray; @@ -416,9 +426,9 @@ export interface IDebugModel extends ITreeElement { * An event describing a change to the set of [breakpoints](#debug.Breakpoint). */ export interface IBreakpointsChangeEvent { - added?: Array; - removed?: Array; - changed?: Array; + added?: Array; + removed?: Array; + changed?: Array; sessionOnly?: boolean; } @@ -754,6 +764,17 @@ export interface IDebugService { */ removeFunctionBreakpoints(id?: string): Promise; + /** + * Adds a new data breakpoint. + */ + addDataBreakpoint(label: string, dataId: string, canPersist: boolean): Promise; + + /** + * Removes all data breakpoints. If id is passed only removes the data breakpoint with the passed id. + * Notifies debug adapter of breakpoint changes. + */ + removeDataBreakpoints(id?: string): Promise; + /** * Sends all breakpoints to the passed session. * If session is not passed, sends all breakpoints to each session. diff --git a/src/vs/workbench/contrib/debug/common/debugModel.ts b/src/vs/workbench/contrib/debug/common/debugModel.ts index 16a838721c4..599c496dcd9 100644 --- a/src/vs/workbench/contrib/debug/common/debugModel.ts +++ b/src/vs/workbench/contrib/debug/common/debugModel.ts @@ -16,7 +16,7 @@ import { distinct, lastIndex } from 'vs/base/common/arrays'; import { Range, IRange } from 'vs/editor/common/core/range'; import { ITreeElement, IExpression, IExpressionContainer, IDebugSession, IStackFrame, IExceptionBreakpoint, IBreakpoint, IFunctionBreakpoint, IDebugModel, IReplElementSource, - IThread, IRawModelUpdate, IScope, IRawStoppedDetails, IEnablement, IBreakpointData, IExceptionInfo, IReplElement, IBreakpointsChangeEvent, IBreakpointUpdateData, IBaseBreakpoint, State + IThread, IRawModelUpdate, IScope, IRawStoppedDetails, IEnablement, IBreakpointData, IExceptionInfo, IReplElement, IBreakpointsChangeEvent, IBreakpointUpdateData, IBaseBreakpoint, State, IDataBreakpoint } from 'vs/workbench/contrib/debug/common/debug'; import { Source, UNKNOWN_SOURCE_LABEL } from 'vs/workbench/contrib/debug/common/debugSource'; import { commonSuffixLength } from 'vs/base/common/strings'; @@ -735,6 +735,34 @@ export class FunctionBreakpoint extends BaseBreakpoint implements IFunctionBreak } } +export class DataBreakpoint extends BaseBreakpoint implements IDataBreakpoint { + + constructor( + public label: string, + public dataId: string, + public canPersist: boolean, + enabled: boolean, + hitCondition: string | undefined, + condition: string | undefined, + logMessage: string | undefined, + id = generateUuid() + ) { + super(enabled, hitCondition, condition, logMessage, id); + } + + toJSON(): any { + const result = super.toJSON(); + result.label = this.label; + result.dataid = this.dataId; + + return result; + } + + toString(): string { + return this.label; + } +} + export class ExceptionBreakpoint extends Enablement implements IExceptionBreakpoint { constructor(public filter: string, public label: string, enabled: boolean) { @@ -778,6 +806,7 @@ export class DebugModel implements IDebugModel { private breakpointsActivated: boolean, private functionBreakpoints: FunctionBreakpoint[], private exceptionBreakpoints: ExceptionBreakpoint[], + private dataBreakopints: DataBreakpoint[], private watchExpressions: Expression[], private textFileService: ITextFileService ) { @@ -918,6 +947,10 @@ export class DebugModel implements IDebugModel { return this.functionBreakpoints; } + getDataBreakpoints(): IDataBreakpoint[] { + return this.dataBreakopints; + } + getExceptionBreakpoints(): IExceptionBreakpoint[] { return this.exceptionBreakpoints; } @@ -991,6 +1024,12 @@ export class DebugModel implements IDebugModel { fbp.setSessionData(sessionId, fbpData); } }); + this.dataBreakopints.forEach(dbp => { + const dbpData = data.get(dbp.getId()); + if (dbpData) { + dbp.setSessionData(sessionId, dbpData); + } + }); this._onDidChangeBreakpoints.fire({ sessionOnly: true @@ -1001,6 +1040,7 @@ export class DebugModel implements IDebugModel { this.breakpointsSessionId = sessionId; this.breakpoints.forEach(bp => bp.setSessionId(sessionId)); this.functionBreakpoints.forEach(fbp => fbp.setSessionId(sessionId)); + this.dataBreakopints.forEach(dbp => dbp.setSessionId(sessionId)); this._onDidChangeBreakpoints.fire({ sessionOnly: true @@ -1038,7 +1078,7 @@ export class DebugModel implements IDebugModel { } enableOrDisableAllBreakpoints(enable: boolean): void { - const changed: Array = []; + const changed: Array = []; this.breakpoints.forEach(bp => { if (bp.enabled !== enable) { @@ -1052,6 +1092,12 @@ export class DebugModel implements IDebugModel { } fbp.enabled = enable; }); + this.dataBreakopints.forEach(dbp => { + if (dbp.enabled !== enable) { + changed.push(dbp); + } + dbp.enabled = enable; + }); this._onDidChangeBreakpoints.fire({ changed: changed }); } @@ -1073,7 +1119,6 @@ export class DebugModel implements IDebugModel { } removeFunctionBreakpoints(id?: string): void { - let removed: FunctionBreakpoint[]; if (id) { removed = this.functionBreakpoints.filter(fbp => fbp.getId() === id); @@ -1082,7 +1127,25 @@ export class DebugModel implements IDebugModel { removed = this.functionBreakpoints; this.functionBreakpoints = []; } - this._onDidChangeBreakpoints.fire({ removed: removed }); + this._onDidChangeBreakpoints.fire({ removed }); + } + + addDataBreakpoint(label: string, dataId: string, canPersist: boolean): void { + const newDataBreakpoint = new DataBreakpoint(label, dataId, canPersist, true, undefined, undefined, undefined); + this.dataBreakopints.push(newDataBreakpoint); + this._onDidChangeBreakpoints.fire({ added: [newDataBreakpoint] }); + } + + removeDataBreakpoints(id?: string): void { + let removed: DataBreakpoint[]; + if (id) { + removed = this.dataBreakopints.filter(fbp => fbp.getId() === id); + this.dataBreakopints = this.dataBreakopints.filter(fbp => fbp.getId() !== id); + } else { + removed = this.dataBreakopints; + this.dataBreakopints = []; + } + this._onDidChangeBreakpoints.fire({ removed }); } getWatchExpressions(): Expression[] { diff --git a/src/vs/workbench/contrib/debug/test/browser/debugModel.test.ts b/src/vs/workbench/contrib/debug/test/browser/debugModel.test.ts index 6b313596ca6..d6ebbfd721b 100644 --- a/src/vs/workbench/contrib/debug/test/browser/debugModel.test.ts +++ b/src/vs/workbench/contrib/debug/test/browser/debugModel.test.ts @@ -23,7 +23,7 @@ suite('Debug - Model', () => { let rawSession: MockRawSession; setup(() => { - model = new DebugModel([], true, [], [], [], { isDirty: (e: any) => false }); + model = new DebugModel([], true, [], [], [], [], { isDirty: (e: any) => false }); rawSession = new MockRawSession(); }); diff --git a/src/vs/workbench/contrib/debug/test/common/mockDebug.ts b/src/vs/workbench/contrib/debug/test/common/mockDebug.ts index 19aae90891d..bb10110ab92 100644 --- a/src/vs/workbench/contrib/debug/test/common/mockDebug.ts +++ b/src/vs/workbench/contrib/debug/test/common/mockDebug.ts @@ -7,7 +7,7 @@ import { URI as uri } from 'vs/base/common/uri'; import { Event } from 'vs/base/common/event'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { Position } from 'vs/editor/common/core/position'; -import { ILaunch, IDebugService, State, IDebugSession, IConfigurationManager, IStackFrame, IBreakpointData, IBreakpointUpdateData, IConfig, IDebugModel, IViewModel, IBreakpoint, LoadedSourceEvent, IThread, IRawModelUpdate, IFunctionBreakpoint, IExceptionBreakpoint, IDebugger, IExceptionInfo, AdapterEndEvent, IReplElement, IExpression, IReplElementSource } from 'vs/workbench/contrib/debug/common/debug'; +import { ILaunch, IDebugService, State, IDebugSession, IConfigurationManager, IStackFrame, IBreakpointData, IBreakpointUpdateData, IConfig, IDebugModel, IViewModel, IBreakpoint, LoadedSourceEvent, IThread, IRawModelUpdate, IFunctionBreakpoint, IExceptionBreakpoint, IDebugger, IExceptionInfo, AdapterEndEvent, IReplElement, IExpression, IReplElementSource, IDataBreakpoint } from 'vs/workbench/contrib/debug/common/debug'; import { Source } from 'vs/workbench/contrib/debug/common/debugSource'; import { CompletionItem } from 'vs/editor/common/modes'; import Severity from 'vs/base/common/severity'; @@ -79,6 +79,13 @@ export class MockDebugService implements IDebugService { throw new Error('not implemented'); } + addDataBreakpoint(label: string, dataId: string, canPersist: boolean): Promise { + throw new Error('Method not implemented.'); + } + removeDataBreakpoints(id?: string | undefined): Promise { + throw new Error('Method not implemented.'); + } + public addReplExpression(name: string): Promise { throw new Error('not implemented'); } @@ -125,6 +132,13 @@ export class MockDebugService implements IDebugService { } export class MockSession implements IDebugSession { + dataBreakpointInfo(name: string, variablesReference?: number | undefined): Promise<{ dataId: string | null; description: string; canPersist?: boolean | undefined; }> { + throw new Error('Method not implemented.'); + } + + sendDataBreakpoints(dbps: IDataBreakpoint[]): Promise { + throw new Error('Method not implemented.'); + } subId: string | undefined; From 623855b7c45993cf3eae9bef262f5222cd9fd827 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 16 Aug 2019 15:56:38 +0200 Subject: [PATCH 731/861] Introduce and adopt asCSSUrl --- src/vs/base/browser/dom.ts | 7 +++++++ src/vs/editor/browser/services/codeEditorServiceImpl.ts | 8 ++++---- .../platform/actions/browser/menuEntryActionViewItem.ts | 6 +++--- src/vs/workbench/api/browser/viewsExtensionPoint.ts | 4 ++-- .../browser/parts/activitybar/activitybarActions.ts | 2 +- .../workbench/browser/parts/quickinput/quickInputUtils.ts | 4 ++-- src/vs/workbench/browser/parts/views/customView.ts | 2 +- .../extensions/browser/extensionsWorkbenchService.ts | 2 +- .../contrib/webview/browser/webviewEditorInput.ts | 6 +++--- .../services/themes/browser/fileIconThemeData.ts | 6 +++--- 10 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 717041747da..0bca0bfdec4 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -1204,3 +1204,10 @@ export function asDomUri(uri: URI): URI { } return uri; } + +/** + * returns url('...') + */ +export function asCSSUrl(uri: URI): string { + return `url('${asDomUri(uri).toString(true).replace(/'/g, '%27')}')`; +} diff --git a/src/vs/editor/browser/services/codeEditorServiceImpl.ts b/src/vs/editor/browser/services/codeEditorServiceImpl.ts index 106c75b5d04..c7cf1da3f45 100644 --- a/src/vs/editor/browser/services/codeEditorServiceImpl.ts +++ b/src/vs/editor/browser/services/codeEditorServiceImpl.ts @@ -229,11 +229,11 @@ const _CSS_MAP: { [prop: string]: string; } = { cursor: 'cursor:{0};', letterSpacing: 'letter-spacing:{0};', - gutterIconPath: 'background:url(\'{0}\') center center no-repeat;', + gutterIconPath: 'background:{0} center center no-repeat;', gutterIconSize: 'background-size:{0};', contentText: 'content:\'{0}\';', - contentIconPath: 'content:url(\'{0}\');', + contentIconPath: 'content:{0};', margin: 'margin:{0};', width: 'width:{0};', height: 'height:{0};' @@ -399,7 +399,7 @@ class DecorationCSSRules { if (typeof opts !== 'undefined') { this.collectBorderSettingsCSSText(opts, cssTextArr); if (typeof opts.contentIconPath !== 'undefined') { - cssTextArr.push(strings.format(_CSS_MAP.contentIconPath, dom.asDomUri(URI.revive(opts.contentIconPath)).toString(true).replace(/'/g, '%27'))); + cssTextArr.push(strings.format(_CSS_MAP.contentIconPath, dom.asCSSUrl(URI.revive(opts.contentIconPath)))); } if (typeof opts.contentText === 'string') { const truncated = opts.contentText.match(/^.*$/m)![0]; // only take first line @@ -426,7 +426,7 @@ class DecorationCSSRules { const cssTextArr: string[] = []; if (typeof opts.gutterIconPath !== 'undefined') { - cssTextArr.push(strings.format(_CSS_MAP.gutterIconPath, dom.asDomUri(URI.revive(opts.gutterIconPath)).toString(true).replace(/'/g, '%27'))); + cssTextArr.push(strings.format(_CSS_MAP.gutterIconPath, dom.asCSSUrl(URI.revive(opts.gutterIconPath)))); if (typeof opts.gutterIconSize !== 'undefined') { cssTextArr.push(strings.format(_CSS_MAP.gutterIconSize, opts.gutterIconSize)); } diff --git a/src/vs/platform/actions/browser/menuEntryActionViewItem.ts b/src/vs/platform/actions/browser/menuEntryActionViewItem.ts index 6c3102bc4df..01d88e2ece8 100644 --- a/src/vs/platform/actions/browser/menuEntryActionViewItem.ts +++ b/src/vs/platform/actions/browser/menuEntryActionViewItem.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { addClasses, createCSSRule, removeClasses, asDomUri } from 'vs/base/browser/dom'; +import { addClasses, createCSSRule, removeClasses, asCSSUrl } from 'vs/base/browser/dom'; import { domEvent } from 'vs/base/browser/event'; import { ActionViewItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { IAction } from 'vs/base/common/actions'; @@ -244,8 +244,8 @@ export class MenuEntryActionViewItem extends ActionViewItem { iconClass = MenuEntryActionViewItem.ICON_PATH_TO_CSS_RULES.get(iconPathMapKey)!; } else { iconClass = ids.nextId(); - createCSSRule(`.icon.${iconClass}`, `background-image: url("${asDomUri(item.iconLocation.light || item.iconLocation.dark).toString()}")`); - createCSSRule(`.vs-dark .icon.${iconClass}, .hc-black .icon.${iconClass}`, `background-image: url("${asDomUri(item.iconLocation.dark).toString()}")`); + createCSSRule(`.icon.${iconClass}`, `background-image: ${asCSSUrl(item.iconLocation.light || item.iconLocation.dark)}`); + createCSSRule(`.vs-dark .icon.${iconClass}, .hc-black .icon.${iconClass}`, `background-image: ${asCSSUrl(item.iconLocation.dark)}`); MenuEntryActionViewItem.ICON_PATH_TO_CSS_RULES.set(iconPathMapKey, iconClass); } diff --git a/src/vs/workbench/api/browser/viewsExtensionPoint.ts b/src/vs/workbench/api/browser/viewsExtensionPoint.ts index b12e7ec2bf6..2a5030ae9f8 100644 --- a/src/vs/workbench/api/browser/viewsExtensionPoint.ts +++ b/src/vs/workbench/api/browser/viewsExtensionPoint.ts @@ -37,7 +37,7 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; -import { createCSSRule, asDomUri } from 'vs/base/browser/dom'; +import { createCSSRule, asCSSUrl } from 'vs/base/browser/dom'; export interface IUserFriendlyViewsContainerDescriptor { id: string; @@ -356,7 +356,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution { // Generate CSS to show the icon in the activity bar const iconClass = `.monaco-workbench .activitybar .monaco-action-bar .action-label.${cssClass}`; - createCSSRule(iconClass, `-webkit-mask: url('${asDomUri(icon)}') no-repeat 50% 50%; -webkit-mask-size: 24px;`); + createCSSRule(iconClass, `-webkit-mask: ${asCSSUrl(icon)} no-repeat 50% 50%; -webkit-mask-size: 24px;`); } return viewContainer; diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts b/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts index d73545fb3ef..5c4c70a2e75 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts @@ -171,7 +171,7 @@ export class PlaceHolderViewletActivityAction extends ViewletActivityAction { super({ id, name: id, cssClass: `extensionViewlet-placeholder-${id.replace(/\./g, '-')}` }, viewletService, layoutService, telemetryService); const iconClass = `.monaco-workbench .activitybar .monaco-action-bar .action-label.${this.class}`; // Generate Placeholder CSS to show the icon in the activity bar - DOM.createCSSRule(iconClass, `-webkit-mask: url('${DOM.asDomUri(iconUrl) || ''}') no-repeat 50% 50%; -webkit-mask-size: 24px;`); + DOM.createCSSRule(iconClass, `-webkit-mask: ${DOM.asCSSUrl(iconUrl)} no-repeat 50% 50%; -webkit-mask-size: 24px;`); } setActivity(activity: IActivity): void { diff --git a/src/vs/workbench/browser/parts/quickinput/quickInputUtils.ts b/src/vs/workbench/browser/parts/quickinput/quickInputUtils.ts index 378d2be0c4c..690543c6959 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInputUtils.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInputUtils.ts @@ -22,8 +22,8 @@ export function getIconClass(iconPath: { dark: URI; light?: URI; } | undefined): iconClass = iconPathToClass[key]; } else { iconClass = iconClassGenerator.nextId(); - dom.createCSSRule(`.${iconClass}`, `background-image: url("${dom.asDomUri(iconPath.light || iconPath.dark).toString()}")`); - dom.createCSSRule(`.vs-dark .${iconClass}, .hc-black .${iconClass}`, `background-image: url("${dom.asDomUri(iconPath.dark).toString()}")`); + dom.createCSSRule(`.${iconClass}`, `background-image: ${dom.asCSSUrl(iconPath.light || iconPath.dark)}`); + dom.createCSSRule(`.vs-dark .${iconClass}, .hc-black .${iconClass}`, `background-image: ${dom.asCSSUrl(iconPath.dark)}`); iconPathToClass[key] = iconClass; } diff --git a/src/vs/workbench/browser/parts/views/customView.ts b/src/vs/workbench/browser/parts/views/customView.ts index 9fd89851d9d..7e98724953d 100644 --- a/src/vs/workbench/browser/parts/views/customView.ts +++ b/src/vs/workbench/browser/parts/views/customView.ts @@ -756,7 +756,7 @@ class TreeRenderer extends Disposable implements ITreeRenderer{ $treeViewId: this.treeViewId, $treeItemHandle: node.handle }; templateData.actionBar.push(this.menus.getResourceActions(node), { icon: true, label: false }); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index e82544c68e3..31f9d115e24 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -131,7 +131,7 @@ class Extension implements IExtension { private get localIconUrl(): string | null { if (this.local && this.local.manifest.icon) { - return asDomUri(resources.joinPath(this.local.location, this.local.manifest.icon)).toString(); + return asDomUri(resources.joinPath(this.local.location, this.local.manifest.icon)).toString(true); } return null; } diff --git a/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts b/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts index c91e93d915f..614097c5ba9 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts @@ -39,11 +39,11 @@ class WebviewIconsManager { this._icons.forEach((value, key) => { const webviewSelector = `.show-file-icons .webview-${key}-name-file-icon::before`; if (URI.isUri(value)) { - cssRules.push(`${webviewSelector} { content: ""; background-image: url(${dom.asDomUri(value).toString()}); }`); + cssRules.push(`${webviewSelector} { content: ""; background-image: ${dom.asCSSUrl(value)}; }`); } else { - cssRules.push(`.vs ${webviewSelector} { content: ""; background-image: url(${dom.asDomUri(value.light).toString()}); }`); - cssRules.push(`.vs-dark ${webviewSelector} { content: ""; background-image: url(${dom.asDomUri(value.dark).toString()}); }`); + cssRules.push(`.vs ${webviewSelector} { content: ""; background-image: ${dom.asCSSUrl(value.light)}; }`); + cssRules.push(`.vs-dark ${webviewSelector} { content: ""; background-image: ${dom.asCSSUrl(value.dark)}; }`); } }); this._styleElement.innerHTML = cssRules.join('\n'); diff --git a/src/vs/workbench/services/themes/browser/fileIconThemeData.ts b/src/vs/workbench/services/themes/browser/fileIconThemeData.ts index 3059579a649..2512af088a0 100644 --- a/src/vs/workbench/services/themes/browser/fileIconThemeData.ts +++ b/src/vs/workbench/services/themes/browser/fileIconThemeData.ts @@ -11,7 +11,7 @@ import * as Json from 'vs/base/common/json'; import { ExtensionData, IThemeExtensionPoint, IFileIconTheme } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { IFileService } from 'vs/platform/files/common/files'; import { getParseErrorMessage } from 'vs/base/common/jsonErrorMessages'; -import { asDomUri } from 'vs/base/browser/dom'; +import { asCSSUrl } from 'vs/base/browser/dom'; export class FileIconThemeData implements IFileIconTheme { id: string; @@ -332,7 +332,7 @@ function _processIconThemeDocument(id: string, iconThemeDocumentLocation: URI, i let fonts = iconThemeDocument.fonts; if (Array.isArray(fonts)) { fonts.forEach(font => { - let src = font.src.map(l => `url('${asDomUri(resolvePath(l.path))}') format('${l.format}')`).join(', '); + let src = font.src.map(l => `${asCSSUrl(resolvePath(l.path))} format('${l.format}')`).join(', '); cssRules.push(`@font-face { src: ${src}; font-family: '${font.id}'; font-weight: ${font.weight}; font-style: ${font.style}; }`); }); cssRules.push(`.show-file-icons .file-icon::before, .show-file-icons .folder-icon::before, .show-file-icons .rootfolder-icon::before { font-family: '${fonts[0].id}'; font-size: ${fonts[0].size || '150%'}}`); @@ -343,7 +343,7 @@ function _processIconThemeDocument(id: string, iconThemeDocumentLocation: URI, i let definition = iconThemeDocument.iconDefinitions[defId]; if (definition) { if (definition.iconPath) { - cssRules.push(`${selectors.join(', ')} { content: ' '; background-image: url("${asDomUri(resolvePath(definition.iconPath))}"); }`); + cssRules.push(`${selectors.join(', ')} { content: ' '; background-image: ${asCSSUrl(resolvePath(definition.iconPath))}; }`); } if (definition.fontCharacter || definition.fontColor) { let body = ''; From 265dba559806b4298fa8f3e7923b80c2d06d9c9b Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 16 Aug 2019 17:37:28 +0200 Subject: [PATCH 732/861] Fixes microsoft/vscode-remote-release#687: - remove ipc message that passes over the resolved authority - don't go through the protocol handler when hitting 127.0.0.1 --- src/vs/base/browser/dom.ts | 16 +-- src/vs/base/common/network.ts | 17 ++- .../electron-browser/workbench/workbench.html | 2 +- src/vs/code/electron-main/app.ts | 122 +----------------- .../remoteAuthorityResolverService.ts | 2 - 5 files changed, 31 insertions(+), 128 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 0bca0bfdec4..a97f27a51e7 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -15,7 +15,7 @@ import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle' import * as platform from 'vs/base/common/platform'; import { coalesce } from 'vs/base/common/arrays'; import { URI } from 'vs/base/common/uri'; -import { Schemas } from 'vs/base/common/network'; +import { Schemas, RemoteAuthorities } from 'vs/base/common/network'; export function clearNode(node: HTMLElement): void { while (node.firstChild) { @@ -1193,14 +1193,14 @@ export function asDomUri(uri: URI): URI { if (!uri) { return uri; } - if (!platform.isWeb) { - //todo@joh remove this once we have sw in electron going - return uri; - } if (Schemas.vscodeRemote === uri.scheme) { - // rewrite vscode-remote-uris to uris of the window location - // so that they can be intercepted by the service worker - return _location.with({ path: '/vscode-remote', query: JSON.stringify(uri) }); + if (platform.isWeb) { + // rewrite vscode-remote-uris to uris of the window location + // so that they can be intercepted by the service worker + return _location.with({ path: '/vscode-remote', query: JSON.stringify(uri) }); + } else { + return RemoteAuthorities.rewrite(uri.authority, uri.path); + } } return uri; } diff --git a/src/vs/base/common/network.ts b/src/vs/base/common/network.ts index f3006bdf3e1..bccc2153602 100644 --- a/src/vs/base/common/network.ts +++ b/src/vs/base/common/network.ts @@ -3,6 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { URI } from 'vs/base/common/uri'; + export namespace Schemas { /** @@ -62,13 +64,26 @@ class RemoteAuthoritiesImpl { } public set(authority: string, host: string, port: number): void { - this._hosts[authority] = host; + this._hosts[authority] = (host === 'localhost' ? '127.0.0.1' : host); this._ports[authority] = port; } public setConnectionToken(authority: string, connectionToken: string): void { this._connectionTokens[authority] = connectionToken; } + + public rewrite(authority: string, path: string): URI { + const host = this._hosts[authority]; + const port = this._ports[authority]; + const connectionToken = this._connectionTokens[authority]; + const scheme = (host === '127.0.0.1' ? Schemas.http : Schemas.vscodeRemote); + return URI.from({ + scheme: scheme, + authority: `${host}:${port}`, + path: `/vscode-remote2`, + query: `path=${encodeURIComponent(path)}&tkn=${encodeURIComponent(connectionToken)}` + }); + } } export const RemoteAuthorities = new RemoteAuthoritiesImpl(); diff --git a/src/vs/code/electron-browser/workbench/workbench.html b/src/vs/code/electron-browser/workbench/workbench.html index 483d01493f5..bef3d951473 100644 --- a/src/vs/code/electron-browser/workbench/workbench.html +++ b/src/vs/code/electron-browser/workbench/workbench.html @@ -3,7 +3,7 @@ - + diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index c17c592775f..f60f4f73c44 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -39,7 +39,6 @@ import { ProxyAuthHandler } from 'vs/code/electron-main/auth'; import { Disposable } from 'vs/base/common/lifecycle'; import { IWindowsMainService, ICodeWindow } from 'vs/platform/windows/electron-main/windows'; import { IHistoryMainService } from 'vs/platform/history/common/history'; -import { withUndefinedAsNull } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { WorkspacesChannel } from 'vs/platform/workspaces/node/workspacesIpc'; import { IWorkspacesMainService, hasWorkspaceFileExtension } from 'vs/platform/workspaces/common/workspaces'; @@ -54,7 +53,6 @@ import { LogLevelSetterChannel } from 'vs/platform/log/common/logIpc'; import { setUnexpectedErrorHandler, onUnexpectedError } from 'vs/base/common/errors'; import { ElectronURLListener } from 'vs/platform/url/electron-main/electronUrlListener'; import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver'; -import { connectRemoteAgentManagement, ManagementPersistentConnection, IConnectionOptions } from 'vs/platform/remote/common/remoteAgentConnection'; import { IMenubarService } from 'vs/platform/menubar/common/menubar'; import { MenubarService } from 'vs/platform/menubar/electron-main/menubarService'; import { MenubarChannel } from 'vs/platform/menubar/node/menubarIpc'; @@ -65,8 +63,6 @@ import { homedir } from 'os'; import { join, sep } from 'vs/base/common/path'; import { localize } from 'vs/nls'; import { Schemas } from 'vs/base/common/network'; -import { REMOTE_FILE_SYSTEM_CHANNEL_NAME } from 'vs/platform/remote/common/remoteAgentFileSystemChannel'; -import { ResolvedAuthority } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { SnapUpdateService } from 'vs/platform/update/electron-main/updateService.snap'; import { IStorageMainService, StorageMainService } from 'vs/platform/storage/node/storageMainService'; import { GlobalStorageDatabaseChannel } from 'vs/platform/storage/node/storageIpc'; @@ -76,11 +72,7 @@ import { IBackupMainService } from 'vs/platform/backup/common/backup'; import { HistoryMainService } from 'vs/platform/history/electron-main/historyMainService'; import { URLService } from 'vs/platform/url/common/urlService'; import { WorkspacesMainService } from 'vs/platform/workspaces/electron-main/workspacesMainService'; -import { RemoteAgentConnectionContext } from 'vs/platform/remote/common/remoteAgentEnvironment'; -import { nodeSocketFactory } from 'vs/platform/remote/node/nodeSocketFactory'; -import { VSBuffer } from 'vs/base/common/buffer'; import { statSync } from 'fs'; -import { ISignService } from 'vs/platform/sign/common/sign'; import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsIpc'; import { IDiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsService'; import { FileService } from 'vs/platform/files/common/fileService'; @@ -103,8 +95,7 @@ export class CodeApplication extends Disposable { @IEnvironmentService private readonly environmentService: IEnvironmentService, @ILifecycleService private readonly lifecycleService: ILifecycleService, @IConfigurationService private readonly configurationService: IConfigurationService, - @IStateService private readonly stateService: IStateService, - @ISignService private readonly signService: ISignService + @IStateService private readonly stateService: IStateService ) { super(); @@ -697,112 +688,11 @@ export class CodeApplication extends Disposable { } private handleRemoteAuthorities(): void { - const connectionPool: Map = new Map(); - - class ActiveConnection { - private readonly _authority: string; - private readonly _connection: Promise; - private readonly _disposeRunner: RunOnceScheduler; - - constructor(authority: string, host: string, port: number, signService: ISignService) { - this._authority = authority; - - const options: IConnectionOptions = { - commit: product.commit, - socketFactory: nodeSocketFactory, - addressProvider: { - getAddress: () => { - return Promise.resolve({ host, port }); - } - }, - signService - }; - - this._connection = connectRemoteAgentManagement(options, authority, `main`); - this._disposeRunner = new RunOnceScheduler(() => this.dispose(), 5000); - } - - dispose(): void { - this._disposeRunner.dispose(); - connectionPool.delete(this._authority); - this._connection.then(connection => connection.dispose()); - } - - async getClient(): Promise> { - this._disposeRunner.schedule(); - const connection = await this._connection; - - return connection.client; - } - } - - const resolvedAuthorities = new Map(); - ipc.on('vscode:remoteAuthorityResolved', (event: Electron.Event, data: ResolvedAuthority) => { - this.logService.info('Received resolved authority', data.authority); - - resolvedAuthorities.set(data.authority, data); - - // Make sure to close and remove any existing connections - if (connectionPool.has(data.authority)) { - connectionPool.get(data.authority)!.dispose(); - } - }); - - const resolveAuthority = (authority: string): ResolvedAuthority | null => { - this.logService.info('Resolving authority', authority); - - if (authority.indexOf('+') >= 0) { - if (resolvedAuthorities.has(authority)) { - return withUndefinedAsNull(resolvedAuthorities.get(authority)); - } - - this.logService.info('Didnot find resolved authority for', authority); - - return null; - } else { - const [host, strPort] = authority.split(':'); - const port = parseInt(strPort, 10); - - return { authority, host, port }; - } - }; - - protocol.registerBufferProtocol(Schemas.vscodeRemote, async (request, callback) => { - if (request.method !== 'GET') { - return callback(undefined); - } - - const uri = URI.parse(request.url); - - let activeConnection: ActiveConnection | undefined; - if (connectionPool.has(uri.authority)) { - activeConnection = connectionPool.get(uri.authority); - } else { - const resolvedAuthority = resolveAuthority(uri.authority); - if (!resolvedAuthority) { - callback(undefined); - return; - } - - activeConnection = new ActiveConnection(uri.authority, resolvedAuthority.host, resolvedAuthority.port, this.signService); - connectionPool.set(uri.authority, activeConnection); - } - - try { - const rawClient = await activeConnection!.getClient(); - if (connectionPool.has(uri.authority)) { // not disposed in the meantime - const channel = rawClient.getChannel(REMOTE_FILE_SYSTEM_CHANNEL_NAME); - - // TODO@alex don't use call directly, wrap it around a `RemoteExtensionsFileSystemProvider` - const fileContents = await channel.call('readFile', [uri]); - callback(fileContents.buffer); - } else { - callback(undefined); - } - } catch (err) { - onUnexpectedError(err); - callback(undefined); - } + protocol.registerHttpProtocol(Schemas.vscodeRemote, (request, callback) => { + callback({ + url: request.url.replace(/^vscode-remote:/, 'http:'), + method: request.method + }); }); } } diff --git a/src/vs/platform/remote/electron-browser/remoteAuthorityResolverService.ts b/src/vs/platform/remote/electron-browser/remoteAuthorityResolverService.ts index 9ab777f67bd..45ad072f2eb 100644 --- a/src/vs/platform/remote/electron-browser/remoteAuthorityResolverService.ts +++ b/src/vs/platform/remote/electron-browser/remoteAuthorityResolverService.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import { ResolvedAuthority, IRemoteAuthorityResolverService, ResolverResult, ResolvedOptions } from 'vs/platform/remote/common/remoteAuthorityResolver'; -import { ipcRenderer as ipc } from 'electron'; import * as errors from 'vs/base/common/errors'; import { RemoteAuthorities } from 'vs/base/common/network'; @@ -50,7 +49,6 @@ export class RemoteAuthorityResolverService implements IRemoteAuthorityResolverS setResolvedAuthority(resolvedAuthority: ResolvedAuthority, options?: ResolvedOptions) { if (this._resolveAuthorityRequests[resolvedAuthority.authority]) { let request = this._resolveAuthorityRequests[resolvedAuthority.authority]; - ipc.send('vscode:remoteAuthorityResolved', resolvedAuthority); RemoteAuthorities.set(resolvedAuthority.authority, resolvedAuthority.host, resolvedAuthority.port); request.resolve({ authority: resolvedAuthority, options }); } From 64875aa7c6198d7d164fbfee2759ed045bebd209 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Fri, 16 Aug 2019 17:58:30 +0200 Subject: [PATCH 733/861] Introduce machine overridable setting --- .../configuration/common/configurationRegistry.ts | 4 ++++ .../api/common/configurationExtensionPoint.ts | 13 ++++++++----- .../preferences/browser/settingsTreeModels.ts | 14 +++++++++----- .../services/configuration/common/configuration.ts | 8 ++++---- .../preferences/common/preferencesModels.ts | 8 ++++++-- 5 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/vs/platform/configuration/common/configurationRegistry.ts b/src/vs/platform/configuration/common/configurationRegistry.ts index 0d27f890edf..329276d4e46 100644 --- a/src/vs/platform/configuration/common/configurationRegistry.ts +++ b/src/vs/platform/configuration/common/configurationRegistry.ts @@ -99,6 +99,10 @@ export const enum ConfigurationScope { * Resource specific configuration, which can be configured in the user, workspace or folder settings. */ RESOURCE, + /** + * Machine specific configuration that can also be configured in workspace or folder settings. + */ + MACHINE_OVERRIDABLE, } export interface IConfigurationPropertySchema extends IJSONSchema { diff --git a/src/vs/workbench/api/common/configurationExtensionPoint.ts b/src/vs/workbench/api/common/configurationExtensionPoint.ts index aa05f7e1187..d36d498330d 100644 --- a/src/vs/workbench/api/common/configurationExtensionPoint.ts +++ b/src/vs/workbench/api/common/configurationExtensionPoint.ts @@ -39,13 +39,14 @@ const configurationEntrySchema: IJSONSchema = { }, scope: { type: 'string', - enum: ['application', 'machine', 'window', 'resource'], + enum: ['application', 'machine', 'window', 'resource', 'machine-overridable'], default: 'window', enumDescriptions: [ - nls.localize('scope.application.description', "Application specific configuration, which can be configured only in the user settings."), - nls.localize('scope.machine.description', "Machine specific configuration, which can be configured only in the user settings when the extension is running locally, or only in the remote settings when the extension is running remotely."), - nls.localize('scope.window.description', "Window specific configuration, which can be configured in the user, remote or workspace settings."), - nls.localize('scope.resource.description', "Resource specific configuration, which can be configured in the user, remote, workspace or folder settings.") + nls.localize('scope.application.description', "Configuration that can be configured only in the user settings."), + nls.localize('scope.machine.description', "Configuration that can be configured only in the user settings when the extension is running locally, or only in the remote settings when the extension is running remotely."), + nls.localize('scope.window.description', "Configuration that can be configured in the user, remote or workspace settings."), + nls.localize('scope.resource.description', "Configuration that can be configured in the user, remote, workspace or folder settings."), + nls.localize('scope.machine-overridable.description', "Machine configuration that can be configured also in workspace or folder settings.") ], description: nls.localize('scope.description', "Scope in which the configuration is applicable. Available scopes are `application`, `machine`, `window` and `resource`.") }, @@ -215,6 +216,8 @@ function validateProperties(configuration: IConfigurationNode, extension: IExten propertyConfiguration.scope = ConfigurationScope.MACHINE; } else if (propertyConfiguration.scope.toString() === 'resource') { propertyConfiguration.scope = ConfigurationScope.RESOURCE; + } else if (propertyConfiguration.scope.toString() === 'machine-overridable') { + propertyConfiguration.scope = ConfigurationScope.MACHINE_OVERRIDABLE; } else { propertyConfiguration.scope = ConfigurationScope.WINDOW; } diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts index c85026c360b..efe952907cd 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts @@ -9,12 +9,12 @@ import { isArray, withUndefinedAsNull } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; import { SettingsTarget } from 'vs/workbench/contrib/preferences/browser/preferencesWidgets'; import { ITOCEntry, knownAcronyms, knownTermMappings } from 'vs/workbench/contrib/preferences/browser/settingsLayout'; import { MODIFIED_SETTING_TAG } from 'vs/workbench/contrib/preferences/common/preferences'; import { IExtensionSetting, ISearchResult, ISetting, SettingValueType } from 'vs/workbench/services/preferences/common/preferences'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; +import { FOLDER_SCOPES, WORKSPACE_SCOPES, REMOTE_MACHINE_SCOPES, LOCAL_MACHINE_SCOPES } from 'vs/workbench/services/configuration/common/configuration'; export const ONLINE_SERVICES_SETTING_TAG = 'usesOnlineServices'; @@ -227,20 +227,24 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { matchesScope(scope: SettingsTarget, isRemote: boolean): boolean { const configTarget = URI.isUri(scope) ? ConfigurationTarget.WORKSPACE_FOLDER : scope; + if (!this.setting.scope) { + return true; + } + if (configTarget === ConfigurationTarget.WORKSPACE_FOLDER) { - return this.setting.scope === ConfigurationScope.RESOURCE; + return FOLDER_SCOPES.indexOf(this.setting.scope) !== -1; } if (configTarget === ConfigurationTarget.WORKSPACE) { - return this.setting.scope === ConfigurationScope.WINDOW || this.setting.scope === ConfigurationScope.RESOURCE; + return WORKSPACE_SCOPES.indexOf(this.setting.scope) !== -1; } if (configTarget === ConfigurationTarget.USER_REMOTE) { - return this.setting.scope === ConfigurationScope.MACHINE || this.setting.scope === ConfigurationScope.WINDOW || this.setting.scope === ConfigurationScope.RESOURCE; + return REMOTE_MACHINE_SCOPES.indexOf(this.setting.scope) !== -1; } if (configTarget === ConfigurationTarget.USER_LOCAL && isRemote) { - return this.setting.scope !== ConfigurationScope.MACHINE; + return LOCAL_MACHINE_SCOPES.indexOf(this.setting.scope) !== -1; } return true; diff --git a/src/vs/workbench/services/configuration/common/configuration.ts b/src/vs/workbench/services/configuration/common/configuration.ts index 170e3f136aa..a5f15850dbf 100644 --- a/src/vs/workbench/services/configuration/common/configuration.ts +++ b/src/vs/workbench/services/configuration/common/configuration.ts @@ -17,9 +17,9 @@ export const folderSettingsSchemaId = 'vscode://schemas/settings/folder'; export const launchSchemaId = 'vscode://schemas/launch'; export const LOCAL_MACHINE_SCOPES = [ConfigurationScope.APPLICATION, ConfigurationScope.WINDOW, ConfigurationScope.RESOURCE]; -export const REMOTE_MACHINE_SCOPES = [ConfigurationScope.MACHINE, ConfigurationScope.WINDOW, ConfigurationScope.RESOURCE]; -export const WORKSPACE_SCOPES = [ConfigurationScope.WINDOW, ConfigurationScope.RESOURCE]; -export const FOLDER_SCOPES = [ConfigurationScope.RESOURCE]; +export const REMOTE_MACHINE_SCOPES = [ConfigurationScope.MACHINE, ConfigurationScope.WINDOW, ConfigurationScope.RESOURCE, ConfigurationScope.MACHINE_OVERRIDABLE]; +export const WORKSPACE_SCOPES = [ConfigurationScope.WINDOW, ConfigurationScope.RESOURCE, ConfigurationScope.MACHINE_OVERRIDABLE]; +export const FOLDER_SCOPES = [ConfigurationScope.RESOURCE, ConfigurationScope.MACHINE_OVERRIDABLE]; export const TASKS_CONFIGURATION_KEY = 'tasks'; export const LAUNCH_CONFIGURATION_KEY = 'launch'; @@ -36,4 +36,4 @@ export interface IConfigurationCache { write(key: ConfigurationKey, content: string): Promise; remove(key: ConfigurationKey): Promise; -} \ No newline at end of file +} diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index d24d2a53f68..3e252282711 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -23,6 +23,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { EditorModel } from 'vs/workbench/common/editor'; import { IFilterMetadata, IFilterResult, IGroupFilter, IKeybindingsEditorModel, ISearchResultGroup, ISetting, ISettingMatch, ISettingMatcher, ISettingsEditorModel, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; import { withNullAsUndefined, isArray } from 'vs/base/common/types'; +import { FOLDER_SCOPES, WORKSPACE_SCOPES } from 'vs/workbench/services/configuration/common/configuration'; export const nullRange: IRange = { startLineNumber: -1, startColumn: -1, endLineNumber: -1, endColumn: -1 }; export function isNullRange(range: IRange): boolean { return range.startLineNumber === -1 && range.startColumn === -1 && range.endLineNumber === -1 && range.endColumn === -1; } @@ -659,11 +660,14 @@ export class DefaultSettings extends Disposable { } private matchesScope(property: IConfigurationNode): boolean { + if (!property.scope) { + return true; + } if (this.target === ConfigurationTarget.WORKSPACE_FOLDER) { - return property.scope === ConfigurationScope.RESOURCE; + return FOLDER_SCOPES.indexOf(property.scope) !== -1; } if (this.target === ConfigurationTarget.WORKSPACE) { - return property.scope === ConfigurationScope.WINDOW || property.scope === ConfigurationScope.RESOURCE; + return WORKSPACE_SCOPES.indexOf(property.scope) !== -1; } return true; } From ae42e42cf10df59773851b2d69db08189d6989eb Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Fri, 16 Aug 2019 18:08:16 +0200 Subject: [PATCH 734/861] Seti uses TS-icon for jsonc-language. Fixes #78261 --- extensions/theme-seti/build/update-icon-theme.js | 6 ++++-- extensions/theme-seti/cgmanifest.json | 2 +- extensions/theme-seti/icons/vs-seti-icon-theme.json | 10 ++++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/extensions/theme-seti/build/update-icon-theme.js b/extensions/theme-seti/build/update-icon-theme.js index 6819e853339..3e14951e342 100644 --- a/extensions/theme-seti/build/update-icon-theme.js +++ b/extensions/theme-seti/build/update-icon-theme.js @@ -32,7 +32,8 @@ let nonBuiltInLanguages = { // { fileNames, extensions } "haml": { extensions: ['haml'] }, "stylus": { extensions: ['styl'] }, "vala": { extensions: ['vala'] }, - "todo": { fileNames: ['todo'] } + "todo": { fileNames: ['todo'] }, + "jsonc": { extensions: ['json'] } }; let FROM_DISK = true; // set to true to take content from a repo checked out next to the vscode repo @@ -109,7 +110,7 @@ function downloadBinary(source, dest) { return new Promise((c, e) => { https.get(source, function (response) { switch (response.statusCode) { - case 200: + case 200: { let file = fs.createWriteStream(dest); response.on('data', function (chunk) { file.write(chunk); @@ -121,6 +122,7 @@ function downloadBinary(source, dest) { e(err.message); }); break; + } case 301: case 302: case 303: diff --git a/extensions/theme-seti/cgmanifest.json b/extensions/theme-seti/cgmanifest.json index c742c019ea3..1c86b8bcb2b 100644 --- a/extensions/theme-seti/cgmanifest.json +++ b/extensions/theme-seti/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "seti-ui", "repositoryUrl": "https://github.com/jesseweed/seti-ui", - "commitHash": "904c16acced1134a81b31d71d60293288c31334b" + "commitHash": "85a222708824c6f19bbecbec71633d2c97077dad" } }, "version": "0.1.0" diff --git a/extensions/theme-seti/icons/vs-seti-icon-theme.json b/extensions/theme-seti/icons/vs-seti-icon-theme.json index 52a81da4596..825ac52ee83 100644 --- a/extensions/theme-seti/icons/vs-seti-icon-theme.json +++ b/extensions/theme-seti/icons/vs-seti-icon-theme.json @@ -1564,6 +1564,7 @@ "version.md": "_clock", "version": "_clock", "mvnw": "_maven", + "tsconfig.json": "_tsconfig", "swagger.json": "_json_1", "swagger.yml": "_json_1", "swagger.yaml": "_json_1", @@ -1573,6 +1574,8 @@ "docker-healthcheck": "_docker_2", "docker-compose.yml": "_docker_3", "docker-compose.yaml": "_docker_3", + "docker-compose.override.yml": "_docker_3", + "docker-compose.override.yaml": "_docker_3", "firebase.json": "_firebase", "geckodriver": "_firefox", "gruntfile.js": "_grunt", @@ -1940,6 +1943,7 @@ "version.md": "_clock_light", "version": "_clock_light", "mvnw": "_maven_light", + "tsconfig.json": "_tsconfig_light", "swagger.json": "_json_1_light", "swagger.yml": "_json_1_light", "swagger.yaml": "_json_1_light", @@ -1949,6 +1953,8 @@ "docker-healthcheck": "_docker_2_light", "docker-compose.yml": "_docker_3_light", "docker-compose.yaml": "_docker_3_light", + "docker-compose.override.yml": "_docker_3_light", + "docker-compose.override.yaml": "_docker_3_light", "firebase.json": "_firebase_light", "geckodriver": "_firefox_light", "gruntfile.js": "_grunt_light", @@ -1980,5 +1986,5 @@ "npm-debug.log": "_npm_ignored_light" } }, - "version": "https://github.com/jesseweed/seti-ui/commit/904c16acced1134a81b31d71d60293288c31334b" -} + "version": "https://github.com/jesseweed/seti-ui/commit/85a222708824c6f19bbecbec71633d2c97077dad" +} \ No newline at end of file From 5470be1b7e73b18ec3741ed85422c8b657b68469 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 15 Aug 2019 16:37:36 -0700 Subject: [PATCH 735/861] flexible height input boxes and fitler out arrow keys --- src/vs/editor/contrib/find/findWidget.css | 6 +- src/vs/editor/contrib/find/findWidget.ts | 78 ++++++++++++++++++++++- 2 files changed, 80 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/find/findWidget.css b/src/vs/editor/contrib/find/findWidget.css index 7e1140442ea..515dcad1123 100644 --- a/src/vs/editor/contrib/find/findWidget.css +++ b/src/vs/editor/contrib/find/findWidget.css @@ -81,7 +81,7 @@ .monaco-editor .find-widget > .find-part .monaco-inputbox, .monaco-editor .find-widget > .replace-part .monaco-inputbox { - height: 25px; + min-height: 25px; } .monaco-editor .find-widget > .find-part .monaco-inputbox > .wrapper > .input { @@ -94,7 +94,9 @@ } .monaco-editor .find-widget > .find-part .monaco-inputbox > .wrapper > .input, -.monaco-editor .find-widget > .replace-part .monaco-inputbox > .wrapper > .input { +.monaco-editor .find-widget > .find-part .monaco-inputbox > .wrapper > .mirror, +.monaco-editor .find-widget > .replace-part .monaco-inputbox > .wrapper > .input, +.monaco-editor .find-widget > .replace-part .monaco-inputbox > .wrapper > .mirror { padding-top: 2px; padding-bottom: 2px; } diff --git a/src/vs/editor/contrib/find/findWidget.ts b/src/vs/editor/contrib/find/findWidget.ts index a25d3b5b464..8436fd3dd47 100644 --- a/src/vs/editor/contrib/find/findWidget.ts +++ b/src/vs/editor/contrib/find/findWidget.ts @@ -84,6 +84,22 @@ export class FindWidgetViewZone implements IViewZone { } } +function stopPropagationForMultiLineUpwards(event: IKeyboardEvent, value: string, textarea: HTMLTextAreaElement | null) { + const isMultiline = !!value.match(/\n/); + if (textarea && isMultiline && textarea.selectionStart > 0) { + event.stopPropagation(); + return; + } +} + +function stopPropagationForMultiLineDownwards(event: IKeyboardEvent, value: string, textarea: HTMLTextAreaElement | null) { + const isMultiline = !!value.match(/\n/); + if (textarea && isMultiline && textarea.selectionEnd < textarea.value.length) { + event.stopPropagation(); + return; + } +} + export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSashLayoutProvider { private static readonly ID = 'editor.contrib.findWidget'; private readonly _codeEditor: ICodeEditor; @@ -646,6 +662,10 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } } + private _tryUpdateHeight() { + + } + // ----- Public public focusFindInput(): void { @@ -705,6 +725,22 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas return; } + if (e.equals(KeyMod.WinCtrl | KeyCode.Enter)) { + const inputElement = this._findInput.inputBox.inputElement; + const start = inputElement.selectionStart; + const end = inputElement.selectionEnd; + const content = inputElement.value; + + if (start && end) { + const value = content.substr(0, start) + '\n' + content.substr(end); + this._findInput.inputBox.value = value; + inputElement.setSelectionRange(start + 1, start + 1); + this._findInput.inputBox.layout(); + e.preventDefault(); + return; + } + } + if (e.equals(KeyCode.Tab)) { if (this._isReplaceVisible) { this._replaceInputBox.focus(); @@ -720,6 +756,14 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas e.preventDefault(); return; } + + if (e.equals(KeyCode.UpArrow)) { + return stopPropagationForMultiLineUpwards(e, this._findInput.getValue(), this._findInput.domNode.querySelector('textarea')); + } + + if (e.equals(KeyCode.DownArrow)) { + return stopPropagationForMultiLineDownwards(e, this._findInput.getValue(), this._findInput.domNode.querySelector('textarea')); + } } private _onReplaceInputKeyDown(e: IKeyboardEvent): void { @@ -730,6 +774,22 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas return; } + if (e.equals(KeyMod.WinCtrl | KeyCode.Enter)) { + const inputElement = this._replaceInputBox.inputElement; + const start = inputElement.selectionStart; + const end = inputElement.selectionEnd; + const content = inputElement.value; + + if (start && end) { + const value = content.substr(0, start) + '\n' + content.substr(end); + this._replaceInputBox.value = value; + inputElement.setSelectionRange(start + 1, start + 1); + this._replaceInputBox.layout(); + e.preventDefault(); + return; + } + } + if (e.equals(KeyMod.CtrlCmd | KeyCode.Enter)) { this._controller.replaceAll(); e.preventDefault(); @@ -753,6 +813,14 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas e.preventDefault(); return; } + + if (e.equals(KeyCode.UpArrow)) { + return stopPropagationForMultiLineUpwards(e, this._replaceInputBox.value, this._replaceInputBox.element.querySelector('textarea')); + } + + if (e.equals(KeyCode.DownArrow)) { + return stopPropagationForMultiLineDownwards(e, this._replaceInputBox.value, this._replaceInputBox.element.querySelector('textarea')); + } } // ----- sash @@ -796,7 +864,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } catch (e) { return { content: e.message }; } - } + }, + flexibleHeight: true }, this._contextKeyService, true)); this._findInput.setRegex(!!this._state.isRegex); this._findInput.setCaseSensitive(!!this._state.matchCase); @@ -823,6 +892,9 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } } })); + this._register(this._findInput.inputBox.onDidHeightChange((e) => { + console.log(e); + })); if (platform.isLinux) { this._register(this._findInput.onMouseDown((e) => this._onFindInputMouseDown(e))); } @@ -907,7 +979,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas this._replaceInputBox = this._register(new ContextScopedHistoryInputBox(replaceInput, undefined, { ariaLabel: NLS_REPLACE_INPUT_LABEL, placeholder: NLS_REPLACE_INPUT_PLACEHOLDER, - history: [] + history: [], + flexibleHeight: true }, this._contextKeyService)); @@ -973,6 +1046,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas this._state.change({ isReplaceRevealed: !this._isReplaceVisible }, false); if (this._isReplaceVisible) { this._replaceInputBox.width = this._findInput.inputBox.width; + this._replaceInputBox.layout(); } this._showViewZone(); } From 60748bc0bc262160071ff0520beb0db97c174467 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 16 Aug 2019 10:41:41 -0700 Subject: [PATCH 736/861] Transion for find widget fade in fade out --- src/vs/editor/contrib/find/findWidget.css | 26 ++++++++++++++--------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/vs/editor/contrib/find/findWidget.css b/src/vs/editor/contrib/find/findWidget.css index 515dcad1123..1dd9a43b671 100644 --- a/src/vs/editor/contrib/find/findWidget.css +++ b/src/vs/editor/contrib/find/findWidget.css @@ -32,11 +32,11 @@ .monaco-editor .find-widget { position: absolute; z-index: 10; - top: -44px; /* find input height + shadow (10px) */ - height: 34px; /* find input height */ + top: unset; + bottom: 10px; overflow: hidden; line-height: 19px; - transition: top 200ms linear; + transition: top bottom 200ms linear; padding: 0 4px; } @@ -45,19 +45,15 @@ } /* Find widget when replace is toggled on */ -.monaco-editor .find-widget.replaceToggled { - top: -74px; /* find input height + replace input height + shadow (10px) */ - height: 64px; /* find input height + replace input height */ -} .monaco-editor .find-widget.replaceToggled > .replace-part { display: flex; display: -webkit-flex; - align-items: center; } .monaco-editor .find-widget.visible, .monaco-editor .find-widget.replaceToggled.visible { top: 0; + bottom: unset; } .monaco-editor .find-widget .monaco-inputbox .input { @@ -76,7 +72,6 @@ font-size: 12px; display: flex; display: -webkit-flex; - align-items: center; } .monaco-editor .find-widget > .find-part .monaco-inputbox, @@ -85,7 +80,6 @@ } .monaco-editor .find-widget > .find-part .monaco-inputbox > .wrapper > .input { - width: 100% !important; padding-right: 66px; } @@ -101,6 +95,18 @@ padding-bottom: 2px; } +.monaco-editor .find-widget > .find-part .find-actions { + height: 25px; + display: flex; + align-items: center; +} + +.monaco-editor .find-widget > .replace-part .replace-actions { + height: 25px; + display: flex; + align-items: center; +} + .monaco-editor .find-widget .monaco-findInput { vertical-align: middle; display: flex; From e1d5f1a51720a954899de50eb81028d23d148c8d Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 16 Aug 2019 10:45:16 -0700 Subject: [PATCH 737/861] tab sequence for preserve case button --- src/vs/editor/contrib/find/findWidget.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/vs/editor/contrib/find/findWidget.ts b/src/vs/editor/contrib/find/findWidget.ts index 8436fd3dd47..e2d476314cd 100644 --- a/src/vs/editor/contrib/find/findWidget.ts +++ b/src/vs/editor/contrib/find/findWidget.ts @@ -892,6 +892,14 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } } })); + this._register(this._findInput.onRegexKeyDown((e) => { + if (e.equals(KeyCode.Tab)) { + if (this._isReplaceVisible) { + this._preserveCase.focus(); + e.preventDefault(); + } + } + })); this._register(this._findInput.inputBox.onDidHeightChange((e) => { console.log(e); })); @@ -1001,6 +1009,22 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas this._replaceInputBox.focus(); } })); + this._register(this._preserveCase.onKeyDown((e) => { + if (e.equals(KeyCode.Tab)) { + if (this._prevBtn.isEnabled()) { + this._prevBtn.focus(); + } else if (this._nextBtn.isEnabled()) { + this._nextBtn.focus(); + } else if (this._toggleSelectionFind.domNode.tabIndex >= 0) { + this._toggleSelectionFind.focus(); + } else if (this._closeBtn.isEnabled()) { + this._closeBtn.focus(); + } + + e.preventDefault(); + } + } + )); // Replace one button this._replaceBtn = this._register(new SimpleButton({ From 88c58b2486fabac9997ae34f21f60babe2af2163 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 16 Aug 2019 10:45:47 -0700 Subject: [PATCH 738/861] flexible height of find widget and align options always at top --- src/vs/editor/contrib/find/findWidget.ts | 50 ++++++++++++++++++++---- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/src/vs/editor/contrib/find/findWidget.ts b/src/vs/editor/contrib/find/findWidget.ts index e2d476314cd..40393e06533 100644 --- a/src/vs/editor/contrib/find/findWidget.ts +++ b/src/vs/editor/contrib/find/findWidget.ts @@ -312,6 +312,10 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } } } + if ((e.isRevealed || e.isReplaceRevealed) && (this._state.isRevealed || this._state.isReplaceRevealed)) { + this._tryUpdateHeight(); + } + if (e.isRegex) { this._findInput.setRegex(this._state.isRegex); } @@ -663,7 +667,25 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } private _tryUpdateHeight() { + let totalheight = 0; + // find input margin top + totalheight += 4; + + // find input height + totalheight += this._findInput.inputBox.height + 2 /** input box border */; + + if (this._isReplaceVisible) { + // replace input margin + totalheight += 4; + + totalheight += this._replaceInputBox.height + 2 /** input box border */; + } + + // margin bottom + totalheight += 4; + + this._domNode.style.height = `${totalheight}px`; } // ----- Public @@ -901,7 +923,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } })); this._register(this._findInput.inputBox.onDidHeightChange((e) => { - console.log(e); + this._tryUpdateHeight(); })); if (platform.isLinux) { this._register(this._findInput.onMouseDown((e) => this._onFindInputMouseDown(e))); @@ -932,13 +954,16 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas let findPart = document.createElement('div'); findPart.className = 'find-part'; findPart.appendChild(this._findInput.domNode); - findPart.appendChild(this._matchesCount); - findPart.appendChild(this._prevBtn.domNode); - findPart.appendChild(this._nextBtn.domNode); + const actionsContainer = document.createElement('div'); + actionsContainer.className = 'find-actions'; + findPart.appendChild(actionsContainer); + actionsContainer.appendChild(this._matchesCount); + actionsContainer.appendChild(this._prevBtn.domNode); + actionsContainer.appendChild(this._nextBtn.domNode); // Toggle selection button this._toggleSelectionFind = this._register(new SimpleCheckbox({ - parent: findPart, + parent: actionsContainer, title: NLS_TOGGLE_SELECTION_FIND_TITLE + this._keybindingLabelFor(FIND_IDS.ToggleSearchScopeCommand), onChange: () => { if (this._toggleSelectionFind.checked) { @@ -978,7 +1003,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } })); - findPart.appendChild(this._closeBtn.domNode); + actionsContainer.appendChild(this._closeBtn.domNode); // Replace input let replaceInput = document.createElement('div'); @@ -996,6 +1021,9 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas this._register(this._replaceInputBox.onDidChange(() => { this._state.change({ replaceString: this._replaceInputBox.value }, false); })); + this._register(this._replaceInputBox.onDidHeightChange((e) => { + this._tryUpdateHeight(); + })); this._preserveCase = this._register(new Checkbox({ actionClassName: 'monaco-preserve-case', @@ -1059,8 +1087,13 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas let replacePart = document.createElement('div'); replacePart.className = 'replace-part'; replacePart.appendChild(replaceInput); - replacePart.appendChild(this._replaceBtn.domNode); - replacePart.appendChild(this._replaceAllBtn.domNode); + + const replaceActionsContainer = document.createElement('div'); + replaceActionsContainer.className = 'replace-actions'; + replacePart.appendChild(replaceActionsContainer); + + replaceActionsContainer.appendChild(this._replaceBtn.domNode); + replaceActionsContainer.appendChild(this._replaceAllBtn.domNode); // Toggle replace button this._toggleReplaceBtn = this._register(new SimpleButton({ @@ -1113,6 +1146,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas return; } this._domNode.style.width = `${width}px`; + this._findInput.inputBox.width = inputBoxWidth; if (this._isReplaceVisible) { this._replaceInputBox.width = inputBoxWidth; } From c6a7d840cb20d0d4e2cde7742aca464f2b8adc78 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 16 Aug 2019 10:52:48 -0700 Subject: [PATCH 739/861] Focus toggle find selection button --- src/vs/editor/contrib/find/findWidget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/find/findWidget.ts b/src/vs/editor/contrib/find/findWidget.ts index 40393e06533..fb73ecbd90c 100644 --- a/src/vs/editor/contrib/find/findWidget.ts +++ b/src/vs/editor/contrib/find/findWidget.ts @@ -1044,7 +1044,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } else if (this._nextBtn.isEnabled()) { this._nextBtn.focus(); } else if (this._toggleSelectionFind.domNode.tabIndex >= 0) { - this._toggleSelectionFind.focus(); + this._toggleSelectionFind.domNode.focus(); } else if (this._closeBtn.isEnabled()) { this._closeBtn.focus(); } From ab62d23bf9103d1074b544d90b4a731397f8ae83 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 16 Aug 2019 10:55:34 -0700 Subject: [PATCH 740/861] toggle selection find box should align with other checkbox --- src/vs/editor/contrib/find/findWidget.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/contrib/find/findWidget.ts b/src/vs/editor/contrib/find/findWidget.ts index fb73ecbd90c..46414dd3a56 100644 --- a/src/vs/editor/contrib/find/findWidget.ts +++ b/src/vs/editor/contrib/find/findWidget.ts @@ -1043,8 +1043,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas this._prevBtn.focus(); } else if (this._nextBtn.isEnabled()) { this._nextBtn.focus(); - } else if (this._toggleSelectionFind.domNode.tabIndex >= 0) { - this._toggleSelectionFind.domNode.focus(); + } else if (this._toggleSelectionFind.isEnabled()) { + this._toggleSelectionFind.focus(); } else if (this._closeBtn.isEnabled()) { this._closeBtn.focus(); } @@ -1209,6 +1209,10 @@ class SimpleCheckbox extends Widget { return this._domNode; } + public isEnabled(): boolean { + return (this._domNode.tabIndex >= 0); + } + public get checked(): boolean { return this._checkbox.checked; } @@ -1218,7 +1222,7 @@ class SimpleCheckbox extends Widget { } public focus(): void { - this._checkbox.focus(); + this._domNode.focus(); } private enable(): void { From 833507b823c74a94239d0f654ec1cf5aa0f59f37 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 16 Aug 2019 11:21:54 -0700 Subject: [PATCH 741/861] update textarea width when find widget or editor resizes --- src/vs/editor/contrib/find/findWidget.css | 6 ++++++ src/vs/editor/contrib/find/findWidget.ts | 7 ++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/contrib/find/findWidget.css b/src/vs/editor/contrib/find/findWidget.css index 1dd9a43b671..f862d6eaf70 100644 --- a/src/vs/editor/contrib/find/findWidget.css +++ b/src/vs/editor/contrib/find/findWidget.css @@ -80,6 +80,7 @@ } .monaco-editor .find-widget > .find-part .monaco-inputbox > .wrapper > .input { + width: 100% !important; padding-right: 66px; } @@ -114,6 +115,11 @@ flex:1; } +.monaco-editor .find-widget .monaco-findInput .monaco-scrollable-element { + /* Make sure textarea inherits the width correctly */ + width: 100%; +} + .monaco-editor .find-widget .matchesCount { display: flex; display: -webkit-flex; diff --git a/src/vs/editor/contrib/find/findWidget.ts b/src/vs/editor/contrib/find/findWidget.ts index 46414dd3a56..dd7419811ae 100644 --- a/src/vs/editor/contrib/find/findWidget.ts +++ b/src/vs/editor/contrib/find/findWidget.ts @@ -635,7 +635,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas if (widgetWidth > FIND_WIDGET_INITIAL_WIDTH) { // as the widget is resized by users, we may need to change the max width of the widget as the editor width changes. this._domNode.style.maxWidth = `${editorWidth - 28 - minimapWidth - 15}px`; - this._replaceInputBox.inputElement.style.width = `${dom.getTotalWidth(this._findInput.inputBox.inputElement)}px`; + this._replaceInputBox.width = dom.getTotalWidth(this._findInput.inputBox.inputElement); return; } } @@ -659,9 +659,10 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } if (this._resized) { - let findInputWidth = dom.getTotalWidth(this._findInput.inputBox.inputElement); + this._findInput.inputBox.layout(); + let findInputWidth = this._findInput.inputBox.width; if (findInputWidth > 0) { - this._replaceInputBox.inputElement.style.width = `${findInputWidth}px`; + this._replaceInputBox.width = findInputWidth; } } } From dc5f96bc62a049300cf32e23af990cba27bef7a4 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 16 Aug 2019 11:25:45 -0700 Subject: [PATCH 742/861] Pick up TS rc --- extensions/package.json | 2 +- extensions/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/extensions/package.json b/extensions/package.json index 57d5f5da311..5c73fcbd3d7 100644 --- a/extensions/package.json +++ b/extensions/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "description": "Dependencies shared by all extensions", "dependencies": { - "typescript": "3.6.0-dev.20190810" + "typescript": "3.6.1-rc" }, "scripts": { "postinstall": "node ./postinstall" diff --git a/extensions/yarn.lock b/extensions/yarn.lock index 233cf189e14..26979cdf9d6 100644 --- a/extensions/yarn.lock +++ b/extensions/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -typescript@3.6.0-dev.20190810: - version "3.6.0-dev.20190810" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.0-dev.20190810.tgz#dda80279480131eec9b05e3b78182a1ba1efe105" - integrity sha512-gubcQ8Sn2G5AO1KhjvLpoFrutV7o/ZJ7wCDBC1IKgNI8R2vadIxTystJxAFqkb9boQ7tyRrZ6FwM5EL5ZYfJrg== +typescript@3.6.1-rc: + version "3.6.1-rc" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.1-rc.tgz#9db650b25d8ef033d9e25b3057bdd1e102bb434b" + integrity sha512-u6AQN9AoocZKYSz8zcc1Qh/V/mbAO+BHc73fTiKlIdjzU60A8TesrK9/7kg3GM8o2RxNyCeOFpcevEtnfUyaLg== From 08bb8bae8354d88c09823bda3a30f4bea6cee527 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 16 Aug 2019 11:39:13 -0700 Subject: [PATCH 743/861] xterm-addon-search@0.2.0-beta5 - Better align search with how monaco does it Fixes #78281 --- package.json | 4 ++-- remote/package.json | 2 +- remote/yarn.lock | 8 ++++---- yarn.lock | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index f8a973d504e..b190a4b3a33 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "vscode-sqlite3": "4.0.8", "vscode-textmate": "^4.2.2", "xterm": "3.15.0-beta99", - "xterm-addon-search": "0.2.0-beta3", + "xterm-addon-search": "0.2.0-beta5", "xterm-addon-web-links": "0.1.0-beta10", "yauzl": "^2.9.2", "yazl": "^2.4.3" @@ -159,4 +159,4 @@ "windows-mutex": "0.3.0", "windows-process-tree": "0.2.4" } -} \ No newline at end of file +} diff --git a/remote/package.json b/remote/package.json index ae754c1ae64..9bbc0f44c5c 100644 --- a/remote/package.json +++ b/remote/package.json @@ -22,7 +22,7 @@ "vscode-ripgrep": "^1.5.6", "vscode-textmate": "^4.2.2", "xterm": "3.15.0-beta99", - "xterm-addon-search": "0.2.0-beta3", + "xterm-addon-search": "0.2.0-beta5", "xterm-addon-web-links": "0.1.0-beta10", "yauzl": "^2.9.2", "yazl": "^2.4.3" diff --git a/remote/yarn.lock b/remote/yarn.lock index 5d578d3130b..54e0619915e 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -1217,10 +1217,10 @@ vscode-windows-registry@1.0.1: dependencies: nan "^2.12.1" -xterm-addon-search@0.2.0-beta3: - version "0.2.0-beta3" - resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.2.0-beta3.tgz#710ce14658e269c5a4791f5a9e2f520883a2e62b" - integrity sha512-KzVdkEtGbKJe9ER2TmrI7XjF/wUq1lir9U63vPJi0t2ymQvIECl1V63f9QtOp1vvpdhbZiXBxO+vGTj+y0tRow== +xterm-addon-search@0.2.0-beta5: + version "0.2.0-beta5" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.2.0-beta5.tgz#258d7cb1511d9060cd4520f0f82e408000fd4f53" + integrity sha512-Tg+d8scch0rYOVmzBbX35Y1GXtq+eu/YlzbXznmTo/yD83j3BQlXOhgECu/Yv8EX5JwFmzbfVRWC+JWnfigwGg== xterm-addon-web-links@0.1.0-beta10: version "0.1.0-beta10" diff --git a/yarn.lock b/yarn.lock index 7f3c5365e14..5dfdc062d4f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9987,10 +9987,10 @@ xtend@~2.1.1: dependencies: object-keys "~0.4.0" -xterm-addon-search@0.2.0-beta3: - version "0.2.0-beta3" - resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.2.0-beta3.tgz#710ce14658e269c5a4791f5a9e2f520883a2e62b" - integrity sha512-KzVdkEtGbKJe9ER2TmrI7XjF/wUq1lir9U63vPJi0t2ymQvIECl1V63f9QtOp1vvpdhbZiXBxO+vGTj+y0tRow== +xterm-addon-search@0.2.0-beta5: + version "0.2.0-beta5" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.2.0-beta5.tgz#258d7cb1511d9060cd4520f0f82e408000fd4f53" + integrity sha512-Tg+d8scch0rYOVmzBbX35Y1GXtq+eu/YlzbXznmTo/yD83j3BQlXOhgECu/Yv8EX5JwFmzbfVRWC+JWnfigwGg== xterm-addon-web-links@0.1.0-beta10: version "0.1.0-beta10" From f2334a79d34986f4ab5834f69a961d7249303fd0 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 16 Aug 2019 11:39:23 -0700 Subject: [PATCH 744/861] Format file --- .../workbench/contrib/debug/browser/variablesView.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/variablesView.ts b/src/vs/workbench/contrib/debug/browser/variablesView.ts index 3c3890b574d..052f2506db1 100644 --- a/src/vs/workbench/contrib/debug/browser/variablesView.ts +++ b/src/vs/workbench/contrib/debug/browser/variablesView.ts @@ -89,11 +89,11 @@ export class VariablesView extends ViewletPanel { this.tree = this.instantiationService.createInstance(WorkbenchAsyncDataTree, treeContainer, new VariablesDelegate(), [this.instantiationService.createInstance(VariablesRenderer), new ScopesRenderer()], new VariablesDataSource(), { - ariaLabel: nls.localize('variablesAriaTreeLabel', "Debug Variables"), - accessibilityProvider: new VariablesAccessibilityProvider(), - identityProvider: { getId: (element: IExpression | IScope) => element.getId() }, - keyboardNavigationLabelProvider: { getKeyboardNavigationLabel: (e: IExpression | IScope) => e } - }); + ariaLabel: nls.localize('variablesAriaTreeLabel', "Debug Variables"), + accessibilityProvider: new VariablesAccessibilityProvider(), + identityProvider: { getId: (element: IExpression | IScope) => element.getId() }, + keyboardNavigationLabelProvider: { getKeyboardNavigationLabel: (e: IExpression | IScope) => e } + }); this.tree.setInput(this.debugService.getViewModel()).then(null, onUnexpectedError); From 1aa34f97fb0f80fd80934ed8f5062115cc9f0601 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 16 Aug 2019 11:46:10 -0700 Subject: [PATCH 745/861] Update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b190a4b3a33..2a43502df64 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "32d06dfa691431ba32bbe11ac39ab4b30663b342", + "distro": "481202cd856f5dbbb010996544e4fa7498154f2e", "author": { "name": "Microsoft Corporation" }, From 1990b5a69ce112353b6e86627e567df5d7bc4825 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 16 Aug 2019 13:47:03 -0700 Subject: [PATCH 746/861] Max height and hidden vertical scrollbar --- src/vs/base/browser/ui/findinput/findInput.ts | 5 ++++- src/vs/editor/contrib/find/findWidget.css | 6 ++++++ src/vs/editor/contrib/find/findWidget.ts | 6 ++++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/vs/base/browser/ui/findinput/findInput.ts b/src/vs/base/browser/ui/findinput/findInput.ts index 2a2964beeef..0c64d37c49e 100644 --- a/src/vs/base/browser/ui/findinput/findInput.ts +++ b/src/vs/base/browser/ui/findinput/findInput.ts @@ -24,6 +24,7 @@ export interface IFindInputOptions extends IFindInputStyles { readonly validation?: IInputValidator; readonly label: string; readonly flexibleHeight?: boolean; + readonly flexibleMaxHeight?: number; readonly appendCaseSensitiveLabel?: string; readonly appendWholeWordsLabel?: string; @@ -119,6 +120,7 @@ export class FindInput extends Widget { const appendRegexLabel = options.appendRegexLabel || ''; const history = options.history || []; const flexibleHeight = !!options.flexibleHeight; + const flexibleMaxHeight = options.flexibleMaxHeight; this.domNode = document.createElement('div'); dom.addClass(this.domNode, 'monaco-findInput'); @@ -142,7 +144,8 @@ export class FindInput extends Widget { inputValidationErrorForeground: this.inputValidationErrorForeground, inputValidationErrorBorder: this.inputValidationErrorBorder, history, - flexibleHeight + flexibleHeight, + flexibleMaxHeight })); this.regex = this._register(new RegexCheckbox({ diff --git a/src/vs/editor/contrib/find/findWidget.css b/src/vs/editor/contrib/find/findWidget.css index f862d6eaf70..ac0a74d55b9 100644 --- a/src/vs/editor/contrib/find/findWidget.css +++ b/src/vs/editor/contrib/find/findWidget.css @@ -120,6 +120,12 @@ width: 100%; } +.monaco-editor .find-widget .monaco-findInput .monaco-scrollable-element .scrollbar.vertical, +.monaco-editor .find-widget .replace-input .monaco-scrollable-element .scrollbar.vertical { + /* Hide vertical scrollbar */ + opacity: 0; +} + .monaco-editor .find-widget .matchesCount { display: flex; display: -webkit-flex; diff --git a/src/vs/editor/contrib/find/findWidget.ts b/src/vs/editor/contrib/find/findWidget.ts index dd7419811ae..3e845b4d1ce 100644 --- a/src/vs/editor/contrib/find/findWidget.ts +++ b/src/vs/editor/contrib/find/findWidget.ts @@ -888,7 +888,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas return { content: e.message }; } }, - flexibleHeight: true + flexibleHeight: true, + flexibleMaxHeight: 118 }, this._contextKeyService, true)); this._findInput.setRegex(!!this._state.isRegex); this._findInput.setCaseSensitive(!!this._state.matchCase); @@ -1014,7 +1015,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas ariaLabel: NLS_REPLACE_INPUT_LABEL, placeholder: NLS_REPLACE_INPUT_PLACEHOLDER, history: [], - flexibleHeight: true + flexibleHeight: true, + flexibleMaxHeight: 118 }, this._contextKeyService)); From 8b6c996439dcf2f0e5632e2180c8ba34693b5418 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 16 Aug 2019 11:48:04 -0700 Subject: [PATCH 747/861] Remove not null suppression --- src/vs/base/browser/markdownRenderer.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/base/browser/markdownRenderer.ts b/src/vs/base/browser/markdownRenderer.ts index 7fd9f63b75a..493f60ef8a1 100644 --- a/src/vs/base/browser/markdownRenderer.ts +++ b/src/vs/base/browser/markdownRenderer.ts @@ -143,8 +143,9 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende }; } - if (options.actionHandler) { - options.actionHandler.disposeables.add(DOM.addStandardDisposableListener(element, 'click', event => { + const actionHandler = options.actionHandler; + if (actionHandler) { + actionHandler.disposeables.add(DOM.addStandardDisposableListener(element, 'click', event => { let target: HTMLElement | null = event.target; if (target.tagName !== 'A') { target = target.parentElement; @@ -155,7 +156,7 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende try { const href = target.dataset['href']; if (href) { - options.actionHandler!.callback(href, event); + actionHandler.callback(href, event); } } catch (err) { onUnexpectedError(err); From ac5887deee760cb2686225080215263bf794ba78 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 16 Aug 2019 14:40:14 -0700 Subject: [PATCH 748/861] Use dispoablestore --- src/vs/workbench/api/common/menusExtensionPoint.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/api/common/menusExtensionPoint.ts b/src/vs/workbench/api/common/menusExtensionPoint.ts index 65395d5ed4c..2ce62f2a367 100644 --- a/src/vs/workbench/api/common/menusExtensionPoint.ts +++ b/src/vs/workbench/api/common/menusExtensionPoint.ts @@ -12,7 +12,7 @@ import { IExtensionPointUser, ExtensionMessageCollector, ExtensionsRegistry } fr import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { MenuId, MenuRegistry, ILocalizedString, IMenuItem } from 'vs/platform/actions/common/actions'; import { URI } from 'vs/base/common/uri'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle'; namespace schema { @@ -329,7 +329,7 @@ namespace schema { }; } -let _commandRegistrations: IDisposable[] = []; +const _commandRegistrations = new DisposableStore(); export const commandsExtensionPoint = ExtensionsRegistry.registerExtensionPoint({ extensionPoint: 'commands', @@ -338,7 +338,7 @@ export const commandsExtensionPoint = ExtensionsRegistry.registerExtensionPoint< commandsExtensionPoint.setHandler(extensions => { - function handleCommand(userFriendlyCommand: schema.IUserFriendlyCommand, extension: IExtensionPointUser, disposables: IDisposable[]) { + function handleCommand(userFriendlyCommand: schema.IUserFriendlyCommand, extension: IExtensionPointUser, disposables: DisposableStore) { if (!schema.isValidCommand(userFriendlyCommand, extension.collector)) { return; @@ -368,16 +368,16 @@ commandsExtensionPoint.setHandler(extensions => { precondition: ContextKeyExpr.deserialize(enablement), iconLocation: absoluteIcon }); - disposables.push(registration); + disposables.add(registration); } // remove all previous command registrations - _commandRegistrations = dispose(_commandRegistrations); + _commandRegistrations.clear(); - for (let extension of extensions) { + for (const extension of extensions) { const { value } = extension; if (Array.isArray(value)) { - for (let command of value) { + for (const command of value) { handleCommand(command, extension, _commandRegistrations); } } else { From 445ad7021bcb00af3a7654f73ecaeecd9884473f Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 16 Aug 2019 14:41:24 -0700 Subject: [PATCH 749/861] Use closure instead of parameters --- src/vs/workbench/api/common/menusExtensionPoint.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/api/common/menusExtensionPoint.ts b/src/vs/workbench/api/common/menusExtensionPoint.ts index 2ce62f2a367..cb6cddcb57d 100644 --- a/src/vs/workbench/api/common/menusExtensionPoint.ts +++ b/src/vs/workbench/api/common/menusExtensionPoint.ts @@ -338,7 +338,7 @@ export const commandsExtensionPoint = ExtensionsRegistry.registerExtensionPoint< commandsExtensionPoint.setHandler(extensions => { - function handleCommand(userFriendlyCommand: schema.IUserFriendlyCommand, extension: IExtensionPointUser, disposables: DisposableStore) { + function handleCommand(userFriendlyCommand: schema.IUserFriendlyCommand, extension: IExtensionPointUser) { if (!schema.isValidCommand(userFriendlyCommand, extension.collector)) { return; @@ -368,7 +368,7 @@ commandsExtensionPoint.setHandler(extensions => { precondition: ContextKeyExpr.deserialize(enablement), iconLocation: absoluteIcon }); - disposables.add(registration); + _commandRegistrations.add(registration); } // remove all previous command registrations @@ -376,12 +376,12 @@ commandsExtensionPoint.setHandler(extensions => { for (const extension of extensions) { const { value } = extension; - if (Array.isArray(value)) { + if (Array.isArray(value)) { for (const command of value) { - handleCommand(command, extension, _commandRegistrations); + handleCommand(command, extension); } } else { - handleCommand(value, extension, _commandRegistrations); + handleCommand(value, extension); } } }); From 4707bc535e1e1141f962ec895c465a7d5a4b1803 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 16 Aug 2019 14:48:23 -0700 Subject: [PATCH 750/861] Use type for IExtensionPointHandler and mark array readonly --- .../services/extensions/common/extensionsRegistry.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/vs/workbench/services/extensions/common/extensionsRegistry.ts b/src/vs/workbench/services/extensions/common/extensionsRegistry.ts index 9776a42da6a..6fba325635f 100644 --- a/src/vs/workbench/services/extensions/common/extensionsRegistry.ts +++ b/src/vs/workbench/services/extensions/common/extensionsRegistry.ts @@ -61,9 +61,7 @@ export interface IExtensionPointUser { collector: ExtensionMessageCollector; } -export interface IExtensionPointHandler { - (extensions: IExtensionPointUser[], delta: ExtensionPointUserDelta): void; -} +export type IExtensionPointHandler = (extensions: readonly IExtensionPointUser[], delta: ExtensionPointUserDelta) => void; export interface IExtensionPoint { name: string; From 70dc55955d586ebd427658b43cdb344f2047f9c2 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 16 Aug 2019 14:49:53 -0700 Subject: [PATCH 751/861] Marking arrays readonly in ExtensionPointUserDelta --- src/vs/workbench/api/browser/viewsExtensionPoint.ts | 8 ++++---- .../services/extensions/common/extensionsRegistry.ts | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/api/browser/viewsExtensionPoint.ts b/src/vs/workbench/api/browser/viewsExtensionPoint.ts index 2a5030ae9f8..e6621fc362c 100644 --- a/src/vs/workbench/api/browser/viewsExtensionPoint.ts +++ b/src/vs/workbench/api/browser/viewsExtensionPoint.ts @@ -210,7 +210,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution { }); } - private addCustomViewContainers(extensionPoints: IExtensionPointUser[], existingViewContainers: ViewContainer[]): void { + private addCustomViewContainers(extensionPoints: readonly IExtensionPointUser[], existingViewContainers: ViewContainer[]): void { const viewContainersRegistry = Registry.as(ViewContainerExtensions.ViewContainersRegistry); let order = TEST_VIEW_CONTAINER_ORDER + viewContainersRegistry.all.filter(v => !!v.extensionId).length + 1; for (let { value, collector, description } of extensionPoints) { @@ -227,7 +227,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution { } } - private removeCustomViewContainers(extensionPoints: IExtensionPointUser[]): void { + private removeCustomViewContainers(extensionPoints: readonly IExtensionPointUser[]): void { const viewContainersRegistry = Registry.as(ViewContainerExtensions.ViewContainersRegistry); const removedExtensions: Set = extensionPoints.reduce((result, e) => { result.add(ExtensionIdentifier.toKey(e.description.identifier)); return result; }, new Set()); for (const viewContainer of viewContainersRegistry.all) { @@ -378,7 +378,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution { }); } - private addViews(extensions: IExtensionPointUser[]): void { + private addViews(extensions: readonly IExtensionPointUser[]): void { for (const extension of extensions) { const { value, collector } = extension; @@ -442,7 +442,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution { return this.viewContainersRegistry.get(EXPLORER)!; } - private removeViews(extensions: IExtensionPointUser[]): void { + private removeViews(extensions: readonly IExtensionPointUser[]): void { const removedExtensions: Set = extensions.reduce((result, e) => { result.add(ExtensionIdentifier.toKey(e.description.identifier)); return result; }, new Set()); for (const viewContainer of this.viewContainersRegistry.all) { const removedViews = this.viewsRegistry.getViews(viewContainer).filter((v: ICustomViewDescriptor) => v.extensionId && removedExtensions.has(ExtensionIdentifier.toKey(v.extensionId))); diff --git a/src/vs/workbench/services/extensions/common/extensionsRegistry.ts b/src/vs/workbench/services/extensions/common/extensionsRegistry.ts index 6fba325635f..f5fd3137e47 100644 --- a/src/vs/workbench/services/extensions/common/extensionsRegistry.ts +++ b/src/vs/workbench/services/extensions/common/extensionsRegistry.ts @@ -71,7 +71,7 @@ export interface IExtensionPoint { export class ExtensionPointUserDelta { - private static _toSet(arr: IExtensionPointUser[]): Set { + private static _toSet(arr: readonly IExtensionPointUser[]): Set { const result = new Set(); for (let i = 0, len = arr.length; i < len; i++) { result.add(ExtensionIdentifier.toKey(arr[i].description.identifier)); @@ -79,7 +79,7 @@ export class ExtensionPointUserDelta { return result; } - public static compute(previous: IExtensionPointUser[] | null, current: IExtensionPointUser[]): ExtensionPointUserDelta { + public static compute(previous: readonly IExtensionPointUser[] | null, current: readonly IExtensionPointUser[]): ExtensionPointUserDelta { if (!previous || !previous.length) { return new ExtensionPointUserDelta(current, []); } @@ -97,8 +97,8 @@ export class ExtensionPointUserDelta { } constructor( - public readonly added: IExtensionPointUser[], - public readonly removed: IExtensionPointUser[], + public readonly added: readonly IExtensionPointUser[], + public readonly removed: readonly IExtensionPointUser[], ) { } } From 45dd218d90b01fa88f24613dfbb668e7e303515b Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 16 Aug 2019 16:06:35 -0700 Subject: [PATCH 752/861] Update extra space on top of editor when find widget state changes --- src/vs/editor/contrib/find/findWidget.ts | 93 ++++++++++++++++-------- 1 file changed, 62 insertions(+), 31 deletions(-) diff --git a/src/vs/editor/contrib/find/findWidget.ts b/src/vs/editor/contrib/find/findWidget.ts index 3e845b4d1ce..6b59dafaba9 100644 --- a/src/vs/editor/contrib/find/findWidget.ts +++ b/src/vs/editor/contrib/find/findWidget.ts @@ -64,9 +64,7 @@ const REPLACE_INPUT_AREA_WIDTH = FIND_INPUT_AREA_WIDTH; let MAX_MATCHES_COUNT_WIDTH = 69; let FIND_ALL_CONTROLS_WIDTH = 17/** Find Input margin-left */ + (MAX_MATCHES_COUNT_WIDTH + 3 + 1) /** Match Results */ + 23 /** Button */ * 4 + 2/** sash */; -const FIND_INPUT_AREA_HEIGHT = 34; // The height of Find Widget when Replace Input is not visible. -const FIND_REPLACE_AREA_HEIGHT = 64; // The height of Find Widget when Replace Input is visible. - +const FIND_INPUT_AREA_HEIGHT = 33; // The height of Find Widget when Replace Input is not visible. export class FindWidgetViewZone implements IViewZone { public readonly afterLineNumber: number; @@ -110,6 +108,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas private readonly _contextKeyService: IContextKeyService; private _domNode!: HTMLElement; + private _cachedHeight: number | null; private _findInput!: FindInput; private _replaceInputBox!: HistoryInputBox; @@ -313,7 +312,9 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } } if ((e.isRevealed || e.isReplaceRevealed) && (this._state.isRevealed || this._state.isReplaceRevealed)) { - this._tryUpdateHeight(); + if (this._tryUpdateHeight()) { + this._showViewZone(); + } } if (e.isRegex) { @@ -532,12 +533,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } this._codeEditor.changeViewZones((accessor) => { - if (this._state.isReplaceRevealed) { - viewZone.heightInPx = FIND_REPLACE_AREA_HEIGHT; - } else { - viewZone.heightInPx = FIND_INPUT_AREA_HEIGHT; - } - + viewZone.heightInPx = this._getHeight(); this._viewZoneId = accessor.addZone(viewZone); // scroll top adjust to make sure the editor doesn't scroll when adding viewzone at the beginning. this._codeEditor.setScrollTop(this._codeEditor.getScrollTop() + viewZone.heightInPx); @@ -545,30 +541,47 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } private _showViewZone(adjustScroll: boolean = true) { - const viewZone = this._viewZone; - if (!this._isVisible || !viewZone) { + if (!this._isVisible) { return; } + const addExtraSpaceOnTop = this._codeEditor.getConfiguration().contribInfo.find.addExtraSpaceOnTop; + + if (!addExtraSpaceOnTop) { + return; + } + + if (this._viewZone === undefined) { + this._viewZone = new FindWidgetViewZone(0); + } + + const viewZone = this._viewZone; + this._codeEditor.changeViewZones((accessor) => { - let scrollAdjustment = FIND_INPUT_AREA_HEIGHT; - if (this._viewZoneId !== undefined) { - if (this._state.isReplaceRevealed) { - viewZone.heightInPx = FIND_REPLACE_AREA_HEIGHT; - scrollAdjustment = FIND_REPLACE_AREA_HEIGHT - FIND_INPUT_AREA_HEIGHT; - } else { - viewZone.heightInPx = FIND_INPUT_AREA_HEIGHT; - scrollAdjustment = FIND_INPUT_AREA_HEIGHT - FIND_REPLACE_AREA_HEIGHT; + // the view zone already exists, we need to update the height + const newHeight = this._getHeight(); + if (newHeight === viewZone.heightInPx) { + return; } - accessor.removeZone(this._viewZoneId); - } else { - viewZone.heightInPx = FIND_INPUT_AREA_HEIGHT; - } - this._viewZoneId = accessor.addZone(viewZone); - if (adjustScroll) { - this._codeEditor.setScrollTop(this._codeEditor.getScrollTop() + scrollAdjustment); + let scrollAdjustment = newHeight - viewZone.heightInPx; + viewZone.heightInPx = newHeight; + accessor.layoutZone(this._viewZoneId); + + if (adjustScroll) { + this._codeEditor.setScrollTop(this._codeEditor.getScrollTop() + scrollAdjustment); + } + + return; + } else { + const scrollAdjustment = this._getHeight(); + viewZone.heightInPx = scrollAdjustment; + this._viewZoneId = accessor.addZone(viewZone); + + if (adjustScroll) { + this._codeEditor.setScrollTop(this._codeEditor.getScrollTop() + scrollAdjustment); + } } }); } @@ -667,7 +680,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } } - private _tryUpdateHeight() { + private _getHeight(): number { let totalheight = 0; // find input margin top @@ -685,8 +698,19 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas // margin bottom totalheight += 4; + return totalheight; + } - this._domNode.style.height = `${totalheight}px`; + private _tryUpdateHeight(): boolean { + const totalHeight = this._getHeight(); + if (this._cachedHeight !== null && this._cachedHeight === totalHeight) { + return false; + } + + this._cachedHeight = totalHeight; + this._domNode.style.height = `${totalHeight}px`; + + return true; } // ----- Public @@ -925,7 +949,9 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } })); this._register(this._findInput.inputBox.onDidHeightChange((e) => { - this._tryUpdateHeight(); + if (this._tryUpdateHeight()) { + this._showViewZone(); + } })); if (platform.isLinux) { this._register(this._findInput.onMouseDown((e) => this._onFindInputMouseDown(e))); @@ -1025,7 +1051,9 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas this._state.change({ replaceString: this._replaceInputBox.value }, false); })); this._register(this._replaceInputBox.onDidHeightChange((e) => { - this._tryUpdateHeight(); + if (this._isReplaceVisible && this._tryUpdateHeight()) { + this._showViewZone(); + } })); this._preserveCase = this._register(new Checkbox({ @@ -1153,6 +1181,9 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas if (this._isReplaceVisible) { this._replaceInputBox.width = inputBoxWidth; } + + this._findInput.inputBox.layout(); + this._tryUpdateHeight(); })); } From 98467c3b7cacf53103f56519673dc9ae81e7ee84 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 17 Aug 2019 10:17:09 +0200 Subject: [PATCH 753/861] web - storage/lifecycle :lipstick: --- src/vs/base/browser/dom.ts | 1 + .../lifecycle/browser/lifecycleService.ts | 12 ++++++--- .../storage/browser/storageService.ts | 27 ++++++++++++------- src/vs/workbench/browser/workbench.ts | 6 ++--- .../textfile/browser/textFileService.ts | 6 ++--- .../textfile/common/textFileService.ts | 4 +-- 6 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index a97f27a51e7..3967d3b3f08 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -855,6 +855,7 @@ export const EventType = { KEY_UP: 'keyup', // HTML Document LOAD: 'load', + BEFORE_UNLOAD: 'beforeunload', UNLOAD: 'unload', ABORT: 'abort', ERROR: 'error', diff --git a/src/vs/platform/lifecycle/browser/lifecycleService.ts b/src/vs/platform/lifecycle/browser/lifecycleService.ts index 9a85a58262e..79301acb261 100644 --- a/src/vs/platform/lifecycle/browser/lifecycleService.ts +++ b/src/vs/platform/lifecycle/browser/lifecycleService.ts @@ -8,6 +8,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import { AbstractLifecycleService } from 'vs/platform/lifecycle/common/lifecycleService'; import { localize } from 'vs/nls'; import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import { addDisposableListener, EventType } from 'vs/base/browser/dom'; export class BrowserLifecycleService extends AbstractLifecycleService { @@ -22,10 +23,10 @@ export class BrowserLifecycleService extends AbstractLifecycleService { } private registerListeners(): void { - window.onbeforeunload = () => this.beforeUnload(); + addDisposableListener(window, EventType.BEFORE_UNLOAD, () => this.onBeforeUnload()); } - private beforeUnload(): string | null { + private onBeforeUnload(): string | null { let veto = false; // Before Shutdown @@ -34,7 +35,7 @@ export class BrowserLifecycleService extends AbstractLifecycleService { if (value === true) { veto = true; } else if (value instanceof Promise && !veto) { - console.warn(new Error('Long running onBeforeShutdown currently not supported')); + console.warn(new Error('Long running onBeforeShutdown currently not supported in the web')); veto = true; } }, @@ -49,11 +50,14 @@ export class BrowserLifecycleService extends AbstractLifecycleService { // No Veto: continue with Will Shutdown this._onWillShutdown.fire({ join() { - console.warn(new Error('Long running onWillShutdown currently not supported')); + console.warn(new Error('Long running onWillShutdown currently not supported in the web')); }, reason: ShutdownReason.QUIT }); + // Finally end with Shutdown event + this._onShutdown.fire(); + return null; } } diff --git a/src/vs/platform/storage/browser/storageService.ts b/src/vs/platform/storage/browser/storageService.ts index cec2d7dc9c7..5648772339f 100644 --- a/src/vs/platform/storage/browser/storageService.ts +++ b/src/vs/platform/storage/browser/storageService.ts @@ -37,7 +37,7 @@ export class BrowserStorageService extends Disposable implements IStorageService private workspaceStorageFile: URI; private initializePromise: Promise; - private periodicSaveScheduler = this._register(new RunOnceScheduler(() => this.saveState(), 5000)); + private periodicSaveScheduler = this._register(new RunOnceScheduler(() => this.collectState(), 5000)); get hasPendingUpdate(): boolean { return this.globalStorageDatabase.hasPendingUpdate || this.workspaceStorageDatabase.hasPendingUpdate; @@ -57,14 +57,19 @@ export class BrowserStorageService extends Disposable implements IStorageService this.periodicSaveScheduler.schedule(); } - private saveState(): void { + private collectState(): void { runWhenIdle(() => { // this event will potentially cause new state to be stored // since new state will only be created while the document // has focus, one optimization is to not run this when the // document has no focus, assuming that state has not changed - if (document.hasFocus()) { + // + // another optimization is to not collect more state if we + // have a pending update already running which indicates + // that the connection is either slow or disconnected and + // thus unhealthy. + if (document.hasFocus() && !this.hasPendingUpdate) { this._onWillSaveState.fire({ reason: WillSaveStateReason.NONE }); } @@ -197,7 +202,7 @@ export class FileStorageDatabase extends Disposable implements IStorageDatabase this._register(this.fileService.watch(this.file)); this._register(this.fileService.onFileChanges(e => { if (document.hasFocus()) { - return; // ignore changes from ourselves by checking for focus + return; // optimization: ignore changes from ourselves by checking for focus } if (!e.contains(this.file, FileChangeType.UPDATED)) { @@ -251,15 +256,17 @@ export class FileStorageDatabase extends Disposable implements IStorageDatabase await this.pendingUpdate; - this._hasPendingUpdate = true; + this.pendingUpdate = (async () => { + try { + this._hasPendingUpdate = true; + + await this.fileService.writeFile(this.file, VSBuffer.fromString(JSON.stringify(mapToSerializable(items)))); - this.pendingUpdate = this.fileService.writeFile(this.file, VSBuffer.fromString(JSON.stringify(mapToSerializable(items)))) - .then(() => { this.ensureWatching(); // now that the file must exist, ensure we watch it for changes - }) - .finally(() => { + } finally { this._hasPendingUpdate = false; - }); + } + })(); return this.pendingUpdate; } diff --git a/src/vs/workbench/browser/workbench.ts b/src/vs/workbench/browser/workbench.ts index 0e61b26920d..e6dde918a2d 100644 --- a/src/vs/workbench/browser/workbench.ts +++ b/src/vs/workbench/browser/workbench.ts @@ -50,12 +50,12 @@ export class Workbench extends Layout { private readonly _onBeforeShutdown = this._register(new Emitter()); readonly onBeforeShutdown: Event = this._onBeforeShutdown.event; - private readonly _onShutdown = this._register(new Emitter()); - readonly onShutdown: Event = this._onShutdown.event; - private readonly _onWillShutdown = this._register(new Emitter()); readonly onWillShutdown: Event = this._onWillShutdown.event; + private readonly _onShutdown = this._register(new Emitter()); + readonly onShutdown: Event = this._onShutdown.event; + constructor( parent: HTMLElement, private readonly serviceCollection: ServiceCollection, diff --git a/src/vs/workbench/services/textfile/browser/textFileService.ts b/src/vs/workbench/services/textfile/browser/textFileService.ts index ac16d811705..3d2d91f5996 100644 --- a/src/vs/workbench/services/textfile/browser/textFileService.ts +++ b/src/vs/workbench/services/textfile/browser/textFileService.ts @@ -17,15 +17,15 @@ export class BrowserTextFileService extends TextFileService { } }; - protected beforeShutdown(reason: ShutdownReason): boolean { + protected onBeforeShutdown(reason: ShutdownReason): boolean { // Web: we cannot perform long running in the shutdown phase // As such we need to check sync if there are any dirty files // that have not been backed up yet and then prevent the shutdown // if that is the case. - return this.doBeforeShutdownSync(reason); + return this.doBeforeShutdownSync(); } - private doBeforeShutdownSync(reason: ShutdownReason): boolean { + private doBeforeShutdownSync(): boolean { const dirtyResources = this.getDirty(); if (!dirtyResources.length) { return false; // no dirty: no veto diff --git a/src/vs/workbench/services/textfile/common/textFileService.ts b/src/vs/workbench/services/textfile/common/textFileService.ts index 713ef13e395..f9147e602e8 100644 --- a/src/vs/workbench/services/textfile/common/textFileService.ts +++ b/src/vs/workbench/services/textfile/common/textFileService.ts @@ -107,7 +107,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer private registerListeners(): void { // Lifecycle - this.lifecycleService.onBeforeShutdown(event => event.veto(this.beforeShutdown(event.reason))); + this.lifecycleService.onBeforeShutdown(event => event.veto(this.onBeforeShutdown(event.reason))); this.lifecycleService.onShutdown(this.dispose, this); // Files configuration changes @@ -118,7 +118,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer })); } - protected beforeShutdown(reason: ShutdownReason): boolean | Promise { + protected onBeforeShutdown(reason: ShutdownReason): boolean | Promise { // Dirty files need treatment on shutdown const dirty = this.getDirty(); From 759d117d03f56e1fe62b5fe32d1b59c0dc0449a9 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Sun, 18 Aug 2019 20:09:13 +0200 Subject: [PATCH 754/861] Fix #79326, cleanup rendering Octicons bugs on Windows/Linux --- .../ui/octiconLabel/octicons/octicons2.css | 4 +- .../ui/octiconLabel/octicons/octicons2.svg | 49 ++++++++---------- .../ui/octiconLabel/octicons/octicons2.ttf | Bin 35276 -> 35564 bytes 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.css b/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.css index 6da9003b49a..2e45f180521 100644 --- a/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.css +++ b/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.css @@ -1,7 +1,7 @@ @font-face { font-family: "octicons2"; - src: url("./octicons2.ttf?064476e75412ccad4ae99d4bf24539b4") format("truetype"), -url("./octicons2.svg?064476e75412ccad4ae99d4bf24539b4#octicons2") format("svg"); + src: url("./octicons2.ttf?dee9935d8deb764a470d194d9f0d07f7") format("truetype"), +url("./octicons2.svg?dee9935d8deb764a470d194d9f0d07f7#octicons2") format("svg"); } .octicon, .mega-octicon { diff --git a/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.svg b/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.svg index e7d0d05d458..4028dd45666 100644 --- a/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.svg +++ b/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.svg @@ -9,7 +9,7 @@ + horiz-adv-x="1000" d=" M527.5 757.5H472.5L62.5 -8.75L90 -55H908.75L936.2499999999998 -8.75zM142.5 7.5L499.9999999999999 677.5L856.25 7.5zM468.7499999999999 445H531.25V195H468.75zM468.7499999999999 132.5H531.25V70H468.75z" /> @@ -198,7 +198,7 @@ horiz-adv-x="1000" d=" M125 132.5H187.5V383.125H125V132.5zM187.5 445.625V476.25L218.75 507.5H495.625L522.5 491.875L549.375 445H812.5H906.25L937.5 413.75V-86.25L906.25 -117.5H218.75L187.5 -86.25V70H93.75L62.5 101.25V663.75L93.75 695H370L397.5 679.375L424.375 632.5H781.25L812.5 601.25V445L750 446.875V570H406.25L379.375 585.625L352.5 632.5H125V445.625H187.5zM504.375 398.125L477.5 445H250V257.5H446.875L472.5 303.75L500 320H875V382.5H531.25L504.375 398.125zM465.625 195H250V-55H875V257.5H518.75L493.125 211.25L465.625 195z" /> + horiz-adv-x="1000" d=" M481.87625 632.5H906.25L938.125 601.25V257.5V-23.75L906.875 -55H94.375625L63.125625 -23.75V413.75V663.75L94.375625 695H406.875625L428.749375 685.62375L481.87625 632.5zM874.375 7.5V101.875L875 351.875625V445.625625H481.250625L427.501875 391.87625L405.624375 382.5H125V351.875625V101.875V7.5H874.375zM468.124375 507.5H874.375L875 569.374375H468.75L446.250625 578.750625L393.12375 631.874375H125V444.374375H392.501875L446.250625 498.12375L468.124375 507.5zM611.253125 253.128125L526.250625 338.753125L572.5 381.874375L711.25 243.1262500000001V198.75375L568.128125 60.625L524.3775 105.61875L611.875 190H526.250625C494.281875 188.5625 464.085 174.9187499999999 441.876875 151.88125C431.1175 141.175 422.6368750000001 128.4 416.94375 114.3249999999999C411.2512500000001 100.25625 408.4625000000001 85.1750000000001 408.75 70H346.25C345.860625 93.1687499999999 350.1443750000001 116.175 358.8425000000001 137.65C367.5406250000001 159.125 380.47375 178.6312499999999 396.875 195C429.649375 229.5450000000001 474.339375 250.32875 521.875 253.128125H611.253125z" /> @@ -225,7 +225,7 @@ horiz-adv-x="1000" d=" M568.75 545L537.5 695H462.5L431.25 545L387.5 526.25L262.5 607.5L206.25 557.5L287.5 432.5L275 388.75L125 357.5V282.5L275 251.25L293.75 201.25L212.5 76.25L262.5 26.25L387.5 107.5L437.5 88.75L462.5 -55H537.5L568.75 95L618.75 113.75L743.75 32.5L793.75 82.5L712.5 207.5L731.25 257.5L875 282.5V357.5L725 388.75L706.25 438.75L787.5 563.75L737.5 613.75L612.5 532.5L568.75 545zM587.5 757.5L618.75 607.5L750 688.75L875 563.75L787.5 432.5L937.5 407.5V232.5L787.5 201.25L875 70L750 -55L618.75 32.5L587.5 -117.5H412.5L381.25 32.5L250 -48.75L125 76.25L212.5 207.5L62.5 232.5V407.5L212.5 438.75L131.25 570L256.25 695L387.5 607.5L412.5 757.5H587.5zM625 320C625 251.25 568.75 195 500 195C431.25 195 375 251.25 375 320C375 388.75 431.25 445 500 445C568.75 445 625 388.75 625 320zM500 257.5C537.5 257.5 562.5 282.5 562.5 320C562.5 357.5 537.5 382.5 500 382.5C462.5 382.5 437.5 357.5 437.5 320C437.5 282.5 462.5 257.5 500 257.5z" /> + horiz-adv-x="1000" d=" M843.75 570H743.75C750 595 750 620 750 645C743.75 663.75 737.5 682.5 725 701.25C712.5 720 700 732.5 681.25 738.75C662.5 745 643.75 757.5 625 757.5C606.25 757.5 587.5 757.5 568.75 745C525 732.5 493.75 701.25 468.75 663.75C443.75 701.25 412.5 732.5 368.75 745C350 751.25 331.25 757.5 312.5 757.5C293.75 757.5 275 751.25 256.25 738.75C237.5 732.5 225 720 212.5 701.25C200 688.75 193.75 663.75 187.5 645C187.5 620 187.5 595 193.75 570H93.75L62.5 538.75V-23.75L93.75 -55H843.75L875 -23.75V538.75L843.75 570zM437.5 7.5H125V507.5H437.5V7.5zM437.5 570H250C250 576.25 250 576.25 250 582.5C243.75 601.25 243.75 613.75 243.75 632.5C250 645 250 657.5 262.5 663.75C268.75 676.25 281.25 682.5 293.75 688.75C300 695 312.5 695 325 695C337.5 695 350 695 362.5 688.75C381.25 682.5 400 670 412.5 651.25C425 632.5 437.5 613.75 437.5 588.75V570zM500 588.75C500 613.75 512.5 632.5 525 651.25C537.5 670 556.25 682.5 575 688.75C587.5 695 600 695 612.5 695C625 695 637.5 695 650 688.75C662.5 682.5 668.75 676.25 681.25 663.75C687.5 657.5 687.5 645 693.75 632.5C693.75 613.75 693.75 601.25 687.5 582.5C687.5 576.25 687.5 576.25 681.25 570H500V588.75zM812.5 7.5H500V507.5H812.5V7.5z" /> @@ -237,16 +237,16 @@ horiz-adv-x="1000" d=" M875.28125 477.43C875.425 506.336875 867.51875 534.713125 852.4562500000001 559.3812499999999C837.3812499999999 584.049375 815.74375 604.035625 789.9562500000001 617.10125C764.1687499999999 630.166875 735.2562499999999 635.795625 706.45625 633.358125C677.64375 630.9200000000001 650.09375 620.51125 626.86875 603.2975C603.645625 586.084375 585.671875 562.7462499999999 574.96375 535.89625C564.255625 509.045625 561.2287500000001 479.744375 566.2318750000001 451.273125C571.235 422.8025 584.060625 396.28375 603.2800000000001 374.693125C622.5 353.09875 647.3562499999999 337.28375 675.0500000000001 329.016875C664.825 308.2325 649 290.706875 629.3625000000001 278.420625C609.724375 266.13125 587.05 259.5625 563.8818749999999 259.450625H439.3225C393.21 259.2887500000001 348.80875 241.9706250000001 314.7625 210.8718749999999V511.74625C352.5675 519.463125 386.160625 540.9425 409.029375 572.020625C431.8981250000001 603.098125 442.41125 641.56 438.5331250000001 679.9493749999999C434.655625 718.33875 416.66125 753.920625 388.039375 779.797C359.4175 805.673125 322.2075 820 283.6225 820C245.0375 820 207.8275 805.673125 179.205 779.797C150.583125 753.920625 132.589375 718.33875 128.71125 679.9493749999999C124.8325 641.56 135.3475 603.098125 158.215625 572.020625C181.08375 540.9425 214.6775 519.463125 252.4825 511.74625V131.8375C214.748125 124.625 180.95875 103.84375 157.488125 73.43125C134.0175 43.0124999999999 122.4875 5.0625 125.073125 -33.2687500000001C127.65875 -71.5999999999999 144.18125 -107.6624999999999 171.524375 -134.6437500000001C198.8675 -161.6312499999999 235.140625 -177.68125 273.5025 -179.7687499999999C311.8643750000001 -181.8499999999999 349.6625 -169.8249999999999 379.7675 -145.9562499999999C409.873125 -122.09375 430.2043750000001 -88.03125 436.9262500000001 -50.20625C443.64875 -12.3812499999999 436.299375 26.59375 416.260625 59.375C396.223125 92.15625 364.883125 116.46875 328.1525000000001 127.7312500000001C338.3975000000001 148.49375 354.226875 165.9875 373.8643750000001 178.25625C393.501875 190.525 416.16875 197.070625 439.3225 197.170625H563.8818749999999C602.744375 197.349375 640.58125 209.643125 672.1312499999999 232.338125C703.6750000000001 255.0325000000001 727.35625 286.99875 739.8875 323.7856250000001C777.2125 328.693125 811.5 346.96625 836.4 375.21625C861.2937499999999 403.46625 875.1062499999999 439.7775 875.28125 477.43zM190.2025 664.27C190.2025 682.746875 195.68125 700.808125 205.94625 716.17125C216.211875 731.53375 230.801875 743.5074999999999 247.871875 750.57875C264.9425000000001 757.649 283.72625 759.499125 301.8475 755.894375C319.969375 752.29 336.615 743.3925 349.68 730.3275C362.745625 717.2625 371.6425 700.6168749999999 375.2475 682.495C378.851875 664.3731250000001 377.001875 645.589375 369.93125 628.5193750000001C362.86 611.449375 350.88625 596.85875 335.52375 586.59375C320.160625 576.32875 302.099375 570.85 283.6225 570.85C258.8456250000001 570.85 235.084375 580.6925 217.564375 598.211875C200.045 615.73125 190.2025 639.493125 190.2025 664.27zM377.0425 -20.80625C377.0425 -39.2875 371.563125 -57.34375 361.2981250000001 -72.7062500000001C351.033125 -88.06875 336.443125 -100.04375 319.3725 -107.11875C302.3025 -114.1875 283.51875 -116.0375 265.3975000000001 -112.4375C247.275625 -108.8312499999999 230.63 -99.93125 217.564375 -86.86875C204.499375 -73.8000000000001 195.6025 -57.15625 191.9975 -39.0375C188.393125 -20.9124999999999 190.243125 -2.13125 197.31375 14.9375C204.384375 32.0125 216.35875 46.6 231.72125 56.86875C247.08375 67.13125 265.145625 72.6125000000001 283.6225 72.6125000000001C308.39875 72.6125000000001 332.160625 62.76875 349.68 45.25C367.2000000000001 27.725 377.0425 3.96875 377.0425 -20.80625zM719.58125 384.01C701.10625 384.01 683.0437499999999 389.490625 667.68125 399.754375C652.3187499999999 410.0193750000001 640.34375 424.61 633.275 441.68C626.20625 458.75 624.351875 477.53375 627.95625 495.655C631.5625 513.776875 640.45625 530.423125 653.525 543.488125C666.5875 556.5531249999999 683.2375000000001 565.45 701.35625 569.0550000000001C719.475 572.659375 738.2625 570.809375 755.33125 563.73875C772.40625 556.668125 786.9937500000001 544.694375 797.25625 529.33125C807.51875 513.96875 813 495.906875 813 477.43C813 452.65375 803.15625 428.8918750000001 785.6375 411.3725C768.11875 393.854375 744.35625 384.01 719.58125 384.01z" /> + horiz-adv-x="1000" d=" M686.175 507.5C652.6875 541.7506249999999 608.665625 563.76125 561.1725 570V820H498.6725V570C447.8575 562.346875 401.35875 537.05125 367.330625 498.543125C333.3025 460.035 313.916875 410.776875 312.5743750000001 359.405625C311.2325 308.035 328.02 257.8306250000001 359.99125 217.598125C391.9625 177.36875 437.076875 149.6687499999999 487.423125 139.375H498.6725V-110.625H561.1725V139.375C579.265 141.65625 596.941875 146.49375 613.6724999999999 153.75C653.7937499999999 170.0625 688.0125 198.18 711.8 234.375C735.75 270.28375 748.575 312.4575 748.675 355.6218750000001C748.61875 412.495625 726.16875 467.06375 686.175 507.5V507.5zM642.4250000000001 242.500625C613.02375 213.2731250000001 573.2525 196.87125 531.7975 196.8768750000001C500.914375 196.8562500000001 470.7175 205.983125 445.02125 223.114375C419.3243750000001 240.245 399.281875 264.60625 387.423125 293.1218750000001C378.4468750000001 314.4525 374.340625 337.51625 375.404375 360.634375C376.468125 383.7518750000001 382.6756250000001 406.341875 393.5718750000001 426.758125C404.46875 447.174375 419.7806250000001 464.91 438.395 478.660625C457.00875 492.411875 478.45625 501.833125 501.173125 506.24875C511.360625 507.17 521.61 507.17 531.7975 506.24875C553.2325000000001 506.709375 574.525625 502.6675 594.2975 494.3775C622.813125 482.518125 647.175 462.471875 664.30625 436.775625C681.4375 411.0793750000001 690.5687499999999 380.881875 690.55 349.9987500000001C689.81875 329.375 685.025 309.0975 676.44375 290.3293750000001C667.8625000000001 271.5606250000001 655.66875 254.67 640.55 240.62375L642.4250000000001 242.500625z" /> + horiz-adv-x="1000" d=" M461.808125 8.0875L382.431875 87.46875L424.308125 131.2125L557.433125 -1.9125V-45.65625L424.308125 -178.78125L379.933125 -134.4125L459.3075 -55.0375H343.6825C323.14 -55.11875 302.78625 -51.13125 283.791875 -43.3062500000001C264.796875 -35.4875 247.538125 -23.98125 233.0125 -9.45625C218.486875 5.06875 206.981875 22.33125 199.15875 41.325C191.335625 60.31875 187.349375 80.675 187.4325 101.2125V448.0925C157.4875 454.468125 129.965 469.200625 108.058125 490.588125C86.3 512.5725 71.495625 540.4762499999999 65.49375 570.819375C59.4916875 601.161875 62.5575 632.6 74.3075 661.211875C86.166875 689.7275 106.21125 714.08875 131.9075 731.219375C157.60375 748.350625 187.799375 757.485 218.6825 757.464375C240.1175 757.925375 261.41 753.883125 281.1825 745.593125C300.123125 737.80125 317.3325000000001 726.330625 331.8150000000001 711.84875C346.296875 697.36625 357.765625 680.153125 365.5575 661.211875C373.848125 641.44 377.89375 620.146875 377.433125 598.711875C377.45375 567.82875 368.3225 537.631875 351.1912500000001 511.935625C334.060625 486.239375 309.6975 466.2 281.1825 454.34125C271.9106250000001 450.485 262.280625 447.553125 252.433125 445.59V101.8375C252.433125 76.9749999999999 262.309375 53.13125 279.89125 35.5500000000001C297.4725 17.96875 321.31875 8.0875 346.183125 8.0875H461.808125zM169.30875 523.7149999999999C184.685625 513.515 202.73 508.08 221.183125 508.09C238.14125 508.08375 254.78375 512.67625 269.3375000000001 521.380625C283.8918750000001 530.085 295.813125 542.576875 303.83 557.52125C311.8475000000001 572.465 315.660625 589.3025 314.864375 606.2425000000001C314.0675 623.1825 308.691875 639.586875 299.308125 653.7125C288.8243750000001 669.24375 274.061875 681.405625 256.808125 688.71625C239.778125 695.653125 221.074375 697.39 203.0575 693.713125C184.808125 690.184375 168.0325 681.275 154.889375 668.131875C141.745625 654.98875 132.836875 638.2168750000001 129.3075 619.9675C125.63125 601.95 127.37 583.24875 134.306875 566.21875C141.6175 548.9649999999999 153.776875 534.19875 169.30875 523.7149999999999zM814.93125 129.9625C844.975 123.8499999999999 872.575 109.08125 894.3125 87.4625000000001C923.5375 58.0625 939.9375 18.29375 939.93125 -23.1625C939.95625 -54.04375 930.825 -84.24375 913.69375 -109.9375C896.5625 -135.6375 872.1999999999999 -155.6812500000001 843.6875 -167.54375C815.1 -179.46875 783.6125000000001 -182.6312500000001 753.225 -176.625C722.8375 -170.625 694.91875 -155.73125 673.01875 -133.825C651.11875 -111.9249999999999 636.21875 -84.00625 630.21875 -53.61875C624.2162500000001 -23.2312499999999 627.38125 8.25 639.30625 36.8375C651.3625 65.1999999999999 671.3249999999999 89.5 696.80625 106.8375C713.60625 118.2125 732.525 126.0749999999999 752.43125 129.9625V476.8375C752.43125 501.70125 742.55625 525.5475 724.975 543.129375C707.3937500000001 560.7106249999999 683.55 570.5875 658.68125 570.5875H543.06L622.4325 491.21125L578.0600000000001 446.83875L444.933125 579.96375V623.71125L578.0600000000001 756.83625L622.4325 712.46375L543.06 633.0875H658.68125C679.225 633.1700000000001 699.5812500000001 629.184375 718.5749999999999 621.3612499999999C737.56875 613.538125 754.8249999999999 602.035 769.35 587.509375C783.875 572.98375 795.3875 555.7225000000001 803.20625 536.728125C811.03125 517.73375 815.0187500000001 497.379375 814.93125 476.8375V129.9625zM792.9937500000001 -116.4312500000001C814.5250000000001 -114.2687499999999 834.6375 -104.725 849.93125 -89.41875C865.24375 -74.125 874.7875 -54 876.95 -32.46875C879.11875 -10.9375 873.76875 10.6750000000001 861.80625 28.7125C851.325 44.24375 836.5625 56.4000000000001 819.30625 63.7125C802.28125 70.6500000000001 783.575 72.3874999999999 765.5625 68.7125C747.3125 65.18125 730.5374999999999 56.275 717.3937500000001 43.13125C704.25 29.9875 695.3375000000001 13.2125 691.8125 -5.0375C688.13125 -23.05 689.86875 -41.75625 696.80625 -58.78125C704.11875 -76.0375 716.275 -90.8062500000001 731.80625 -101.2875C749.84375 -113.2437500000001 771.4625000000001 -118.59375 792.9937500000001 -116.4312500000001z" /> + horiz-adv-x="1000" d=" M829.55625 336.840625C800.15625 366.068125 760.38125 382.4700000000001 718.9250000000001 382.464375C688.0437499999999 382.485 657.85 373.350625 632.15 356.219375C606.454375 339.08875 586.411875 314.7275 574.5525 286.2118750000001C570.90625 277.3493749999999 568.183125 268.1375 566.4275 258.7156250000001C502.53125 265.7275000000001 442.93875 294.318125 397.4856250000001 339.770625C352.033125 385.223125 323.43875 444.8193750000001 316.4275 508.715625C325.84875 510.47125 335.0643750000001 513.194375 343.9275 516.84125C372.443125 528.7 396.8037500000001 548.739375 413.935 574.435625C431.065625 600.131875 440.196875 630.32875 440.17625 661.211875C440.636875 682.646875 436.59125 703.94 428.3012500000001 723.711875C420.50875 742.653125 409.0425 759.866125 394.56 774.3484375C380.0775 788.83075 362.8687500000001 800.30125 343.9275 808.09325C324.1550000000001 816.38343125 302.8625 820.4254025 281.4275 819.9645975C250.544375 819.9851908125 220.346875 810.850375 194.650625 793.7195C168.954375 776.5885625 148.911875 752.2275 137.0525 723.711875C125.3025 695.1 122.23875 663.661875 128.240625 633.319375C134.2425 602.97625 149.043125 575.0725 170.80125 553.088125C192.708125 531.700625 220.2325 516.968125 250.1775 510.5925V191.8375000000001C230.268125 187.9500000000001 211.346875 180.0875 194.551875 168.7125C169.065625 151.3812499999999 149.10625 127.08125 137.0525 98.7125C125.123125 70.125 121.96 38.6437500000001 127.9625 8.25625C133.964375 -22.13125 148.86125 -50.05 170.763125 -71.95C192.665 -93.85 220.58375 -108.75 250.97125 -114.75C281.3581250000001 -120.75 312.844375 -117.59375 341.42875 -105.6625C369.944375 -93.8062500000001 394.305625 -73.75625 411.4362500000001 -48.0625C428.5668750000001 -22.36875 437.698125 7.83125 437.6775 38.7125C438.138125 60.15 434.0925 81.44375 425.8025 101.2125C418.010625 120.15625 406.54375 137.3625 392.06125 151.84375C377.579375 166.3250000000001 360.37 177.7937500000001 341.42875 185.5875C332.156875 189.4437499999999 322.525625 192.375 312.6775 194.3375V344.340625C344.968125 298.703125 387.865625 261.598125 437.6775 236.2168750000001C478.380625 215.3768749999999 522.745 202.6425000000001 568.3043749999999 198.718125C572.82375 176.05625 582.311875 154.675 596.086875 136.125C609.86125 117.5750000000001 627.58125 102.3125 647.9625 91.43125C668.34375 80.5562500000001 690.8874999999999 74.33125 713.96875 73.2125C737.05 72.09375 760.0875 76.1062499999999 781.4250000000001 84.9625C809.9437499999999 96.8249999999999 834.30625 116.86875 851.4375 142.5687499999999C868.56875 168.2625000000001 877.69375 198.459375 877.675 229.3425000000001C876.20625 270.06625 858.95 308.618125 829.55625 336.840625V336.840625zM317.053125 125.5875C334.3062500000001 118.28125 349.06875 106.11875 359.5525 90.5875C371.56625 72.5562500000001 376.96125 50.9250000000001 374.8225 29.3625C372.684375 7.8 363.14375 -12.3625 347.8225 -27.6812500000001C332.500625 -43.00625 312.346875 -52.5437499999999 290.7850000000001 -54.6875C269.223125 -56.8249999999999 247.58375 -51.425 229.55125 -39.4125C214.02 -28.9250000000001 201.8625 -14.1625 194.551875 3.09375C187.615 20.125 185.8775 38.825 189.554375 56.84375C193.083125 75.09375 201.9925 91.8625 215.135625 105.00625C228.27875 118.15 245.054375 127.05625 263.30375 130.5875C281.32125 134.2625000000001 300.023125 132.5250000000001 317.053125 125.5875V125.5875zM281.4275 569.964375C262.975 569.954375 244.92875 575.389375 229.55125 585.589375C214.02 596.073125 201.8625 610.839375 194.551875 628.093125C187.615 645.1231250000001 185.8775 663.8243749999999 189.554375 681.8418750000001C193.083125 700.09125 201.9925 716.863125 215.135625 730.00625C228.27875 743.149375 245.054375 752.05875 263.30375 755.5875C281.32125 759.2644375 300.023125 757.5274375 317.053125 750.590625C334.3062500000001 743.28 349.06875 731.118125 359.5525 715.586875C368.9362500000001 701.4612500000001 374.3125 685.056875 375.10875 668.1168749999999C375.905 651.176875 372.09375 634.339375 364.0768750000001 619.395625C356.059375 604.45125 344.13875 591.959375 329.584375 583.255C315.03 574.550625 298.38625 569.958125 281.4275 569.964375V569.964375zM785.175 159.9625C769.8812499999999 144.65625 749.76875 135.1125000000001 728.2375 132.9437499999999C706.70625 130.78125 685.0875 136.13125 667.0500000000001 148.0875C651.5187500000001 158.5749999999999 639.3625 173.3375 632.05 190.59375C625.1125 207.623125 623.3775 226.3243749999999 627.05625 244.341875C630.58125 262.59125 639.49375 279.363125 652.6374999999999 292.50625C665.78125 305.6493750000001 682.55625 314.5587500000001 700.80625 318.0875000000001C718.8187499999999 321.764375 737.525 320.0275000000001 754.5500000000001 313.090625C771.80625 305.78 786.56875 293.618125 797.0500000000001 278.086875C809.0125 260.051875 814.3625 238.436875 812.19375 216.906875C810.03125 195.3762499999999 800.4875000000001 175.25625 785.175 159.9625V159.9625z" /> + horiz-adv-x="1000" d=" M382.431875 149.96875L461.808125 70.5875H346.183125C321.31875 70.5875 297.4725 80.46875 279.89125 98.0500000000001C262.309375 115.63125 252.433125 139.4749999999999 252.433125 164.3375V508.09C262.280625 510.053125 271.9106250000001 512.985 281.1825 516.84125C309.6975 528.7 334.060625 548.739375 351.1912500000001 574.435625C368.3225 600.131875 377.45375 630.32875 377.433125 661.211875C377.89375 682.646875 373.848125 703.94 365.5575 723.711875C357.765625 742.653125 346.296875 759.866125 331.8150000000001 774.3484375C317.3325000000001 788.83075 300.123125 800.30125 281.1825 808.09325C261.41 816.38343125 240.1175 820.4254025 218.6825 819.9645975C187.799375 819.9851908125 157.60375 810.850375 131.9075 793.7195C106.21125 776.5885625 86.166875 752.2275 74.3075 723.711875C62.5575 695.1 59.4916875 663.661875 65.49375 633.319375C71.495625 602.97625 86.3 575.0725 108.058125 553.088125C129.965 531.700625 157.4875 516.968125 187.4325 510.5925V163.7125C187.349375 143.175 191.335625 122.81875 199.15875 103.8250000000001C206.981875 84.83125 218.486875 67.56875 233.0125 53.04375C247.538125 38.51875 264.796875 27.0125 283.791875 19.1937499999999C302.78625 11.36875 323.14 7.38125 343.6825 7.4625H459.3075L379.933125 -71.9125L424.308125 -116.28125L557.433125 16.84375V60.5875L424.308125 193.7125L382.431875 149.96875zM221.183125 570.59C202.73 570.5799999999999 184.685625 576.015 169.30875 586.215C153.776875 596.69875 141.6175 611.465 134.306875 628.71875C127.37 645.74875 125.63125 664.45 129.3075 682.4675C132.836875 700.716875 141.745625 717.48875 154.889375 730.631875C168.0325 743.775 184.808125 752.684375 203.0575 756.213125C221.074375 759.8900625 239.778125 758.1530625 256.808125 751.21625C274.061875 743.905625 288.8243750000001 731.74375 299.308125 716.2125C308.691875 702.086875 314.0675 685.6825 314.864375 668.7425000000001C315.660625 651.8025 311.8475000000001 634.965 303.83 620.02125C295.813125 605.076875 283.8918750000001 592.585 269.3375000000001 583.880625C254.78375 575.17625 238.14125 570.58375 221.183125 570.59V570.59z M894.3125 149.9625000000001C872.575 171.58125 844.975 186.3499999999999 814.93125 192.4625V539.3375000000001C815.0187500000001 559.879375 811.03125 580.23375 803.20625 599.228125C795.3875 618.2225 783.875 635.48375 769.35 650.009375C754.8249999999999 664.535 737.56875 676.038125 718.5749999999999 683.8612499999999C699.5812500000001 691.684375 679.225 695.67 658.68125 695.5875H543.06L622.4325 774.9636875L578.0600000000001 819.33624375L444.933125 686.21125V642.46375L578.0600000000001 509.33875L622.4325 553.7112500000001L543.06 633.0875H658.68125C683.55 633.0875 707.3937500000001 623.210625 724.975 605.629375C742.55625 588.0475 752.43125 564.20125 752.43125 539.3375000000001V192.4625C732.525 188.5749999999999 713.60625 180.7125 696.80625 169.3375C671.3249999999999 152 651.3625 127.6999999999999 639.30625 99.3375C627.38125 70.75 624.2162500000001 39.2687500000001 630.21875 8.88125C636.21875 -21.50625 651.11875 -49.425 673.01875 -71.325C694.91875 -93.23125 722.8375 -108.125 753.225 -114.125C783.6125000000001 -120.13125 815.1 -116.96875 843.6875 -105.04375C872.1999999999999 -93.1812500000001 896.5625 -73.1375 913.69375 -47.4375C930.825 -21.74375 939.95625 8.45625 939.93125 39.3375C939.9375 80.7937500000001 923.5375 120.5625 894.3125 149.9625000000001V149.9625000000001zM849.93125 -26.91875C834.6375 -42.225 814.5250000000001 -51.76875 792.9937500000001 -53.9312500000001C771.4625000000001 -56.09375 749.84375 -50.7437500000001 731.80625 -38.7875C716.275 -28.3062500000001 704.11875 -13.5375 696.80625 3.71875C689.86875 20.74375 688.13125 39.45 691.8125 57.4625C695.3375000000001 75.7125 704.25 92.4875 717.3937500000001 105.63125C730.5374999999999 118.775 747.3125 127.68125 765.5625 131.2125C783.575 134.8874999999999 802.28125 133.1500000000001 819.30625 126.2125C836.5625 118.9000000000001 851.325 106.74375 861.80625 91.2125C873.76875 73.1750000000001 879.11875 51.5625 876.95 30.03125C874.7875 8.5 865.24375 -11.625 849.93125 -26.91875V-26.91875z" /> @@ -261,7 +261,7 @@ horiz-adv-x="1000" d=" M93.75 -55H937.5V7.5H125V820H62.5V-23.75L93.75 -55zM187.5 101.25V601.25L218.75 632.5H343.75L375 601.25V101.25L343.75 70H218.75L187.5 101.25zM312.5 132.5V570H250V132.5H312.5zM687.5 726.25V101.25L718.75 70H843.75L875 101.25V726.25L843.75 757.5H718.75L687.5 726.25zM812.5 695V132.5H750V695H812.5zM437.5 101.25V476.25L468.75 507.5H593.75L625 476.25V101.25L593.75 70H468.75L437.5 101.25zM562.5 132.5V445H500V132.5H562.5z" /> + horiz-adv-x="1000" d=" M930 521.24625C924.95625 540.984375 917.175 559.9200000000001 906.875 577.498125C896.9875000000001 595.78375 884.3312500000001 612.439375 869.375 626.875625C847.6875 648.4918749999999 822 665.681875 793.75 677.4962499999999C736.8875 700.834375 673.1125 700.834375 616.249375 677.4962499999999C589.5475 666.19375 565.016875 650.3325 543.75125 630.6212499999999L540.6268749999999 626.875625L500.000625 586.24875L459.374375 626.875625L456.25 630.6212499999999C434.984375 650.3325 410.45375 666.19375 383.75125 677.4962499999999C326.88625 700.834375 263.115 700.834375 206.25 677.4962499999999C177.99875 665.681875 152.31625 648.4918749999999 130.6275 626.875625C115.656875 612.294375 102.82125 595.669375 92.50125 577.498125C82.66125 559.770625 75.100625 540.869375 70 521.24625C64.70125 500.845 62.1788125 479.821875 62.500625 458.74625C62.533125 438.9262500000001 65.0525 419.1925 70 400C75.24 380.6225 82.795 361.945 92.50125 344.374375C102.98375 326.31125 115.803125 309.7075 130.6275 294.996875L500.000625 -74.38125L869.375 294.996875C884.19375 309.556875 896.8249999999999 326.190625 906.875 344.374375C917.05625 361.78875 924.8375 380.500625 930 400C934.95 419.1925 937.46875 438.9262500000001 937.5 458.74625C937.825 479.821875 935.3 500.845 930 521.24625V521.24625zM867.5 419.3712500000001C863.8249999999999 405.395 858.3625000000001 391.949375 851.25 379.37V379.37C843.825 366.411875 834.8 354.445625 824.375 343.74875L498.749375 18.75L173.126875 343.74875C162.515625 354.435 153.2775 366.39875 145.626875 379.37C138.426875 392.2025 132.761875 405.8400000000001 128.750625 419.996875C125.548125 434.151875 123.8725 448.613125 123.75125 463.125625C123.83625 478.053125 125.51125 492.92625 128.750625 507.498125C132.644375 521.6956250000001 138.315 535.346875 145.626875 548.125C153.123125 561.2 162.37625 573.183125 173.126875 583.7462499999999C189.183125 599.5875 208.0425 612.301875 228.74875 621.245C270.475 637.936875 317.024375 637.936875 358.75 621.245C379.323125 612.676875 398.01125 600.15 413.750625 584.371875L498.749375 498.7475L583.7525 584.371875C599.49125 600.15 618.175625 612.676875 638.75 621.245C680.475 637.936875 727.025 637.936875 768.75 621.245C789.45625 612.301875 808.31875 599.5875 824.375 583.7462499999999C835.26875 573.46 844.35 561.42125 851.25 548.125V548.125C858.3625000000001 535.545 863.8249999999999 522.1 867.5 508.12375V508.12375C871.2562499999999 493.84375 873.14375 479.141875 873.125 464.376875C873.98125 449.275625 872.71875 434.1225 869.375 419.3712500000001H867.5z" /> @@ -279,13 +279,13 @@ horiz-adv-x="1000" d=" M93.75 -55H906.25L937.5 -23.75V257.5L764.375 736.25L735 757.5H266.875L237.5 736.875L62.5 273.75V-23.75L93.75 -55zM875 7.5H125V193.75H284.375625L330.625625 115.625L357.500625 100.625H643.125L670.625 116.875L713.75 193.75H875V7.5zM873.625 256.24875H695L668.125 239.99875L625 163.125H375.625625L328.750625 241.24875L301.875625 256.24875H125V257.5L288.75 695H712.5L873.625 256.24875z" /> + horiz-adv-x="1000" d=" M535.52375 755.545C634.96875 745.600625 727.7249999999999 700.92625 797.5 629.3775C873.51875 552.153125 918.46875 449.6550000000001 923.76875 341.42125C929.06875 233.188125 894.3625 126.7937499999999 826.25625 42.5125C763.6125000000001 -35.35625 675.70625 -88.85 577.7681249999999 -108.7125000000001C479.829375 -128.5749999999999 378.0275000000001 -113.55625 290.0025 -66.25C201.788125 -17.9124999999999 132.923125 59.3375 95.0025 152.5C56.912375 246.1462499999999 51.8418125 349.973125 80.626875 446.8825C109.35 543.4143750000001 170.498125 627.075 253.75125 683.7525C336.313125 740.0675 436.080625 765.489375 535.52375 755.545zM565.0037500000001 -47.49375C648.93125 -30.46875 724.2937499999999 15.275 778.125 81.875C836.4125 154.31875 866.06875 245.649375 861.4625 338.5143750000001C856.8562499999999 431.38 818.3000000000001 519.316875 753.125 585.630625C693.4312500000001 646.5675 614.216875 684.583125 529.3325 693.0375C444.448125 701.49125 359.293125 679.845625 288.7512500000001 631.88C235.653125 595.293125 192.7775 545.755 164.181875 487.959375C135.586875 430.16375 122.220625 366.025625 125.350625 301.61875C128.48 237.2125 148.001875 174.6687499999999 182.065625 119.9187500000001C216.129375 65.1687500000001 263.60625 20.0187500000001 320.0012500000001 -11.25C394.89625 -51.66875 481.6125 -64.49375 565.0037500000001 -47.49375zM531.87625 382.501875L469.37625 382.501875L469.37625 132.5L531.87625 132.5L531.87625 382.501875zM531.87625 507.501875L469.37625 507.501875L469.37625 445.001875L531.87625 445.001875L531.87625 507.501875z" /> + horiz-adv-x="1000" d=" M468.749375 757.5C388.40125 757.5 309.856875 733.673125 243.049375 689.03375C176.241875 644.3943750000001 124.17125 580.946875 93.42375 506.714375C62.675625 432.481875 54.631125 350.8006250000001 70.30625 271.995625C85.981875 193.19375 124.6725 120.8 181.4875 63.9875000000001C238.3025 7.175 310.690625 -31.51875 389.495625 -47.19375C468.3 -62.86875 549.9812499999999 -54.8249999999999 624.21375 -24.075C698.44375 6.66875 761.8937500000001 58.74375 806.53125 125.55C851.1750000000001 192.3562500000001 875 270.90125 875 351.25C875 458.994375 832.2 562.325 756.0124999999999 638.511875C679.825 714.69875 576.49375 757.5 468.749375 757.5zM468.749375 7.5C400.7625000000001 7.5 334.3 27.65625 277.770625 65.43125C221.24125 103.2000000000001 177.1825 156.89375 151.164375 219.70375C125.146875 282.51625 118.339375 351.63125 131.603125 418.3125C144.86625 484.993125 177.606875 546.2406249999999 225.680625 594.315C273.7550000000001 642.389375 335.00625 675.129375 401.6875 688.393125C468.368125 701.656875 537.48375 694.84875 600.295625 668.83125C663.10625 642.81375 716.79375 598.7581250000001 754.56875 542.22875C792.3375 485.699375 812.5 419.2375 812.5 351.25C812.5 260.081875 776.28125 172.65 711.8187499999999 108.1875C647.35 43.71875 559.9174999999999 7.5 468.749375 7.5zM500 570H437.5V257.5H500V570zM437.5 195H500V132.5H437.5V195z" /> @@ -306,7 +306,7 @@ horiz-adv-x="1000" d=" M709.4375 751.81C763.99375 740.70125 814.0625 713.746875 853.375 674.3199999999999C886.6125000000001 640.7975 911.03125 599.564375 924.44375 554.3043749999999C937.85625 509.04375 939.85 461.165 930.25 414.945C916.3375 351.58 881.325 294.8143750000001 830.9499999999999 253.94C780.56875 213.0650000000001 717.8125 190.5 652.9375 189.94375C625.56875 189.9 598.3375 193.88125 572.125 201.7574999999999L522.125 143.1937499999999L498.4375 132.25625H437.5V38.50625L406.25 7.25625H312.5V-86.49375L281.25 -117.74375H93.75L62.5 -86.49375V57.69375L71.625 79.75625L382.5 390.5700000000001C373.6775 418.9875 369.4575 448.6325 370 478.3825C370.76375 534.05375 387.9325 588.263125 419.3556250000001 634.224375C450.779375 680.185 495.061875 715.85625 546.660625 736.771875C598.2593750000001 757.6875 654.88125 762.918375 709.4375 751.81zM791.83125 301.8368750000001C831.08125 333.6287500000001 858.38125 377.805 869.25 427.1325L869.5 426.8200000000001C877.21875 462.88625 875.80625 500.309375 865.39375 535.6912500000001C854.975 571.073125 835.8875 603.293125 809.8625000000001 629.425625C783.8375 655.5587499999999 751.69375 674.77625 716.35625 685.334375C681.0125 695.8925 643.5999999999999 697.455625 607.5 689.8824999999999C558.79875 679.07375 515.114375 652.281875 483.40125 613.7731249999999C451.688125 575.264375 433.77 527.2525 432.5 477.3825C431.824375 448.950625 436.9056250000001 420.675625 447.4375 394.2575L440.5625 360.3825L125 44.75625V-55.24375H250V38.50625L281.25 69.75625H375V163.50625L406.25 194.75625H484.0625L538.8125 258.2575L573.875 267.0075000000001C599.149375 257.13125 626.05 252.0856250000001 653.1875 252.1325000000001C703.7 252.520625 752.58125 270.0450000000001 791.83125 301.8368750000001zM739.46875 472.5325C746.3375 482.810625 750 494.894375 750 507.255625C750 523.831875 743.4125 539.72875 731.69375 551.45C719.975 563.17125 704.075 569.755625 687.5 569.755625C675.1374999999999 569.755625 663.05625 566.0899999999999 652.775 559.2225000000001C642.5 552.355 634.4875 542.59375 629.75625 531.1737499999999C625.0250000000001 519.753125 623.789375 507.18625 626.1999999999999 495.0625C628.6125000000001 482.93875 634.5625 471.8025 643.30625 463.061875C652.04375 454.320625 663.1812500000001 448.368125 675.30625 445.9568750000001C687.4312500000001 443.545 700 444.783125 711.41875 449.513125C722.8375 454.24375 732.6 462.254375 739.46875 472.5325z" /> + horiz-adv-x="1000" d=" M875 632.5H187.5C170.92375 632.5 155.0275 625.918125 143.306875 614.196875C131.585625 602.47625 125 586.57625 125 570V132.5C125 115.925 131.585625 100.025 143.306875 88.3C155.0275 76.58125 170.92375 70 187.5 70H875C891.575 70 907.475 76.58125 919.19375 88.3C930.9125 100.025 937.5 115.925 937.5 132.5V570C937.5 586.57625 930.9125 602.47625 919.19375 614.196875C907.475 625.918125 891.575 632.5 875 632.5zM875 132.5H187.5V570H875V132.5zM687.5 507.5H625V445H687.5V507.5zM625 382.5H562.5V320H625V382.5zM750 507.5H812.5V445H750V507.5zM812.5 257.5H750V195H812.5V257.5zM375 257.5H687.5V195H375V257.5zM812.5 382.5H687.5V320H812.5V382.5zM500 507.5H562.5V445H500V507.5zM500 382.5H437.5V320H500V382.5zM250 257.5H312.5V195H250V257.5zM250 507.5H312.5V445H250V507.5zM437.5 507.5H375V445H437.5V507.5zM250 382.5H375V320H250V382.5z" /> @@ -330,7 +330,7 @@ horiz-adv-x="1000" d=" M677.04375 652.025625C630.3562499999999 698.714375 567.29375 725.344375 501.27125 726.25H498.77125C432.7487500000001 725.344375 369.685 698.714375 322.995625 652.025625C276.30625 605.3362500000001 249.676875 542.2725 248.77125 476.25C247.931875 429.3575 261.1212500000001 383.283125 286.64625 343.9375L483.361875 -55H516.680625L713.3937500000001 343.9375C738.9187499999999 383.283125 752.1125 429.3575 751.2687500000001 476.25C750.36875 542.2725 723.7375000000001 605.3362500000001 677.04375 652.025625zM495.27125 663.75L500.39625 663.125L505.02125 663.75C554.119375 661.611875 600.5325 640.745625 634.71875 605.441875C668.90625 570.138125 688.275 523.0787499999999 688.83125 473.9375C689.30625 439.0612500000001 679.125 404.8712500000001 659.64375 375.9375L658.39375 373.8125L657.3312500000001 371.625L500.02125 52.5625L342.70875 371.3125L341.64625 373.75L340.39625 375.875C320.9175 404.80875 310.734375 438.99875 311.20875 473.875C311.741875 523.073125 331.1287500000001 570.191875 365.374375 605.51875C399.62 640.8456249999999 446.1131250000001 661.688125 495.27125 663.75zM533.4875 528.2168750000001C523.209375 535.084375 511.125625 538.75 498.764375 538.75C482.188125 538.75 466.29125 532.165 454.57 520.444375C442.84875 508.723125 436.264375 492.82625 436.264375 476.25C436.264375 463.88875 439.929375 451.805 446.7975 441.526875C453.665 431.2487500000001 463.42625 423.2381250000001 474.84625 418.5075000000001C486.266875 413.776875 498.83375 412.539375 510.9575 414.950625C523.0812500000001 417.3625 534.2175 423.315 542.958125 432.055625C551.69875 440.796875 557.651875 451.933125 560.063125 464.056875C562.4749999999999 476.180625 561.2368749999999 488.7475 556.5068749999999 500.1675C551.77625 511.588125 543.7650000000001 521.349375 533.4875 528.2168750000001zM429.318125 580.18375C449.8737500000001 593.91875 474.04125 601.25 498.764375 601.25C531.91625 601.25 563.710625 588.080625 587.1524999999999 564.638125C610.594375 541.19625 623.7643750000001 509.401875 623.7643750000001 476.25C623.7643750000001 451.5275 616.433125 427.36 602.698125 406.8037500000001C588.9625000000001 386.2475 569.4399999999999 370.22625 546.599375 360.765C523.7587500000001 351.304375 498.625625 348.82875 474.3775 353.651875C450.13 358.475 427.8575 370.38 410.375625 387.861875C392.8943750000001 405.3431250000001 380.989375 427.6162500000001 376.16625 451.86375C371.3425000000001 476.11125 373.818125 501.244375 383.279375 524.0856249999999C392.74 546.92625 408.761875 566.44875 429.318125 580.18375z" /> + horiz-adv-x="1000" d=" M812.5 382.5H750V507.5C750 573.8043749999999 723.6625 637.38875 676.775 684.2731249999999C629.8937500000001 731.156875 566.3043749999999 757.5 500 757.5C433.695625 757.5 370.1075 731.156875 323.223125 684.2731249999999C276.33875 637.38875 250 573.8043749999999 250 507.5V382.5H187.5L125 320V-55L187.5 -117.5H812.5L875 -55V320L812.5 382.5zM312.5 507.5C312.5 557.2281250000001 332.253125 604.920625 367.41625 640.08375C402.5793750000001 675.246875 450.271875 695 500 695C549.728125 695 597.4206250000001 675.246875 632.58125 640.08375C667.74375 604.920625 687.5 557.2281250000001 687.5 507.5V382.5H312.5V507.5zM812.5 -55H187.5V320H812.5V-55z" /> @@ -378,16 +378,16 @@ horiz-adv-x="1000" d=" M538.125 632.5L896.875 536.875L937.5 507.5V86.25L914.375 56.25L531.25 -49.375L147.5 56.25L125 86.25V507.5L163.125 536.875L521.25 632.5H538.125zM532.5 570L282.5 507.5L316.875 495L531.25 438.75L718.75 489.375L778.125 507.5L532.5 570zM187.5 110L500 24.375V382.5L187.5 466.25V110zM562.5 382.5V24.375L875 110V468.125L748.75 433.5325V273.124375L686.25 256.874375V416.4075L562.5 382.5z" /> + horiz-adv-x="1000" d=" M908.7875 81.80625L837.5375 276.8143750000001V280.560625L530.6625 587.4375V664.936875C530.555 677.334375 528.2275 689.60875 523.78875 701.184375C518.92625 712.565 511.8287500000001 722.85375 502.918125 731.4425C494.0075 740.03125 483.464375 746.7475 471.9125 751.1875C460.398125 755.779375 448.04875 757.907 435.66125 757.435625C423.433125 757.6960625 411.289375 755.35375 400.035625 750.561875C388.8125 745.943125 378.615 739.146875 370.0331250000001 730.565C361.45125 721.983125 354.655 711.7825 350.036875 700.55875C345.245 689.305625 342.9025 677.165 343.1625 664.936875V461.18625L151.9125 273.68625C134.655625 255.95125 125 232.1781249999999 125 207.433125C125 182.6875 134.655625 158.9250000000001 151.9125 141.1875L378.788125 -85.6875C387.53875 -94.5124999999999 397.945625 -101.5187500000001 409.4125 -106.3125C432.275625 -115.4875000000001 457.8 -115.4875000000001 480.663125 -106.3125C492.13 -101.5187500000001 502.536875 -94.5124999999999 511.2875 -85.6875L819.4125 221.8143749999999L778.1625 84.3125C776.29375 74.81875 776.29375 65.05625 778.1625 55.5625C780.1687499999999 46.05625 784.21875 37.09375 790.0374999999999 29.30625C796.09375 21.75 803.5124999999999 15.3937500000001 811.9125 10.5625C820.68125 6.1875 830.25 3.6375 840.0375 3.0625C850.35 2.4312500000001 860.65625 4.3625 870.0375 8.6875C879.36875 12.90625 887.6875 19.09375 894.4125 26.8125C901.2125 34.69375 905.9375 44.14375 908.1625 54.3125C910.125 63.3562500000001 910.3375 72.6875 908.7875 81.80625V81.80625zM408.786875 664.936875C407.87 669.053125 407.87 673.3175 408.786875 677.43375C410.5456250000001 681.4449999999999 413.09625 685.061875 416.2862500000001 688.061875C419.674375 690.73875 423.473125 692.8475 427.53625 694.31C431.861875 695.239375 436.336875 695.239375 440.6625 694.31C448.248125 693.72375 455.36 690.389375 460.663125 684.93375C465.574375 679.19125 468.238125 671.8668749999999 468.1625 664.31125V585.560625L405.6625 523.0606250000001L408.786875 664.936875zM471.286875 -44.4375C468.64625 -47.6 465.18875 -49.975 461.2887500000001 -51.3125C457.548125 -52.9625 453.503125 -53.81875 449.4131250000001 -53.81875C445.32375 -53.81875 441.27875 -52.9625 437.538125 -51.3125C433.638125 -49.975 430.176875 -47.6 427.53625 -44.4375L200.660625 181.8125C197.81375 184.7312499999999 195.489375 188.1062499999999 193.786875 191.80625C192.15375 195.6637499999999 191.315 199.8125 191.315 203.999375C191.315 208.186875 192.15375 212.328125 193.786875 216.1837499999999C195.489375 219.885625 197.81375 223.27 200.660625 226.185625L472.538125 498.059375V319.935625C467.775625 315.57125 463.97875 310.2543750000001 461.395 304.33375C458.811875 298.4131250000001 457.499375 292.0175 457.53875 285.5575C456.77625 277.3318750000001 458.201875 269.053125 461.67 261.555625C465.138125 254.058125 470.525 247.60875 477.2875 242.86375C484.049375 238.11875 491.945 235.24375 500.175625 234.5325000000001C508.405625 233.8212500000001 516.6787499999999 235.2981249999999 524.154375 238.8125C531.630625 242.326875 538.0443750000001 247.753125 542.7475000000001 254.544375C547.450625 261.3356250000001 550.276875 269.2512500000001 550.9375 277.4856250000001C551.5981250000001 285.7206250000001 550.0693749999999 293.988125 546.50875 301.441875C542.948125 308.89625 537.4825 315.274375 530.6625 319.935625V496.808125L771.2875 254.933125L471.286875 -44.4375z" /> + horiz-adv-x="1000" d=" M826.875 757.5H735.625L220.00125 241.875L209.999375 228.1268750000001L62.5 -29.375L150.623125 -117.5L408.126875 30L421.875 40L937.5 555.62625V646.87375L826.875 757.5zM150.623125 -29.375L244.99875 158.125L335.625 67.5L150.623125 -29.375zM389.999375 99.375L279.373125 209.999375L779.375 709.999375L890 599.373125L389.999375 99.375z" /> + horiz-adv-x="1000" d=" M615.001875 757.5L558.124375 735.000625V601.25L344.375625 446.876875C312.088125 462.23125 276.160625 468.293125 240.62375 464.37875C205.404375 460.41 172.033125 446.54 144.375 424.3775V378.74625L321.87625 206.253125L60.001375 -55H154.99875L369.99875 159.99375L525.623125 8.125H573.1237500000001C595.604375 34.58125 609.7418749999999 67.1 613.746875 101.5875C617.75125 136.06875 611.44625 170.96875 595.626875 201.874375L755 409.378125H892.5L915.625 464.37875L615.001875 757.5zM740 474.373125L713.125 461.250625L533.74875 226.875625L529.99875 195C547.994375 160.61875 553.0962499999999 120.9375 544.37625 83.125L419.3762500000001 208.1225000000001L371.875625 254.371875L224.99875 397.499375C263.8625 405.660625 304.34125 400.6025 340 383.125625L373.1268750000001 386.8718750000001L614.3762499999999 561.249375L627.5 586.87625V658.7525L815 476.25L740 474.373125z" /> @@ -411,16 +411,13 @@ horiz-adv-x="1000" d=" M737.5 257.5L625 632.5H562.5L447.375625 217.5L374.375 526.875H313.75L240.625 257.5H62.5V195.625H264.375L295 218.75L341.25 387.5L411.875 70H476.25L593.125 510L684.375 217.5L714.375 195H937.5V257.5H737.5z" /> + horiz-adv-x="1000" d=" M468.750625 757.5C388.401875 757.5 309.8575 733.673125 243.05 689.03375C176.2425 644.3943750000001 124.174375 580.946875 93.42625 506.714375C62.678125 432.481875 54.6301875 350.8006250000001 70.305625 271.995625C85.980625 193.19375 124.67375 120.8 181.48875 63.9875000000001C238.30375 7.175 310.691875 -31.51875 389.49625 -47.19375C468.30125 -62.86875 549.9825000000001 -54.8249999999999 624.2149999999999 -24.075C698.45 6.66875 761.8937500000001 58.74375 806.53125 125.55C851.1750000000001 192.3562500000001 875 270.90125 875 351.25C875 458.994375 832.2 562.325 756.0124999999999 638.511875C679.825 714.69875 576.495 757.5 468.750625 757.5zM468.750625 7.5C400.763125 7.5 334.3006250000001 27.65625 277.77125 65.43125C221.241875 103.2000000000001 177.183125 156.89375 151.165625 219.70375C125.148125 282.51625 118.34 351.63125 131.60375 418.3125C144.8675 484.993125 177.6075 546.2406249999999 225.681875 594.315C273.75625 642.389375 335.0075 675.129375 401.688125 688.393125C468.369375 701.656875 537.484375 694.84875 600.29625 668.83125C663.10625 642.81375 716.79375 598.7581250000001 754.56875 542.22875C792.3375 485.699375 812.5 419.2375 812.5 351.25C812.5 260.081875 776.2875 172.65 711.8187499999999 108.1875C647.3562499999999 43.71875 559.91875 7.5 468.750625 7.5zM565.624375 533.7537500000001C554.82625 544.9975 541.85625 553.923125 527.5 559.99875C509.4375 567.2306249999999 490.073125 570.638125 470.626875 570.000625C451.7525 570.34375 433.015625 566.72125 415.62625 559.3731250000001C400.71625 553.1075000000001 387.455 543.485625 376.876875 531.25125C366.52625 519.9937500000001 358.46 506.83375 353.12625 492.50125C348.1675 477.9425 345.0175 462.83125 343.75 447.503125H420.6237500000001C421.078125 460.94125 426.6706250000001 473.68875 436.2487500000001 483.125C440.745625 487.805625 446.2025 491.455625 452.24375 493.82875C458.285 496.2025 464.768125 497.24125 471.24875 496.873125C476.83875 497.761875 482.535 497.761875 488.125 496.873125C493.26 494.93125 497.9425 491.951875 501.876875 488.1225C506.2187500000001 484.365 509.63875 479.6625 511.8749999999999 474.374375C514.435625 468.459375 515.713125 462.073125 515.625 455.62875C515.648125 444.834375 513.301875 434.166875 508.750625 424.3787500000001C504.211875 414.198125 498.550625 404.55 491.875 395.62375L470.00125 369.378125C462.50125 361.253125 454.99875 352.50125 448.12375 343.7512500000001C441.4575 335.041875 435.799375 325.61 431.25125 315.6293750000001C426.9156250000001 305.7924999999999 424.78 295.126875 424.999375 284.379375V243.1268750000001H500V273.7512500000001C500.211875 282.9181249999999 502.565625 291.910625 506.874375 300.004375C511.989375 309.015 517.844375 317.580625 524.375625 325.62375L546.875 353.1275C555.06625 362.590625 562.58375 372.6137500000001 569.374375 383.12625C576.556875 393.84625 582.4337499999999 405.3900000000001 586.875625 417.504375C591.43375 430.3475 593.7581250000001 443.87 593.75 457.498125C593.86125 471.696875 591.7543750000001 485.828125 587.50125 499.375625C582.781875 512.28125 575.31625 524.0125 565.624375 533.7537500000001zM425 205.6275000000001H498.125V132.5H425V205.6275000000001z" /> - + horiz-adv-x="1000" d=" M187.400625 471.2525C188.040625 562.236875 224.4025 649.326875 288.650625 713.753125L244.274375 757.5C206.480625 720.0231249999999 176.485 675.435 156.01375 626.3050000000001C135.541875 577.174375 125 524.4775 125 471.2525C125 418.0281250000001 135.541875 365.330625 156.01375 316.200625C176.485 267.07 206.480625 222.4825 244.274375 185.00625L288.650625 228.7525C224.4025 293.178125 188.040625 380.26875 187.400625 471.2525zM253.649375 471.2525C253.488125 434.3950000000001 260.705625 397.88 274.874375 363.8537500000001C289.0431250000001 329.8275 309.876875 298.9756250000001 336.15 273.125L380.52625 317.505C359.984375 337.270625 343.8037500000001 361.114375 333.025625 387.505C321.87125 414.0168750000001 316.1325 442.49 316.149375 471.2525C316.061875 499.820625 321.805 528.103125 333.025625 554.375C343.643125 581.03375 359.83875 605.114375 380.52625 625L336.15 669.380625C309.989375 643.445625 289.229375 612.5825 275.06875 578.575625C260.90875 544.5687499999999 253.6275 508.09 253.649375 471.2525zM731.775 270.63L687.4 315.0025C708.0125 334.9500000000001 724.1999999999999 359.01375 734.9 385.628125C746.05625 412.14 751.79375 440.613125 751.775 469.375625C751.8625 497.94375 746.125 526.23375 734.9 552.505625C724.28125 579.1643750000001 708.0875 603.245 687.4 623.13125L731.775 666.878125C757.8937500000001 640.915 778.61875 610.044375 792.75625 576.0425C806.9 542.040625 814.18125 505.575625 814.18125 468.75C814.18125 431.925 806.9 395.4675000000001 792.75625 361.465625C778.61875 327.46375 757.8937500000001 296.59375 731.775 270.63zM816.775 757.5L772.4 713.1275C804.4875000000001 681.54625 829.975 643.896875 847.36875 602.37125C864.7625 560.8456249999999 873.71875 516.274375 873.71875 471.2525C873.71875 426.23125 864.7625 381.659375 847.36875 340.13375C829.975 298.6081250000001 804.4875000000001 260.95875 772.4 229.3781250000001L816.775 185.00625C854.56875 222.4825 884.56875 267.07 905.04375 316.200625C925.5125 365.330625 936.05 418.0281250000001 936.05 471.2525C936.05 524.4775 925.5125 577.174375 905.04375 626.3050000000001C884.56875 675.435 854.56875 720.0231249999999 816.775 757.5zM624.54625 480.60625C626.6875 459.044375 621.2893750000001 437.413125 609.275625 419.380625C604.0875 414.09875 598.439375 409.281875 592.399375 404.999375L807.4 -78.125L749.9 -103.11875L701.7750000000001 5.00625H355.52625L307.4000000000001 -103.11875L249.900625 -78.125L464.90125 404.999375C451.840625 418.1925 442.9337500000001 434.924375 439.2775 453.125625C435.60125 471.1425 437.3381250000001 489.844375 444.275 506.874375C451.585625 524.128125 463.743125 538.894375 479.275 549.378125C497.306875 561.39125 518.9462500000001 566.79 540.508125 564.651875C562.0706250000001 562.51375 582.224375 552.973125 597.545625 537.65125C612.866875 522.3299999999999 622.4075 502.16875 624.54625 480.60625zM524.9025 501.8775C518.9775 500.48125 513.56375 497.44875 509.2775 493.12625C505.9193749999999 489.15875 503.55875 484.445 502.399375 479.378125C500.530625 473.48125 500.530625 467.148125 502.399375 461.250625C504.861875 455.578125 508.7343749999999 450.630625 513.64875 446.876875C518.9143750000001 443.639375 524.969375 441.9125 531.150625 441.8793750000001C539.38875 442.039375 547.24375 445.384375 553.0699999999999 451.2106250000001C558.89625 457.036875 562.240625 464.891875 562.400625 473.129375C562.368125 479.310625 560.6375 485.36625 557.4 490.63125C553.64625 495.54625 548.69875 499.415 543.02625 501.8775C537.1287500000001 503.74625 530.7993749999999 503.74625 524.9025 501.8775zM539.27625 373.749375H522.4L468.025 252.503125H593.025L539.27625 373.749375zM676.775 65L621.15125 190H441.150625L385.5250000000001 65H676.775z" /> @@ -429,7 +426,7 @@ horiz-adv-x="1000" d=" M394.153125 685.845L142.903125 434.594375V390.400625L394.153125 139.1500000000001L438.346875 183.34375L237.940625 383.75125H355.625C531.4475 383.75125 643.43125 345.945625 712.2062500000001 275.715625C781.0875000000001 205.370625 813.125 95.8937500000001 813.125 -63.125V-85H875.625V-63.125C875.625 102.2312500000001 842.6625 231.81875 756.85625 319.443125C670.9437499999999 407.1818750000001 538.5525 446.25125 355.625 446.25125H242.9475L438.346875 641.650625L394.153125 685.845z" /> + horiz-adv-x="1000" d=" M812.5 195H249.998125V695H499.998125V757.5H233.7475C219.413125 757.34125 205.226875 754.588125 191.87375 749.375C178.3075 743.470625 166.16 734.731875 156.248125 723.7475C146.12 713.150625 138.2525 700.606875 133.12375 686.875C127.9825 674.5899999999999 125.225 661.44 124.998125 648.125V54.375C124.848125 40.0125 127.6125 25.7624999999999 133.12375 12.5C144.080625 -14.2874999999999 165.20625 -35.6375 191.87375 -46.875C205.226875 -52.0875 219.413125 -54.84375 233.7475 -55H249.998125V7.5H233.7475C227.51125 7.48125 221.340625 8.7625 215.62375 11.25625C204.455625 16.1625 195.53375 25.08125 190.6225 36.25C189.674375 42.25 189.674375 48.36875 190.6225 54.375V85.625C189.674375 91.63125 189.674375 97.75 190.6225 103.75C195.53375 114.9187500000001 204.455625 123.8375 215.62375 128.74375C221.340625 131.2375 227.51125 132.51875 233.7475 132.5H812.5V7.5H562.498125V-55H843.75L875 -23.75V257.5H812.5V195zM375 632.5H312.5V570H375V632.5zM312.5 507.5H375V445H312.5V507.5zM312.5 382.5H375V320H312.5V382.5zM330 -117.5H312.5V70H500V-117.5H482.5L406.25 -23.125L330 -117.5zM625 757.5H906.25L937.5 726.25V351.25L906.25 320H750V257.5H687.5V320H625C608.42375 320 592.5275 326.5818750000001 580.806875 338.303125C569.085625 350.02375 562.5 365.92375 562.5 382.5V695C562.5 711.57625 569.085625 727.4762499999999 580.806875 739.196875C592.5275 750.918125 608.42375 757.5 625 757.5zM656.25 382.5H687.5V445H656.25C647.9625 445 640.0124999999999 441.705 634.15 435.845C628.2937499999999 429.984375 625 422.038125 625 413.75C625 405.461875 628.2937499999999 397.515625 634.15 391.6550000000001C640.0124999999999 385.795 647.9625 382.5 656.25 382.5zM750 382.5H875V445H750V382.5zM687.5 507.5H875V695H687.5V507.5z" /> @@ -468,7 +465,7 @@ horiz-adv-x="1000" d=" M218.75 570H62.5V632.5H187.5V757.5H250V601.25L218.75 570zM812.5 632.5V757.5H750V601.25L781.25 570H937.5V632.5H812.5zM750 38.75V-117.5H812.5V7.5H937.5V70H781.25L750 38.75zM62.5 70V7.5H187.5V-117.5H250V38.75L218.75 70H62.5zM750 163.75L718.75 132.5H281.25L250 163.75V476.25L281.25 507.5H718.75L750 476.25V163.75zM625 382.5H375V257.5H625V382.5z" /> + horiz-adv-x="1000" d=" M622.2881249999999 757.5C559.8087499999999 757.5645625 498.645625 739.565625 446.156875 705.674375C393.668125 671.783125 352.0925 623.4456250000001 326.44 566.475C300.7875 509.505 292.1500000000001 446.33 301.5668750000001 384.564375C310.9831250000001 322.7987500000001 338.05375 265.071875 379.516875 218.33375L62.5 -141.10625L106.69375 -180L422.535 178.2687500000001C463.19125 146.425 510.8675 124.7562499999999 561.59375 115.06875C612.319375 105.3875000000001 664.625 107.96875 714.15625 122.59375C763.68125 137.21875 809 163.46875 846.325 199.1575C883.6500000000001 234.844375 911.9125 278.933125 928.75 327.7537500000001C945.5875 376.5743750000001 950.50625 428.71125 943.1125 479.82125C935.71875 530.9312500000001 916.21875 579.534375 886.2375 621.580625C856.25 663.6268749999999 816.65625 697.899375 770.74375 721.541875C724.8312500000001 745.185 673.93125 757.5123125 622.2881249999999 757.5V757.5zM622.2881249999999 168.25C569.84375 168.25 518.5775 183.8000000000001 474.971875 212.9393749999999C431.36625 242.075625 397.3787500000001 283.4881250000001 377.3087500000001 331.94C357.2393750000001 380.3925000000001 351.99 433.7075000000001 362.221875 485.14375C372.453125 536.580625 397.708125 583.828125 434.791875 620.911875C471.875625 657.995625 519.1231250000001 683.250625 570.56 693.481875C621.99625 703.71375 675.3125 698.4606249999999 723.7624999999999 678.39125C772.2125 658.321875 813.625 624.3375 842.7624999999999 580.731875C871.9 537.12625 887.4499999999999 485.85625 887.4499999999999 433.411875C887.53125 398.56875 880.725 364.053125 867.425 331.846875C854.125 299.640625 834.6 270.3775 809.9625 245.739375C785.325 221.1012499999999 756.0625 201.5725 723.8562499999999 188.275C691.65 174.975 657.1312499999999 168.1687500000001 622.2881249999999 168.25V168.25z" /> @@ -486,7 +483,7 @@ horiz-adv-x="1000" d=" M688.75 584.375V486.875L751.25 548.75V663.75L720 695H157.50125L126.25125 663.75V633.375625L125 632.498125V-10.625L147.5 -39.375L460 -146.875L500 -117.5V-54.99375H720L751.25 -23.74375V7.50625V89.38125L688.75 151.88125V7.50625H500V525.6231250000001L479.375 554.3731250000001L252.2618750000001 632.5H438.75125H688.75V584.375zM437.5 -72.5L187.5 11.25V587.4981250000001L437.5 503.748125V-72.5zM845 289.996875H534.374375V352.496875H842.5L742.5 452.496875L786.875 496.246875L941.25 342.4968750000001V298.1218750000001L785.625 143.11875L741.875 186.86875L845 289.996875z" /> + horiz-adv-x="1000" d=" M256.938125 683.769375C328.885 731.8425 413.4700000000001 757.5 499.999375 757.5C616.031875 757.5 727.3125 711.40375 809.3625 629.356875C891.40625 547.309375 937.5 436.0325 937.5 320C937.5 233.470625 911.84375 148.88125 863.76875 76.9375C815.69375 4.9875 747.3625000000001 -51.0812500000001 667.4250000000001 -84.2C587.48 -117.3125 499.5125 -125.975 414.645625 -109.09375C329.77875 -92.2125 251.824375 -50.5437499999999 190.63875 10.64375C129.45375 71.83125 87.788125 149.78125 70.906875 234.65C54.026 319.516875 62.688125 407.484375 95.801875 487.426875C128.915 567.37 184.991875 635.69625 256.938125 683.769375zM291.66 8.2C353.328125 -33.0062499999999 425.83125 -55 499.999375 -55C599.455625 -55 694.8375 -15.4937500000001 765.1625 54.8312500000001C835.4875000000001 125.15625 875 220.5437499999999 875 320C875 394.168125 853.0062499999999 466.6675 811.8 528.335625C770.59375 590.004375 712.025 638.075625 643.5062499999999 666.458125C574.9825 694.84125 499.58375 702.2675 426.84125 687.798125C354.098125 673.328125 287.280625 637.611875 234.83625 585.1675C182.39125 532.7225 146.675 465.90125 132.205625 393.1581250000001C117.73625 320.415625 125.161875 245.013125 153.545 176.4937500000001C181.9275 107.96875 229.99125 49.40625 291.66 8.2zM406.25 382.5C406.25 347.9825 378.2675 320 343.75 320C309.2325 320 281.25 347.9825 281.25 382.5C281.25 417.0175 309.2325 445 343.75 445C378.2675 445 406.25 417.0175 406.25 382.5zM718.75 382.5C718.75 347.9825 690.7687500000001 320 656.25 320C621.7318750000001 320 593.75 347.9825 593.75 382.5C593.75 417.0175 621.7318750000001 445 656.25 445C690.7687500000001 445 718.75 417.0175 718.75 382.5zM500 132.5C466.038125 132.4187499999999 432.689375 141.55625 403.51875 158.9499999999999C374.348125 176.34375 350.44875 201.3306250000001 334.3737500000001 231.2475L279.9987500000001 201.24875C301.883125 160.75 334.5250000000001 127.08125 374.3250000000001 103.9500000000001C414.124375 80.81875 459.536875 69.13125 505.558125 70.1687500000001C551.57875 71.1999999999999 596.423125 84.9187499999999 635.14375 109.8125C673.8625000000001 134.70625 704.95625 169.8125 725 211.250625L668.75 238.1212500000001C653.375 206.4475000000001 629.39375 179.74375 599.551875 161.0625C569.70875 142.3875000000001 535.2075 132.4875000000001 500 132.5z" /> @@ -495,7 +492,7 @@ horiz-adv-x="1000" d=" M599.65875 429.243125L500 757.5L400.34125 429.243125H62.5L335.819375 216.7206250000001L234.35 -117.5L500 89.0625L765.6500000000001 -117.5L664.18125 216.7206250000001L937.5 429.243125H599.65875z" /> + horiz-adv-x="1000" d=" M256.938125 683.769375C328.885 731.8425 413.4700000000001 757.5 499.999375 757.5C616.031875 757.5 727.3125 711.40375 809.3625 629.356875C891.40625 547.309375 937.5 436.0325 937.5 320C937.5 233.470625 911.84375 148.88125 863.76875 76.9375C815.69375 4.9875 747.3625000000001 -51.0812500000001 667.4250000000001 -84.2C587.48 -117.3125 499.5125 -125.975 414.645625 -109.09375C329.77875 -92.2125 251.824375 -50.5437499999999 190.63875 10.64375C129.45375 71.83125 87.788125 149.78125 70.906875 234.65C54.026 319.516875 62.688125 407.484375 95.801875 487.426875C128.915 567.37 184.991875 635.69625 256.938125 683.769375zM291.66 8.2C353.328125 -33.0062499999999 425.83125 -55 499.999375 -55C599.455625 -55 694.8375 -15.4937500000001 765.1625 54.8312500000001C835.4875000000001 125.15625 875 220.5437499999999 875 320C875 394.168125 853.0062499999999 466.6675 811.8 528.335625C770.59375 590.004375 712.025 638.075625 643.5062499999999 666.458125C574.9825 694.84125 499.58375 702.2675 426.84125 687.798125C354.098125 673.328125 287.280625 637.611875 234.83625 585.1675C182.39125 532.7225 146.675 465.90125 132.205625 393.1581250000001C117.73625 320.415625 125.161875 245.013125 153.545 176.4937500000001C181.9275 107.96875 229.99125 49.40625 291.66 8.2zM508.1250000000001 353.125L660.625 507.5L704.375 463.125L551.875 308.75L704.375 153.75L660.625 110L508.1250000000001 264.375L356.25 110L312.5 153.75L465 308.75L312.5 463.125L356.25 507.5L508.1250000000001 353.125z" /> @@ -513,7 +510,7 @@ horiz-adv-x="1000" d=" M62.5 757.5H937.5V-117.5H62.5V757.5zM125 -55H875V695H125V-55zM250.005 463.306875L294.19875 507.500625L515.1700000000001 286.53L470.975625 242.335625L470.9737500000001 242.3375L294.1943750000001 65.55625L250 109.75L426.78 286.531875L250.005 463.306875z" /> + horiz-adv-x="1000" d=" M209.999375 382.5L62.5 7.5H146.251875L178.12375 99.375H319.374375L352.500625 7.5H437.5L290.62625 382.5H209.999375zM200.62625 161.875L249.374375 295.624375L298.12625 161.875H200.62625z M738.75 570H638.75L437.5 7.5H535L581.875 150.625H791.875L840 7.5H937.5L738.75 570zM604.3737500000001 226.25L678.125 450.623125C681.8125 462.21625 684.3249999999999 474.155625 685.625 486.251875C687.3125 474.268125 689.6062499999999 462.37375 692.5 450.623125L770.625 226.25H604.3737500000001z" /> @@ -528,7 +525,7 @@ horiz-adv-x="1000" d=" M333.584375 539.8824999999999L439.93 433.53625L386.4525 380.075L280.115 486.413125L226.023125 487.035625L115.971875 650.55625L169.440625 704.025625L332.961875 593.974375L333.584375 539.8824999999999zM513.393125 253.134375L513.3950000000001 253.1331250000001L566.871875 306.594375L566.870625 306.595625L636.8125 376.518125C668.00625 361.5487500000001 703.075 356.6125 737.19375 362.3893750000001C771.3125 368.166875 802.8 384.3725 827.31875 408.77625C851.73125 433.28625 867.95 464.75875 873.725 498.86C879.50625 532.961875 874.56875 568.015625 859.59375 599.19625L748.23125 487.66125L668.91875 566.9375L780.78125 678.24875C749.59375 693.385625 714.46875 698.435625 680.275 692.6975C646.0875000000001 686.95875 614.53125 670.71625 590.0006249999999 646.2275C565.47 621.73875 549.180625 590.22 543.396875 556.051875C537.6125000000001 521.88375 542.62125 486.7625 557.725625 455.570625L119.981875 17.95625V-21.56875L159.525625 -61.09375H199.07L513.393125 253.134375zM682.33125 -22.74375L507.78875 151.8L654.76875 298.733125C665.38125 296.2050000000001 676.15625 294.419375 687.0125 293.3887500000001L842.7375000000001 137.6624999999999C864.5 115.9000000000001 876.925 86.5750000000001 877.28125 56.1375C877.63125 25.70625 865.875 -3.3375000000001 844.60625 -24.6125C770.29375 -100.0125 682.33125 -22.74375 682.33125 -22.74375z" /> + horiz-adv-x="1000" d=" M750 570H625V632.5C625 649.07625 618.414375 664.97625 606.693125 676.696875C594.9725 688.418125 579.07625 695 562.5 695H375C358.42375 695 342.5275 688.418125 330.806875 676.696875C319.085625 664.97625 312.5 649.07625 312.5 632.5V570H125V507.5H187.5V-55L250 -117.5H687.5L750 -55V507.5H812.5V570H750zM375 632.5H562.5V570H375V632.5zM687.5 -55H250V507.5H687.5V-55zM437.5 445H500V7.5H437.5V445zM562.5 445H625V7.5H562.5V445zM312.5 445H375V7.5H312.5V445z" /> diff --git a/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.ttf b/src/vs/base/browser/ui/octiconLabel/octicons/octicons2.ttf index 654cfe91291a4b391122cf0b76277f89e8723e80..daa9a772ad2ea0963483e58ae0f3d30c2d558cc9 100644 GIT binary patch delta 4908 zcma)A3y>Vub$$1BPxt(1dOqDVv$HeP^XuK6@6L43?5w07NxNE$)uNS*erP3ODf$Hj z`j!MLc84Oc1_73om9UU-0>%(R2)_l4S>a$P7p8)+0~HYiaT#zq6lDmZWW}ttLvGJX zQQ=A@={Mc)_3M7G-@EtRd+wb#Cg|^u(<5^EuBE>r1nwq;topO-H}1Ns$J$N^`!XT+ zkGJi(Y3ps`xj{m_0Ya|t-@awzX3_LU&(RfG^O9d~zmX8((W7@nJh!YPgvNL6+`G^5 zlc1ZBTW>k~LNV5JD*f~|uDQP_Hs)iTo&2)VzvFWK)xd-q{s~^3d>6i?g)9N%5tAlN ztChvtip$6nmQLe?4P-tskw|(=`jPZw=_e+ssT~?S$S!g#mLudZ$uV+*{0sRN`8BX$ z2PgO-260G2`eNyTF33WqReE8z%!T<_24N|zf;F%fcEK+E)Cy8171Bc%kpZ%djFCIY zQS8}F4wJjdcgQ`&MGlZ*ay^MnKESP{mea<%@%Yh1(>y+T#F8;jyd;b@9&ml^Ug16> ztPpM#?iYUS>GAy5t9yUp3;Q1TFZKUgOp33FXQi0*9qDYq99SB7HtX-v!yS}tI98`W_3v2 zpzcy{RgbCfYpV8Q#a>xhxuf!Z!V>b;>&)NM^Qa{=v6IP~_wGpJb>{Er4^fXE5++3i znJfvstO!+E0?jMCKo&r*$_0@9a#d2QlAl+q2`3{ZRGn7gLwGb6z3_H43N;a4g64ir zZ2lXphI^rTt)w;2fn9reW#Q1_?3z`9jO>AWsCz+@-V~cT9F5YaqL!KX+6}O#Vrkw9 z=jK_p)0N+^%G{Mblv@ElIU^+&lp~Z(?kUYNHO`X)DWkFtKoLk(sueA*->`Au>S zA*oB?i|45(3Xo*KFq)N}?UUeT%&UoJ(c zpV8^;i&8^`HRFIvk6M7hX$+*-BMCI-T0e2~38Hyp^;qA+4zxPFZaf$W?Z z%ErVrA62T9b+_eIu@UgwI(pRRR!h7kxsgAt{=Y<3DMSBuU($rSp+v+ugS z=*tXizKywo(TGll$Xc?!rM^Vm5J#R-TB@t$DIa$NVp-sLtWjo~+OiqV0Dgo){Wdi0 zFyXD!kcdttCT>)Q{7~z7wtDe7$1}Rv8!ZfbIHs_AQ77keWK{@e=E#NNq^B<*2`VX1 z--gv%AlvSAb`Q;4#CPcfv8)C`aptR#;NgmWZ2=KC8%l-?My(1?8ffG~@COOECfYiy zn%m0=GvND1DEx)5ZTg@;zC1=kE0k3pj|~aBG4oRyC(dp1bq=Y z2Y9KfDPNaRTA2vXi8N5Ymn8*b%l0W%mlFll()n=G+m{Pud!u^|xcuYA?YmtxkPFcV z<-7rsOGr{GElKvTM@fp=z`{$C@o<5AhpTB=!~BUz9yV~humv}`DLM;3znTv4-6%olLAFvu;&PinzfQ zkzhCMmLe`N>zvKzZca5{bc;5d=w2PD_tgU{R|a&f1gp)&fr(lo6;V!jgm$*GlWi9~ z30bVn)q5*q^DyidE4}lgTm4=y&H{_vN>?tUxC5b(F$rGXKCj=OlO`Wp@G@;YKrav< z=_I+9w?n&#P-9PdR%g7eU7#)GjV{AxBH&H<%L1M>F!*h?cY(QFF5EJ4?6xg6K6CZx z(e3pcIkLpwfHnp_BDFOC#dq-FJWY=)sk#3ui<2 zzEb7(yKX7vdhF3;&r?7Bn?lqBQ`2yuKJj_~nTBE0KV^0xL;Fdl#diea=#5#OMZ2Yl zJ8VT*^lOw!2xY$PPryIV+q?P7yiKaDy!OD2JJ#cMZj*)Uvd zS2vEObmO4s6MY+Y-njqTRXqWFerU_yxyz65)n`2Iwc!n0e4E!UF8Zv>{FR%^{bL(d zT5A5RJ{cb9V;U~vB@&WElq869acxyHhtx?Q;zW*fe!~UJrHUd{(hL$Nk76^x>623^N?jkt>tMa!9Bi@U^P{89 z*NpCIL(r%3H#$mhN`;zBaC8u!4<(xpcuueD_{oaeLwMB!Av@jR}%gkZA8ychC z>jo5MU|siUy?Lju!-3POMQVGyx+r}!uKB>^2g5^-#$5!P ziy~QxNKzQKL=0X6_ z;v~*c!t=&d_{#7{4&LSBajHYkc6`YZXm`?Ya1Jv|L9j2a&%AC-^C4@u+gWfw!+R_a z$;lWK@=t$(*#ScM5W0}_#DXCv<{8K#JX4cWRnVX+RTYq!IU_R{tP^VhiJHCe>4uTY zPB^!do}ankY<{(7!b;hZnRQcZqed^8SiIri8^>@uFCvcs@8{DT@0XxlmC8CO)pAvF zQS>zhs7Q6HNpxH7Z1;}LGtKF1-nqY!um}G7kn~jBB$l3b0MC;CnW^Epwf=Ap{9 zDugU{fuaKjkkttII4^HpdCBPEMdS}JugJXO%>#yLs6ylxD3>Zmgo1HZ;hp}m?riP&gU4&x;#hyrHYL}-eD$(OR@wFy$wn?VcWr~0bH%Yc z#)_?1-;amQT(sF9+_57FANhJzj8qDC>JTu%c355fU)+R_XyV}JhZ+XAXk;!1Wd=?# z>rTl+S(6bFhLbdc2ra=GsY+E#8%al5Mt_JoN&+srLO+7To6zv8c#Uif{iW85NYskA zj4jS5R-A7FS&PLS9?x~7qx#g;t8lIkLd@^=%{<}nj0kmL&4R@evseT(J6exI2wBST zq|GH$QyUmZta)ct*Ha!|n5%uV!KHyi?!ZT^2{~9$q#+FS_S@$FGLY!A%-Hzx~OV7B}xx zU~4gw+j0E@s`sOk=m#7a^O1JIK<@W3m8)c@b7~d5?lvv2uT&w zEsPcoqHpEjWzFDygHd@5sJwVGc+$^CQ=zF)5~k`pJdem4JbfBTeh{9YM%qV;$9Sc; h9zoaHYri?6%q+3P|!gH;YMLH#uM-I+){TCXu4}$;z delta 4752 zcmZu#3v?6LnZ9>M(#W4trTMuAZ5ZqqcoNq3>$?#V9XbxscL+2nLnlJrozA@*ed zk@16^&Uoft-S_?O|9}5C{`eSiVU&0>DnHTvJB09IgwUG1x7~GL_h5fBLZ(*{vR&W2 z_2EtDyH6cK$lZX@R?lDGbJs=&*%uyNEm^axx(^^kpF4UW>?*Y*M8xjfv1_;e=YA(b z-@NnaxlE*r__r^HYTN&WYRHdZboBP#ji1h@Uv`aJ@o(_i@;mr*BAr6ms3IE>S;Lw<$V5y)#UPrG%qSecC;oi=RQ$yv&=V1w_aC7Bu$5Xe4JK$c9d+=Jk4)^1ocqdG?8mTCcn$aS(81Pd{3E zzV@nfo%3mW9X(8cpMKq?xlXwW_fzh7JR3dNy-#^BGY>K&%v-F+?q|=jx^JWJgztC$ zF8^Nt<$x`)De%J}6MQuIXR{qYl}_)GEMixx32t`q;G!P9W6;X=c;#@&q<=B=LhdLot> zPP~-3Dy@^Al+H_kOlFe9$*ZZ>)IX>6w3a@d*_t_!d98_Q+THZsrmI;;c7C=$`>I?o z@04Gb|5d&$|6ZQREzF%%V#;pil=5l58krFK@|WZb#C13@E3%<-qx*2U^d@!Rmyn2YCNp}2%pW5tdR~SN0PnR*x2wT$c}=#>T>3K#p#*9{x1j~# zAt{oAh43jX#vKGKh^J^as?s8#H#4lPKzRx*kFuB*4XgQV7_$szfnCv286M(e3$L^W zIhiKtTsYX4tGAeKn>dcR%5j_Rx`iZvVwO0%KE|3!j4cU{7P_N8GifEr>-rnGMZ+!n z8^jagY>2d1Cqkh_wVe!Q!wmvAc@ajDIl)I++BM~HB`RR z{4Oqy5TB4a8f9u z=2|5m&PgGy5cJ>H73KW%V}+(hRSpbv;0a7tbq@3?KBcI96sfY7N z%o7t--4fxEzZtL_{$iNP#+`Nwd2< z!?j4h8>Oj+Y3QQw$Lo!o>Tl< zgK=mqRwTQ_+_>nD%*+NV`@;*hu8hMGl6=bA0XSkY5KckTH46lR=YTi)$!tZ53NYg9|xMID;ls(5qI+r36SQRNRtBP`#@y-C| zu?TYjdt9s>uaa=o);j6{m&!4UelFeN7KZ0wQNkb3wVl+hW;OYTnWlMsX%@A)py@yV z%kccmT+6!Ekg8`5t*&Belm9f^*g1<|`Lec;D4he^J%_@m1Ki#4>6k%DU`z3s;rbqM z?J97o6sGbjcz#npCpN`JrP9)92py)|Ve(Kd6I(ryXoyHsq#-e|I>vAg2gev;li_Ny zV*_1NW42h#H8oDZwovo+_WD*r>UT0VH4Kdx5gh?G%DbGLBymm`A7z!c_Le-WAHnyt z`Ih#!-_UOC_If483n}db+gh{6c+=v%` zLZ(a_sowI71wNzTA)NDfrE<-QRojch_pfQ9;>)+}UEKAAa$AQy^yqh@39Q6Ke21xU$zCsz?KPOb_Ff}c1I@4)0L ztxy;*6yV)8mFNeH!ZJt$5C*Crwnd!Q4`$bFT9eh6b?!Q_tFxeK zlSg2_`|(7vnC;7E`{cdF&Rq*}=dR9TK|csE?kVV9c#nRt{F9#L_R=A8C-G;HlgSEB zVCZlj4#LYq;2>fSn2oY{IIyE^UWII!)QB`z1PJCHX1W;2*JFvrb1L4WVW*990_QM5Np#o&lU)g6>E*yOMEST z^3o8tywtcY`(GfZGwjIU`s|;KwyV)U+VOZ-;ANA8vRIE_!sdTWMQ!Yf{jC1BihrHi za^Z+AK)&c-@(Q;7ZzRxKhX~llugM7UO8NOa6GZ8kST42$J^Nu>&EzJKWb z!Tx+RXtn;q_lNrPB~{m!I=nuw!xl=%xHRX)%gF#!1*dKI_&oNdOYzV^Pj@PP>u`hH zp|3hKTr-SzrjfJzgLM%h(HQl3d5K|ymKwU64hQ|g&~r;G`+k{xkhqAv6&(gU^5*5y zckh0%^ehPHFW^l5D2`-wJNg=0i~500a(PuW?2%PdpkS0Rh5#sPI2Sk1smKXx(`*d| zY6|R^WYs9El7JPcx;YApvWS!n@>Kk(l1VmeT5~d^5Tzwji>9?mnOsiy(P2qUB*Y{a z!@D3iuR-FX(J@2Bc!>XQ$>8;wmP=L(M4T!oMLJxr8jRg$t2Mv(xQh8^{NBRhCaLAv z_m07E!#FSD>HLA=?F}&W=KD5_64%qW9kM$%!{9xAJz^MQnTOCrfog42%E(k z+HE&kYpd<94vZhsibXWK{hl9`3}LoWP8Dx8OiYuX3h8_tbX7Mm>7_z)Uh+cRoc+;{9+8%63Y_-J za#^dLZBC|vb6Tz8Mg~{kz}HSjBKn7c`uactR;WenE|)zrHm1K}@H$-d@)h*hFADnq zaD}32bolFRw4mFH9NrTF%6u~*XhqExa23ZipjxejE7xuwrb?^Gw?MIbKqMnP zYyDq!2@uL6_F9|na$@wgm@T;RZ|%Xb^zfUNSJkCd~G%mPDjK|dp6zO+TPxJ_ol0mX~XS< zkQD&&oFL%8f}oSDuYYXugAvuYcI!G{GxxAsiLTS#EAduqyV-rtIA;V|nEAW0q>W3e zt(oBb73EF4%D7~Z)C=UHN@Ry%^%vv18NO8DgTW5gW~BMScOzyK{EEW3G;r}!q4 zCn2u0n391FEm)+8(#AJ7Wd1XK*XXLz)!etDcyZT{y3GWsmztW0hbJ!{Ibwvw{(e06 z!3QpvOTV~(KPtcW(7gupCV_d$igK9}7ch;NkMag(@G(mWgF95dc4fs3U*~4<3%5-3 zZbKVK From 5a36d17ea6a3a56bd8e43eaf47caeeb5c2e53455 Mon Sep 17 00:00:00 2001 From: Andy Liu Date: Sun, 18 Aug 2019 20:11:46 -0700 Subject: [PATCH 755/861] fix Markdown Preview scroll remains same after clicking on some other link --- extensions/markdown-language-features/src/features/preview.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extensions/markdown-language-features/src/features/preview.ts b/extensions/markdown-language-features/src/features/preview.ts index c874f5791ed..b79939d1bd4 100644 --- a/extensions/markdown-language-features/src/features/preview.ts +++ b/extensions/markdown-language-features/src/features/preview.ts @@ -286,6 +286,8 @@ export class MarkdownPreview extends Disposable { const editor = vscode.window.activeTextEditor; if (editor && editor.document.uri.fsPath === resource.fsPath) { this.line = getVisibleLine(editor); + } else { + this.line = 0; } // If we have changed resources, cancel any pending updates From 34daff0fd7e4a5710261e2c18ef27f0cf0a1f68b Mon Sep 17 00:00:00 2001 From: Aidan Dang Date: Mon, 19 Aug 2019 14:27:05 +1000 Subject: [PATCH 756/861] Fix trivial zsh completion typo --- resources/completions/zsh/_code | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/completions/zsh/_code b/resources/completions/zsh/_code index 25dfe7ca984..c7abee1bc58 100644 --- a/resources/completions/zsh/_code +++ b/resources/completions/zsh/_code @@ -17,7 +17,7 @@ arguments=( '--telemetry[show all telemetry events which VS code collects]' '--extensions-dir[set the root path for extensions]:root path:_directories' '--list-extensions[list the installed extensions]' - '--category[filters instaled extension list by category, when using --list-extension]' + '--category[filters installed extension list by category, when using --list-extension]' '--show-versions[show versions of installed extensions, when using --list-extension]' '--install-extension[install an extension]:id or path:_files -g "*.vsix(-.)"' '--uninstall-extension[uninstall an extension]:id or path:_files -g "*.vsix(-.)"' From 9a2001bc7e6734974a7192212ef68c00b7e8fd80 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Wed, 14 Aug 2019 12:54:59 -0700 Subject: [PATCH 757/861] Improvements --- .../editor/browser/services/openerService.ts | 60 ++++++++++++- .../standalone/browser/standaloneEditor.ts | 8 +- .../browser/services/openerService.test.ts | 90 ++++++++++++++++++- src/vs/platform/request/common/request.ts | 8 ++ .../contrib/url/common/url.contribution.ts | 50 ++++++++++- .../opener/electron-browser/openerService.ts | 8 +- 6 files changed, 212 insertions(+), 12 deletions(-) diff --git a/src/vs/editor/browser/services/openerService.ts b/src/vs/editor/browser/services/openerService.ts index 608d6e3b5d9..2ffdcad0906 100644 --- a/src/vs/editor/browser/services/openerService.ts +++ b/src/vs/editor/browser/services/openerService.ts @@ -14,6 +14,9 @@ import { IOpenerService, IOpener } from 'vs/platform/opener/common/opener'; import { equalsIgnoreCase } from 'vs/base/common/strings'; import { IDisposable } from 'vs/base/common/lifecycle'; import { LinkedList } from 'vs/base/common/linkedList'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; +import { localize } from 'vs/nls'; export class OpenerService implements IOpenerService { @@ -24,6 +27,8 @@ export class OpenerService implements IOpenerService { constructor( @ICodeEditorService private readonly _editorService: ICodeEditorService, @ICommandService private readonly _commandService: ICommandService, + @IConfigurationService private readonly _configurationService: IConfigurationService, + @IDialogService private readonly _dialogService: IDialogService ) { // } @@ -51,12 +56,42 @@ export class OpenerService implements IOpenerService { private _doOpen(resource: URI, options?: { openToSide?: boolean }): Promise { - const { scheme, path, query, fragment } = resource; + const { scheme, authority, path, query, fragment } = resource; - if (equalsIgnoreCase(scheme, Schemas.http) || equalsIgnoreCase(scheme, Schemas.https) || equalsIgnoreCase(scheme, Schemas.mailto)) { - // open http or default mail application + if (equalsIgnoreCase(scheme, Schemas.mailto)) { + // open default mail application return this.openExternal(resource); + } + if (equalsIgnoreCase(scheme, Schemas.http) || equalsIgnoreCase(scheme, Schemas.https)) { + const trustedDomains = this._configurationService.getValue('http.trustedDomains'); + const domainToOpen = `${scheme}://${authority}`; + + if (isDomainTrusted(domainToOpen, trustedDomains)) { + return this.openExternal(resource); + } else { + return this._dialogService.confirm({ + title: localize('openExternalLink', 'Open External Link'), + type: 'question', + message: localize('openExternalLinkAt', 'Do you want to leave VS Code and open the external website at') + ` ${resource.toString()}?`, + detail: resource.toString(), + primaryButton: localize('openLink', 'Open Link'), + secondaryButton: localize('cance', 'Cancel'), + checkbox: { + label: localize('trustAllLinksOn', 'Trust all links on') + ` ${domainToOpen}`, + checked: false + } + }).then(({ confirmed, checkboxChecked }) => { + if (checkboxChecked) { + this._configurationService.updateValue('http.trustedDomains', [...trustedDomains, domainToOpen]); + } + if (confirmed) { + return this.openExternal(resource); + } + + return Promise.resolve(false); + }); + } } else if (equalsIgnoreCase(scheme, Schemas.command)) { // run command or bail out if command isn't known if (!CommandsRegistry.getCommand(path)) { @@ -106,3 +141,22 @@ export class OpenerService implements IOpenerService { return Promise.resolve(true); } } + +/** + * Check whether a domain like https://www.microsoft.com matches + * the list of trusted domains. + * + */ +function isDomainTrusted(domain: string, trustedDomains: string[]) { + for (let i = 0; i < trustedDomains.length; i++) { + if (trustedDomains[i] === '*') { + return true; + } + + if (trustedDomains[i] === domain) { + return true; + } + } + + return false; +} diff --git a/src/vs/editor/standalone/browser/standaloneEditor.ts b/src/vs/editor/standalone/browser/standaloneEditor.ts index 8750db8f943..4712be0dfb7 100644 --- a/src/vs/editor/standalone/browser/standaloneEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneEditor.ts @@ -38,6 +38,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { clearAllFontInfos } from 'vs/editor/browser/config/configuration'; +import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; type Omit = Pick>; @@ -51,7 +52,12 @@ function withAllStandaloneServices(domElement: H } if (!services.has(IOpenerService)) { - services.set(IOpenerService, new OpenerService(services.get(ICodeEditorService), services.get(ICommandService))); + services.set(IOpenerService, new OpenerService( + services.get(ICodeEditorService), + services.get(ICommandService), + services.get(IConfigurationService), + services.get(IDialogService), + )); } let result = callback(services); diff --git a/src/vs/editor/test/browser/services/openerService.test.ts b/src/vs/editor/test/browser/services/openerService.test.ts index eadf902357a..c82f40ea429 100644 --- a/src/vs/editor/test/browser/services/openerService.test.ts +++ b/src/vs/editor/test/browser/services/openerService.test.ts @@ -7,6 +7,9 @@ import { URI } from 'vs/base/common/uri'; import { OpenerService } from 'vs/editor/browser/services/openerService'; import { TestCodeEditorService } from 'vs/editor/test/browser/editorTestServices'; import { CommandsRegistry, ICommandService, NullCommandService } from 'vs/platform/commands/common/commands'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { deepClone } from 'vs/base/common/objects'; +import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; suite('OpenerService', function () { @@ -24,19 +27,56 @@ suite('OpenerService', function () { } }; + function getConfigurationService(trustedDomainsSetting: string[]) { + let _settings = deepClone(trustedDomainsSetting); + + return new class implements IConfigurationService { + getValue = () => _settings; + updateValue = (key: string, val: string[]) => { + _settings = val; + return Promise.resolve(); + } + + // Don't care + _serviceBrand: any; + onDidChangeConfiguration = () => ({ dispose: () => { } }); + getConfigurationData = () => null; + reloadConfiguration = () => Promise.resolve(); + inspect = () => null as any; + keys = () => null as any; + }; + } + + function getDialogService() { + return new class implements IDialogService { + _confirmInvoked = 0; + confirm = () => { + this._confirmInvoked++; + return Promise.resolve({} as any); + } + get confirmInvoked() { return this._confirmInvoked; } + + // Don't care + _serviceBrand: any; + show = () => { + return Promise.resolve({} as any); + } + }; + } + setup(function () { lastCommand = undefined; }); test('delegate to editorService, scheme:///fff', function () { - const openerService = new OpenerService(editorService, NullCommandService); + const openerService = new OpenerService(editorService, NullCommandService, getConfigurationService([]), getDialogService()); openerService.open(URI.parse('another:///somepath')); assert.equal(editorService.lastInput!.options!.selection, undefined); }); test('delegate to editorService, scheme:///fff#L123', function () { - const openerService = new OpenerService(editorService, NullCommandService); + const openerService = new OpenerService(editorService, NullCommandService, getConfigurationService([]), getDialogService()); openerService.open(URI.parse('file:///somepath#L23')); assert.equal(editorService.lastInput!.options!.selection!.startLineNumber, 23); @@ -59,7 +99,7 @@ suite('OpenerService', function () { test('delegate to editorService, scheme:///fff#123,123', function () { - const openerService = new OpenerService(editorService, NullCommandService); + const openerService = new OpenerService(editorService, NullCommandService, getConfigurationService([]), getDialogService()); openerService.open(URI.parse('file:///somepath#23')); assert.equal(editorService.lastInput!.options!.selection!.startLineNumber, 23); @@ -78,7 +118,7 @@ suite('OpenerService', function () { test('delegate to commandsService, command:someid', function () { - const openerService = new OpenerService(editorService, commandService); + const openerService = new OpenerService(editorService, commandService, getConfigurationService([]), getDialogService()); const id = `aCommand${Math.random()}`; CommandsRegistry.registerCommand(id, function () { }); @@ -98,4 +138,46 @@ suite('OpenerService', function () { assert.equal(lastCommand!.args[0], 12); assert.equal(lastCommand!.args[1], true); }); + + test('links are protected by dialog confirmation', function () { + const dialogService = getDialogService(); + const openerService = new OpenerService(editorService, commandService, getConfigurationService([]), dialogService); + + openerService.open(URI.parse('https://www.microsoft.com')); + assert.equal(dialogService.confirmInvoked, 1); + }); + + test('links on the whitelisted domains can be opened without dialog confirmation', function () { + const dialogService = getDialogService(); + const openerService = new OpenerService(editorService, commandService, getConfigurationService(['https://microsoft.com']), dialogService); + + openerService.open(URI.parse('https://microsoft.com')); + openerService.open(URI.parse('https://microsoft.com/')); + openerService.open(URI.parse('https://microsoft.com/en-us/')); + openerService.open(URI.parse('https://microsoft.com/en-us/?foo=bar')); + openerService.open(URI.parse('https://microsoft.com/en-us/?foo=bar#baz')); + + assert.equal(dialogService.confirmInvoked, 0); + }); + + test('variations of links are protected by dialog confirmation', function () { + const dialogService = getDialogService(); + const openerService = new OpenerService(editorService, commandService, getConfigurationService(['https://microsoft.com']), dialogService); + + openerService.open(URI.parse('http://microsoft.com')); + openerService.open(URI.parse('https://www.microsoft.com')); + + assert.equal(dialogService.confirmInvoked, 2); + }); + + test('* removes all link protection', function () { + const dialogService = getDialogService(); + const openerService = new OpenerService(editorService, commandService, getConfigurationService(['*']), dialogService); + + openerService.open(URI.parse('https://code.visualstudio.com/')); + openerService.open(URI.parse('https://www.microsoft.com')); + openerService.open(URI.parse('https://www.github.com')); + + assert.equal(dialogService.confirmInvoked, 0); + }); }); diff --git a/src/vs/platform/request/common/request.ts b/src/vs/platform/request/common/request.ts index 31e3c314242..27601de0ef0 100644 --- a/src/vs/platform/request/common/request.ts +++ b/src/vs/platform/request/common/request.ts @@ -117,6 +117,14 @@ Registry.as(Extensions.Configuration) type: 'boolean', default: true, description: localize('systemCertificates', "Controls whether CA certificates should be loaded from the OS. (On Windows and macOS a reload of the window is required after turning this off.)") + }, + 'http.trustedDomains': { + type: 'array', + default: ['https://code.visualstudio.com'], + description: localize('trustedDomains', "Controls whether a http/https link can be opened directly in browser.\n\nAdd `*` to the list to whitelist all domains."), + items: { + type: 'string' + } } } }); diff --git a/src/vs/workbench/contrib/url/common/url.contribution.ts b/src/vs/workbench/contrib/url/common/url.contribution.ts index cbed9bef6a3..66302cb5411 100644 --- a/src/vs/workbench/contrib/url/common/url.contribution.ts +++ b/src/vs/workbench/contrib/url/common/url.contribution.ts @@ -11,6 +11,7 @@ import { IURLService } from 'vs/platform/url/common/url'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { URI } from 'vs/base/common/uri'; import { Action } from 'vs/base/common/actions'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; export class OpenUrlAction extends Action { @@ -34,5 +35,50 @@ export class OpenUrlAction extends Action { } } -Registry.as(ActionExtensions.WorkbenchActions) - .registerWorkbenchAction(new SyncActionDescriptor(OpenUrlAction, OpenUrlAction.ID, OpenUrlAction.LABEL), 'Open URL', localize('developer', "Developer")); \ No newline at end of file +export class ConfigureTrustedDomainsAction extends Action { + + static readonly ID = 'workbench.action.configureTrustedDomains'; + static readonly LABEL = localize('configureTrustedDomains', "Configure Trusted Domains"); + + constructor( + id: string, + label: string, + @IQuickInputService private readonly quickInputService: IQuickInputService, + @IConfigurationService private readonly configurationService: IConfigurationService + ) { + super(id, label); + } + + run(): Promise { + const trustedDomains = this.configurationService.getValue('http.trustedDomains'); + + return this.quickInputService.pick(trustedDomains.map(d => { + return { + type: 'item', + label: d, + picked: true, + }; + }), { + canPickMany: true + }).then(result => { + if (result) { + this.configurationService.updateValue('http.trustedDomains', result.map(r => r.label)); + } + }); + } +} + +Registry.as(ActionExtensions.WorkbenchActions).registerWorkbenchAction( + new SyncActionDescriptor(OpenUrlAction, OpenUrlAction.ID, OpenUrlAction.LABEL), + 'Open URL', + localize('developer', 'Developer') +); +Registry.as(ActionExtensions.WorkbenchActions).registerWorkbenchAction( + new SyncActionDescriptor( + ConfigureTrustedDomainsAction, + ConfigureTrustedDomainsAction.ID, + ConfigureTrustedDomainsAction.LABEL + ), + 'Configure Trusted Domains' +); + diff --git a/src/vs/workbench/services/opener/electron-browser/openerService.ts b/src/vs/workbench/services/opener/electron-browser/openerService.ts index 3085bd78a14..160ba1cbf71 100644 --- a/src/vs/workbench/services/opener/electron-browser/openerService.ts +++ b/src/vs/workbench/services/opener/electron-browser/openerService.ts @@ -12,6 +12,8 @@ import { Schemas } from 'vs/base/common/network'; import { URI } from 'vs/base/common/uri'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; export class OpenerService extends BaseOpenerService { @@ -20,9 +22,11 @@ export class OpenerService extends BaseOpenerService { constructor( @ICodeEditorService codeEditorService: ICodeEditorService, @ICommandService commandService: ICommandService, - @IWindowsService private readonly windowsService: IWindowsService + @IWindowsService private readonly windowsService: IWindowsService, + @IConfigurationService readonly configurationService: IConfigurationService, + @IDialogService readonly dialogService: IDialogService ) { - super(codeEditorService, commandService); + super(codeEditorService, commandService, configurationService, dialogService); } async openExternal(resource: URI): Promise { From 821519ddfb5e143c0de9150b88e5e2aa9f2d677f Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Wed, 14 Aug 2019 19:40:48 -0700 Subject: [PATCH 758/861] Drop Configure Trusted Domains command for now --- .../contrib/url/common/url.contribution.ts | 50 +------------------ 1 file changed, 2 insertions(+), 48 deletions(-) diff --git a/src/vs/workbench/contrib/url/common/url.contribution.ts b/src/vs/workbench/contrib/url/common/url.contribution.ts index 66302cb5411..828ad0cf30b 100644 --- a/src/vs/workbench/contrib/url/common/url.contribution.ts +++ b/src/vs/workbench/contrib/url/common/url.contribution.ts @@ -11,7 +11,6 @@ import { IURLService } from 'vs/platform/url/common/url'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { URI } from 'vs/base/common/uri'; import { Action } from 'vs/base/common/actions'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; export class OpenUrlAction extends Action { @@ -35,50 +34,5 @@ export class OpenUrlAction extends Action { } } -export class ConfigureTrustedDomainsAction extends Action { - - static readonly ID = 'workbench.action.configureTrustedDomains'; - static readonly LABEL = localize('configureTrustedDomains', "Configure Trusted Domains"); - - constructor( - id: string, - label: string, - @IQuickInputService private readonly quickInputService: IQuickInputService, - @IConfigurationService private readonly configurationService: IConfigurationService - ) { - super(id, label); - } - - run(): Promise { - const trustedDomains = this.configurationService.getValue('http.trustedDomains'); - - return this.quickInputService.pick(trustedDomains.map(d => { - return { - type: 'item', - label: d, - picked: true, - }; - }), { - canPickMany: true - }).then(result => { - if (result) { - this.configurationService.updateValue('http.trustedDomains', result.map(r => r.label)); - } - }); - } -} - -Registry.as(ActionExtensions.WorkbenchActions).registerWorkbenchAction( - new SyncActionDescriptor(OpenUrlAction, OpenUrlAction.ID, OpenUrlAction.LABEL), - 'Open URL', - localize('developer', 'Developer') -); -Registry.as(ActionExtensions.WorkbenchActions).registerWorkbenchAction( - new SyncActionDescriptor( - ConfigureTrustedDomainsAction, - ConfigureTrustedDomainsAction.ID, - ConfigureTrustedDomainsAction.LABEL - ), - 'Configure Trusted Domains' -); - +Registry.as(ActionExtensions.WorkbenchActions) + .registerWorkbenchAction(new SyncActionDescriptor(OpenUrlAction, OpenUrlAction.ID, OpenUrlAction.LABEL), 'Open URL', localize('developer', "Developer")); From 5979aced9077a0178a79bf79cf7aefe16126a2b3 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Wed, 14 Aug 2019 19:43:37 -0700 Subject: [PATCH 759/861] :lipstick: --- src/vs/editor/browser/services/openerService.ts | 4 ++-- src/vs/workbench/contrib/url/common/url.contribution.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/browser/services/openerService.ts b/src/vs/editor/browser/services/openerService.ts index 2ffdcad0906..25c232c09ea 100644 --- a/src/vs/editor/browser/services/openerService.ts +++ b/src/vs/editor/browser/services/openerService.ts @@ -73,10 +73,10 @@ export class OpenerService implements IOpenerService { return this._dialogService.confirm({ title: localize('openExternalLink', 'Open External Link'), type: 'question', - message: localize('openExternalLinkAt', 'Do you want to leave VS Code and open the external website at') + ` ${resource.toString()}?`, + message: localize('openExternalLinkAt', 'Do you want to leave VS Code to open the external website at') + ` ${resource.toString()}?`, detail: resource.toString(), primaryButton: localize('openLink', 'Open Link'), - secondaryButton: localize('cance', 'Cancel'), + secondaryButton: localize('cancel', 'Cancel'), checkbox: { label: localize('trustAllLinksOn', 'Trust all links on') + ` ${domainToOpen}`, checked: false diff --git a/src/vs/workbench/contrib/url/common/url.contribution.ts b/src/vs/workbench/contrib/url/common/url.contribution.ts index 828ad0cf30b..cbed9bef6a3 100644 --- a/src/vs/workbench/contrib/url/common/url.contribution.ts +++ b/src/vs/workbench/contrib/url/common/url.contribution.ts @@ -35,4 +35,4 @@ export class OpenUrlAction extends Action { } Registry.as(ActionExtensions.WorkbenchActions) - .registerWorkbenchAction(new SyncActionDescriptor(OpenUrlAction, OpenUrlAction.ID, OpenUrlAction.LABEL), 'Open URL', localize('developer', "Developer")); + .registerWorkbenchAction(new SyncActionDescriptor(OpenUrlAction, OpenUrlAction.ID, OpenUrlAction.LABEL), 'Open URL', localize('developer', "Developer")); \ No newline at end of file From d41ffa2112c6b9bae157b6039b25df3c2f64bbe2 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Thu, 15 Aug 2019 08:32:19 -0700 Subject: [PATCH 760/861] Drop details & on -> from --- src/vs/editor/browser/services/openerService.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/editor/browser/services/openerService.ts b/src/vs/editor/browser/services/openerService.ts index 25c232c09ea..48cf5fbd4ad 100644 --- a/src/vs/editor/browser/services/openerService.ts +++ b/src/vs/editor/browser/services/openerService.ts @@ -74,11 +74,10 @@ export class OpenerService implements IOpenerService { title: localize('openExternalLink', 'Open External Link'), type: 'question', message: localize('openExternalLinkAt', 'Do you want to leave VS Code to open the external website at') + ` ${resource.toString()}?`, - detail: resource.toString(), primaryButton: localize('openLink', 'Open Link'), secondaryButton: localize('cancel', 'Cancel'), checkbox: { - label: localize('trustAllLinksOn', 'Trust all links on') + ` ${domainToOpen}`, + label: localize('trustAllLinksFrom', 'Trust all links from') + ` ${domainToOpen}`, checked: false } }).then(({ confirmed, checkboxChecked }) => { From 8ebb596b3d71efc431e1de4c538d3cc7ff34e197 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Thu, 15 Aug 2019 08:54:59 -0700 Subject: [PATCH 761/861] Address feedbacks --- src/vs/editor/browser/services/openerService.ts | 11 +++++++++-- src/vs/nls.d.ts | 7 +++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/browser/services/openerService.ts b/src/vs/editor/browser/services/openerService.ts index 48cf5fbd4ad..f732093c32b 100644 --- a/src/vs/editor/browser/services/openerService.ts +++ b/src/vs/editor/browser/services/openerService.ts @@ -17,6 +17,7 @@ import { LinkedList } from 'vs/base/common/linkedList'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { localize } from 'vs/nls'; +import { IProductService } from 'vs/platform/product/common/product'; export class OpenerService implements IOpenerService { @@ -28,7 +29,8 @@ export class OpenerService implements IOpenerService { @ICodeEditorService private readonly _editorService: ICodeEditorService, @ICommandService private readonly _commandService: ICommandService, @IConfigurationService private readonly _configurationService: IConfigurationService, - @IDialogService private readonly _dialogService: IDialogService + @IDialogService private readonly _dialogService: IDialogService, + @IProductService private readonly _productService: IProductService ) { // } @@ -73,7 +75,12 @@ export class OpenerService implements IOpenerService { return this._dialogService.confirm({ title: localize('openExternalLink', 'Open External Link'), type: 'question', - message: localize('openExternalLinkAt', 'Do you want to leave VS Code to open the external website at') + ` ${resource.toString()}?`, + message: localize( + 'openExternalLinkAt', + 'Do you want {0} to open the external website at {1}?', + this._productService.productConfiguration.nameShort, + resource.toString(true) + ), primaryButton: localize('openLink', 'Open Link'), secondaryButton: localize('cancel', 'Cancel'), checkbox: { diff --git a/src/vs/nls.d.ts b/src/vs/nls.d.ts index 38bbd076068..3942ff08669 100644 --- a/src/vs/nls.d.ts +++ b/src/vs/nls.d.ts @@ -8,5 +8,12 @@ export interface ILocalizeInfo { comment: string[]; } +/** + * Localize a message. `message` can contain `{n}` notation where it is replaced by the nth value in `...args`. + */ export declare function localize(info: ILocalizeInfo, message: string, ...args: (string | number | boolean | undefined | null)[]): string; + +/** + * Localize a message. `message` can contain `{n}` notation where it is replaced by the nth value in `...args`. + */ export declare function localize(key: string, message: string, ...args: (string | number | boolean | undefined | null)[]): string; From b258e13432e74b32b3ad0bb235a05cfc7390e204 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Thu, 15 Aug 2019 09:06:57 -0700 Subject: [PATCH 762/861] Fix services --- .../standalone/browser/standaloneEditor.ts | 2 + .../browser/services/openerService.test.ts | 77 +++++++++++++++++-- .../opener/electron-browser/openerService.ts | 6 +- 3 files changed, 75 insertions(+), 10 deletions(-) diff --git a/src/vs/editor/standalone/browser/standaloneEditor.ts b/src/vs/editor/standalone/browser/standaloneEditor.ts index 4712be0dfb7..b92f2d803f8 100644 --- a/src/vs/editor/standalone/browser/standaloneEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneEditor.ts @@ -39,6 +39,7 @@ import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { clearAllFontInfos } from 'vs/editor/browser/config/configuration'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; +import { IProductService } from 'vs/platform/product/common/product'; type Omit = Pick>; @@ -57,6 +58,7 @@ function withAllStandaloneServices(domElement: H services.get(ICommandService), services.get(IConfigurationService), services.get(IDialogService), + services.get(IProductService) )); } diff --git a/src/vs/editor/test/browser/services/openerService.test.ts b/src/vs/editor/test/browser/services/openerService.test.ts index c82f40ea429..187ddf901b8 100644 --- a/src/vs/editor/test/browser/services/openerService.test.ts +++ b/src/vs/editor/test/browser/services/openerService.test.ts @@ -10,6 +10,7 @@ import { CommandsRegistry, ICommandService, NullCommandService } from 'vs/platfo import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { deepClone } from 'vs/base/common/objects'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; +import { IProductService } from 'vs/platform/product/common/product'; suite('OpenerService', function () { @@ -64,19 +65,43 @@ suite('OpenerService', function () { }; } + function getProductService() { + return new class implements IProductService { + // Don't care + _serviceBrand: any; + + productConfiguration = { + nameShort: 'VS Code' + } as any; + }; + } + + setup(function () { lastCommand = undefined; }); test('delegate to editorService, scheme:///fff', function () { - const openerService = new OpenerService(editorService, NullCommandService, getConfigurationService([]), getDialogService()); + const openerService = new OpenerService( + editorService, + NullCommandService, + getConfigurationService([]), + getDialogService(), + getProductService() + ); openerService.open(URI.parse('another:///somepath')); assert.equal(editorService.lastInput!.options!.selection, undefined); }); test('delegate to editorService, scheme:///fff#L123', function () { - const openerService = new OpenerService(editorService, NullCommandService, getConfigurationService([]), getDialogService()); + const openerService = new OpenerService( + editorService, + NullCommandService, + getConfigurationService([]), + getDialogService(), + getProductService() + ); openerService.open(URI.parse('file:///somepath#L23')); assert.equal(editorService.lastInput!.options!.selection!.startLineNumber, 23); @@ -99,7 +124,13 @@ suite('OpenerService', function () { test('delegate to editorService, scheme:///fff#123,123', function () { - const openerService = new OpenerService(editorService, NullCommandService, getConfigurationService([]), getDialogService()); + const openerService = new OpenerService( + editorService, + NullCommandService, + getConfigurationService([]), + getDialogService(), + getProductService() + ); openerService.open(URI.parse('file:///somepath#23')); assert.equal(editorService.lastInput!.options!.selection!.startLineNumber, 23); @@ -118,7 +149,13 @@ suite('OpenerService', function () { test('delegate to commandsService, command:someid', function () { - const openerService = new OpenerService(editorService, commandService, getConfigurationService([]), getDialogService()); + const openerService = new OpenerService( + editorService, + commandService, + getConfigurationService([]), + getDialogService(), + getProductService() + ); const id = `aCommand${Math.random()}`; CommandsRegistry.registerCommand(id, function () { }); @@ -141,7 +178,13 @@ suite('OpenerService', function () { test('links are protected by dialog confirmation', function () { const dialogService = getDialogService(); - const openerService = new OpenerService(editorService, commandService, getConfigurationService([]), dialogService); + const openerService = new OpenerService( + editorService, + commandService, + getConfigurationService([]), + dialogService, + getProductService() + ); openerService.open(URI.parse('https://www.microsoft.com')); assert.equal(dialogService.confirmInvoked, 1); @@ -149,7 +192,13 @@ suite('OpenerService', function () { test('links on the whitelisted domains can be opened without dialog confirmation', function () { const dialogService = getDialogService(); - const openerService = new OpenerService(editorService, commandService, getConfigurationService(['https://microsoft.com']), dialogService); + const openerService = new OpenerService( + editorService, + commandService, + getConfigurationService(['https://microsoft.com']), + dialogService, + getProductService() + ); openerService.open(URI.parse('https://microsoft.com')); openerService.open(URI.parse('https://microsoft.com/')); @@ -162,7 +211,13 @@ suite('OpenerService', function () { test('variations of links are protected by dialog confirmation', function () { const dialogService = getDialogService(); - const openerService = new OpenerService(editorService, commandService, getConfigurationService(['https://microsoft.com']), dialogService); + const openerService = new OpenerService( + editorService, + commandService, + getConfigurationService(['https://microsoft.com']), + dialogService, + getProductService() + ); openerService.open(URI.parse('http://microsoft.com')); openerService.open(URI.parse('https://www.microsoft.com')); @@ -172,7 +227,13 @@ suite('OpenerService', function () { test('* removes all link protection', function () { const dialogService = getDialogService(); - const openerService = new OpenerService(editorService, commandService, getConfigurationService(['*']), dialogService); + const openerService = new OpenerService( + editorService, + commandService, + getConfigurationService(['*']), + dialogService, + getProductService() + ); openerService.open(URI.parse('https://code.visualstudio.com/')); openerService.open(URI.parse('https://www.microsoft.com')); diff --git a/src/vs/workbench/services/opener/electron-browser/openerService.ts b/src/vs/workbench/services/opener/electron-browser/openerService.ts index 160ba1cbf71..b9faebbefbf 100644 --- a/src/vs/workbench/services/opener/electron-browser/openerService.ts +++ b/src/vs/workbench/services/opener/electron-browser/openerService.ts @@ -14,6 +14,7 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; +import { IProductService } from 'vs/platform/product/common/product'; export class OpenerService extends BaseOpenerService { @@ -24,9 +25,10 @@ export class OpenerService extends BaseOpenerService { @ICommandService commandService: ICommandService, @IWindowsService private readonly windowsService: IWindowsService, @IConfigurationService readonly configurationService: IConfigurationService, - @IDialogService readonly dialogService: IDialogService + @IDialogService readonly dialogService: IDialogService, + @IProductService readonly productService: IProductService ) { - super(codeEditorService, commandService, configurationService, dialogService); + super(codeEditorService, commandService, configurationService, dialogService, productService); } async openExternal(resource: URI): Promise { From c62a21ffec7f880f1ecb5b98e71d5684be01173c Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Thu, 15 Aug 2019 11:13:03 -0700 Subject: [PATCH 763/861] Storage instead of setting. Add command for configuring --- .../editor/browser/services/openerService.ts | 14 ++-- .../standalone/browser/standaloneEditor.ts | 3 +- .../browser/services/openerService.test.ts | 42 ++++++------ .../contrib/url/common/url.contribution.ts | 68 ++++++++++++++++++- .../opener/electron-browser/openerService.ts | 6 +- 5 files changed, 100 insertions(+), 33 deletions(-) diff --git a/src/vs/editor/browser/services/openerService.ts b/src/vs/editor/browser/services/openerService.ts index f732093c32b..e2d8dd2529e 100644 --- a/src/vs/editor/browser/services/openerService.ts +++ b/src/vs/editor/browser/services/openerService.ts @@ -14,10 +14,10 @@ import { IOpenerService, IOpener } from 'vs/platform/opener/common/opener'; import { equalsIgnoreCase } from 'vs/base/common/strings'; import { IDisposable } from 'vs/base/common/lifecycle'; import { LinkedList } from 'vs/base/common/linkedList'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { localize } from 'vs/nls'; import { IProductService } from 'vs/platform/product/common/product'; +import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; export class OpenerService implements IOpenerService { @@ -28,7 +28,7 @@ export class OpenerService implements IOpenerService { constructor( @ICodeEditorService private readonly _editorService: ICodeEditorService, @ICommandService private readonly _commandService: ICommandService, - @IConfigurationService private readonly _configurationService: IConfigurationService, + @IStorageService private readonly _storageService: IStorageService, @IDialogService private readonly _dialogService: IDialogService, @IProductService private readonly _productService: IProductService ) { @@ -66,7 +66,11 @@ export class OpenerService implements IOpenerService { } if (equalsIgnoreCase(scheme, Schemas.http) || equalsIgnoreCase(scheme, Schemas.https)) { - const trustedDomains = this._configurationService.getValue('http.trustedDomains'); + let trustedDomains: string[] = []; + try { + trustedDomains = JSON.parse(this._storageService.get('http.trustedDomains', StorageScope.GLOBAL, '[]')); + } catch (err) { } + const domainToOpen = `${scheme}://${authority}`; if (isDomainTrusted(domainToOpen, trustedDomains)) { @@ -77,7 +81,7 @@ export class OpenerService implements IOpenerService { type: 'question', message: localize( 'openExternalLinkAt', - 'Do you want {0} to open the external website at {1}?', + 'Do you want {0} to open the external website?\n{1}', this._productService.productConfiguration.nameShort, resource.toString(true) ), @@ -89,7 +93,7 @@ export class OpenerService implements IOpenerService { } }).then(({ confirmed, checkboxChecked }) => { if (checkboxChecked) { - this._configurationService.updateValue('http.trustedDomains', [...trustedDomains, domainToOpen]); + this._storageService.store('http.trustedDomains', JSON.stringify([...trustedDomains, domainToOpen]), StorageScope.GLOBAL); } if (confirmed) { return this.openExternal(resource); diff --git a/src/vs/editor/standalone/browser/standaloneEditor.ts b/src/vs/editor/standalone/browser/standaloneEditor.ts index b92f2d803f8..ddba66741d9 100644 --- a/src/vs/editor/standalone/browser/standaloneEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneEditor.ts @@ -40,6 +40,7 @@ import { IAccessibilityService } from 'vs/platform/accessibility/common/accessib import { clearAllFontInfos } from 'vs/editor/browser/config/configuration'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IProductService } from 'vs/platform/product/common/product'; +import { IStorageService } from 'vs/platform/storage/common/storage'; type Omit = Pick>; @@ -56,7 +57,7 @@ function withAllStandaloneServices(domElement: H services.set(IOpenerService, new OpenerService( services.get(ICodeEditorService), services.get(ICommandService), - services.get(IConfigurationService), + services.get(IStorageService), services.get(IDialogService), services.get(IProductService) )); diff --git a/src/vs/editor/test/browser/services/openerService.test.ts b/src/vs/editor/test/browser/services/openerService.test.ts index 187ddf901b8..f42e3c399ef 100644 --- a/src/vs/editor/test/browser/services/openerService.test.ts +++ b/src/vs/editor/test/browser/services/openerService.test.ts @@ -7,10 +7,10 @@ import { URI } from 'vs/base/common/uri'; import { OpenerService } from 'vs/editor/browser/services/openerService'; import { TestCodeEditorService } from 'vs/editor/test/browser/editorTestServices'; import { CommandsRegistry, ICommandService, NullCommandService } from 'vs/platform/commands/common/commands'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { deepClone } from 'vs/base/common/objects'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IProductService } from 'vs/platform/product/common/product'; +import { IStorageService } from 'vs/platform/storage/common/storage'; suite('OpenerService', function () { @@ -28,23 +28,23 @@ suite('OpenerService', function () { } }; - function getConfigurationService(trustedDomainsSetting: string[]) { + function getStorageService(trustedDomainsSetting: string[]) { let _settings = deepClone(trustedDomainsSetting); - return new class implements IConfigurationService { - getValue = () => _settings; - updateValue = (key: string, val: string[]) => { - _settings = val; - return Promise.resolve(); - } + return new class implements IStorageService { + get = () => JSON.stringify(_settings); + store = (key: string, val: string) => _settings = JSON.parse(val); // Don't care _serviceBrand: any; - onDidChangeConfiguration = () => ({ dispose: () => { } }); - getConfigurationData = () => null; - reloadConfiguration = () => Promise.resolve(); - inspect = () => null as any; - keys = () => null as any; + + onDidChangeStorage = () => ({ dispose: () => { } }); + onWillSaveState = () => ({ dispose: () => { } }); + + getBoolean = () => true; + getNumber = () => 0; + remove = () => { }; + logStorage = () => { }; }; } @@ -85,7 +85,7 @@ suite('OpenerService', function () { const openerService = new OpenerService( editorService, NullCommandService, - getConfigurationService([]), + getStorageService([]), getDialogService(), getProductService() ); @@ -98,7 +98,7 @@ suite('OpenerService', function () { const openerService = new OpenerService( editorService, NullCommandService, - getConfigurationService([]), + getStorageService([]), getDialogService(), getProductService() ); @@ -127,7 +127,7 @@ suite('OpenerService', function () { const openerService = new OpenerService( editorService, NullCommandService, - getConfigurationService([]), + getStorageService([]), getDialogService(), getProductService() ); @@ -152,7 +152,7 @@ suite('OpenerService', function () { const openerService = new OpenerService( editorService, commandService, - getConfigurationService([]), + getStorageService([]), getDialogService(), getProductService() ); @@ -181,7 +181,7 @@ suite('OpenerService', function () { const openerService = new OpenerService( editorService, commandService, - getConfigurationService([]), + getStorageService([]), dialogService, getProductService() ); @@ -195,7 +195,7 @@ suite('OpenerService', function () { const openerService = new OpenerService( editorService, commandService, - getConfigurationService(['https://microsoft.com']), + getStorageService(['https://microsoft.com']), dialogService, getProductService() ); @@ -214,7 +214,7 @@ suite('OpenerService', function () { const openerService = new OpenerService( editorService, commandService, - getConfigurationService(['https://microsoft.com']), + getStorageService(['https://microsoft.com']), dialogService, getProductService() ); @@ -230,7 +230,7 @@ suite('OpenerService', function () { const openerService = new OpenerService( editorService, commandService, - getConfigurationService(['*']), + getStorageService(['*']), dialogService, getProductService() ); diff --git a/src/vs/workbench/contrib/url/common/url.contribution.ts b/src/vs/workbench/contrib/url/common/url.contribution.ts index cbed9bef6a3..14ab5356509 100644 --- a/src/vs/workbench/contrib/url/common/url.contribution.ts +++ b/src/vs/workbench/contrib/url/common/url.contribution.ts @@ -8,9 +8,10 @@ import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; import { Registry } from 'vs/platform/registry/common/platform'; import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions'; import { IURLService } from 'vs/platform/url/common/url'; -import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; import { URI } from 'vs/base/common/uri'; import { Action } from 'vs/base/common/actions'; +import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; export class OpenUrlAction extends Action { @@ -34,5 +35,66 @@ export class OpenUrlAction extends Action { } } -Registry.as(ActionExtensions.WorkbenchActions) - .registerWorkbenchAction(new SyncActionDescriptor(OpenUrlAction, OpenUrlAction.ID, OpenUrlAction.LABEL), 'Open URL', localize('developer', "Developer")); \ No newline at end of file +export class ConfigureTrustedDomainsAction extends Action { + + static readonly ID = 'workbench.action.configureTrustedDomains'; + static readonly LABEL = localize('configureTrustedDomains', "Configure Trusted Domains"); + + constructor( + id: string, + label: string, + @IQuickInputService private readonly quickInputService: IQuickInputService, + @IStorageService private readonly storageService: IStorageService + ) { + super(id, label); + } + + run(): Promise { + let trustedDomains: string[] = []; + try { + trustedDomains = JSON.parse(this.storageService.get('http.trustedDomains', StorageScope.GLOBAL, '[]')); + } catch (err) { } + + const quickPickItems: (IQuickPickItem | IQuickPickSeparator)[] = trustedDomains + .filter(d => d !== '*') + .map(d => { + return { + type: 'item', + label: d, + picked: true, + }; + }); + + quickPickItems.unshift({ + type: 'separator' + }); + quickPickItems.unshift({ + type: 'item', + label: '*', + description: 'Allow all links to be open without protection', + picked: trustedDomains.indexOf('*') !== -1 + }); + + return this.quickInputService.pick(quickPickItems, { + canPickMany: true + }).then(result => { + if (result) { + this.storageService.store('http.trustedDomains', JSON.stringify(result.map(r => r.label)), StorageScope.GLOBAL); + } + }); + } +} + +Registry.as(ActionExtensions.WorkbenchActions).registerWorkbenchAction( + new SyncActionDescriptor(OpenUrlAction, OpenUrlAction.ID, OpenUrlAction.LABEL), + 'Open URL', + localize('developer', 'Developer') +); +Registry.as(ActionExtensions.WorkbenchActions).registerWorkbenchAction( + new SyncActionDescriptor( + ConfigureTrustedDomainsAction, + ConfigureTrustedDomainsAction.ID, + ConfigureTrustedDomainsAction.LABEL + ), + 'Configure Trusted Domains' +); diff --git a/src/vs/workbench/services/opener/electron-browser/openerService.ts b/src/vs/workbench/services/opener/electron-browser/openerService.ts index b9faebbefbf..d6cc8bb5bec 100644 --- a/src/vs/workbench/services/opener/electron-browser/openerService.ts +++ b/src/vs/workbench/services/opener/electron-browser/openerService.ts @@ -12,9 +12,9 @@ import { Schemas } from 'vs/base/common/network'; import { URI } from 'vs/base/common/uri'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IProductService } from 'vs/platform/product/common/product'; +import { IStorageService } from 'vs/platform/storage/common/storage'; export class OpenerService extends BaseOpenerService { @@ -24,11 +24,11 @@ export class OpenerService extends BaseOpenerService { @ICodeEditorService codeEditorService: ICodeEditorService, @ICommandService commandService: ICommandService, @IWindowsService private readonly windowsService: IWindowsService, - @IConfigurationService readonly configurationService: IConfigurationService, + @IStorageService readonly storageService: IStorageService, @IDialogService readonly dialogService: IDialogService, @IProductService readonly productService: IProductService ) { - super(codeEditorService, commandService, configurationService, dialogService, productService); + super(codeEditorService, commandService, storageService, dialogService, productService); } async openExternal(resource: URI): Promise { From d521cf4d2bd36fda74e792a6812066da57b5fca1 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Thu, 15 Aug 2019 14:06:59 -0700 Subject: [PATCH 764/861] Don't add star to quickpick --- src/vs/workbench/contrib/url/common/url.contribution.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/url/common/url.contribution.ts b/src/vs/workbench/contrib/url/common/url.contribution.ts index 14ab5356509..f28a49ed47c 100644 --- a/src/vs/workbench/contrib/url/common/url.contribution.ts +++ b/src/vs/workbench/contrib/url/common/url.contribution.ts @@ -70,8 +70,7 @@ export class ConfigureTrustedDomainsAction extends Action { }); quickPickItems.unshift({ type: 'item', - label: '*', - description: 'Allow all links to be open without protection', + label: 'Allow all links to be open without protection', picked: trustedDomains.indexOf('*') !== -1 }); From 970538a0c955fe62f8ef4dc0488f6ad703c8b89b Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Sun, 18 Aug 2019 21:55:59 -0700 Subject: [PATCH 765/861] Update UX --- .../editor/browser/services/openerService.ts | 44 ++++--- .../contrib/url/common/url.contribution.ts | 115 ++++++++++++------ 2 files changed, 103 insertions(+), 56 deletions(-) diff --git a/src/vs/editor/browser/services/openerService.ts b/src/vs/editor/browser/services/openerService.ts index e2d8dd2529e..7b30565fc12 100644 --- a/src/vs/editor/browser/services/openerService.ts +++ b/src/vs/editor/browser/services/openerService.ts @@ -18,6 +18,7 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { localize } from 'vs/nls'; import { IProductService } from 'vs/platform/product/common/product'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; +import Severity from 'vs/base/common/severity'; export class OpenerService implements IOpenerService { @@ -76,31 +77,34 @@ export class OpenerService implements IOpenerService { if (isDomainTrusted(domainToOpen, trustedDomains)) { return this.openExternal(resource); } else { - return this._dialogService.confirm({ - title: localize('openExternalLink', 'Open External Link'), - type: 'question', - message: localize( + return this._dialogService.show( + Severity.Info, + localize( 'openExternalLinkAt', 'Do you want {0} to open the external website?\n{1}', this._productService.productConfiguration.nameShort, resource.toString(true) ), - primaryButton: localize('openLink', 'Open Link'), - secondaryButton: localize('cancel', 'Cancel'), - checkbox: { - label: localize('trustAllLinksFrom', 'Trust all links from') + ` ${domainToOpen}`, - checked: false - } - }).then(({ confirmed, checkboxChecked }) => { - if (checkboxChecked) { - this._storageService.store('http.trustedDomains', JSON.stringify([...trustedDomains, domainToOpen]), StorageScope.GLOBAL); - } - if (confirmed) { - return this.openExternal(resource); - } - - return Promise.resolve(false); - }); + [ + localize('openLink', 'Open Link'), + localize('cancel', 'Cancel'), + localize('configureLinkPermission', 'Configure Link Permission'), + ], + { + cancelId: 1 + }).then((choice) => { + if (choice === 0) { + return this.openExternal(resource); + } else if (choice === 2) { + return this._commandService.executeCommand('_workbench.action.configureTrustedDomains', domainToOpen).then((pickedDomains: string[]) => { + if (pickedDomains.indexOf(domainToOpen) !== -1) { + return this.openExternal(resource); + } + return Promise.resolve(false); + }); + } + return Promise.resolve(false); + }); } } else if (equalsIgnoreCase(scheme, Schemas.command)) { // run command or bail out if command isn't known diff --git a/src/vs/workbench/contrib/url/common/url.contribution.ts b/src/vs/workbench/contrib/url/common/url.contribution.ts index f28a49ed47c..ef5eeb6a96a 100644 --- a/src/vs/workbench/contrib/url/common/url.contribution.ts +++ b/src/vs/workbench/contrib/url/common/url.contribution.ts @@ -12,6 +12,7 @@ import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/plat import { URI } from 'vs/base/common/uri'; import { Action } from 'vs/base/common/actions'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; +import { CommandsRegistry } from 'vs/platform/commands/common/commands'; export class OpenUrlAction extends Action { @@ -35,6 +36,70 @@ export class OpenUrlAction extends Action { } } +Registry.as(ActionExtensions.WorkbenchActions).registerWorkbenchAction( + new SyncActionDescriptor(OpenUrlAction, OpenUrlAction.ID, OpenUrlAction.LABEL), + 'Open URL', + localize('developer', 'Developer') +); + +const configureTrustedDomainsHandler = ( + quickInputService: IQuickInputService, + storageService: IStorageService, + domainToConfigure?: string +) => { + let trustedDomains: string[] = []; + try { + trustedDomains = JSON.parse(storageService.get('http.trustedDomains', StorageScope.GLOBAL, '[]')); + } catch (err) { } + + const domainQuickPickItems: IQuickPickItem[] = trustedDomains + .filter(d => d !== '*') + .map(d => { + return { + type: 'item', + label: d, + picked: true, + }; + }); + + const specialQuickPickItems: IQuickPickItem[] = [ + { + type: 'item', + label: localize('allowAllLinks', 'Allow all links to be open without protection'), + picked: trustedDomains.indexOf('*') !== -1 + } + ]; + + let domainToConfigureItem: IQuickPickItem | undefined = undefined; + if (domainToConfigure) { + domainToConfigureItem = { + type: 'item', + label: domainToConfigure, + picked: true, + description: localize('trustDomainAndOpenLink', 'Trust domain and open link') + }; + specialQuickPickItems.push(domainToConfigureItem); + } + + const quickPickItems: (IQuickPickItem | IQuickPickSeparator)[] = domainQuickPickItems.length === 0 + ? specialQuickPickItems + : [...specialQuickPickItems, { type: 'separator' }, ...domainQuickPickItems]; + + return quickInputService.pick(quickPickItems, { + canPickMany: true, + activeItem: domainToConfigureItem + }).then(result => { + if (result) { + const pickedDomains = result.map(r => r.label); + storageService.store('http.trustedDomains', JSON.stringify(pickedDomains), StorageScope.GLOBAL); + + return pickedDomains; + } + + return []; + }); +}; + export class ConfigureTrustedDomainsAction extends Action { static readonly ID = 'workbench.action.configureTrustedDomains'; @@ -50,45 +115,10 @@ export class ConfigureTrustedDomainsAction extends Action { } run(): Promise { - let trustedDomains: string[] = []; - try { - trustedDomains = JSON.parse(this.storageService.get('http.trustedDomains', StorageScope.GLOBAL, '[]')); - } catch (err) { } - - const quickPickItems: (IQuickPickItem | IQuickPickSeparator)[] = trustedDomains - .filter(d => d !== '*') - .map(d => { - return { - type: 'item', - label: d, - picked: true, - }; - }); - - quickPickItems.unshift({ - type: 'separator' - }); - quickPickItems.unshift({ - type: 'item', - label: 'Allow all links to be open without protection', - picked: trustedDomains.indexOf('*') !== -1 - }); - - return this.quickInputService.pick(quickPickItems, { - canPickMany: true - }).then(result => { - if (result) { - this.storageService.store('http.trustedDomains', JSON.stringify(result.map(r => r.label)), StorageScope.GLOBAL); - } - }); + return configureTrustedDomainsHandler(this.quickInputService, this.storageService); } } -Registry.as(ActionExtensions.WorkbenchActions).registerWorkbenchAction( - new SyncActionDescriptor(OpenUrlAction, OpenUrlAction.ID, OpenUrlAction.LABEL), - 'Open URL', - localize('developer', 'Developer') -); Registry.as(ActionExtensions.WorkbenchActions).registerWorkbenchAction( new SyncActionDescriptor( ConfigureTrustedDomainsAction, @@ -97,3 +127,16 @@ Registry.as(ActionExtensions.WorkbenchActions).registe ), 'Configure Trusted Domains' ); +CommandsRegistry.registerCommand({ + id: '_workbench.action.configureTrustedDomains', + description: { + description: 'Configure Trusted Domains', + args: [{ name: 'domainToConfigure', schema: { type: 'string' } }] + }, + handler: (accessor, domainToConfigure?: string) => { + const quickInputService = accessor.get(IQuickInputService); + const storageService = accessor.get(IStorageService); + + return configureTrustedDomainsHandler(quickInputService, storageService, domainToConfigure); + } +}); From e9c0427ac561677e46aa0f4a74737d246c7463ef Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Sun, 18 Aug 2019 22:09:51 -0700 Subject: [PATCH 766/861] Build errors and test failures --- .../editor/browser/services/openerService.ts | 2 +- .../browser/services/openerService.test.ts | 27 +++++++++---------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/vs/editor/browser/services/openerService.ts b/src/vs/editor/browser/services/openerService.ts index 7b30565fc12..f41ec79d480 100644 --- a/src/vs/editor/browser/services/openerService.ts +++ b/src/vs/editor/browser/services/openerService.ts @@ -82,7 +82,7 @@ export class OpenerService implements IOpenerService { localize( 'openExternalLinkAt', 'Do you want {0} to open the external website?\n{1}', - this._productService.productConfiguration.nameShort, + this._productService.nameShort, resource.toString(true) ), [ diff --git a/src/vs/editor/test/browser/services/openerService.test.ts b/src/vs/editor/test/browser/services/openerService.test.ts index f42e3c399ef..3e1ef9e80cb 100644 --- a/src/vs/editor/test/browser/services/openerService.test.ts +++ b/src/vs/editor/test/browser/services/openerService.test.ts @@ -50,30 +50,27 @@ suite('OpenerService', function () { function getDialogService() { return new class implements IDialogService { - _confirmInvoked = 0; - confirm = () => { - this._confirmInvoked++; + _showInvoked = 0; + show = () => { + this._showInvoked++; return Promise.resolve({} as any); } - get confirmInvoked() { return this._confirmInvoked; } + get confirmInvoked() { return this._showInvoked; } // Don't care _serviceBrand: any; - show = () => { + confirm = () => { return Promise.resolve({} as any); } }; } - function getProductService() { - return new class implements IProductService { - // Don't care - _serviceBrand: any; + function getProductService(): IProductService { + return new class { + nameShort: 'VS Code'; - productConfiguration = { - nameShort: 'VS Code' - } as any; - }; + _serviceBrand: any; + } as IProductService; } @@ -176,7 +173,7 @@ suite('OpenerService', function () { assert.equal(lastCommand!.args[1], true); }); - test('links are protected by dialog confirmation', function () { + test('links are protected by dialog.show', function () { const dialogService = getDialogService(); const openerService = new OpenerService( editorService, @@ -190,7 +187,7 @@ suite('OpenerService', function () { assert.equal(dialogService.confirmInvoked, 1); }); - test('links on the whitelisted domains can be opened without dialog confirmation', function () { + test('links on the whitelisted domains can be opened without dialog.show', function () { const dialogService = getDialogService(); const openerService = new OpenerService( editorService, From f0398e992f5d6b2f9919216bd0c8aa0b935a85e4 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Sun, 18 Aug 2019 22:25:54 -0700 Subject: [PATCH 767/861] :lipstick: --- src/vs/editor/browser/services/openerService.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/editor/browser/services/openerService.ts b/src/vs/editor/browser/services/openerService.ts index f41ec79d480..c6aa9891cf5 100644 --- a/src/vs/editor/browser/services/openerService.ts +++ b/src/vs/editor/browser/services/openerService.ts @@ -159,7 +159,6 @@ export class OpenerService implements IOpenerService { /** * Check whether a domain like https://www.microsoft.com matches * the list of trusted domains. - * */ function isDomainTrusted(domain: string, trustedDomains: string[]) { for (let i = 0; i < trustedDomains.length; i++) { From 6865ffbcceec1545980f6f70545a3d1cff32ded7 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 19 Aug 2019 08:06:06 +0200 Subject: [PATCH 768/861] debt - fix some layer breakers --- src/vs/workbench/browser/dnd.ts | 2 +- .../workbench/contrib/terminal/browser/terminalPanel.ts | 2 +- .../contrib/terminal/common/terminalEnvironment.ts | 2 +- .../workbench/contrib/welcome/page/browser/welcomePage.ts | 2 +- .../walkThrough/browser/editor/editorWalkThrough.ts | 2 +- .../walkThrough/browser/walkThrough.contribution.ts | 4 ++-- .../walkThrough/{common => browser}/walkThroughInput.ts | 0 .../welcome/walkThrough/browser/walkThroughPart.ts | 2 +- .../services/extensions/node/extensionHostProcessSetup.ts | 1 + .../workbench/services/files/common/workspaceWatcher.ts | 8 +++++--- .../workbench/services/integrity/node/integrityService.ts | 6 ++++-- .../services/keybinding/browser/keybindingService.ts | 2 +- .../services/keybinding/browser/keymapService.ts | 2 +- .../keybinding/{common => browser}/navigatorKeyboard.ts | 0 .../services/userData/common/inMemoryUserDataProvider.ts | 5 ++--- 15 files changed, 22 insertions(+), 18 deletions(-) rename src/vs/workbench/contrib/welcome/walkThrough/{common => browser}/walkThroughInput.ts (100%) rename src/vs/workbench/services/keybinding/{common => browser}/navigatorKeyboard.ts (100%) diff --git a/src/vs/workbench/browser/dnd.ts b/src/vs/workbench/browser/dnd.ts index cf1d6b5b60f..b99f800164d 100644 --- a/src/vs/workbench/browser/dnd.ts +++ b/src/vs/workbench/browser/dnd.ts @@ -113,7 +113,7 @@ export function extractResources(e: DragEvent, externalOnly?: boolean): Array r.resource.fsPath === file.path) /* prevent duplicates */) { + if (file && file.path /* Electron only */ && !resources.some(r => r.resource.fsPath === file.path) /* prevent duplicates */) { try { resources.push({ resource: URI.file(file.path), isExternal: true }); } catch (error) { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts b/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts index 334c3ab0b13..5c3eae374ef 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts @@ -276,7 +276,7 @@ export class TerminalPanel extends Panel { const resources = e.dataTransfer.getData(DataTransfers.RESOURCES); if (resources) { path = URI.parse(JSON.parse(resources)[0]).fsPath; - } else if (e.dataTransfer.files.length > 0) { + } else if (e.dataTransfer.files.length > 0 && e.dataTransfer.files[0].path /* Electron only */) { // Check if the file was dragged from the filesystem path = URI.file(e.dataTransfer.files[0].path).fsPath; } diff --git a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index e6936280a46..6b9a3ec87b7 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -62,7 +62,7 @@ export function addTerminalEnvironmentKeys(env: platform.IProcessEnvironment, ve env['COLORTERM'] = 'truecolor'; } -function mergeNonNullKeys(env: platform.IProcessEnvironment, other: ITerminalEnvironment | NodeJS.ProcessEnv | undefined) { +function mergeNonNullKeys(env: platform.IProcessEnvironment, other: ITerminalEnvironment | undefined) { if (!other) { return; } diff --git a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts index ab0d4193c40..f549552738b 100644 --- a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts +++ b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts @@ -8,7 +8,7 @@ import { URI } from 'vs/base/common/uri'; import * as strings from 'vs/base/common/strings'; import { ICommandService } from 'vs/platform/commands/common/commands'; import * as arrays from 'vs/base/common/arrays'; -import { WalkThroughInput } from 'vs/workbench/contrib/welcome/walkThrough/common/walkThroughInput'; +import { WalkThroughInput } from 'vs/workbench/contrib/welcome/walkThrough/browser/walkThroughInput'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; diff --git a/src/vs/workbench/contrib/welcome/walkThrough/browser/editor/editorWalkThrough.ts b/src/vs/workbench/contrib/welcome/walkThrough/browser/editor/editorWalkThrough.ts index 7a95ffda9e4..8493b87f2cd 100644 --- a/src/vs/workbench/contrib/welcome/walkThrough/browser/editor/editorWalkThrough.ts +++ b/src/vs/workbench/contrib/welcome/walkThrough/browser/editor/editorWalkThrough.ts @@ -8,7 +8,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { Action } from 'vs/base/common/actions'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { URI } from 'vs/base/common/uri'; -import { WalkThroughInput, WalkThroughInputOptions } from 'vs/workbench/contrib/welcome/walkThrough/common/walkThroughInput'; +import { WalkThroughInput, WalkThroughInputOptions } from 'vs/workbench/contrib/welcome/walkThrough/browser/walkThroughInput'; import { Schemas } from 'vs/base/common/network'; import { IEditorInputFactory, EditorInput } from 'vs/workbench/common/editor'; diff --git a/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThrough.contribution.ts b/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThrough.contribution.ts index 9eed29a774f..8a91091c6b7 100644 --- a/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThrough.contribution.ts +++ b/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThrough.contribution.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { localize } from 'vs/nls'; -import { WalkThroughInput } from 'vs/workbench/contrib/welcome/walkThrough/common/walkThroughInput'; +import { WalkThroughInput } from 'vs/workbench/contrib/welcome/walkThrough/browser/walkThroughInput'; import { WalkThroughPart } from 'vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart'; import { WalkThroughArrowUp, WalkThroughArrowDown, WalkThroughPageUp, WalkThroughPageDown } from 'vs/workbench/contrib/welcome/walkThrough/browser/walkThroughActions'; import { WalkThroughContentProvider, WalkThroughSnippetContentProvider } from 'vs/workbench/contrib/welcome/walkThrough/common/walkThroughContentProvider'; @@ -55,4 +55,4 @@ MenuRegistry.appendMenuItem(MenuId.MenubarHelpMenu, { title: localize({ key: 'miInteractivePlayground', comment: ['&& denotes a mnemonic'] }, "I&&nteractive Playground") }, order: 2 -}); \ No newline at end of file +}); diff --git a/src/vs/workbench/contrib/welcome/walkThrough/common/walkThroughInput.ts b/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughInput.ts similarity index 100% rename from src/vs/workbench/contrib/welcome/walkThrough/common/walkThroughInput.ts rename to src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughInput.ts diff --git a/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.ts b/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.ts index afd74dc859b..71faece75fd 100644 --- a/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.ts +++ b/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.ts @@ -12,7 +12,7 @@ import { IDisposable, dispose, toDisposable, DisposableStore } from 'vs/base/com import { EditorOptions, IEditorMemento } from 'vs/workbench/common/editor'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { WalkThroughInput } from 'vs/workbench/contrib/welcome/walkThrough/common/walkThroughInput'; +import { WalkThroughInput } from 'vs/workbench/contrib/welcome/walkThrough/browser/walkThroughInput'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import * as marked from 'vs/base/common/marked/marked'; import { IModelService } from 'vs/editor/common/services/modelService'; diff --git a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts index 1e887093123..8b5028acac6 100644 --- a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts +++ b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts @@ -62,6 +62,7 @@ function patchProcess(allowExit: boolean) { } } as (code?: number) => never; + // override Electron's process.crash() method process.crash = function () { const err = new Error('An extension called process.crash() and this was prevented.'); console.warn(err.stack); diff --git a/src/vs/workbench/services/files/common/workspaceWatcher.ts b/src/vs/workbench/services/files/common/workspaceWatcher.ts index 46badeabf80..1f9049858d3 100644 --- a/src/vs/workbench/services/files/common/workspaceWatcher.ts +++ b/src/vs/workbench/services/files/common/workspaceWatcher.ts @@ -16,6 +16,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { INotificationService, Severity, NeverShowAgainScope } from 'vs/platform/notification/common/notification'; import { localize } from 'vs/nls'; import { FileService } from 'vs/platform/files/common/fileService'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; export class WorkspaceWatcher extends Disposable { @@ -25,7 +26,8 @@ export class WorkspaceWatcher extends Disposable { @IFileService private readonly fileService: FileService, @IConfigurationService private readonly configurationService: IConfigurationService, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, - @INotificationService private readonly notificationService: INotificationService + @INotificationService private readonly notificationService: INotificationService, + @IOpenerService private readonly openerService: IOpenerService ) { super(); @@ -77,7 +79,7 @@ export class WorkspaceWatcher extends Disposable { localize('netVersionError', "The Microsoft .NET Framework 4.5 is required. Please follow the link to install it."), [{ label: localize('installNet', "Download .NET Framework 4.5"), - run: () => window.open('https://go.microsoft.com/fwlink/?LinkId=786533') + run: () => this.openerService.openExternal(URI.parse('https://go.microsoft.com/fwlink/?LinkId=786533')) }], { sticky: true, @@ -93,7 +95,7 @@ export class WorkspaceWatcher extends Disposable { localize('enospcError', "Unable to watch for file changes in this large workspace. Please follow the instructions link to resolve this issue."), [{ label: localize('learnMore', "Instructions"), - run: () => window.open('https://go.microsoft.com/fwlink/?linkid=867693') + run: () => this.openerService.openExternal(URI.parse('https://go.microsoft.com/fwlink/?linkid=867693')) }], { sticky: true, diff --git a/src/vs/workbench/services/integrity/node/integrityService.ts b/src/vs/workbench/services/integrity/node/integrityService.ts index 021fb9543b5..81f5317fe99 100644 --- a/src/vs/workbench/services/integrity/node/integrityService.ts +++ b/src/vs/workbench/services/integrity/node/integrityService.ts @@ -15,6 +15,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; interface IStorageData { dontShowPrompt: boolean; @@ -64,7 +65,8 @@ export class IntegrityServiceImpl implements IIntegrityService { constructor( @INotificationService private readonly notificationService: INotificationService, @IStorageService storageService: IStorageService, - @ILifecycleService private readonly lifecycleService: ILifecycleService + @ILifecycleService private readonly lifecycleService: ILifecycleService, + @IOpenerService private readonly openerService: IOpenerService ) { this._storage = new IntegrityStorage(storageService); @@ -91,7 +93,7 @@ export class IntegrityServiceImpl implements IIntegrityService { [ { label: nls.localize('integrity.moreInformation', "More Information"), - run: () => window.open(URI.parse(product.checksumFailMoreInfoUrl).toString(true)) + run: () => this.openerService.openExternal(URI.parse(product.checksumFailMoreInfoUrl)) }, { label: nls.localize('integrity.dontShowAgain', "Don't Show Again"), diff --git a/src/vs/workbench/services/keybinding/browser/keybindingService.ts b/src/vs/workbench/services/keybinding/browser/keybindingService.ts index c9394b52fc8..b90651c4f33 100644 --- a/src/vs/workbench/services/keybinding/browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/browser/keybindingService.ts @@ -45,7 +45,7 @@ import * as objects from 'vs/base/common/objects'; import { IKeymapService } from 'vs/workbench/services/keybinding/common/keymapInfo'; import { getDispatchConfig } from 'vs/workbench/services/keybinding/common/dispatchConfig'; import { isArray } from 'vs/base/common/types'; -import { INavigatorWithKeyboard } from 'vs/workbench/services/keybinding/common/navigatorKeyboard'; +import { INavigatorWithKeyboard } from 'vs/workbench/services/keybinding/browser/navigatorKeyboard'; import { ScanCodeUtils, IMMUTABLE_CODE_TO_KEY_CODE } from 'vs/base/common/scanCode'; interface ContributedKeyBinding { diff --git a/src/vs/workbench/services/keybinding/browser/keymapService.ts b/src/vs/workbench/services/keybinding/browser/keymapService.ts index faacc11fbf5..c90e58fc0a9 100644 --- a/src/vs/workbench/services/keybinding/browser/keymapService.ts +++ b/src/vs/workbench/services/keybinding/browser/keymapService.ts @@ -25,7 +25,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { Registry } from 'vs/platform/registry/common/platform'; import { Extensions as ConfigExtensions, IConfigurationRegistry, IConfigurationNode } from 'vs/platform/configuration/common/configurationRegistry'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { INavigatorWithKeyboard } from 'vs/workbench/services/keybinding/common/navigatorKeyboard'; +import { INavigatorWithKeyboard } from 'vs/workbench/services/keybinding/browser/navigatorKeyboard'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IStorageService } from 'vs/platform/storage/common/storage'; diff --git a/src/vs/workbench/services/keybinding/common/navigatorKeyboard.ts b/src/vs/workbench/services/keybinding/browser/navigatorKeyboard.ts similarity index 100% rename from src/vs/workbench/services/keybinding/common/navigatorKeyboard.ts rename to src/vs/workbench/services/keybinding/browser/navigatorKeyboard.ts diff --git a/src/vs/workbench/services/userData/common/inMemoryUserDataProvider.ts b/src/vs/workbench/services/userData/common/inMemoryUserDataProvider.ts index ffed9c53d53..622da2547a3 100644 --- a/src/vs/workbench/services/userData/common/inMemoryUserDataProvider.ts +++ b/src/vs/workbench/services/userData/common/inMemoryUserDataProvider.ts @@ -209,8 +209,7 @@ export class InMemoryUserDataProvider extends Disposable implements IFileSystemP readonly onDidChangeFile: Event = this._onDidChangeFile.event; private _bufferedChanges: IFileChange[] = []; - private _fireSoonHandle?: NodeJS.Timer; - + private _fireSoonHandle?: any; watch(resource: URI, opts: IWatchOptions): IDisposable { // ignore, fires for all changes... @@ -229,4 +228,4 @@ export class InMemoryUserDataProvider extends Disposable implements IFileSystemP this._bufferedChanges.length = 0; }, 5); } -} \ No newline at end of file +} From dd2a230a561f1b86e020e35dbc9324feb25dbf87 Mon Sep 17 00:00:00 2001 From: skprabhanjan Date: Mon, 19 Aug 2019 11:46:30 +0530 Subject: [PATCH 769/861] Added buildReplaceStringWithCasePreserved generic function to be used in both search side and the find side --- src/vs/base/common/search.ts | 23 ++++++++++++++++++ src/vs/editor/contrib/find/replacePattern.ts | 15 +++--------- .../contrib/find/test/replacePattern.test.ts | 24 +++++++++++++++++++ .../services/search/common/replace.ts | 15 +++--------- 4 files changed, 53 insertions(+), 24 deletions(-) create mode 100644 src/vs/base/common/search.ts diff --git a/src/vs/base/common/search.ts b/src/vs/base/common/search.ts new file mode 100644 index 00000000000..c18233d61b9 --- /dev/null +++ b/src/vs/base/common/search.ts @@ -0,0 +1,23 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as strings from './strings'; + +export function buildReplaceStringWithCasePreserved(matches: string[] | null, pattern: string): string { + if (matches && (matches[0] !== '')) { + if (matches[0].toUpperCase() === matches[0]) { + return pattern.toUpperCase(); + } else if (matches[0].toLowerCase() === matches[0]) { + return pattern.toLowerCase(); + } else if (strings.containsUppercaseCharacter(matches[0][0])) { + return pattern[0].toUpperCase() + pattern.substr(1); + } else { + // we don't understand its pattern yet. + return pattern; + } + } else { + return pattern; + } +} diff --git a/src/vs/editor/contrib/find/replacePattern.ts b/src/vs/editor/contrib/find/replacePattern.ts index 50e90d7f3ea..12a05d93536 100644 --- a/src/vs/editor/contrib/find/replacePattern.ts +++ b/src/vs/editor/contrib/find/replacePattern.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { CharCode } from 'vs/base/common/charCode'; -import { containsUppercaseCharacter } from 'vs/base/common/strings'; +import { buildReplaceStringWithCasePreserved } from 'vs/base/common/search'; const enum ReplacePatternKind { StaticValue = 0, @@ -51,17 +51,8 @@ export class ReplacePattern { public buildReplaceString(matches: string[] | null, preserveCase?: boolean): string { if (this._state.kind === ReplacePatternKind.StaticValue) { - if (preserveCase && matches && (matches[0] !== '')) { - if (matches[0].toUpperCase() === matches[0]) { - return this._state.staticValue.toUpperCase(); - } else if (matches[0].toLowerCase() === matches[0]) { - return this._state.staticValue.toLowerCase(); - } else if (containsUppercaseCharacter(matches[0][0])) { - return this._state.staticValue[0].toUpperCase() + this._state.staticValue.substr(1); - } else { - // we don't understand its pattern yet. - return this._state.staticValue; - } + if (preserveCase) { + return buildReplaceStringWithCasePreserved(matches, this._state.staticValue); } else { return this._state.staticValue; } diff --git a/src/vs/editor/contrib/find/test/replacePattern.test.ts b/src/vs/editor/contrib/find/test/replacePattern.test.ts index d252ac74c6a..e4c78422b8f 100644 --- a/src/vs/editor/contrib/find/test/replacePattern.test.ts +++ b/src/vs/editor/contrib/find/test/replacePattern.test.ts @@ -5,6 +5,7 @@ import * as assert from 'assert'; import { ReplacePattern, ReplacePiece, parseReplaceString } from 'vs/editor/contrib/find/replacePattern'; +import { buildReplaceStringWithCasePreserved } from 'vs/base/common/search'; suite('Replace Pattern test', () => { @@ -154,6 +155,29 @@ suite('Replace Pattern test', () => { assert.equal(actual, 'a{}'); }); + test('buildReplaceStringWithCasePreserved test', () => { + let replacePattern = 'Def'; + let actual: string | string[] = 'abc'; + + assert.equal(buildReplaceStringWithCasePreserved([actual], replacePattern), 'def'); + actual = 'Abc'; + assert.equal(buildReplaceStringWithCasePreserved([actual], replacePattern), 'Def'); + actual = 'ABC'; + assert.equal(buildReplaceStringWithCasePreserved([actual], replacePattern), 'DEF'); + + actual = ['abc', 'Abc']; + assert.equal(buildReplaceStringWithCasePreserved(actual, replacePattern), 'def'); + actual = ['Abc', 'abc']; + assert.equal(buildReplaceStringWithCasePreserved(actual, replacePattern), 'Def'); + actual = ['ABC', 'abc']; + assert.equal(buildReplaceStringWithCasePreserved(actual, replacePattern), 'DEF'); + + actual = ['AbC']; + assert.equal(buildReplaceStringWithCasePreserved(actual, replacePattern), 'Def'); + actual = ['aBC']; + assert.equal(buildReplaceStringWithCasePreserved(actual, replacePattern), 'Def'); + }); + test('preserve case', () => { let replacePattern = parseReplaceString('Def'); let actual = replacePattern.buildReplaceString(['abc'], true); diff --git a/src/vs/workbench/services/search/common/replace.ts b/src/vs/workbench/services/search/common/replace.ts index 3f58ea89fe0..99f610bbcf5 100644 --- a/src/vs/workbench/services/search/common/replace.ts +++ b/src/vs/workbench/services/search/common/replace.ts @@ -6,6 +6,7 @@ import * as strings from 'vs/base/common/strings'; import { IPatternInfo } from 'vs/workbench/services/search/common/search'; import { CharCode } from 'vs/base/common/charCode'; +import { buildReplaceStringWithCasePreserved } from 'vs/base/common/search'; export class ReplacePattern { @@ -72,18 +73,8 @@ export class ReplacePattern { } public buildReplaceString(matches: string[] | null, preserveCase?: boolean): string { - - if (preserveCase && matches && (matches[0] !== '')) { - if (matches[0].toUpperCase() === matches[0]) { - return this._replacePattern.toUpperCase(); - } else if (matches[0].toLowerCase() === matches[0]) { - return this._replacePattern.toLowerCase(); - } else if (strings.containsUppercaseCharacter(matches[0][0])) { - return this._replacePattern[0].toUpperCase() + this._replacePattern.substr(1); - } else { - // we don't understand its pattern yet. - return this._replacePattern; - } + if (preserveCase) { + return buildReplaceStringWithCasePreserved(matches, this._replacePattern); } else { return this._replacePattern; } From 6f5198cfb4bee67961e0aad7401e28c224c9dd02 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 19 Aug 2019 08:41:58 +0200 Subject: [PATCH 770/861] :lipstick: imports --- src/vs/workbench/contrib/debug/browser/linkDetector.ts | 2 +- src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts | 2 +- tslint.json | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/linkDetector.ts b/src/vs/workbench/contrib/debug/browser/linkDetector.ts index 58cbb394e5f..df911b7d7c9 100644 --- a/src/vs/workbench/contrib/debug/browser/linkDetector.ts +++ b/src/vs/workbench/contrib/debug/browser/linkDetector.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import strings = require('vs/base/common/strings'); +import * as strings from 'vs/base/common/strings'; import { isAbsolute } from 'vs/base/common/path'; import { URI as uri } from 'vs/base/common/uri'; import { isMacintosh } from 'vs/base/common/platform'; diff --git a/src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts b/src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts index 18c24058910..46a2661d1ff 100644 --- a/src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts +++ b/src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts @@ -7,7 +7,7 @@ import * as platform from 'vs/base/common/platform'; import { Emitter, Event } from 'vs/base/common/event'; import { ITerminalInstance, IWindowsShellHelper } from 'vs/workbench/contrib/terminal/common/terminal'; import { Terminal as XTermTerminal } from 'xterm'; -import WindowsProcessTreeType = require('windows-process-tree'); +import * as WindowsProcessTreeType from 'windows-process-tree'; import { Disposable } from 'vs/base/common/lifecycle'; const SHELL_EXECUTABLES = [ diff --git a/tslint.json b/tslint.json index 4b23918f0fc..059d2cea868 100644 --- a/tslint.json +++ b/tslint.json @@ -5,6 +5,7 @@ "rules": { "no-arg": true, "no-construct": true, + "no-debugger": true, "no-duplicate-super": true, "no-duplicate-switch-case": true, "no-duplicate-variable": true, From b0a495e8663a3127c9845af07021c0c5247afbf7 Mon Sep 17 00:00:00 2001 From: DiamondYuan Date: Mon, 19 Aug 2019 17:17:45 +0800 Subject: [PATCH 771/861] refactor: GlobalStorageDatabaseChannel should dependents in IStorageMainService (#79387) --- src/vs/code/electron-main/app.ts | 2 +- src/vs/platform/storage/node/storageIpc.ts | 6 +++--- src/vs/platform/storage/node/storageMainService.ts | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index f60f4f73c44..1953c269a6b 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -560,7 +560,7 @@ export class CodeApplication extends Disposable { electronIpcServer.registerChannel('url', urlChannel); const storageMainService = accessor.get(IStorageMainService); - const storageChannel = this._register(new GlobalStorageDatabaseChannel(this.logService, storageMainService as StorageMainService)); + const storageChannel = this._register(new GlobalStorageDatabaseChannel(this.logService, storageMainService)); electronIpcServer.registerChannel('storage', storageChannel); // Log level management diff --git a/src/vs/platform/storage/node/storageIpc.ts b/src/vs/platform/storage/node/storageIpc.ts index aaba475a269..8ed04953e41 100644 --- a/src/vs/platform/storage/node/storageIpc.ts +++ b/src/vs/platform/storage/node/storageIpc.ts @@ -5,7 +5,7 @@ import { IChannel, IServerChannel } from 'vs/base/parts/ipc/common/ipc'; import { Event, Emitter } from 'vs/base/common/event'; -import { StorageMainService, IStorageChangeEvent } from 'vs/platform/storage/node/storageMainService'; +import { IStorageChangeEvent, IStorageMainService } from 'vs/platform/storage/node/storageMainService'; import { IUpdateRequest, IStorageDatabase, IStorageItemsChangeEvent } from 'vs/base/parts/storage/common/storage'; import { mapToSerializable, serializableToMap, values } from 'vs/base/common/map'; import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; @@ -38,7 +38,7 @@ export class GlobalStorageDatabaseChannel extends Disposable implements IServerC constructor( private logService: ILogService, - private storageMainService: StorageMainService + private storageMainService: IStorageMainService ) { super(); @@ -203,4 +203,4 @@ export class GlobalStorageDatabaseChannelClient extends Disposable implements IS dispose(this.onDidChangeItemsOnMainListener); } -} \ No newline at end of file +} diff --git a/src/vs/platform/storage/node/storageMainService.ts b/src/vs/platform/storage/node/storageMainService.ts index d1f06b6ecb2..e1bb2173566 100644 --- a/src/vs/platform/storage/node/storageMainService.ts +++ b/src/vs/platform/storage/node/storageMainService.ts @@ -34,6 +34,10 @@ export interface IStorageMainService { */ readonly onWillSaveState: Event; + readonly items: Map; + + initialize(): Promise; + /** * Retrieve an element stored with the given key from storage. Use * the provided defaultValue if the element is null or undefined. From 84dc5c035c31d35fd0c76c4a8b6d6339e3a45371 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 19 Aug 2019 11:18:47 +0200 Subject: [PATCH 772/861] :lipstick: --- src/vs/platform/storage/node/storageMainService.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vs/platform/storage/node/storageMainService.ts b/src/vs/platform/storage/node/storageMainService.ts index e1bb2173566..2f2dd9e3bd2 100644 --- a/src/vs/platform/storage/node/storageMainService.ts +++ b/src/vs/platform/storage/node/storageMainService.ts @@ -34,8 +34,14 @@ export interface IStorageMainService { */ readonly onWillSaveState: Event; + /** + * Access to all cached items of this storage service. + */ readonly items: Map; + /** + * Required call to ensure the service can be used. + */ initialize(): Promise; /** From 3e25e2688f016bb9ee1e0ae20f689f1c25dd5fcc Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 19 Aug 2019 11:38:01 +0200 Subject: [PATCH 773/861] build - have different worker extension host entrypoint, copy worker bootstrap file --- build/gulpfile.vscode.web.js | 3 +++ src/buildfile.js | 8 +------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/build/gulpfile.vscode.web.js b/build/gulpfile.vscode.web.js index 81e08f8e0a6..c09f27252dd 100644 --- a/build/gulpfile.vscode.web.js +++ b/build/gulpfile.vscode.web.js @@ -41,6 +41,9 @@ const vscodeWebResources = [ // Webview 'out-build/vs/workbench/contrib/webview/browser/pre/*.js', + // Extension Worker + 'vs/workbench/services/extensions/worker/extensionHostWorkerMain.js', + // Excludes '!out-build/vs/**/{node,electron-browser,electron-main}/**', '!out-build/vs/editor/standalone/**', diff --git a/src/buildfile.js b/src/buildfile.js index 27928e946eb..746975249ed 100644 --- a/src/buildfile.js +++ b/src/buildfile.js @@ -23,13 +23,7 @@ exports.serviceWorker = [{ dest: 'vs/workbench/contrib/resources/browser/resourceServiceWorkerMain.js' }]; -exports.workerExtensionHost = [{ - name: 'vs/workbench/services/extensions/worker/extensionHostWorker', - // include: [], - prepend: ['vs/loader.js', 'vs/nls.js'], - append: ['vs/workbench/services/extensions/worker/extensionHostWorkerMain'], - dest: 'vs/workbench/services/extensions/worker/extensionHostWorkerMain.js' -}]; +exports.workerExtensionHost = [entrypoint('vs/workbench/services/extensions/worker/extensionHostWorker')]; exports.workbench = require('./vs/workbench/buildfile').collectModules(['vs/workbench/workbench.desktop.main']); exports.workbenchWeb = entrypoint('vs/workbench/workbench.web.api'); From 1b16063cca17e19af49dfd006c400ec360b9d113 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 19 Aug 2019 11:54:37 +0200 Subject: [PATCH 774/861] fix #76573 --- src/vs/workbench/browser/labels.ts | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/browser/labels.ts b/src/vs/workbench/browser/labels.ts index 9db4979a3aa..7216a12b82f 100644 --- a/src/vs/workbench/browser/labels.ts +++ b/src/vs/workbench/browser/labels.ts @@ -317,40 +317,31 @@ class ResourceLabelWidget extends IconLabel { } notifyFormattersChange(): void { - if (this.label && this.label.resource) { - this.setFile(this.label.resource, this.options); - } this.render(false); } setResource(label: IResourceLabelProps, options?: IResourceLabelOptions): void { - const hasResourceChanged = this.hasResourceChanged(label, options); - this.label = label; this.options = options; - if (hasResourceChanged) { + if (this.hasPathLabelChanged(label, options)) { this.computedPathLabel = undefined; // reset path label due to resource change } - this.render(hasResourceChanged); + this.render(this.clearIconCache(label, options)); } - private hasResourceChanged(label: IResourceLabelProps, options?: IResourceLabelOptions): boolean { - const newResource = label ? label.resource : undefined; + private clearIconCache(newLabel: IResourceLabelProps, newOptions?: IResourceLabelOptions): boolean { + const newResource = newLabel ? newLabel.resource : undefined; const oldResource = this.label ? this.label.resource : undefined; - const newFileKind = options ? options.fileKind : undefined; + const newFileKind = newOptions ? newOptions.fileKind : undefined; const oldFileKind = this.options ? this.options.fileKind : undefined; if (newFileKind !== oldFileKind) { return true; // same resource but different kind (file, folder) } - if (newResource && this.computedPathLabel !== this.labelService.getUriLabel(newResource)) { - return true; - } - if (newResource && oldResource) { return newResource.toString() !== oldResource.toString(); } @@ -362,6 +353,12 @@ class ResourceLabelWidget extends IconLabel { return true; } + private hasPathLabelChanged(newLabel: IResourceLabelProps, newOptions?: IResourceLabelOptions): boolean { + const newResource = newLabel ? newLabel.resource : undefined; + + return !!newResource && this.computedPathLabel !== this.labelService.getUriLabel(newResource); + } + setEditor(editor: IEditorInput, options?: IResourceLabelOptions): void { this.setResource({ resource: toResource(editor, { supportSideBySide: SideBySideEditor.MASTER }), From de881573e78d712b66edef59191e6122133f21de Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 19 Aug 2019 12:22:06 +0200 Subject: [PATCH 775/861] fix path --- build/gulpfile.vscode.web.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/gulpfile.vscode.web.js b/build/gulpfile.vscode.web.js index c09f27252dd..8f63d7b7d0b 100644 --- a/build/gulpfile.vscode.web.js +++ b/build/gulpfile.vscode.web.js @@ -42,7 +42,7 @@ const vscodeWebResources = [ 'out-build/vs/workbench/contrib/webview/browser/pre/*.js', // Extension Worker - 'vs/workbench/services/extensions/worker/extensionHostWorkerMain.js', + 'out-build/vs/workbench/services/extensions/worker/extensionHostWorkerMain.js', // Excludes '!out-build/vs/**/{node,electron-browser,electron-main}/**', From 7226b82a187ca84ed98c43e556b41aee2c9387bf Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 19 Aug 2019 12:41:20 +0200 Subject: [PATCH 776/861] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2a43502df64..e01ec81fc97 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "481202cd856f5dbbb010996544e4fa7498154f2e", + "distro": "79dcce2b3cd0772344a028cd703b7da03f3ffa83", "author": { "name": "Microsoft Corporation" }, From 815f7b05dd3fe25965863cad6814d0acabd3c7d6 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 19 Aug 2019 13:01:21 +0200 Subject: [PATCH 777/861] Localization test fails on remote smoketest. Fixes #78412 --- test/smoke/src/application.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/smoke/src/application.ts b/test/smoke/src/application.ts index 874a17421b2..60ed794ae9a 100644 --- a/test/smoke/src/application.ts +++ b/test/smoke/src/application.ts @@ -142,7 +142,7 @@ export class Application { await this.code.waitForElement('.monaco-workbench'); if (this.remote) { - await this.code.waitForElement('.monaco-workbench .statusbar-item[title="Editing on TestResolver"]'); + await this.code.waitForElement('.monaco-workbench .statusbar-item[id="status.host"]'); } // wait a bit, since focus might be stolen off widgets From 57379e0f97931249a88f483bb63128c7848e8c2c Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 19 Aug 2019 14:19:06 +0200 Subject: [PATCH 778/861] Fix microsoft/vscode-remote-release/issues/1027 --- .../download/common/downloadService.ts | 2 +- .../common/extensionManagement.ts | 1 + .../common/extensionManagementIpc.ts | 7 +++- .../node/extensionManagementService.ts | 8 +++- .../common/extensionManagementService.ts | 39 +++++++++++++++++-- .../node/extensionManagementService.ts | 32 ++++++--------- 6 files changed, 61 insertions(+), 28 deletions(-) diff --git a/src/vs/platform/download/common/downloadService.ts b/src/vs/platform/download/common/downloadService.ts index a2b8365df4c..54d2f1a9835 100644 --- a/src/vs/platform/download/common/downloadService.ts +++ b/src/vs/platform/download/common/downloadService.ts @@ -20,7 +20,7 @@ export class DownloadService implements IDownloadService { ) { } async download(resource: URI, target: URI, cancellationToken: CancellationToken = CancellationToken.None): Promise { - if (resource.scheme === Schemas.file) { + if (resource.scheme === Schemas.file || resource.scheme === Schemas.vscodeRemote) { await this.fileService.copy(resource, target); return; } diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index b075553498d..dd19996782d 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -195,6 +195,7 @@ export interface IExtensionManagementService { zip(extension: ILocalExtension): Promise; unzip(zipLocation: URI, type: ExtensionType): Promise; + getManifest(vsix: URI): Promise; install(vsix: URI): Promise; installFromGallery(extension: IGalleryExtension): Promise; uninstall(extension: ILocalExtension, force?: boolean): Promise; diff --git a/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts b/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts index b88350f44c7..349223b9210 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagementIpc.ts @@ -9,7 +9,7 @@ import { Event } from 'vs/base/common/event'; import { URI, UriComponents } from 'vs/base/common/uri'; import { IURITransformer, DefaultURITransformer, transformAndReviveIncomingURIs } from 'vs/base/common/uriIpc'; import { cloneAndChange } from 'vs/base/common/objects'; -import { ExtensionType } from 'vs/platform/extensions/common/extensions'; +import { ExtensionType, IExtensionManifest } from 'vs/platform/extensions/common/extensions'; function transformIncomingURI(uri: UriComponents, transformer: IURITransformer | null): URI { return URI.revive(transformer ? transformer.transformIncoming(uri) : uri); @@ -62,6 +62,7 @@ export class ExtensionManagementChannel implements IServerChannel { case 'zip': return this.service.zip(transformIncomingExtension(args[0], uriTransformer)).then(uri => transformOutgoingURI(uri, uriTransformer)); case 'unzip': return this.service.unzip(transformIncomingURI(args[0], uriTransformer), args[1]); case 'install': return this.service.install(transformIncomingURI(args[0], uriTransformer)); + case 'getManifest': return this.service.getManifest(transformIncomingURI(args[0], uriTransformer)); case 'installFromGallery': return this.service.installFromGallery(args[0]); case 'uninstall': return this.service.uninstall(transformIncomingExtension(args[0], uriTransformer), args[1]); case 'reinstallFromGallery': return this.service.reinstallFromGallery(transformIncomingExtension(args[0], uriTransformer)); @@ -99,6 +100,10 @@ export class ExtensionManagementChannelClient implements IExtensionManagementSer return Promise.resolve(this.channel.call('install', [vsix])).then(local => transformIncomingExtension(local, null)); } + getManifest(vsix: URI): Promise { + return Promise.resolve(this.channel.call('getManifest', [vsix])); + } + installFromGallery(extension: IGalleryExtension): Promise { return Promise.resolve(this.channel.call('installFromGallery', [extension])).then(local => transformIncomingExtension(local, null)); } diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index 70cd46c824a..7d0b568fc7f 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -161,6 +161,12 @@ export class ExtensionManagementService extends Disposable implements IExtension return this.install(zipLocation, type).then(local => local.identifier); } + async getManifest(vsix: URI): Promise { + const downloadLocation = await this.downloadVsix(vsix); + const zipPath = path.resolve(downloadLocation.fsPath); + return getManifest(zipPath); + } + private collectFiles(extension: ILocalExtension): Promise { const collectFilesFromDirectory = async (dir: string): Promise => { @@ -983,4 +989,4 @@ export class ExtensionManagementService extends Disposable implements IExtension */ this.telemetryService.publicLog(eventName, assign(extensionData, { success: !error, duration, errorcode })); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts b/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts index 337f52b278a..f1831bdbc19 100644 --- a/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/common/extensionManagementService.ts @@ -8,7 +8,7 @@ import { IExtensionManagementService, ILocalExtension, IGalleryExtension, InstallExtensionEvent, DidInstallExtensionEvent, IExtensionIdentifier, DidUninstallExtensionEvent, IReportedExtension, IGalleryMetadata, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IExtensionManagementServer, IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; -import { ExtensionType, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions'; +import { ExtensionType, isLanguagePackExtension, IExtensionManifest } from 'vs/platform/extensions/common/extensions'; import { URI } from 'vs/base/common/uri'; import { Disposable } from 'vs/base/common/lifecycle'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -17,6 +17,8 @@ import { areSameExtensions } from 'vs/platform/extensionManagement/common/extens import { localize } from 'vs/nls'; import { isUIExtension } from 'vs/workbench/services/extensions/common/extensionsUtil'; import { IProductService } from 'vs/platform/product/common/product'; +import { Schemas } from 'vs/base/common/network'; +import { IDownloadService } from 'vs/platform/download/common/download'; export class ExtensionManagementService extends Disposable implements IExtensionManagementService { @@ -34,6 +36,7 @@ export class ExtensionManagementService extends Disposable implements IExtension @IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService, @IConfigurationService protected readonly configurationService: IConfigurationService, @IProductService protected readonly productService: IProductService, + @IDownloadService protected readonly downloadService: IDownloadService, ) { super(); if (this.extensionManagementServerService.localExtensionManagementServer) { @@ -142,15 +145,43 @@ export class ExtensionManagementService extends Disposable implements IExtension } async install(vsix: URI): Promise { + if (this.extensionManagementServerService.localExtensionManagementServer && this.extensionManagementServerService.remoteExtensionManagementServer) { + const manifest = await this.getManifest(vsix); + if (isLanguagePackExtension(manifest)) { + // Install on both servers + const [local] = await Promise.all(this.servers.map(server => this.installVSIX(vsix, server))); + return local; + } + if (isUIExtension(manifest, this.productService, this.configurationService)) { + // Install only on local server + return this.installVSIX(vsix, this.extensionManagementServerService.localExtensionManagementServer); + } + // Install only on remote server + return this.installVSIX(vsix, this.extensionManagementServerService.remoteExtensionManagementServer); + } if (this.extensionManagementServerService.localExtensionManagementServer) { - return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.install(vsix); + return this.installVSIX(vsix, this.extensionManagementServerService.localExtensionManagementServer); } if (this.extensionManagementServerService.remoteExtensionManagementServer) { - return this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.install(vsix); + return this.installVSIX(vsix, this.extensionManagementServerService.remoteExtensionManagementServer); } return Promise.reject('No Servers to Install'); } + protected installVSIX(vsix: URI, server: IExtensionManagementServer): Promise { + return server.extensionManagementService.install(vsix); + } + + getManifest(vsix: URI): Promise { + if (vsix.scheme === Schemas.file && this.extensionManagementServerService.localExtensionManagementServer) { + return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.getManifest(vsix); + } + if (vsix.scheme === Schemas.vscodeRemote && this.extensionManagementServerService.remoteExtensionManagementServer) { + return this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.getManifest(vsix); + } + return Promise.reject('No Servers'); + } + async installFromGallery(gallery: IGalleryExtension): Promise { if (this.extensionManagementServerService.localExtensionManagementServer && this.extensionManagementServerService.remoteExtensionManagementServer) { const manifest = await this.extensionGalleryService.getManifest(gallery, CancellationToken.None); @@ -191,4 +222,4 @@ export class ExtensionManagementService extends Disposable implements IExtension private getServer(extension: ILocalExtension): IExtensionManagementServer | null { return this.extensionManagementServerService.getExtensionManagementServer(extension.location); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/services/extensionManagement/node/extensionManagementService.ts b/src/vs/workbench/services/extensionManagement/node/extensionManagementService.ts index b2b5e78f90e..143026c2b91 100644 --- a/src/vs/workbench/services/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/workbench/services/extensionManagement/node/extensionManagementService.ts @@ -3,35 +3,25 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { tmpdir } from 'os'; +import { generateUuid } from 'vs/base/common/uuid'; import { ILocalExtension, IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { isLanguagePackExtension } from 'vs/platform/extensions/common/extensions'; import { URI } from 'vs/base/common/uri'; -import { getManifest } from 'vs/platform/extensionManagement/node/extensionManagementUtil'; -import { isUIExtension } from 'vs/workbench/services/extensions/common/extensionsUtil'; import { ExtensionManagementService as BaseExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagementService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IExtensionManagementServer } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; +import { Schemas } from 'vs/base/common/network'; +import * as path from 'vs/base/common/path'; export class ExtensionManagementService extends BaseExtensionManagementService { - async install(vsix: URI): Promise { - if (this.extensionManagementServerService.localExtensionManagementServer && this.extensionManagementServerService.remoteExtensionManagementServer) { - const manifest = await getManifest(vsix.fsPath); - if (isLanguagePackExtension(manifest)) { - // Install on both servers - const [local] = await Promise.all(this.servers.map(server => server.extensionManagementService.install(vsix))); - return local; - } - if (isUIExtension(manifest, this.productService, this.configurationService)) { - // Install only on local server - return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.install(vsix); - } - // Install only on remote server - return this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.install(vsix); + protected async installVSIX(vsix: URI, server: IExtensionManagementServer): Promise { + if (vsix.scheme === Schemas.vscodeRemote && server === this.extensionManagementServerService.localExtensionManagementServer) { + const downloadedLocation = URI.file(path.join(tmpdir(), generateUuid())); + await this.downloadService.download(vsix, downloadedLocation); + vsix = downloadedLocation; } - if (this.extensionManagementServerService.localExtensionManagementServer) { - return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.install(vsix); - } - return Promise.reject('No Servers to Install'); + return server.extensionManagementService.install(vsix); } } From c8d44e24dd250d416475a10efe64e35c9e2c65b3 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 19 Aug 2019 14:11:46 +0200 Subject: [PATCH 779/861] fix scope when falling back to original load function --- src/vs/workbench/api/common/extHostRequireInterceptor.ts | 8 ++++---- src/vs/workbench/api/node/extHostExtensionService.ts | 6 +++++- src/vs/workbench/api/worker/extHostExtensionService.ts | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/api/common/extHostRequireInterceptor.ts b/src/vs/workbench/api/common/extHostRequireInterceptor.ts index ad16a75c56b..46866f7db08 100644 --- a/src/vs/workbench/api/common/extHostRequireInterceptor.ts +++ b/src/vs/workbench/api/common/extHostRequireInterceptor.ts @@ -21,12 +21,12 @@ import { platform } from 'vs/base/common/process'; interface LoadFunction { - (request: string, parent: { filename: string; }, isMain: any): any; + (request: string): any; } interface INodeModuleFactory { readonly nodeModuleName: string | string[]; - load(request: string, parent: URI, isMain: any, original: LoadFunction): any; + load(request: string, parent: URI, original: LoadFunction): any; alternativeModuleName?(name: string): string | undefined; } @@ -245,7 +245,7 @@ class OpenNodeModuleFactory implements INodeModuleFactory { }; } - public load(request: string, parent: URI, isMain: any, original: LoadFunction): any { + public load(request: string, parent: URI, original: LoadFunction): any { // get extension id from filename and api for extension const extension = this._extensionPaths.findSubstr(parent.fsPath); if (extension) { @@ -253,7 +253,7 @@ class OpenNodeModuleFactory implements INodeModuleFactory { this.sendShimmingTelemetry(); } - this._original = original(request, { filename: parent.fsPath }, isMain); + this._original = original(request); return this._impl; } diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 10161ac3355..8e96e6738ec 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -31,7 +31,11 @@ class NodeModuleRequireInterceptor extends RequireInterceptor { if (!that._factories.has(request)) { return original.apply(this, arguments); } - return that._factories.get(request)!.load(request, URI.file(parent.filename), isMain, original); + return that._factories.get(request)!.load( + request, + URI.file(parent.filename), + request => original.apply(this, [request, parent, isMain]) + ); }; } } diff --git a/src/vs/workbench/api/worker/extHostExtensionService.ts b/src/vs/workbench/api/worker/extHostExtensionService.ts index fdc57cbb2ec..a40ce65b7bf 100644 --- a/src/vs/workbench/api/worker/extHostExtensionService.ts +++ b/src/vs/workbench/api/worker/extHostExtensionService.ts @@ -89,7 +89,7 @@ class WorkerRequireInterceptor extends RequireInterceptor { } if (this._factories.has(request)) { - return this._factories.get(request)!.load(request, parent, false, () => { throw new Error(); }); + return this._factories.get(request)!.load(request, parent, () => { throw new Error('CANNOT LOAD MODULE from here.'); }); } return undefined; } From 21821141a653378e263448c2954a3384ccce5bee Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Mon, 19 Aug 2019 06:40:15 -0700 Subject: [PATCH 780/861] Wording update --- src/vs/workbench/contrib/url/common/url.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/url/common/url.contribution.ts b/src/vs/workbench/contrib/url/common/url.contribution.ts index ef5eeb6a96a..b8f67e2e598 100644 --- a/src/vs/workbench/contrib/url/common/url.contribution.ts +++ b/src/vs/workbench/contrib/url/common/url.contribution.ts @@ -65,7 +65,7 @@ const configureTrustedDomainsHandler = ( const specialQuickPickItems: IQuickPickItem[] = [ { type: 'item', - label: localize('allowAllLinks', 'Allow all links to be open without protection'), + label: localize('openAllLinksWithoutPrompt', 'Open all links without prompt'), picked: trustedDomains.indexOf('*') !== -1 } ]; From 34339f92c435a48f49f4e04eee8feeda86925f84 Mon Sep 17 00:00:00 2001 From: Salvador Cabrera Date: Mon, 19 Aug 2019 09:35:06 -0500 Subject: [PATCH 781/861] Fix: Markdown Preview scroll remains same after clicking on some other link #78465 Improves the behavior on how markdown preview behaves when clicking a link --- .../markdown-language-features/media/index.js | 29 +++++++++++++++---- .../preview-src/index.ts | 23 ++++++++++----- .../preview-src/scroll-sync.ts | 9 ++++++ .../src/features/preview.ts | 12 +++++++- 4 files changed, 60 insertions(+), 13 deletions(-) diff --git a/extensions/markdown-language-features/media/index.js b/extensions/markdown-language-features/media/index.js index 00afdf196af..9a0fd91b45a 100644 --- a/extensions/markdown-language-features/media/index.js +++ b/extensions/markdown-language-features/media/index.js @@ -659,10 +659,20 @@ window.onload = () => { events_1.onceDocumentLoaded(() => { if (settings.scrollPreviewWithEditor) { setTimeout(() => { - const initialLine = +settings.line; - if (!isNaN(initialLine)) { - scrollDisabled = true; - scroll_sync_1.scrollToRevealSourceLine(initialLine); + // Try to scroll to fragment if available + if (state.fragment) { + const element = scroll_sync_1.getLineElementForFragment(state.fragment); + if (element) { + scrollDisabled = true; + scroll_sync_1.scrollToRevealSourceLine(element.line); + } + } + else { + const initialLine = +settings.line; + if (!isNaN(initialLine)) { + scrollDisabled = true; + scroll_sync_1.scrollToRevealSourceLine(initialLine); + } } }, 0); } @@ -940,6 +950,15 @@ function getEditorLineNumberForPageOffset(offset) { return null; } exports.getEditorLineNumberForPageOffset = getEditorLineNumberForPageOffset; +/** + * Try to find the html element by using a fragment id + */ +function getLineElementForFragment(fragment) { + return getCodeLineElements().find((element) => { + return element.element.id === fragment; + }); +} +exports.getLineElementForFragment = getLineElementForFragment; /***/ }), @@ -986,4 +1005,4 @@ exports.getSettings = getSettings; /***/ }) /******/ }); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2xvZGFzaC50aHJvdHRsZS9pbmRleC5qcyIsIndlYnBhY2s6Ly8vKHdlYnBhY2spL2J1aWxkaW4vZ2xvYmFsLmpzIiwid2VicGFjazovLy8uL3ByZXZpZXctc3JjL2FjdGl2ZUxpbmVNYXJrZXIudHMiLCJ3ZWJwYWNrOi8vLy4vcHJldmlldy1zcmMvZXZlbnRzLnRzIiwid2VicGFjazovLy8uL3ByZXZpZXctc3JjL2luZGV4LnRzIiwid2VicGFjazovLy8uL3ByZXZpZXctc3JjL21lc3NhZ2luZy50cyIsIndlYnBhY2s6Ly8vLi9wcmV2aWV3LXNyYy9zY3JvbGwtc3luYy50cyIsIndlYnBhY2s6Ly8vLi9wcmV2aWV3LXNyYy9zZXR0aW5ncy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQSx5REFBaUQsY0FBYztBQUMvRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBMkIsMEJBQTBCLEVBQUU7QUFDdkQseUNBQWlDLGVBQWU7QUFDaEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOERBQXNELCtEQUErRDs7QUFFckg7QUFDQTs7O0FBR0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxPQUFPO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFNBQVM7QUFDcEIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTyxZQUFZO0FBQzlCLFdBQVcsUUFBUTtBQUNuQjtBQUNBLFdBQVcsT0FBTztBQUNsQjtBQUNBLFdBQVcsUUFBUTtBQUNuQjtBQUNBLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLDhDQUE4QyxrQkFBa0I7QUFDaEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFNBQVM7QUFDcEIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTyxZQUFZO0FBQzlCLFdBQVcsUUFBUTtBQUNuQjtBQUNBLFdBQVcsUUFBUTtBQUNuQjtBQUNBLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtREFBbUQsb0JBQW9CO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLEVBQUU7QUFDYixhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsRUFBRTtBQUNiLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0Esb0JBQW9CO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLEVBQUU7QUFDYixhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxFQUFFO0FBQ2IsYUFBYSxPQUFPO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7Ozs7Ozs7Ozs7O0FDdGJBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsNENBQTRDOztBQUU1Qzs7Ozs7Ozs7Ozs7Ozs7O0FDbkJBOzs7Z0dBR2dHO0FBQ2hHLCtGQUF5RDtBQUV6RCxNQUFhLGdCQUFnQjtJQUc1Qiw4QkFBOEIsQ0FBQyxJQUFZO1FBQzFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsR0FBRyxzQ0FBd0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwRCxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVELE9BQU8sQ0FBQyxNQUErQjtRQUN0QyxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQztJQUN4QixDQUFDO0lBRUQsb0JBQW9CLENBQUMsT0FBZ0M7UUFDcEQsSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNiLE9BQU87U0FDUDtRQUNELE9BQU8sQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsdUJBQXVCLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDNUUsQ0FBQztJQUVELGtCQUFrQixDQUFDLE9BQWdDO1FBQ2xELElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDYixPQUFPO1NBQ1A7UUFDRCxPQUFPLENBQUMsU0FBUyxJQUFJLG1CQUFtQixDQUFDO0lBQzFDLENBQUM7Q0FDRDtBQTNCRCw0Q0EyQkM7Ozs7Ozs7Ozs7Ozs7O0FDakNEOzs7Z0dBR2dHOztBQUVoRyxTQUFnQixrQkFBa0IsQ0FBQyxDQUFhO0lBQy9DLElBQUksUUFBUSxDQUFDLFVBQVUsS0FBSyxTQUFTLElBQUksUUFBUSxDQUFDLFVBQW9CLEtBQUssZUFBZSxFQUFFO1FBQzNGLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBQUMsQ0FBQztLQUNqRDtTQUFNO1FBQ04sQ0FBQyxFQUFFLENBQUM7S0FDSjtBQUNGLENBQUM7QUFORCxnREFNQzs7Ozs7Ozs7Ozs7Ozs7QUNYRDs7O2dHQUdnRzs7QUFFaEcsOEdBQXNEO0FBQ3RELGdGQUE4QztBQUM5Qyx5RkFBb0Q7QUFDcEQsK0ZBQTJGO0FBQzNGLHNGQUFrRDtBQUNsRCx1R0FBNkM7QUFJN0MsSUFBSSxjQUFjLEdBQUcsSUFBSSxDQUFDO0FBQzFCLE1BQU0sTUFBTSxHQUFHLElBQUksbUNBQWdCLEVBQUUsQ0FBQztBQUN0QyxNQUFNLFFBQVEsR0FBRyxzQkFBVyxFQUFFLENBQUM7QUFFL0IsTUFBTSxNQUFNLEdBQUcsZ0JBQWdCLEVBQUUsQ0FBQztBQUVsQyxvQkFBb0I7QUFDcEIsSUFBSSxLQUFLLEdBQUcsa0JBQU8sQ0FBbUIsWUFBWSxDQUFDLENBQUM7QUFDcEQsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUV2QixNQUFNLFNBQVMsR0FBRyxpQ0FBcUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUVoRCxNQUFNLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUN2QyxNQUFNLENBQUMsbUJBQW1CLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBRWhELE1BQU0sQ0FBQyxNQUFNLEdBQUcsR0FBRyxFQUFFO0lBQ3BCLGdCQUFnQixFQUFFLENBQUM7QUFDcEIsQ0FBQyxDQUFDO0FBRUYsMkJBQWtCLENBQUMsR0FBRyxFQUFFO0lBQ3ZCLElBQUksUUFBUSxDQUFDLHVCQUF1QixFQUFFO1FBQ3JDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZixNQUFNLFdBQVcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7WUFDbkMsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsRUFBRTtnQkFDeEIsY0FBYyxHQUFHLElBQUksQ0FBQztnQkFDdEIsc0NBQXdCLENBQUMsV0FBVyxDQUFDLENBQUM7YUFDdEM7UUFDRixDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7S0FDTjtBQUNGLENBQUMsQ0FBQyxDQUFDO0FBRUgsTUFBTSxZQUFZLEdBQUcsQ0FBQyxHQUFHLEVBQUU7SUFDMUIsTUFBTSxRQUFRLEdBQUcsUUFBUSxDQUFDLENBQUMsSUFBWSxFQUFFLEVBQUU7UUFDMUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUN0QixzQ0FBd0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNoQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFFUCxPQUFPLENBQUMsSUFBWSxFQUFFLFFBQWEsRUFBRSxFQUFFO1FBQ3RDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDakIsUUFBUSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7WUFDckIsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQ2Y7SUFDRixDQUFDLENBQUM7QUFDSCxDQUFDLENBQUMsRUFBRSxDQUFDO0FBRUwsSUFBSSxnQkFBZ0IsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFO0lBQ3BDLE1BQU0sU0FBUyxHQUFvRCxFQUFFLENBQUM7SUFDdEUsSUFBSSxNQUFNLEdBQUcsUUFBUSxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2xELElBQUksTUFBTSxFQUFFO1FBQ1gsSUFBSSxDQUFDLENBQUM7UUFDTixLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDbkMsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRXRCLElBQUksR0FBRyxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEVBQUU7Z0JBQ3RDLEdBQUcsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO2FBQ2hDO1lBRUQsU0FBUyxDQUFDLElBQUksQ0FBQztnQkFDZCxFQUFFLEVBQUUsR0FBRyxDQUFDLEVBQUU7Z0JBQ1YsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNO2dCQUNsQixLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUs7YUFDaEIsQ0FBQyxDQUFDO1NBQ0g7UUFFRCxTQUFTLENBQUMsV0FBVyxDQUFDLGlCQUFpQixFQUFFLFNBQVMsQ0FBQyxDQUFDO0tBQ3BEO0FBQ0YsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBRVAsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxHQUFHLEVBQUU7SUFDdEMsY0FBYyxHQUFHLElBQUksQ0FBQztJQUN0QixnQkFBZ0IsRUFBRSxDQUFDO0FBQ3BCLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUVULE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLEVBQUU7SUFDMUMsSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sS0FBSyxRQUFRLENBQUMsTUFBTSxFQUFFO1FBQzFDLE9BQU87S0FDUDtJQUVELFFBQVEsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUU7UUFDeEIsS0FBSyxnQ0FBZ0M7WUFDcEMsTUFBTSxDQUFDLDhCQUE4QixDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdkQsTUFBTTtRQUVQLEtBQUssWUFBWTtZQUNoQixZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDeEMsTUFBTTtLQUNQO0FBQ0YsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBRVYsUUFBUSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsRUFBRSxLQUFLLENBQUMsRUFBRTtJQUM3QyxJQUFJLENBQUMsUUFBUSxDQUFDLDJCQUEyQixFQUFFO1FBQzFDLE9BQU87S0FDUDtJQUVELHlCQUF5QjtJQUN6QixLQUFLLElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQyxNQUFxQixFQUFFLElBQUksRUFBRSxJQUFJLEdBQUcsSUFBSSxDQUFDLFVBQXlCLEVBQUU7UUFDekYsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLEdBQUcsRUFBRTtZQUN6QixPQUFPO1NBQ1A7S0FDRDtJQUVELE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUM7SUFDM0IsTUFBTSxJQUFJLEdBQUcsOENBQWdDLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDdEQsSUFBSSxPQUFPLElBQUksS0FBSyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUU7UUFDN0MsU0FBUyxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7S0FDOUQ7QUFDRixDQUFDLENBQUMsQ0FBQztBQUVILFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLEVBQUU7SUFDMUMsSUFBSSxDQUFDLEtBQUssRUFBRTtRQUNYLE9BQU87S0FDUDtJQUVELElBQUksSUFBSSxHQUFRLEtBQUssQ0FBQyxNQUFNLENBQUM7SUFDN0IsT0FBTyxJQUFJLEVBQUU7UUFDWixJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLE9BQU8sS0FBSyxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksRUFBRTtZQUN0RCxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFO2dCQUM5QyxNQUFNO2FBQ047WUFDRCxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLGtCQUFrQixDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLEVBQUU7Z0JBQ3RJLE1BQU0sQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsZ0NBQWdDLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksTUFBTSxDQUFDLElBQUksWUFBWSxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDbEssU0FBUyxDQUFDLFdBQVcsQ0FBQyxXQUFXLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztnQkFDdkQsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUN2QixLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ3hCLE1BQU07YUFDTjtZQUNELE1BQU07U0FDTjtRQUNELElBQUksR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO0tBQ3ZCO0FBQ0YsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBRVQsSUFBSSxRQUFRLENBQUMsdUJBQXVCLEVBQUU7SUFDckMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsR0FBRyxFQUFFO1FBQy9DLElBQUksY0FBYyxFQUFFO1lBQ25CLGNBQWMsR0FBRyxLQUFLLENBQUM7U0FDdkI7YUFBTTtZQUNOLE1BQU0sSUFBSSxHQUFHLDhDQUFnQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUM5RCxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRTtnQkFDN0MsU0FBUyxDQUFDLFdBQVcsQ0FBQyxZQUFZLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUM5QyxLQUFLLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztnQkFDbEIsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUN2QjtTQUNEO0lBQ0YsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7Q0FDUjtBQUVELFNBQVMsWUFBWSxDQUFDLElBQVk7SUFDakMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLDBCQUEwQixFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ3pELENBQUM7Ozs7Ozs7Ozs7Ozs7O0FDbktEOzs7Z0dBR2dHOztBQUVoRyxzRkFBeUM7QUFTNUIsNkJBQXFCLEdBQUcsQ0FBQyxNQUFXLEVBQUUsRUFBRTtJQUNwRCxPQUFPLElBQUk7UUFDVixXQUFXLENBQUMsSUFBWSxFQUFFLElBQVk7WUFDckMsTUFBTSxDQUFDLFdBQVcsQ0FBQztnQkFDbEIsSUFBSTtnQkFDSixNQUFNLEVBQUUsc0JBQVcsRUFBRSxDQUFDLE1BQU07Z0JBQzVCLElBQUk7YUFDSixDQUFDLENBQUM7UUFDSixDQUFDO0tBQ0QsQ0FBQztBQUNILENBQUMsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7QUN4QkY7OztnR0FHZ0c7O0FBRWhHLHNGQUF5QztBQUd6QyxTQUFTLEtBQUssQ0FBQyxHQUFXLEVBQUUsR0FBVyxFQUFFLEtBQWE7SUFDckQsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQzVDLENBQUM7QUFFRCxTQUFTLFNBQVMsQ0FBQyxJQUFZO0lBQzlCLE9BQU8sS0FBSyxDQUFDLENBQUMsRUFBRSxzQkFBVyxFQUFFLENBQUMsU0FBUyxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUNwRCxDQUFDO0FBUUQsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLEdBQUcsRUFBRTtJQUNqQyxJQUFJLFFBQTJCLENBQUM7SUFDaEMsT0FBTyxHQUFHLEVBQUU7UUFDWCxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ2QsUUFBUSxHQUFHLENBQUMsRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNqRCxLQUFLLE1BQU0sT0FBTyxJQUFJLFFBQVEsQ0FBQyxzQkFBc0IsQ0FBQyxXQUFXLENBQUMsRUFBRTtnQkFDbkUsTUFBTSxJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBRSxDQUFDO2dCQUNqRCxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFO29CQUNqQixRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLE9BQXNCLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztpQkFDekQ7YUFDRDtTQUNEO1FBQ0QsT0FBTyxRQUFRLENBQUM7SUFDakIsQ0FBQyxDQUFDO0FBQ0gsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUVMOzs7OztHQUtHO0FBQ0gsU0FBZ0Isd0JBQXdCLENBQUMsVUFBa0I7SUFDMUQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxQyxNQUFNLEtBQUssR0FBRyxtQkFBbUIsRUFBRSxDQUFDO0lBQ3BDLElBQUksUUFBUSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUM7SUFDaEMsS0FBSyxNQUFNLEtBQUssSUFBSSxLQUFLLEVBQUU7UUFDMUIsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLFVBQVUsRUFBRTtZQUM5QixPQUFPLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLENBQUM7U0FDNUM7YUFBTSxJQUFJLEtBQUssQ0FBQyxJQUFJLEdBQUcsVUFBVSxFQUFFO1lBQ25DLE9BQU8sRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDO1NBQ2pDO1FBQ0QsUUFBUSxHQUFHLEtBQUssQ0FBQztLQUNqQjtJQUNELE9BQU8sRUFBRSxRQUFRLEVBQUUsQ0FBQztBQUNyQixDQUFDO0FBYkQsNERBYUM7QUFFRDs7R0FFRztBQUNILFNBQWdCLDJCQUEyQixDQUFDLE1BQWM7SUFDekQsTUFBTSxLQUFLLEdBQUcsbUJBQW1CLEVBQUUsQ0FBQztJQUNwQyxNQUFNLFFBQVEsR0FBRyxNQUFNLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQztJQUN6QyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNaLElBQUksRUFBRSxHQUFHLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQzFCLE9BQU8sRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLEVBQUU7UUFDbkIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN0QyxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFDMUQsSUFBSSxNQUFNLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQyxNQUFNLElBQUksUUFBUSxFQUFFO1lBQzNDLEVBQUUsR0FBRyxHQUFHLENBQUM7U0FDVDthQUNJO1lBQ0osRUFBRSxHQUFHLEdBQUcsQ0FBQztTQUNUO0tBQ0Q7SUFDRCxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDNUIsTUFBTSxRQUFRLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO0lBQzNELElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxRQUFRLENBQUMsR0FBRyxHQUFHLFFBQVEsRUFBRTtRQUN2QyxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDNUIsT0FBTyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxDQUFDO0tBQ2hEO0lBQ0QsT0FBTyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsQ0FBQztBQUNoQyxDQUFDO0FBdEJELGtFQXNCQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0Isd0JBQXdCLENBQUMsSUFBWTtJQUNwRCxJQUFJLENBQUMsc0JBQVcsRUFBRSxDQUFDLHVCQUF1QixFQUFFO1FBQzNDLE9BQU87S0FDUDtJQUVELElBQUksSUFBSSxJQUFJLENBQUMsRUFBRTtRQUNkLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNqQyxPQUFPO0tBQ1A7SUFFRCxNQUFNLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxHQUFHLHdCQUF3QixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzFELElBQUksQ0FBQyxRQUFRLEVBQUU7UUFDZCxPQUFPO0tBQ1A7SUFDRCxJQUFJLFFBQVEsR0FBRyxDQUFDLENBQUM7SUFDakIsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO0lBQ3RELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUM7SUFDN0IsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxRQUFRLENBQUMsSUFBSSxFQUFFO1FBQ3hDLDhEQUE4RDtRQUM5RCxNQUFNLGVBQWUsR0FBRyxDQUFDLElBQUksR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3RSxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLHFCQUFxQixFQUFFLENBQUMsR0FBRyxHQUFHLFdBQVcsQ0FBQztRQUM3RSxRQUFRLEdBQUcsV0FBVyxHQUFHLGVBQWUsR0FBRyxhQUFhLENBQUM7S0FDekQ7U0FBTTtRQUNOLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbEQsUUFBUSxHQUFHLFdBQVcsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsaUJBQWlCLENBQUMsQ0FBQztLQUMzRDtJQUNELE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsT0FBTyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUM7QUFDdkUsQ0FBQztBQTNCRCw0REEyQkM7QUFFRCxTQUFnQixnQ0FBZ0MsQ0FBQyxNQUFjO0lBQzlELE1BQU0sRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLEdBQUcsMkJBQTJCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDL0QsSUFBSSxRQUFRLEVBQUU7UUFDYixNQUFNLGNBQWMsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFDaEUsTUFBTSxrQkFBa0IsR0FBRyxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsT0FBTyxHQUFHLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMxRSxJQUFJLElBQUksRUFBRTtZQUNULE1BQU0sdUJBQXVCLEdBQUcsa0JBQWtCLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLHFCQUFxQixFQUFFLENBQUMsR0FBRyxHQUFHLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNySCxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsSUFBSSxHQUFHLHVCQUF1QixHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDbkYsT0FBTyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDdkI7YUFDSTtZQUNKLE1BQU0scUJBQXFCLEdBQUcsa0JBQWtCLEdBQUcsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDM0UsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLElBQUksR0FBRyxxQkFBcUIsQ0FBQztZQUNuRCxPQUFPLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUN2QjtLQUNEO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDYixDQUFDO0FBakJELDRFQWlCQzs7Ozs7Ozs7Ozs7Ozs7QUN2SUQ7OztnR0FHZ0c7O0FBYWhHLElBQUksY0FBYyxHQUFnQyxTQUFTLENBQUM7QUFFNUQsU0FBZ0IsT0FBTyxDQUFTLEdBQVc7SUFDMUMsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO0lBQ3hFLElBQUksT0FBTyxFQUFFO1FBQ1osTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN2QyxJQUFJLElBQUksRUFBRTtZQUNULE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUN4QjtLQUNEO0lBRUQsTUFBTSxJQUFJLEtBQUssQ0FBQywyQkFBMkIsR0FBRyxFQUFFLENBQUMsQ0FBQztBQUNuRCxDQUFDO0FBVkQsMEJBVUM7QUFFRCxTQUFnQixXQUFXO0lBQzFCLElBQUksY0FBYyxFQUFFO1FBQ25CLE9BQU8sY0FBYyxDQUFDO0tBQ3RCO0lBRUQsY0FBYyxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUMxQyxJQUFJLGNBQWMsRUFBRTtRQUNuQixPQUFPLGNBQWMsQ0FBQztLQUN0QjtJQUVELE1BQU0sSUFBSSxLQUFLLENBQUMseUJBQXlCLENBQUMsQ0FBQztBQUM1QyxDQUFDO0FBWEQsa0NBV0MiLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHtcbiBcdFx0XHRcdGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gXHRcdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuIFx0XHRcdFx0Z2V0OiBnZXR0ZXJcbiBcdFx0XHR9KTtcbiBcdFx0fVxuIFx0fTtcblxuIFx0Ly8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5yID0gZnVuY3Rpb24oZXhwb3J0cykge1xuIFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuIFx0fTtcblxuIFx0Ly8gZ2V0RGVmYXVsdEV4cG9ydCBmdW5jdGlvbiBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIG5vbi1oYXJtb255IG1vZHVsZXNcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubiA9IGZ1bmN0aW9uKG1vZHVsZSkge1xuIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbiBcdFx0XHRmdW5jdGlvbiBnZXREZWZhdWx0KCkgeyByZXR1cm4gbW9kdWxlWydkZWZhdWx0J107IH0gOlxuIFx0XHRcdGZ1bmN0aW9uIGdldE1vZHVsZUV4cG9ydHMoKSB7IHJldHVybiBtb2R1bGU7IH07XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbiBcdFx0cmV0dXJuIGdldHRlcjtcbiBcdH07XG5cbiBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5vID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpOyB9O1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblxuXG4gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbiBcdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKF9fd2VicGFja19yZXF1aXJlX18ucyA9IFwiLi9wcmV2aWV3LXNyYy9pbmRleC50c1wiKTtcbiIsIi8qKlxuICogbG9kYXNoIChDdXN0b20gQnVpbGQpIDxodHRwczovL2xvZGFzaC5jb20vPlxuICogQnVpbGQ6IGBsb2Rhc2ggbW9kdWxhcml6ZSBleHBvcnRzPVwibnBtXCIgLW8gLi9gXG4gKiBDb3B5cmlnaHQgalF1ZXJ5IEZvdW5kYXRpb24gYW5kIG90aGVyIGNvbnRyaWJ1dG9ycyA8aHR0cHM6Ly9qcXVlcnkub3JnLz5cbiAqIFJlbGVhc2VkIHVuZGVyIE1JVCBsaWNlbnNlIDxodHRwczovL2xvZGFzaC5jb20vbGljZW5zZT5cbiAqIEJhc2VkIG9uIFVuZGVyc2NvcmUuanMgMS44LjMgPGh0dHA6Ly91bmRlcnNjb3JlanMub3JnL0xJQ0VOU0U+XG4gKiBDb3B5cmlnaHQgSmVyZW15IEFzaGtlbmFzLCBEb2N1bWVudENsb3VkIGFuZCBJbnZlc3RpZ2F0aXZlIFJlcG9ydGVycyAmIEVkaXRvcnNcbiAqL1xuXG4vKiogVXNlZCBhcyB0aGUgYFR5cGVFcnJvcmAgbWVzc2FnZSBmb3IgXCJGdW5jdGlvbnNcIiBtZXRob2RzLiAqL1xudmFyIEZVTkNfRVJST1JfVEVYVCA9ICdFeHBlY3RlZCBhIGZ1bmN0aW9uJztcblxuLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdmFyaW91cyBgTnVtYmVyYCBjb25zdGFudHMuICovXG52YXIgTkFOID0gMCAvIDA7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBzeW1ib2xUYWcgPSAnW29iamVjdCBTeW1ib2xdJztcblxuLyoqIFVzZWQgdG8gbWF0Y2ggbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZS4gKi9cbnZhciByZVRyaW0gPSAvXlxccyt8XFxzKyQvZztcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IGJhZCBzaWduZWQgaGV4YWRlY2ltYWwgc3RyaW5nIHZhbHVlcy4gKi9cbnZhciByZUlzQmFkSGV4ID0gL15bLStdMHhbMC05YS1mXSskL2k7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBiaW5hcnkgc3RyaW5nIHZhbHVlcy4gKi9cbnZhciByZUlzQmluYXJ5ID0gL14wYlswMV0rJC9pO1xuXG4vKiogVXNlZCB0byBkZXRlY3Qgb2N0YWwgc3RyaW5nIHZhbHVlcy4gKi9cbnZhciByZUlzT2N0YWwgPSAvXjBvWzAtN10rJC9pO1xuXG4vKiogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgd2l0aG91dCBhIGRlcGVuZGVuY3kgb24gYHJvb3RgLiAqL1xudmFyIGZyZWVQYXJzZUludCA9IHBhcnNlSW50O1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGdsb2JhbGAgZnJvbSBOb2RlLmpzLiAqL1xudmFyIGZyZWVHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsID09ICdvYmplY3QnICYmIGdsb2JhbCAmJiBnbG9iYWwuT2JqZWN0ID09PSBPYmplY3QgJiYgZ2xvYmFsO1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYHNlbGZgLiAqL1xudmFyIGZyZWVTZWxmID0gdHlwZW9mIHNlbGYgPT0gJ29iamVjdCcgJiYgc2VsZiAmJiBzZWxmLk9iamVjdCA9PT0gT2JqZWN0ICYmIHNlbGY7XG5cbi8qKiBVc2VkIGFzIGEgcmVmZXJlbmNlIHRvIHRoZSBnbG9iYWwgb2JqZWN0LiAqL1xudmFyIHJvb3QgPSBmcmVlR2xvYmFsIHx8IGZyZWVTZWxmIHx8IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZVxuICogW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmplY3RUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWF4ID0gTWF0aC5tYXgsXG4gICAgbmF0aXZlTWluID0gTWF0aC5taW47XG5cbi8qKlxuICogR2V0cyB0aGUgdGltZXN0YW1wIG9mIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRoYXQgaGF2ZSBlbGFwc2VkIHNpbmNlXG4gKiB0aGUgVW5peCBlcG9jaCAoMSBKYW51YXJ5IDE5NzAgMDA6MDA6MDAgVVRDKS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDIuNC4wXG4gKiBAY2F0ZWdvcnkgRGF0ZVxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgdGltZXN0YW1wLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmRlZmVyKGZ1bmN0aW9uKHN0YW1wKSB7XG4gKiAgIGNvbnNvbGUubG9nKF8ubm93KCkgLSBzdGFtcCk7XG4gKiB9LCBfLm5vdygpKTtcbiAqIC8vID0+IExvZ3MgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgaXQgdG9vayBmb3IgdGhlIGRlZmVycmVkIGludm9jYXRpb24uXG4gKi9cbnZhciBub3cgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHJvb3QuRGF0ZS5ub3coKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIGRlYm91bmNlZCBmdW5jdGlvbiB0aGF0IGRlbGF5cyBpbnZva2luZyBgZnVuY2AgdW50aWwgYWZ0ZXIgYHdhaXRgXG4gKiBtaWxsaXNlY29uZHMgaGF2ZSBlbGFwc2VkIHNpbmNlIHRoZSBsYXN0IHRpbWUgdGhlIGRlYm91bmNlZCBmdW5jdGlvbiB3YXNcbiAqIGludm9rZWQuIFRoZSBkZWJvdW5jZWQgZnVuY3Rpb24gY29tZXMgd2l0aCBhIGBjYW5jZWxgIG1ldGhvZCB0byBjYW5jZWxcbiAqIGRlbGF5ZWQgYGZ1bmNgIGludm9jYXRpb25zIGFuZCBhIGBmbHVzaGAgbWV0aG9kIHRvIGltbWVkaWF0ZWx5IGludm9rZSB0aGVtLlxuICogUHJvdmlkZSBgb3B0aW9uc2AgdG8gaW5kaWNhdGUgd2hldGhlciBgZnVuY2Agc2hvdWxkIGJlIGludm9rZWQgb24gdGhlXG4gKiBsZWFkaW5nIGFuZC9vciB0cmFpbGluZyBlZGdlIG9mIHRoZSBgd2FpdGAgdGltZW91dC4gVGhlIGBmdW5jYCBpcyBpbnZva2VkXG4gKiB3aXRoIHRoZSBsYXN0IGFyZ3VtZW50cyBwcm92aWRlZCB0byB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uLiBTdWJzZXF1ZW50XG4gKiBjYWxscyB0byB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uIHJldHVybiB0aGUgcmVzdWx0IG9mIHRoZSBsYXN0IGBmdW5jYFxuICogaW52b2NhdGlvbi5cbiAqXG4gKiAqKk5vdGU6KiogSWYgYGxlYWRpbmdgIGFuZCBgdHJhaWxpbmdgIG9wdGlvbnMgYXJlIGB0cnVlYCwgYGZ1bmNgIGlzXG4gKiBpbnZva2VkIG9uIHRoZSB0cmFpbGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0IG9ubHkgaWYgdGhlIGRlYm91bmNlZCBmdW5jdGlvblxuICogaXMgaW52b2tlZCBtb3JlIHRoYW4gb25jZSBkdXJpbmcgdGhlIGB3YWl0YCB0aW1lb3V0LlxuICpcbiAqIElmIGB3YWl0YCBpcyBgMGAgYW5kIGBsZWFkaW5nYCBpcyBgZmFsc2VgLCBgZnVuY2AgaW52b2NhdGlvbiBpcyBkZWZlcnJlZFxuICogdW50aWwgdG8gdGhlIG5leHQgdGljaywgc2ltaWxhciB0byBgc2V0VGltZW91dGAgd2l0aCBhIHRpbWVvdXQgb2YgYDBgLlxuICpcbiAqIFNlZSBbRGF2aWQgQ29yYmFjaG8ncyBhcnRpY2xlXShodHRwczovL2Nzcy10cmlja3MuY29tL2RlYm91bmNpbmctdGhyb3R0bGluZy1leHBsYWluZWQtZXhhbXBsZXMvKVxuICogZm9yIGRldGFpbHMgb3ZlciB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiBgXy5kZWJvdW5jZWAgYW5kIGBfLnRocm90dGxlYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRlYm91bmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IFt3YWl0PTBdIFRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIGRlbGF5LlxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zPXt9XSBUaGUgb3B0aW9ucyBvYmplY3QuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmxlYWRpbmc9ZmFsc2VdXG4gKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgbGVhZGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLm1heFdhaXRdXG4gKiAgVGhlIG1heGltdW0gdGltZSBgZnVuY2AgaXMgYWxsb3dlZCB0byBiZSBkZWxheWVkIGJlZm9yZSBpdCdzIGludm9rZWQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnRyYWlsaW5nPXRydWVdXG4gKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGRlYm91bmNlZCBmdW5jdGlvbi5cbiAqIEBleGFtcGxlXG4gKlxuICogLy8gQXZvaWQgY29zdGx5IGNhbGN1bGF0aW9ucyB3aGlsZSB0aGUgd2luZG93IHNpemUgaXMgaW4gZmx1eC5cbiAqIGpRdWVyeSh3aW5kb3cpLm9uKCdyZXNpemUnLCBfLmRlYm91bmNlKGNhbGN1bGF0ZUxheW91dCwgMTUwKSk7XG4gKlxuICogLy8gSW52b2tlIGBzZW5kTWFpbGAgd2hlbiBjbGlja2VkLCBkZWJvdW5jaW5nIHN1YnNlcXVlbnQgY2FsbHMuXG4gKiBqUXVlcnkoZWxlbWVudCkub24oJ2NsaWNrJywgXy5kZWJvdW5jZShzZW5kTWFpbCwgMzAwLCB7XG4gKiAgICdsZWFkaW5nJzogdHJ1ZSxcbiAqICAgJ3RyYWlsaW5nJzogZmFsc2VcbiAqIH0pKTtcbiAqXG4gKiAvLyBFbnN1cmUgYGJhdGNoTG9nYCBpcyBpbnZva2VkIG9uY2UgYWZ0ZXIgMSBzZWNvbmQgb2YgZGVib3VuY2VkIGNhbGxzLlxuICogdmFyIGRlYm91bmNlZCA9IF8uZGVib3VuY2UoYmF0Y2hMb2csIDI1MCwgeyAnbWF4V2FpdCc6IDEwMDAgfSk7XG4gKiB2YXIgc291cmNlID0gbmV3IEV2ZW50U291cmNlKCcvc3RyZWFtJyk7XG4gKiBqUXVlcnkoc291cmNlKS5vbignbWVzc2FnZScsIGRlYm91bmNlZCk7XG4gKlxuICogLy8gQ2FuY2VsIHRoZSB0cmFpbGluZyBkZWJvdW5jZWQgaW52b2NhdGlvbi5cbiAqIGpRdWVyeSh3aW5kb3cpLm9uKCdwb3BzdGF0ZScsIGRlYm91bmNlZC5jYW5jZWwpO1xuICovXG5mdW5jdGlvbiBkZWJvdW5jZShmdW5jLCB3YWl0LCBvcHRpb25zKSB7XG4gIHZhciBsYXN0QXJncyxcbiAgICAgIGxhc3RUaGlzLFxuICAgICAgbWF4V2FpdCxcbiAgICAgIHJlc3VsdCxcbiAgICAgIHRpbWVySWQsXG4gICAgICBsYXN0Q2FsbFRpbWUsXG4gICAgICBsYXN0SW52b2tlVGltZSA9IDAsXG4gICAgICBsZWFkaW5nID0gZmFsc2UsXG4gICAgICBtYXhpbmcgPSBmYWxzZSxcbiAgICAgIHRyYWlsaW5nID0gdHJ1ZTtcblxuICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgfVxuICB3YWl0ID0gdG9OdW1iZXIod2FpdCkgfHwgMDtcbiAgaWYgKGlzT2JqZWN0KG9wdGlvbnMpKSB7XG4gICAgbGVhZGluZyA9ICEhb3B0aW9ucy5sZWFkaW5nO1xuICAgIG1heGluZyA9ICdtYXhXYWl0JyBpbiBvcHRpb25zO1xuICAgIG1heFdhaXQgPSBtYXhpbmcgPyBuYXRpdmVNYXgodG9OdW1iZXIob3B0aW9ucy5tYXhXYWl0KSB8fCAwLCB3YWl0KSA6IG1heFdhaXQ7XG4gICAgdHJhaWxpbmcgPSAndHJhaWxpbmcnIGluIG9wdGlvbnMgPyAhIW9wdGlvbnMudHJhaWxpbmcgOiB0cmFpbGluZztcbiAgfVxuXG4gIGZ1bmN0aW9uIGludm9rZUZ1bmModGltZSkge1xuICAgIHZhciBhcmdzID0gbGFzdEFyZ3MsXG4gICAgICAgIHRoaXNBcmcgPSBsYXN0VGhpcztcblxuICAgIGxhc3RBcmdzID0gbGFzdFRoaXMgPSB1bmRlZmluZWQ7XG4gICAgbGFzdEludm9rZVRpbWUgPSB0aW1lO1xuICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkodGhpc0FyZywgYXJncyk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGxlYWRpbmdFZGdlKHRpbWUpIHtcbiAgICAvLyBSZXNldCBhbnkgYG1heFdhaXRgIHRpbWVyLlxuICAgIGxhc3RJbnZva2VUaW1lID0gdGltZTtcbiAgICAvLyBTdGFydCB0aGUgdGltZXIgZm9yIHRoZSB0cmFpbGluZyBlZGdlLlxuICAgIHRpbWVySWQgPSBzZXRUaW1lb3V0KHRpbWVyRXhwaXJlZCwgd2FpdCk7XG4gICAgLy8gSW52b2tlIHRoZSBsZWFkaW5nIGVkZ2UuXG4gICAgcmV0dXJuIGxlYWRpbmcgPyBpbnZva2VGdW5jKHRpbWUpIDogcmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gcmVtYWluaW5nV2FpdCh0aW1lKSB7XG4gICAgdmFyIHRpbWVTaW5jZUxhc3RDYWxsID0gdGltZSAtIGxhc3RDYWxsVGltZSxcbiAgICAgICAgdGltZVNpbmNlTGFzdEludm9rZSA9IHRpbWUgLSBsYXN0SW52b2tlVGltZSxcbiAgICAgICAgcmVzdWx0ID0gd2FpdCAtIHRpbWVTaW5jZUxhc3RDYWxsO1xuXG4gICAgcmV0dXJuIG1heGluZyA/IG5hdGl2ZU1pbihyZXN1bHQsIG1heFdhaXQgLSB0aW1lU2luY2VMYXN0SW52b2tlKSA6IHJlc3VsdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNob3VsZEludm9rZSh0aW1lKSB7XG4gICAgdmFyIHRpbWVTaW5jZUxhc3RDYWxsID0gdGltZSAtIGxhc3RDYWxsVGltZSxcbiAgICAgICAgdGltZVNpbmNlTGFzdEludm9rZSA9IHRpbWUgLSBsYXN0SW52b2tlVGltZTtcblxuICAgIC8vIEVpdGhlciB0aGlzIGlzIHRoZSBmaXJzdCBjYWxsLCBhY3Rpdml0eSBoYXMgc3RvcHBlZCBhbmQgd2UncmUgYXQgdGhlXG4gICAgLy8gdHJhaWxpbmcgZWRnZSwgdGhlIHN5c3RlbSB0aW1lIGhhcyBnb25lIGJhY2t3YXJkcyBhbmQgd2UncmUgdHJlYXRpbmdcbiAgICAvLyBpdCBhcyB0aGUgdHJhaWxpbmcgZWRnZSwgb3Igd2UndmUgaGl0IHRoZSBgbWF4V2FpdGAgbGltaXQuXG4gICAgcmV0dXJuIChsYXN0Q2FsbFRpbWUgPT09IHVuZGVmaW5lZCB8fCAodGltZVNpbmNlTGFzdENhbGwgPj0gd2FpdCkgfHxcbiAgICAgICh0aW1lU2luY2VMYXN0Q2FsbCA8IDApIHx8IChtYXhpbmcgJiYgdGltZVNpbmNlTGFzdEludm9rZSA+PSBtYXhXYWl0KSk7XG4gIH1cblxuICBmdW5jdGlvbiB0aW1lckV4cGlyZWQoKSB7XG4gICAgdmFyIHRpbWUgPSBub3coKTtcbiAgICBpZiAoc2hvdWxkSW52b2tlKHRpbWUpKSB7XG4gICAgICByZXR1cm4gdHJhaWxpbmdFZGdlKHRpbWUpO1xuICAgIH1cbiAgICAvLyBSZXN0YXJ0IHRoZSB0aW1lci5cbiAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHJlbWFpbmluZ1dhaXQodGltZSkpO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJhaWxpbmdFZGdlKHRpbWUpIHtcbiAgICB0aW1lcklkID0gdW5kZWZpbmVkO1xuXG4gICAgLy8gT25seSBpbnZva2UgaWYgd2UgaGF2ZSBgbGFzdEFyZ3NgIHdoaWNoIG1lYW5zIGBmdW5jYCBoYXMgYmVlblxuICAgIC8vIGRlYm91bmNlZCBhdCBsZWFzdCBvbmNlLlxuICAgIGlmICh0cmFpbGluZyAmJiBsYXN0QXJncykge1xuICAgICAgcmV0dXJuIGludm9rZUZ1bmModGltZSk7XG4gICAgfVxuICAgIGxhc3RBcmdzID0gbGFzdFRoaXMgPSB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNhbmNlbCgpIHtcbiAgICBpZiAodGltZXJJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZXJJZCk7XG4gICAgfVxuICAgIGxhc3RJbnZva2VUaW1lID0gMDtcbiAgICBsYXN0QXJncyA9IGxhc3RDYWxsVGltZSA9IGxhc3RUaGlzID0gdGltZXJJZCA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZsdXNoKCkge1xuICAgIHJldHVybiB0aW1lcklkID09PSB1bmRlZmluZWQgPyByZXN1bHQgOiB0cmFpbGluZ0VkZ2Uobm93KCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gZGVib3VuY2VkKCkge1xuICAgIHZhciB0aW1lID0gbm93KCksXG4gICAgICAgIGlzSW52b2tpbmcgPSBzaG91bGRJbnZva2UodGltZSk7XG5cbiAgICBsYXN0QXJncyA9IGFyZ3VtZW50cztcbiAgICBsYXN0VGhpcyA9IHRoaXM7XG4gICAgbGFzdENhbGxUaW1lID0gdGltZTtcblxuICAgIGlmIChpc0ludm9raW5nKSB7XG4gICAgICBpZiAodGltZXJJZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBsZWFkaW5nRWRnZShsYXN0Q2FsbFRpbWUpO1xuICAgICAgfVxuICAgICAgaWYgKG1heGluZykge1xuICAgICAgICAvLyBIYW5kbGUgaW52b2NhdGlvbnMgaW4gYSB0aWdodCBsb29wLlxuICAgICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHdhaXQpO1xuICAgICAgICByZXR1cm4gaW52b2tlRnVuYyhsYXN0Q2FsbFRpbWUpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodGltZXJJZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHdhaXQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIGRlYm91bmNlZC5jYW5jZWwgPSBjYW5jZWw7XG4gIGRlYm91bmNlZC5mbHVzaCA9IGZsdXNoO1xuICByZXR1cm4gZGVib3VuY2VkO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSB0aHJvdHRsZWQgZnVuY3Rpb24gdGhhdCBvbmx5IGludm9rZXMgYGZ1bmNgIGF0IG1vc3Qgb25jZSBwZXJcbiAqIGV2ZXJ5IGB3YWl0YCBtaWxsaXNlY29uZHMuIFRoZSB0aHJvdHRsZWQgZnVuY3Rpb24gY29tZXMgd2l0aCBhIGBjYW5jZWxgXG4gKiBtZXRob2QgdG8gY2FuY2VsIGRlbGF5ZWQgYGZ1bmNgIGludm9jYXRpb25zIGFuZCBhIGBmbHVzaGAgbWV0aG9kIHRvXG4gKiBpbW1lZGlhdGVseSBpbnZva2UgdGhlbS4gUHJvdmlkZSBgb3B0aW9uc2AgdG8gaW5kaWNhdGUgd2hldGhlciBgZnVuY2BcbiAqIHNob3VsZCBiZSBpbnZva2VkIG9uIHRoZSBsZWFkaW5nIGFuZC9vciB0cmFpbGluZyBlZGdlIG9mIHRoZSBgd2FpdGBcbiAqIHRpbWVvdXQuIFRoZSBgZnVuY2AgaXMgaW52b2tlZCB3aXRoIHRoZSBsYXN0IGFyZ3VtZW50cyBwcm92aWRlZCB0byB0aGVcbiAqIHRocm90dGxlZCBmdW5jdGlvbi4gU3Vic2VxdWVudCBjYWxscyB0byB0aGUgdGhyb3R0bGVkIGZ1bmN0aW9uIHJldHVybiB0aGVcbiAqIHJlc3VsdCBvZiB0aGUgbGFzdCBgZnVuY2AgaW52b2NhdGlvbi5cbiAqXG4gKiAqKk5vdGU6KiogSWYgYGxlYWRpbmdgIGFuZCBgdHJhaWxpbmdgIG9wdGlvbnMgYXJlIGB0cnVlYCwgYGZ1bmNgIGlzXG4gKiBpbnZva2VkIG9uIHRoZSB0cmFpbGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0IG9ubHkgaWYgdGhlIHRocm90dGxlZCBmdW5jdGlvblxuICogaXMgaW52b2tlZCBtb3JlIHRoYW4gb25jZSBkdXJpbmcgdGhlIGB3YWl0YCB0aW1lb3V0LlxuICpcbiAqIElmIGB3YWl0YCBpcyBgMGAgYW5kIGBsZWFkaW5nYCBpcyBgZmFsc2VgLCBgZnVuY2AgaW52b2NhdGlvbiBpcyBkZWZlcnJlZFxuICogdW50aWwgdG8gdGhlIG5leHQgdGljaywgc2ltaWxhciB0byBgc2V0VGltZW91dGAgd2l0aCBhIHRpbWVvdXQgb2YgYDBgLlxuICpcbiAqIFNlZSBbRGF2aWQgQ29yYmFjaG8ncyBhcnRpY2xlXShodHRwczovL2Nzcy10cmlja3MuY29tL2RlYm91bmNpbmctdGhyb3R0bGluZy1leHBsYWluZWQtZXhhbXBsZXMvKVxuICogZm9yIGRldGFpbHMgb3ZlciB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiBgXy50aHJvdHRsZWAgYW5kIGBfLmRlYm91bmNlYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHRocm90dGxlLlxuICogQHBhcmFtIHtudW1iZXJ9IFt3YWl0PTBdIFRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIHRocm90dGxlIGludm9jYXRpb25zIHRvLlxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zPXt9XSBUaGUgb3B0aW9ucyBvYmplY3QuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmxlYWRpbmc9dHJ1ZV1cbiAqICBTcGVjaWZ5IGludm9raW5nIG9uIHRoZSBsZWFkaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnRyYWlsaW5nPXRydWVdXG4gKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHRocm90dGxlZCBmdW5jdGlvbi5cbiAqIEBleGFtcGxlXG4gKlxuICogLy8gQXZvaWQgZXhjZXNzaXZlbHkgdXBkYXRpbmcgdGhlIHBvc2l0aW9uIHdoaWxlIHNjcm9sbGluZy5cbiAqIGpRdWVyeSh3aW5kb3cpLm9uKCdzY3JvbGwnLCBfLnRocm90dGxlKHVwZGF0ZVBvc2l0aW9uLCAxMDApKTtcbiAqXG4gKiAvLyBJbnZva2UgYHJlbmV3VG9rZW5gIHdoZW4gdGhlIGNsaWNrIGV2ZW50IGlzIGZpcmVkLCBidXQgbm90IG1vcmUgdGhhbiBvbmNlIGV2ZXJ5IDUgbWludXRlcy5cbiAqIHZhciB0aHJvdHRsZWQgPSBfLnRocm90dGxlKHJlbmV3VG9rZW4sIDMwMDAwMCwgeyAndHJhaWxpbmcnOiBmYWxzZSB9KTtcbiAqIGpRdWVyeShlbGVtZW50KS5vbignY2xpY2snLCB0aHJvdHRsZWQpO1xuICpcbiAqIC8vIENhbmNlbCB0aGUgdHJhaWxpbmcgdGhyb3R0bGVkIGludm9jYXRpb24uXG4gKiBqUXVlcnkod2luZG93KS5vbigncG9wc3RhdGUnLCB0aHJvdHRsZWQuY2FuY2VsKTtcbiAqL1xuZnVuY3Rpb24gdGhyb3R0bGUoZnVuYywgd2FpdCwgb3B0aW9ucykge1xuICB2YXIgbGVhZGluZyA9IHRydWUsXG4gICAgICB0cmFpbGluZyA9IHRydWU7XG5cbiAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gIH1cbiAgaWYgKGlzT2JqZWN0KG9wdGlvbnMpKSB7XG4gICAgbGVhZGluZyA9ICdsZWFkaW5nJyBpbiBvcHRpb25zID8gISFvcHRpb25zLmxlYWRpbmcgOiBsZWFkaW5nO1xuICAgIHRyYWlsaW5nID0gJ3RyYWlsaW5nJyBpbiBvcHRpb25zID8gISFvcHRpb25zLnRyYWlsaW5nIDogdHJhaWxpbmc7XG4gIH1cbiAgcmV0dXJuIGRlYm91bmNlKGZ1bmMsIHdhaXQsIHtcbiAgICAnbGVhZGluZyc6IGxlYWRpbmcsXG4gICAgJ21heFdhaXQnOiB3YWl0LFxuICAgICd0cmFpbGluZyc6IHRyYWlsaW5nXG4gIH0pO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHRoZVxuICogW2xhbmd1YWdlIHR5cGVdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1lY21hc2NyaXB0LWxhbmd1YWdlLXR5cGVzKVxuICogb2YgYE9iamVjdGAuIChlLmcuIGFycmF5cywgZnVuY3Rpb25zLCBvYmplY3RzLCByZWdleGVzLCBgbmV3IE51bWJlcigwKWAsIGFuZCBgbmV3IFN0cmluZygnJylgKVxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzT2JqZWN0KHt9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChfLm5vb3ApO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QobnVsbCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkge1xuICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgcmV0dXJuICEhdmFsdWUgJiYgKHR5cGUgPT0gJ29iamVjdCcgfHwgdHlwZSA9PSAnZnVuY3Rpb24nKTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZS4gQSB2YWx1ZSBpcyBvYmplY3QtbGlrZSBpZiBpdCdzIG5vdCBgbnVsbGBcbiAqIGFuZCBoYXMgYSBgdHlwZW9mYCByZXN1bHQgb2YgXCJvYmplY3RcIi5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZSwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZSh7fSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdExpa2UoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShfLm5vb3ApO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShudWxsKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0TGlrZSh2YWx1ZSkge1xuICByZXR1cm4gISF2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCc7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBTeW1ib2xgIHByaW1pdGl2ZSBvciBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBzeW1ib2wsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc1N5bWJvbChTeW1ib2wuaXRlcmF0b3IpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNTeW1ib2woJ2FiYycpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3ltYm9sJyB8fFxuICAgIChpc09iamVjdExpa2UodmFsdWUpICYmIG9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpID09IHN5bWJvbFRhZyk7XG59XG5cbi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIG51bWJlci5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG51bWJlci5cbiAqIEBleGFtcGxlXG4gKlxuICogXy50b051bWJlcigzLjIpO1xuICogLy8gPT4gMy4yXG4gKlxuICogXy50b051bWJlcihOdW1iZXIuTUlOX1ZBTFVFKTtcbiAqIC8vID0+IDVlLTMyNFxuICpcbiAqIF8udG9OdW1iZXIoSW5maW5pdHkpO1xuICogLy8gPT4gSW5maW5pdHlcbiAqXG4gKiBfLnRvTnVtYmVyKCczLjInKTtcbiAqIC8vID0+IDMuMlxuICovXG5mdW5jdGlvbiB0b051bWJlcih2YWx1ZSkge1xuICBpZiAodHlwZW9mIHZhbHVlID09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIGlmIChpc1N5bWJvbCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gTkFOO1xuICB9XG4gIGlmIChpc09iamVjdCh2YWx1ZSkpIHtcbiAgICB2YXIgb3RoZXIgPSB0eXBlb2YgdmFsdWUudmFsdWVPZiA9PSAnZnVuY3Rpb24nID8gdmFsdWUudmFsdWVPZigpIDogdmFsdWU7XG4gICAgdmFsdWUgPSBpc09iamVjdChvdGhlcikgPyAob3RoZXIgKyAnJykgOiBvdGhlcjtcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiArdmFsdWU7XG4gIH1cbiAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKHJlVHJpbSwgJycpO1xuICB2YXIgaXNCaW5hcnkgPSByZUlzQmluYXJ5LnRlc3QodmFsdWUpO1xuICByZXR1cm4gKGlzQmluYXJ5IHx8IHJlSXNPY3RhbC50ZXN0KHZhbHVlKSlcbiAgICA/IGZyZWVQYXJzZUludCh2YWx1ZS5zbGljZSgyKSwgaXNCaW5hcnkgPyAyIDogOClcbiAgICA6IChyZUlzQmFkSGV4LnRlc3QodmFsdWUpID8gTkFOIDogK3ZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0aHJvdHRsZTtcbiIsInZhciBnO1xyXG5cclxuLy8gVGhpcyB3b3JrcyBpbiBub24tc3RyaWN0IG1vZGVcclxuZyA9IChmdW5jdGlvbigpIHtcclxuXHRyZXR1cm4gdGhpcztcclxufSkoKTtcclxuXHJcbnRyeSB7XHJcblx0Ly8gVGhpcyB3b3JrcyBpZiBldmFsIGlzIGFsbG93ZWQgKHNlZSBDU1ApXHJcblx0ZyA9IGcgfHwgRnVuY3Rpb24oXCJyZXR1cm4gdGhpc1wiKSgpIHx8ICgxLCBldmFsKShcInRoaXNcIik7XHJcbn0gY2F0Y2ggKGUpIHtcclxuXHQvLyBUaGlzIHdvcmtzIGlmIHRoZSB3aW5kb3cgcmVmZXJlbmNlIGlzIGF2YWlsYWJsZVxyXG5cdGlmICh0eXBlb2Ygd2luZG93ID09PSBcIm9iamVjdFwiKSBnID0gd2luZG93O1xyXG59XHJcblxyXG4vLyBnIGNhbiBzdGlsbCBiZSB1bmRlZmluZWQsIGJ1dCBub3RoaW5nIHRvIGRvIGFib3V0IGl0Li4uXHJcbi8vIFdlIHJldHVybiB1bmRlZmluZWQsIGluc3RlYWQgb2Ygbm90aGluZyBoZXJlLCBzbyBpdCdzXHJcbi8vIGVhc2llciB0byBoYW5kbGUgdGhpcyBjYXNlLiBpZighZ2xvYmFsKSB7IC4uLn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZztcclxuIiwiLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqICBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqICBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxuICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5pbXBvcnQgeyBnZXRFbGVtZW50c0ZvclNvdXJjZUxpbmUgfSBmcm9tICcuL3Njcm9sbC1zeW5jJztcblxuZXhwb3J0IGNsYXNzIEFjdGl2ZUxpbmVNYXJrZXIge1xuXHRwcml2YXRlIF9jdXJyZW50OiBhbnk7XG5cblx0b25EaWRDaGFuZ2VUZXh0RWRpdG9yU2VsZWN0aW9uKGxpbmU6IG51bWJlcikge1xuXHRcdGNvbnN0IHsgcHJldmlvdXMgfSA9IGdldEVsZW1lbnRzRm9yU291cmNlTGluZShsaW5lKTtcblx0XHR0aGlzLl91cGRhdGUocHJldmlvdXMgJiYgcHJldmlvdXMuZWxlbWVudCk7XG5cdH1cblxuXHRfdXBkYXRlKGJlZm9yZTogSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQpIHtcblx0XHR0aGlzLl91bm1hcmtBY3RpdmVFbGVtZW50KHRoaXMuX2N1cnJlbnQpO1xuXHRcdHRoaXMuX21hcmtBY3RpdmVFbGVtZW50KGJlZm9yZSk7XG5cdFx0dGhpcy5fY3VycmVudCA9IGJlZm9yZTtcblx0fVxuXG5cdF91bm1hcmtBY3RpdmVFbGVtZW50KGVsZW1lbnQ6IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkKSB7XG5cdFx0aWYgKCFlbGVtZW50KSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGVsZW1lbnQuY2xhc3NOYW1lID0gZWxlbWVudC5jbGFzc05hbWUucmVwbGFjZSgvXFxiY29kZS1hY3RpdmUtbGluZVxcYi9nLCAnJyk7XG5cdH1cblxuXHRfbWFya0FjdGl2ZUVsZW1lbnQoZWxlbWVudDogSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQpIHtcblx0XHRpZiAoIWVsZW1lbnQpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0ZWxlbWVudC5jbGFzc05hbWUgKz0gJyBjb2RlLWFjdGl2ZS1saW5lJztcblx0fVxufSIsIi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiAgQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiAgTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLiBTZWUgTGljZW5zZS50eHQgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cbiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5leHBvcnQgZnVuY3Rpb24gb25jZURvY3VtZW50TG9hZGVkKGY6ICgpID0+IHZvaWQpIHtcblx0aWYgKGRvY3VtZW50LnJlYWR5U3RhdGUgPT09ICdsb2FkaW5nJyB8fCBkb2N1bWVudC5yZWFkeVN0YXRlIGFzIHN0cmluZyA9PT0gJ3VuaW5pdGlhbGl6ZWQnKSB7XG5cdFx0ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsIGYpO1xuXHR9IGVsc2Uge1xuXHRcdGYoKTtcblx0fVxufSIsIi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiAgQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiAgTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLiBTZWUgTGljZW5zZS50eHQgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cbiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5pbXBvcnQgeyBBY3RpdmVMaW5lTWFya2VyIH0gZnJvbSAnLi9hY3RpdmVMaW5lTWFya2VyJztcbmltcG9ydCB7IG9uY2VEb2N1bWVudExvYWRlZCB9IGZyb20gJy4vZXZlbnRzJztcbmltcG9ydCB7IGNyZWF0ZVBvc3RlckZvclZzQ29kZSB9IGZyb20gJy4vbWVzc2FnaW5nJztcbmltcG9ydCB7IGdldEVkaXRvckxpbmVOdW1iZXJGb3JQYWdlT2Zmc2V0LCBzY3JvbGxUb1JldmVhbFNvdXJjZUxpbmUgfSBmcm9tICcuL3Njcm9sbC1zeW5jJztcbmltcG9ydCB7IGdldFNldHRpbmdzLCBnZXREYXRhIH0gZnJvbSAnLi9zZXR0aW5ncyc7XG5pbXBvcnQgdGhyb3R0bGUgPSByZXF1aXJlKCdsb2Rhc2gudGhyb3R0bGUnKTtcblxuZGVjbGFyZSB2YXIgYWNxdWlyZVZzQ29kZUFwaTogYW55O1xuXG5sZXQgc2Nyb2xsRGlzYWJsZWQgPSB0cnVlO1xuY29uc3QgbWFya2VyID0gbmV3IEFjdGl2ZUxpbmVNYXJrZXIoKTtcbmNvbnN0IHNldHRpbmdzID0gZ2V0U2V0dGluZ3MoKTtcblxuY29uc3QgdnNjb2RlID0gYWNxdWlyZVZzQ29kZUFwaSgpO1xuXG4vLyBTZXQgVlMgQ29kZSBzdGF0ZVxubGV0IHN0YXRlID0gZ2V0RGF0YTx7IGxpbmU6IG51bWJlciB9PignZGF0YS1zdGF0ZScpO1xudnNjb2RlLnNldFN0YXRlKHN0YXRlKTtcblxuY29uc3QgbWVzc2FnaW5nID0gY3JlYXRlUG9zdGVyRm9yVnNDb2RlKHZzY29kZSk7XG5cbndpbmRvdy5jc3BBbGVydGVyLnNldFBvc3RlcihtZXNzYWdpbmcpO1xud2luZG93LnN0eWxlTG9hZGluZ01vbml0b3Iuc2V0UG9zdGVyKG1lc3NhZ2luZyk7XG5cbndpbmRvdy5vbmxvYWQgPSAoKSA9PiB7XG5cdHVwZGF0ZUltYWdlU2l6ZXMoKTtcbn07XG5cbm9uY2VEb2N1bWVudExvYWRlZCgoKSA9PiB7XG5cdGlmIChzZXR0aW5ncy5zY3JvbGxQcmV2aWV3V2l0aEVkaXRvcikge1xuXHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0Y29uc3QgaW5pdGlhbExpbmUgPSArc2V0dGluZ3MubGluZTtcblx0XHRcdGlmICghaXNOYU4oaW5pdGlhbExpbmUpKSB7XG5cdFx0XHRcdHNjcm9sbERpc2FibGVkID0gdHJ1ZTtcblx0XHRcdFx0c2Nyb2xsVG9SZXZlYWxTb3VyY2VMaW5lKGluaXRpYWxMaW5lKTtcblx0XHRcdH1cblx0XHR9LCAwKTtcblx0fVxufSk7XG5cbmNvbnN0IG9uVXBkYXRlVmlldyA9ICgoKSA9PiB7XG5cdGNvbnN0IGRvU2Nyb2xsID0gdGhyb3R0bGUoKGxpbmU6IG51bWJlcikgPT4ge1xuXHRcdHNjcm9sbERpc2FibGVkID0gdHJ1ZTtcblx0XHRzY3JvbGxUb1JldmVhbFNvdXJjZUxpbmUobGluZSk7XG5cdH0sIDUwKTtcblxuXHRyZXR1cm4gKGxpbmU6IG51bWJlciwgc2V0dGluZ3M6IGFueSkgPT4ge1xuXHRcdGlmICghaXNOYU4obGluZSkpIHtcblx0XHRcdHNldHRpbmdzLmxpbmUgPSBsaW5lO1xuXHRcdFx0ZG9TY3JvbGwobGluZSk7XG5cdFx0fVxuXHR9O1xufSkoKTtcblxubGV0IHVwZGF0ZUltYWdlU2l6ZXMgPSB0aHJvdHRsZSgoKSA9PiB7XG5cdGNvbnN0IGltYWdlSW5mbzogeyBpZDogc3RyaW5nLCBoZWlnaHQ6IG51bWJlciwgd2lkdGg6IG51bWJlciB9W10gPSBbXTtcblx0bGV0IGltYWdlcyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdpbWcnKTtcblx0aWYgKGltYWdlcykge1xuXHRcdGxldCBpO1xuXHRcdGZvciAoaSA9IDA7IGkgPCBpbWFnZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGNvbnN0IGltZyA9IGltYWdlc1tpXTtcblxuXHRcdFx0aWYgKGltZy5jbGFzc0xpc3QuY29udGFpbnMoJ2xvYWRpbmcnKSkge1xuXHRcdFx0XHRpbWcuY2xhc3NMaXN0LnJlbW92ZSgnbG9hZGluZycpO1xuXHRcdFx0fVxuXG5cdFx0XHRpbWFnZUluZm8ucHVzaCh7XG5cdFx0XHRcdGlkOiBpbWcuaWQsXG5cdFx0XHRcdGhlaWdodDogaW1nLmhlaWdodCxcblx0XHRcdFx0d2lkdGg6IGltZy53aWR0aFxuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0bWVzc2FnaW5nLnBvc3RNZXNzYWdlKCdjYWNoZUltYWdlU2l6ZXMnLCBpbWFnZUluZm8pO1xuXHR9XG59LCA1MCk7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCAoKSA9PiB7XG5cdHNjcm9sbERpc2FibGVkID0gdHJ1ZTtcblx0dXBkYXRlSW1hZ2VTaXplcygpO1xufSwgdHJ1ZSk7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZXZlbnQgPT4ge1xuXHRpZiAoZXZlbnQuZGF0YS5zb3VyY2UgIT09IHNldHRpbmdzLnNvdXJjZSkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdHN3aXRjaCAoZXZlbnQuZGF0YS50eXBlKSB7XG5cdFx0Y2FzZSAnb25EaWRDaGFuZ2VUZXh0RWRpdG9yU2VsZWN0aW9uJzpcblx0XHRcdG1hcmtlci5vbkRpZENoYW5nZVRleHRFZGl0b3JTZWxlY3Rpb24oZXZlbnQuZGF0YS5saW5lKTtcblx0XHRcdGJyZWFrO1xuXG5cdFx0Y2FzZSAndXBkYXRlVmlldyc6XG5cdFx0XHRvblVwZGF0ZVZpZXcoZXZlbnQuZGF0YS5saW5lLCBzZXR0aW5ncyk7XG5cdFx0XHRicmVhaztcblx0fVxufSwgZmFsc2UpO1xuXG5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdkYmxjbGljaycsIGV2ZW50ID0+IHtcblx0aWYgKCFzZXR0aW5ncy5kb3VibGVDbGlja1RvU3dpdGNoVG9FZGl0b3IpIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHQvLyBJZ25vcmUgY2xpY2tzIG9uIGxpbmtzXG5cdGZvciAobGV0IG5vZGUgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7IG5vZGU7IG5vZGUgPSBub2RlLnBhcmVudE5vZGUgYXMgSFRNTEVsZW1lbnQpIHtcblx0XHRpZiAobm9kZS50YWdOYW1lID09PSAnQScpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdH1cblxuXHRjb25zdCBvZmZzZXQgPSBldmVudC5wYWdlWTtcblx0Y29uc3QgbGluZSA9IGdldEVkaXRvckxpbmVOdW1iZXJGb3JQYWdlT2Zmc2V0KG9mZnNldCk7XG5cdGlmICh0eXBlb2YgbGluZSA9PT0gJ251bWJlcicgJiYgIWlzTmFOKGxpbmUpKSB7XG5cdFx0bWVzc2FnaW5nLnBvc3RNZXNzYWdlKCdkaWRDbGljaycsIHsgbGluZTogTWF0aC5mbG9vcihsaW5lKSB9KTtcblx0fVxufSk7XG5cbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZXZlbnQgPT4ge1xuXHRpZiAoIWV2ZW50KSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0bGV0IG5vZGU6IGFueSA9IGV2ZW50LnRhcmdldDtcblx0d2hpbGUgKG5vZGUpIHtcblx0XHRpZiAobm9kZS50YWdOYW1lICYmIG5vZGUudGFnTmFtZSA9PT0gJ0EnICYmIG5vZGUuaHJlZikge1xuXHRcdFx0aWYgKG5vZGUuZ2V0QXR0cmlidXRlKCdocmVmJykuc3RhcnRzV2l0aCgnIycpKSB7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0aWYgKG5vZGUuaHJlZi5zdGFydHNXaXRoKCdmaWxlOi8vJykgfHwgbm9kZS5ocmVmLnN0YXJ0c1dpdGgoJ3ZzY29kZS1yZXNvdXJjZTonKSB8fCBub2RlLmhyZWYuc3RhcnRzV2l0aChzZXR0aW5ncy53ZWJ2aWV3UmVzb3VyY2VSb290KSkge1xuXHRcdFx0XHRjb25zdCBbcGF0aCwgZnJhZ21lbnRdID0gbm9kZS5ocmVmLnJlcGxhY2UoL14oZmlsZTpcXC9cXC98dnNjb2RlLXJlc291cmNlOikvaSwgJycpLnJlcGxhY2UobmV3IFJlZ0V4cChgXiR7ZXNjYXBlUmVnRXhwKHNldHRpbmdzLndlYnZpZXdSZXNvdXJjZVJvb3QpfWApKS5zcGxpdCgnIycpO1xuXHRcdFx0XHRtZXNzYWdpbmcucG9zdE1lc3NhZ2UoJ2NsaWNrTGluaycsIHsgcGF0aCwgZnJhZ21lbnQgfSk7XG5cdFx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdGJyZWFrO1xuXHRcdH1cblx0XHRub2RlID0gbm9kZS5wYXJlbnROb2RlO1xuXHR9XG59LCB0cnVlKTtcblxuaWYgKHNldHRpbmdzLnNjcm9sbEVkaXRvcldpdGhQcmV2aWV3KSB7XG5cdHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCB0aHJvdHRsZSgoKSA9PiB7XG5cdFx0aWYgKHNjcm9sbERpc2FibGVkKSB7XG5cdFx0XHRzY3JvbGxEaXNhYmxlZCA9IGZhbHNlO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb25zdCBsaW5lID0gZ2V0RWRpdG9yTGluZU51bWJlckZvclBhZ2VPZmZzZXQod2luZG93LnNjcm9sbFkpO1xuXHRcdFx0aWYgKHR5cGVvZiBsaW5lID09PSAnbnVtYmVyJyAmJiAhaXNOYU4obGluZSkpIHtcblx0XHRcdFx0bWVzc2FnaW5nLnBvc3RNZXNzYWdlKCdyZXZlYWxMaW5lJywgeyBsaW5lIH0pO1xuXHRcdFx0XHRzdGF0ZS5saW5lID0gbGluZTtcblx0XHRcdFx0dnNjb2RlLnNldFN0YXRlKHN0YXRlKTtcblx0XHRcdH1cblx0XHR9XG5cdH0sIDUwKSk7XG59XG5cbmZ1bmN0aW9uIGVzY2FwZVJlZ0V4cCh0ZXh0OiBzdHJpbmcpIHtcblx0cmV0dXJuIHRleHQucmVwbGFjZSgvWy1bXFxde30oKSorPy4sXFxcXF4kfCNcXHNdL2csICdcXFxcJCYnKTtcbn0iLCIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXG4gKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuaW1wb3J0IHsgZ2V0U2V0dGluZ3MgfSBmcm9tICcuL3NldHRpbmdzJztcblxuZXhwb3J0IGludGVyZmFjZSBNZXNzYWdlUG9zdGVyIHtcblx0LyoqXG5cdCAqIFBvc3QgYSBtZXNzYWdlIHRvIHRoZSBtYXJrZG93biBleHRlbnNpb25cblx0ICovXG5cdHBvc3RNZXNzYWdlKHR5cGU6IHN0cmluZywgYm9keTogb2JqZWN0KTogdm9pZDtcbn1cblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVBvc3RlckZvclZzQ29kZSA9ICh2c2NvZGU6IGFueSkgPT4ge1xuXHRyZXR1cm4gbmV3IGNsYXNzIGltcGxlbWVudHMgTWVzc2FnZVBvc3RlciB7XG5cdFx0cG9zdE1lc3NhZ2UodHlwZTogc3RyaW5nLCBib2R5OiBvYmplY3QpOiB2b2lkIHtcblx0XHRcdHZzY29kZS5wb3N0TWVzc2FnZSh7XG5cdFx0XHRcdHR5cGUsXG5cdFx0XHRcdHNvdXJjZTogZ2V0U2V0dGluZ3MoKS5zb3VyY2UsXG5cdFx0XHRcdGJvZHlcblx0XHRcdH0pO1xuXHRcdH1cblx0fTtcbn07XG5cbiIsIi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiAgQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiAgTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLiBTZWUgTGljZW5zZS50eHQgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cbiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5pbXBvcnQgeyBnZXRTZXR0aW5ncyB9IGZyb20gJy4vc2V0dGluZ3MnO1xuXG5cbmZ1bmN0aW9uIGNsYW1wKG1pbjogbnVtYmVyLCBtYXg6IG51bWJlciwgdmFsdWU6IG51bWJlcikge1xuXHRyZXR1cm4gTWF0aC5taW4obWF4LCBNYXRoLm1heChtaW4sIHZhbHVlKSk7XG59XG5cbmZ1bmN0aW9uIGNsYW1wTGluZShsaW5lOiBudW1iZXIpIHtcblx0cmV0dXJuIGNsYW1wKDAsIGdldFNldHRpbmdzKCkubGluZUNvdW50IC0gMSwgbGluZSk7XG59XG5cblxuZXhwb3J0IGludGVyZmFjZSBDb2RlTGluZUVsZW1lbnQge1xuXHRlbGVtZW50OiBIVE1MRWxlbWVudDtcblx0bGluZTogbnVtYmVyO1xufVxuXG5jb25zdCBnZXRDb2RlTGluZUVsZW1lbnRzID0gKCgpID0+IHtcblx0bGV0IGVsZW1lbnRzOiBDb2RlTGluZUVsZW1lbnRbXTtcblx0cmV0dXJuICgpID0+IHtcblx0XHRpZiAoIWVsZW1lbnRzKSB7XG5cdFx0XHRlbGVtZW50cyA9IFt7IGVsZW1lbnQ6IGRvY3VtZW50LmJvZHksIGxpbmU6IDAgfV07XG5cdFx0XHRmb3IgKGNvbnN0IGVsZW1lbnQgb2YgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnY29kZS1saW5lJykpIHtcblx0XHRcdFx0Y29uc3QgbGluZSA9ICtlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1saW5lJykhO1xuXHRcdFx0XHRpZiAoIWlzTmFOKGxpbmUpKSB7XG5cdFx0XHRcdFx0ZWxlbWVudHMucHVzaCh7IGVsZW1lbnQ6IGVsZW1lbnQgYXMgSFRNTEVsZW1lbnQsIGxpbmUgfSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGVsZW1lbnRzO1xuXHR9O1xufSkoKTtcblxuLyoqXG4gKiBGaW5kIHRoZSBodG1sIGVsZW1lbnRzIHRoYXQgbWFwIHRvIGEgc3BlY2lmaWMgdGFyZ2V0IGxpbmUgaW4gdGhlIGVkaXRvci5cbiAqXG4gKiBJZiBhbiBleGFjdCBtYXRjaCwgcmV0dXJucyBhIHNpbmdsZSBlbGVtZW50LiBJZiB0aGUgbGluZSBpcyBiZXR3ZWVuIGVsZW1lbnRzLFxuICogcmV0dXJucyB0aGUgZWxlbWVudCBwcmlvciB0byBhbmQgdGhlIGVsZW1lbnQgYWZ0ZXIgdGhlIGdpdmVuIGxpbmUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRFbGVtZW50c0ZvclNvdXJjZUxpbmUodGFyZ2V0TGluZTogbnVtYmVyKTogeyBwcmV2aW91czogQ29kZUxpbmVFbGVtZW50OyBuZXh0PzogQ29kZUxpbmVFbGVtZW50OyB9IHtcblx0Y29uc3QgbGluZU51bWJlciA9IE1hdGguZmxvb3IodGFyZ2V0TGluZSk7XG5cdGNvbnN0IGxpbmVzID0gZ2V0Q29kZUxpbmVFbGVtZW50cygpO1xuXHRsZXQgcHJldmlvdXMgPSBsaW5lc1swXSB8fCBudWxsO1xuXHRmb3IgKGNvbnN0IGVudHJ5IG9mIGxpbmVzKSB7XG5cdFx0aWYgKGVudHJ5LmxpbmUgPT09IGxpbmVOdW1iZXIpIHtcblx0XHRcdHJldHVybiB7IHByZXZpb3VzOiBlbnRyeSwgbmV4dDogdW5kZWZpbmVkIH07XG5cdFx0fSBlbHNlIGlmIChlbnRyeS5saW5lID4gbGluZU51bWJlcikge1xuXHRcdFx0cmV0dXJuIHsgcHJldmlvdXMsIG5leHQ6IGVudHJ5IH07XG5cdFx0fVxuXHRcdHByZXZpb3VzID0gZW50cnk7XG5cdH1cblx0cmV0dXJuIHsgcHJldmlvdXMgfTtcbn1cblxuLyoqXG4gKiBGaW5kIHRoZSBodG1sIGVsZW1lbnRzIHRoYXQgYXJlIGF0IGEgc3BlY2lmaWMgcGl4ZWwgb2Zmc2V0IG9uIHRoZSBwYWdlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TGluZUVsZW1lbnRzQXRQYWdlT2Zmc2V0KG9mZnNldDogbnVtYmVyKTogeyBwcmV2aW91czogQ29kZUxpbmVFbGVtZW50OyBuZXh0PzogQ29kZUxpbmVFbGVtZW50OyB9IHtcblx0Y29uc3QgbGluZXMgPSBnZXRDb2RlTGluZUVsZW1lbnRzKCk7XG5cdGNvbnN0IHBvc2l0aW9uID0gb2Zmc2V0IC0gd2luZG93LnNjcm9sbFk7XG5cdGxldCBsbyA9IC0xO1xuXHRsZXQgaGkgPSBsaW5lcy5sZW5ndGggLSAxO1xuXHR3aGlsZSAobG8gKyAxIDwgaGkpIHtcblx0XHRjb25zdCBtaWQgPSBNYXRoLmZsb29yKChsbyArIGhpKSAvIDIpO1xuXHRcdGNvbnN0IGJvdW5kcyA9IGxpbmVzW21pZF0uZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblx0XHRpZiAoYm91bmRzLnRvcCArIGJvdW5kcy5oZWlnaHQgPj0gcG9zaXRpb24pIHtcblx0XHRcdGhpID0gbWlkO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdGxvID0gbWlkO1xuXHRcdH1cblx0fVxuXHRjb25zdCBoaUVsZW1lbnQgPSBsaW5lc1toaV07XG5cdGNvbnN0IGhpQm91bmRzID0gaGlFbGVtZW50LmVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cdGlmIChoaSA+PSAxICYmIGhpQm91bmRzLnRvcCA+IHBvc2l0aW9uKSB7XG5cdFx0Y29uc3QgbG9FbGVtZW50ID0gbGluZXNbbG9dO1xuXHRcdHJldHVybiB7IHByZXZpb3VzOiBsb0VsZW1lbnQsIG5leHQ6IGhpRWxlbWVudCB9O1xuXHR9XG5cdHJldHVybiB7IHByZXZpb3VzOiBoaUVsZW1lbnQgfTtcbn1cblxuLyoqXG4gKiBBdHRlbXB0IHRvIHJldmVhbCB0aGUgZWxlbWVudCBmb3IgYSBzb3VyY2UgbGluZSBpbiB0aGUgZWRpdG9yLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsVG9SZXZlYWxTb3VyY2VMaW5lKGxpbmU6IG51bWJlcikge1xuXHRpZiAoIWdldFNldHRpbmdzKCkuc2Nyb2xsUHJldmlld1dpdGhFZGl0b3IpIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHRpZiAobGluZSA8PSAwKSB7XG5cdFx0d2luZG93LnNjcm9sbCh3aW5kb3cuc2Nyb2xsWCwgMCk7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0Y29uc3QgeyBwcmV2aW91cywgbmV4dCB9ID0gZ2V0RWxlbWVudHNGb3JTb3VyY2VMaW5lKGxpbmUpO1xuXHRpZiAoIXByZXZpb3VzKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cdGxldCBzY3JvbGxUbyA9IDA7XG5cdGNvbnN0IHJlY3QgPSBwcmV2aW91cy5lbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXHRjb25zdCBwcmV2aW91c1RvcCA9IHJlY3QudG9wO1xuXHRpZiAobmV4dCAmJiBuZXh0LmxpbmUgIT09IHByZXZpb3VzLmxpbmUpIHtcblx0XHQvLyBCZXR3ZWVuIHR3byBlbGVtZW50cy4gR28gdG8gcGVyY2VudGFnZSBvZmZzZXQgYmV0d2VlbiB0aGVtLlxuXHRcdGNvbnN0IGJldHdlZW5Qcm9ncmVzcyA9IChsaW5lIC0gcHJldmlvdXMubGluZSkgLyAobmV4dC5saW5lIC0gcHJldmlvdXMubGluZSk7XG5cdFx0Y29uc3QgZWxlbWVudE9mZnNldCA9IG5leHQuZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS50b3AgLSBwcmV2aW91c1RvcDtcblx0XHRzY3JvbGxUbyA9IHByZXZpb3VzVG9wICsgYmV0d2VlblByb2dyZXNzICogZWxlbWVudE9mZnNldDtcblx0fSBlbHNlIHtcblx0XHRjb25zdCBwcm9ncmVzc0luRWxlbWVudCA9IGxpbmUgLSBNYXRoLmZsb29yKGxpbmUpO1xuXHRcdHNjcm9sbFRvID0gcHJldmlvdXNUb3AgKyAocmVjdC5oZWlnaHQgKiBwcm9ncmVzc0luRWxlbWVudCk7XG5cdH1cblx0d2luZG93LnNjcm9sbCh3aW5kb3cuc2Nyb2xsWCwgTWF0aC5tYXgoMSwgd2luZG93LnNjcm9sbFkgKyBzY3JvbGxUbykpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RWRpdG9yTGluZU51bWJlckZvclBhZ2VPZmZzZXQob2Zmc2V0OiBudW1iZXIpIHtcblx0Y29uc3QgeyBwcmV2aW91cywgbmV4dCB9ID0gZ2V0TGluZUVsZW1lbnRzQXRQYWdlT2Zmc2V0KG9mZnNldCk7XG5cdGlmIChwcmV2aW91cykge1xuXHRcdGNvbnN0IHByZXZpb3VzQm91bmRzID0gcHJldmlvdXMuZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblx0XHRjb25zdCBvZmZzZXRGcm9tUHJldmlvdXMgPSAob2Zmc2V0IC0gd2luZG93LnNjcm9sbFkgLSBwcmV2aW91c0JvdW5kcy50b3ApO1xuXHRcdGlmIChuZXh0KSB7XG5cdFx0XHRjb25zdCBwcm9ncmVzc0JldHdlZW5FbGVtZW50cyA9IG9mZnNldEZyb21QcmV2aW91cyAvIChuZXh0LmVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wIC0gcHJldmlvdXNCb3VuZHMudG9wKTtcblx0XHRcdGNvbnN0IGxpbmUgPSBwcmV2aW91cy5saW5lICsgcHJvZ3Jlc3NCZXR3ZWVuRWxlbWVudHMgKiAobmV4dC5saW5lIC0gcHJldmlvdXMubGluZSk7XG5cdFx0XHRyZXR1cm4gY2xhbXBMaW5lKGxpbmUpO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdGNvbnN0IHByb2dyZXNzV2l0aGluRWxlbWVudCA9IG9mZnNldEZyb21QcmV2aW91cyAvIChwcmV2aW91c0JvdW5kcy5oZWlnaHQpO1xuXHRcdFx0Y29uc3QgbGluZSA9IHByZXZpb3VzLmxpbmUgKyBwcm9ncmVzc1dpdGhpbkVsZW1lbnQ7XG5cdFx0XHRyZXR1cm4gY2xhbXBMaW5lKGxpbmUpO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gbnVsbDtcbn1cbiIsIi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiAgQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiAgTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLiBTZWUgTGljZW5zZS50eHQgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cbiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5leHBvcnQgaW50ZXJmYWNlIFByZXZpZXdTZXR0aW5ncyB7XG5cdHJlYWRvbmx5IHNvdXJjZTogc3RyaW5nO1xuXHRyZWFkb25seSBsaW5lOiBudW1iZXI7XG5cdHJlYWRvbmx5IGxpbmVDb3VudDogbnVtYmVyO1xuXHRyZWFkb25seSBzY3JvbGxQcmV2aWV3V2l0aEVkaXRvcj86IGJvb2xlYW47XG5cdHJlYWRvbmx5IHNjcm9sbEVkaXRvcldpdGhQcmV2aWV3OiBib29sZWFuO1xuXHRyZWFkb25seSBkaXNhYmxlU2VjdXJpdHlXYXJuaW5nczogYm9vbGVhbjtcblx0cmVhZG9ubHkgZG91YmxlQ2xpY2tUb1N3aXRjaFRvRWRpdG9yOiBib29sZWFuO1xuXHRyZWFkb25seSB3ZWJ2aWV3UmVzb3VyY2VSb290OiBzdHJpbmc7XG59XG5cbmxldCBjYWNoZWRTZXR0aW5nczogUHJldmlld1NldHRpbmdzIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGF0YTxUID0ge30+KGtleTogc3RyaW5nKTogVCB7XG5cdGNvbnN0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndnNjb2RlLW1hcmtkb3duLXByZXZpZXctZGF0YScpO1xuXHRpZiAoZWxlbWVudCkge1xuXHRcdGNvbnN0IGRhdGEgPSBlbGVtZW50LmdldEF0dHJpYnV0ZShrZXkpO1xuXHRcdGlmIChkYXRhKSB7XG5cdFx0XHRyZXR1cm4gSlNPTi5wYXJzZShkYXRhKTtcblx0XHR9XG5cdH1cblxuXHR0aHJvdyBuZXcgRXJyb3IoYENvdWxkIG5vdCBsb2FkIGRhdGEgZm9yICR7a2V5fWApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2V0dGluZ3MoKTogUHJldmlld1NldHRpbmdzIHtcblx0aWYgKGNhY2hlZFNldHRpbmdzKSB7XG5cdFx0cmV0dXJuIGNhY2hlZFNldHRpbmdzO1xuXHR9XG5cblx0Y2FjaGVkU2V0dGluZ3MgPSBnZXREYXRhKCdkYXRhLXNldHRpbmdzJyk7XG5cdGlmIChjYWNoZWRTZXR0aW5ncykge1xuXHRcdHJldHVybiBjYWNoZWRTZXR0aW5ncztcblx0fVxuXG5cdHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IGxvYWQgc2V0dGluZ3MnKTtcbn1cbiJdLCJzb3VyY2VSb290IjoiIn0= \ No newline at end of file +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2xvZGFzaC50aHJvdHRsZS9pbmRleC5qcyIsIndlYnBhY2s6Ly8vKHdlYnBhY2spL2J1aWxkaW4vZ2xvYmFsLmpzIiwid2VicGFjazovLy8uL3ByZXZpZXctc3JjL2FjdGl2ZUxpbmVNYXJrZXIudHMiLCJ3ZWJwYWNrOi8vLy4vcHJldmlldy1zcmMvZXZlbnRzLnRzIiwid2VicGFjazovLy8uL3ByZXZpZXctc3JjL2luZGV4LnRzIiwid2VicGFjazovLy8uL3ByZXZpZXctc3JjL21lc3NhZ2luZy50cyIsIndlYnBhY2s6Ly8vLi9wcmV2aWV3LXNyYy9zY3JvbGwtc3luYy50cyIsIndlYnBhY2s6Ly8vLi9wcmV2aWV3LXNyYy9zZXR0aW5ncy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQSx5REFBaUQsY0FBYztBQUMvRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBMkIsMEJBQTBCLEVBQUU7QUFDdkQseUNBQWlDLGVBQWU7QUFDaEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOERBQXNELCtEQUErRDs7QUFFckg7QUFDQTs7O0FBR0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxPQUFPO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFNBQVM7QUFDcEIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTyxZQUFZO0FBQzlCLFdBQVcsUUFBUTtBQUNuQjtBQUNBLFdBQVcsT0FBTztBQUNsQjtBQUNBLFdBQVcsUUFBUTtBQUNuQjtBQUNBLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLDhDQUE4QyxrQkFBa0I7QUFDaEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFNBQVM7QUFDcEIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTyxZQUFZO0FBQzlCLFdBQVcsUUFBUTtBQUNuQjtBQUNBLFdBQVcsUUFBUTtBQUNuQjtBQUNBLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtREFBbUQsb0JBQW9CO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLEVBQUU7QUFDYixhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsRUFBRTtBQUNiLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0Esb0JBQW9CO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLEVBQUU7QUFDYixhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxFQUFFO0FBQ2IsYUFBYSxPQUFPO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7Ozs7Ozs7Ozs7O0FDdGJBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsNENBQTRDOztBQUU1Qzs7Ozs7Ozs7Ozs7Ozs7O0FDbkJBOzs7Z0dBR2dHO0FBQ2hHLCtGQUF5RDtBQUV6RCxNQUFhLGdCQUFnQjtJQUc1Qiw4QkFBOEIsQ0FBQyxJQUFZO1FBQzFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsR0FBRyxzQ0FBd0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwRCxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVELE9BQU8sQ0FBQyxNQUErQjtRQUN0QyxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQztJQUN4QixDQUFDO0lBRUQsb0JBQW9CLENBQUMsT0FBZ0M7UUFDcEQsSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNiLE9BQU87U0FDUDtRQUNELE9BQU8sQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsdUJBQXVCLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDNUUsQ0FBQztJQUVELGtCQUFrQixDQUFDLE9BQWdDO1FBQ2xELElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDYixPQUFPO1NBQ1A7UUFDRCxPQUFPLENBQUMsU0FBUyxJQUFJLG1CQUFtQixDQUFDO0lBQzFDLENBQUM7Q0FDRDtBQTNCRCw0Q0EyQkM7Ozs7Ozs7Ozs7Ozs7O0FDakNEOzs7Z0dBR2dHOztBQUVoRyxTQUFnQixrQkFBa0IsQ0FBQyxDQUFhO0lBQy9DLElBQUksUUFBUSxDQUFDLFVBQVUsS0FBSyxTQUFTLElBQUksUUFBUSxDQUFDLFVBQW9CLEtBQUssZUFBZSxFQUFFO1FBQzNGLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBQUMsQ0FBQztLQUNqRDtTQUFNO1FBQ04sQ0FBQyxFQUFFLENBQUM7S0FDSjtBQUNGLENBQUM7QUFORCxnREFNQzs7Ozs7Ozs7Ozs7Ozs7QUNYRDs7O2dHQUdnRzs7QUFFaEcsOEdBQXNEO0FBQ3RELGdGQUE4QztBQUM5Qyx5RkFBb0Q7QUFDcEQsK0ZBQXNIO0FBQ3RILHNGQUFrRDtBQUNsRCx1R0FBNkM7QUFJN0MsSUFBSSxjQUFjLEdBQUcsSUFBSSxDQUFDO0FBQzFCLE1BQU0sTUFBTSxHQUFHLElBQUksbUNBQWdCLEVBQUUsQ0FBQztBQUN0QyxNQUFNLFFBQVEsR0FBRyxzQkFBVyxFQUFFLENBQUM7QUFFL0IsTUFBTSxNQUFNLEdBQUcsZ0JBQWdCLEVBQUUsQ0FBQztBQUVsQyxvQkFBb0I7QUFDcEIsSUFBSSxLQUFLLEdBQUcsa0JBQU8sQ0FBc0MsWUFBWSxDQUFDLENBQUM7QUFDdkUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUV2QixNQUFNLFNBQVMsR0FBRyxpQ0FBcUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUVoRCxNQUFNLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUN2QyxNQUFNLENBQUMsbUJBQW1CLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBRWhELE1BQU0sQ0FBQyxNQUFNLEdBQUcsR0FBRyxFQUFFO0lBQ3BCLGdCQUFnQixFQUFFLENBQUM7QUFDcEIsQ0FBQyxDQUFDO0FBRUYsMkJBQWtCLENBQUMsR0FBRyxFQUFFO0lBQ3ZCLElBQUksUUFBUSxDQUFDLHVCQUF1QixFQUFFO1FBQ3JDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZix5Q0FBeUM7WUFDekMsSUFBSSxLQUFLLENBQUMsUUFBUSxFQUFFO2dCQUNuQixNQUFNLE9BQU8sR0FBRyx1Q0FBeUIsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQzFELElBQUksT0FBTyxFQUFFO29CQUNaLGNBQWMsR0FBRyxJQUFJLENBQUM7b0JBQ3RCLHNDQUF3QixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztpQkFDdkM7YUFDRDtpQkFBTTtnQkFDTixNQUFNLFdBQVcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7Z0JBQ25DLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLEVBQUU7b0JBQ3hCLGNBQWMsR0FBRyxJQUFJLENBQUM7b0JBQ3RCLHNDQUF3QixDQUFDLFdBQVcsQ0FBQyxDQUFDO2lCQUN0QzthQUNEO1FBQ0YsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0tBQ047QUFDRixDQUFDLENBQUMsQ0FBQztBQUVILE1BQU0sWUFBWSxHQUFHLENBQUMsR0FBRyxFQUFFO0lBQzFCLE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxDQUFDLElBQVksRUFBRSxFQUFFO1FBQzFDLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFDdEIsc0NBQXdCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDaEMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBRVAsT0FBTyxDQUFDLElBQVksRUFBRSxRQUFhLEVBQUUsRUFBRTtRQUN0QyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ2pCLFFBQVEsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1lBQ3JCLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNmO0lBQ0YsQ0FBQyxDQUFDO0FBQ0gsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUVMLElBQUksZ0JBQWdCLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRTtJQUNwQyxNQUFNLFNBQVMsR0FBb0QsRUFBRSxDQUFDO0lBQ3RFLElBQUksTUFBTSxHQUFHLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNsRCxJQUFJLE1BQU0sRUFBRTtRQUNYLElBQUksQ0FBQyxDQUFDO1FBQ04sS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ25DLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUV0QixJQUFJLEdBQUcsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxFQUFFO2dCQUN0QyxHQUFHLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQzthQUNoQztZQUVELFNBQVMsQ0FBQyxJQUFJLENBQUM7Z0JBQ2QsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFFO2dCQUNWLE1BQU0sRUFBRSxHQUFHLENBQUMsTUFBTTtnQkFDbEIsS0FBSyxFQUFFLEdBQUcsQ0FBQyxLQUFLO2FBQ2hCLENBQUMsQ0FBQztTQUNIO1FBRUQsU0FBUyxDQUFDLFdBQVcsQ0FBQyxpQkFBaUIsRUFBRSxTQUFTLENBQUMsQ0FBQztLQUNwRDtBQUNGLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUVQLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsR0FBRyxFQUFFO0lBQ3RDLGNBQWMsR0FBRyxJQUFJLENBQUM7SUFDdEIsZ0JBQWdCLEVBQUUsQ0FBQztBQUNwQixDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFFVCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxFQUFFO0lBQzFDLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEtBQUssUUFBUSxDQUFDLE1BQU0sRUFBRTtRQUMxQyxPQUFPO0tBQ1A7SUFFRCxRQUFRLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFO1FBQ3hCLEtBQUssZ0NBQWdDO1lBQ3BDLE1BQU0sQ0FBQyw4QkFBOEIsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3ZELE1BQU07UUFFUCxLQUFLLFlBQVk7WUFDaEIsWUFBWSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQ3hDLE1BQU07S0FDUDtBQUNGLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztBQUVWLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLEVBQUU7SUFDN0MsSUFBSSxDQUFDLFFBQVEsQ0FBQywyQkFBMkIsRUFBRTtRQUMxQyxPQUFPO0tBQ1A7SUFFRCx5QkFBeUI7SUFDekIsS0FBSyxJQUFJLElBQUksR0FBRyxLQUFLLENBQUMsTUFBcUIsRUFBRSxJQUFJLEVBQUUsSUFBSSxHQUFHLElBQUksQ0FBQyxVQUF5QixFQUFFO1FBQ3pGLElBQUksSUFBSSxDQUFDLE9BQU8sS0FBSyxHQUFHLEVBQUU7WUFDekIsT0FBTztTQUNQO0tBQ0Q7SUFFRCxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDO0lBQzNCLE1BQU0sSUFBSSxHQUFHLDhDQUFnQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3RELElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFO1FBQzdDLFNBQVMsQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0tBQzlEO0FBQ0YsQ0FBQyxDQUFDLENBQUM7QUFFSCxRQUFRLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxFQUFFO0lBQzFDLElBQUksQ0FBQyxLQUFLLEVBQUU7UUFDWCxPQUFPO0tBQ1A7SUFFRCxJQUFJLElBQUksR0FBUSxLQUFLLENBQUMsTUFBTSxDQUFDO0lBQzdCLE9BQU8sSUFBSSxFQUFFO1FBQ1osSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxPQUFPLEtBQUssR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUU7WUFDdEQsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRTtnQkFDOUMsTUFBTTthQUNOO1lBQ0QsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFO2dCQUN0SSxNQUFNLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGdDQUFnQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLE1BQU0sQ0FBQyxJQUFJLFlBQVksQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ2xLLFNBQVMsQ0FBQyxXQUFXLENBQUMsV0FBVyxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7Z0JBQ3ZELEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDdkIsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUN4QixNQUFNO2FBQ047WUFDRCxNQUFNO1NBQ047UUFDRCxJQUFJLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztLQUN2QjtBQUNGLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUVULElBQUksUUFBUSxDQUFDLHVCQUF1QixFQUFFO0lBQ3JDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLEdBQUcsRUFBRTtRQUMvQyxJQUFJLGNBQWMsRUFBRTtZQUNuQixjQUFjLEdBQUcsS0FBSyxDQUFDO1NBQ3ZCO2FBQU07WUFDTixNQUFNLElBQUksR0FBRyw4Q0FBZ0MsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDOUQsSUFBSSxPQUFPLElBQUksS0FBSyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQzdDLFNBQVMsQ0FBQyxXQUFXLENBQUMsWUFBWSxFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztnQkFDOUMsS0FBSyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7Z0JBQ2xCLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDdkI7U0FDRDtJQUNGLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0NBQ1I7QUFFRCxTQUFTLFlBQVksQ0FBQyxJQUFZO0lBQ2pDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQywwQkFBMEIsRUFBRSxNQUFNLENBQUMsQ0FBQztBQUN6RCxDQUFDOzs7Ozs7Ozs7Ozs7OztBQzVLRDs7O2dHQUdnRzs7QUFFaEcsc0ZBQXlDO0FBUzVCLDZCQUFxQixHQUFHLENBQUMsTUFBVyxFQUFFLEVBQUU7SUFDcEQsT0FBTyxJQUFJO1FBQ1YsV0FBVyxDQUFDLElBQVksRUFBRSxJQUFZO1lBQ3JDLE1BQU0sQ0FBQyxXQUFXLENBQUM7Z0JBQ2xCLElBQUk7Z0JBQ0osTUFBTSxFQUFFLHNCQUFXLEVBQUUsQ0FBQyxNQUFNO2dCQUM1QixJQUFJO2FBQ0osQ0FBQyxDQUFDO1FBQ0osQ0FBQztLQUNELENBQUM7QUFDSCxDQUFDLENBQUM7Ozs7Ozs7Ozs7Ozs7O0FDeEJGOzs7Z0dBR2dHOztBQUVoRyxzRkFBeUM7QUFHekMsU0FBUyxLQUFLLENBQUMsR0FBVyxFQUFFLEdBQVcsRUFBRSxLQUFhO0lBQ3JELE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUM1QyxDQUFDO0FBRUQsU0FBUyxTQUFTLENBQUMsSUFBWTtJQUM5QixPQUFPLEtBQUssQ0FBQyxDQUFDLEVBQUUsc0JBQVcsRUFBRSxDQUFDLFNBQVMsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDcEQsQ0FBQztBQVFELE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxHQUFHLEVBQUU7SUFDakMsSUFBSSxRQUEyQixDQUFDO0lBQ2hDLE9BQU8sR0FBRyxFQUFFO1FBQ1gsSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNkLFFBQVEsR0FBRyxDQUFDLEVBQUUsT0FBTyxFQUFFLFFBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDakQsS0FBSyxNQUFNLE9BQU8sSUFBSSxRQUFRLENBQUMsc0JBQXNCLENBQUMsV0FBVyxDQUFDLEVBQUU7Z0JBQ25FLE1BQU0sSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUUsQ0FBQztnQkFDakQsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRTtvQkFDakIsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSxPQUFzQixFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7aUJBQ3pEO2FBQ0Q7U0FDRDtRQUNELE9BQU8sUUFBUSxDQUFDO0lBQ2pCLENBQUMsQ0FBQztBQUNILENBQUMsQ0FBQyxFQUFFLENBQUM7QUFFTDs7Ozs7R0FLRztBQUNILFNBQWdCLHdCQUF3QixDQUFDLFVBQWtCO0lBQzFELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDMUMsTUFBTSxLQUFLLEdBQUcsbUJBQW1CLEVBQUUsQ0FBQztJQUNwQyxJQUFJLFFBQVEsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDO0lBQ2hDLEtBQUssTUFBTSxLQUFLLElBQUksS0FBSyxFQUFFO1FBQzFCLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxVQUFVLEVBQUU7WUFDOUIsT0FBTyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxDQUFDO1NBQzVDO2FBQU0sSUFBSSxLQUFLLENBQUMsSUFBSSxHQUFHLFVBQVUsRUFBRTtZQUNuQyxPQUFPLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQztTQUNqQztRQUNELFFBQVEsR0FBRyxLQUFLLENBQUM7S0FDakI7SUFDRCxPQUFPLEVBQUUsUUFBUSxFQUFFLENBQUM7QUFDckIsQ0FBQztBQWJELDREQWFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQiwyQkFBMkIsQ0FBQyxNQUFjO0lBQ3pELE1BQU0sS0FBSyxHQUFHLG1CQUFtQixFQUFFLENBQUM7SUFDcEMsTUFBTSxRQUFRLEdBQUcsTUFBTSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUM7SUFDekMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDWixJQUFJLEVBQUUsR0FBRyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUMxQixPQUFPLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFO1FBQ25CLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDdEMsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQzFELElBQUksTUFBTSxDQUFDLEdBQUcsR0FBRyxNQUFNLENBQUMsTUFBTSxJQUFJLFFBQVEsRUFBRTtZQUMzQyxFQUFFLEdBQUcsR0FBRyxDQUFDO1NBQ1Q7YUFDSTtZQUNKLEVBQUUsR0FBRyxHQUFHLENBQUM7U0FDVDtLQUNEO0lBQ0QsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzVCLE1BQU0sUUFBUSxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUMzRCxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksUUFBUSxDQUFDLEdBQUcsR0FBRyxRQUFRLEVBQUU7UUFDdkMsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzVCLE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsQ0FBQztLQUNoRDtJQUNELE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLENBQUM7QUFDaEMsQ0FBQztBQXRCRCxrRUFzQkM7QUFFRDs7R0FFRztBQUNILFNBQWdCLHdCQUF3QixDQUFDLElBQVk7SUFDcEQsSUFBSSxDQUFDLHNCQUFXLEVBQUUsQ0FBQyx1QkFBdUIsRUFBRTtRQUMzQyxPQUFPO0tBQ1A7SUFFRCxJQUFJLElBQUksSUFBSSxDQUFDLEVBQUU7UUFDZCxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDakMsT0FBTztLQUNQO0lBRUQsTUFBTSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsR0FBRyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMxRCxJQUFJLENBQUMsUUFBUSxFQUFFO1FBQ2QsT0FBTztLQUNQO0lBQ0QsSUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFDO0lBQ2pCLE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUN0RCxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDO0lBQzdCLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssUUFBUSxDQUFDLElBQUksRUFBRTtRQUN4Qyw4REFBOEQ7UUFDOUQsTUFBTSxlQUFlLEdBQUcsQ0FBQyxJQUFJLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDN0UsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsRUFBRSxDQUFDLEdBQUcsR0FBRyxXQUFXLENBQUM7UUFDN0UsUUFBUSxHQUFHLFdBQVcsR0FBRyxlQUFlLEdBQUcsYUFBYSxDQUFDO0tBQ3pEO1NBQU07UUFDTixNQUFNLGlCQUFpQixHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2xELFFBQVEsR0FBRyxXQUFXLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLGlCQUFpQixDQUFDLENBQUM7S0FDM0Q7SUFDRCxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDO0FBQ3ZFLENBQUM7QUEzQkQsNERBMkJDO0FBRUQsU0FBZ0IsZ0NBQWdDLENBQUMsTUFBYztJQUM5RCxNQUFNLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxHQUFHLDJCQUEyQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQy9ELElBQUksUUFBUSxFQUFFO1FBQ2IsTUFBTSxjQUFjLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQ2hFLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLE9BQU8sR0FBRyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDMUUsSUFBSSxJQUFJLEVBQUU7WUFDVCxNQUFNLHVCQUF1QixHQUFHLGtCQUFrQixHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsRUFBRSxDQUFDLEdBQUcsR0FBRyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDckgsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLElBQUksR0FBRyx1QkFBdUIsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ25GLE9BQU8sU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQ3ZCO2FBQ0k7WUFDSixNQUFNLHFCQUFxQixHQUFHLGtCQUFrQixHQUFHLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzNFLE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxJQUFJLEdBQUcscUJBQXFCLENBQUM7WUFDbkQsT0FBTyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDdkI7S0FDRDtJQUNELE9BQU8sSUFBSSxDQUFDO0FBQ2IsQ0FBQztBQWpCRCw0RUFpQkM7QUFFRDs7R0FFRztBQUNILFNBQWdCLHlCQUF5QixDQUFDLFFBQWdCO0lBQ3pELE9BQU8sbUJBQW1CLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtRQUM3QyxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxLQUFLLFFBQVEsQ0FBQztJQUN4QyxDQUFDLENBQUMsQ0FBQztBQUNKLENBQUM7QUFKRCw4REFJQzs7Ozs7Ozs7Ozs7Ozs7QUNoSkQ7OztnR0FHZ0c7O0FBYWhHLElBQUksY0FBYyxHQUFnQyxTQUFTLENBQUM7QUFFNUQsU0FBZ0IsT0FBTyxDQUFTLEdBQVc7SUFDMUMsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO0lBQ3hFLElBQUksT0FBTyxFQUFFO1FBQ1osTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN2QyxJQUFJLElBQUksRUFBRTtZQUNULE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUN4QjtLQUNEO0lBRUQsTUFBTSxJQUFJLEtBQUssQ0FBQywyQkFBMkIsR0FBRyxFQUFFLENBQUMsQ0FBQztBQUNuRCxDQUFDO0FBVkQsMEJBVUM7QUFFRCxTQUFnQixXQUFXO0lBQzFCLElBQUksY0FBYyxFQUFFO1FBQ25CLE9BQU8sY0FBYyxDQUFDO0tBQ3RCO0lBRUQsY0FBYyxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUMxQyxJQUFJLGNBQWMsRUFBRTtRQUNuQixPQUFPLGNBQWMsQ0FBQztLQUN0QjtJQUVELE1BQU0sSUFBSSxLQUFLLENBQUMseUJBQXlCLENBQUMsQ0FBQztBQUM1QyxDQUFDO0FBWEQsa0NBV0MiLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHtcbiBcdFx0XHRcdGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gXHRcdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuIFx0XHRcdFx0Z2V0OiBnZXR0ZXJcbiBcdFx0XHR9KTtcbiBcdFx0fVxuIFx0fTtcblxuIFx0Ly8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5yID0gZnVuY3Rpb24oZXhwb3J0cykge1xuIFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuIFx0fTtcblxuIFx0Ly8gZ2V0RGVmYXVsdEV4cG9ydCBmdW5jdGlvbiBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIG5vbi1oYXJtb255IG1vZHVsZXNcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubiA9IGZ1bmN0aW9uKG1vZHVsZSkge1xuIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbiBcdFx0XHRmdW5jdGlvbiBnZXREZWZhdWx0KCkgeyByZXR1cm4gbW9kdWxlWydkZWZhdWx0J107IH0gOlxuIFx0XHRcdGZ1bmN0aW9uIGdldE1vZHVsZUV4cG9ydHMoKSB7IHJldHVybiBtb2R1bGU7IH07XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbiBcdFx0cmV0dXJuIGdldHRlcjtcbiBcdH07XG5cbiBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5vID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpOyB9O1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblxuXG4gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbiBcdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKF9fd2VicGFja19yZXF1aXJlX18ucyA9IFwiLi9wcmV2aWV3LXNyYy9pbmRleC50c1wiKTtcbiIsIi8qKlxuICogbG9kYXNoIChDdXN0b20gQnVpbGQpIDxodHRwczovL2xvZGFzaC5jb20vPlxuICogQnVpbGQ6IGBsb2Rhc2ggbW9kdWxhcml6ZSBleHBvcnRzPVwibnBtXCIgLW8gLi9gXG4gKiBDb3B5cmlnaHQgalF1ZXJ5IEZvdW5kYXRpb24gYW5kIG90aGVyIGNvbnRyaWJ1dG9ycyA8aHR0cHM6Ly9qcXVlcnkub3JnLz5cbiAqIFJlbGVhc2VkIHVuZGVyIE1JVCBsaWNlbnNlIDxodHRwczovL2xvZGFzaC5jb20vbGljZW5zZT5cbiAqIEJhc2VkIG9uIFVuZGVyc2NvcmUuanMgMS44LjMgPGh0dHA6Ly91bmRlcnNjb3JlanMub3JnL0xJQ0VOU0U+XG4gKiBDb3B5cmlnaHQgSmVyZW15IEFzaGtlbmFzLCBEb2N1bWVudENsb3VkIGFuZCBJbnZlc3RpZ2F0aXZlIFJlcG9ydGVycyAmIEVkaXRvcnNcbiAqL1xuXG4vKiogVXNlZCBhcyB0aGUgYFR5cGVFcnJvcmAgbWVzc2FnZSBmb3IgXCJGdW5jdGlvbnNcIiBtZXRob2RzLiAqL1xudmFyIEZVTkNfRVJST1JfVEVYVCA9ICdFeHBlY3RlZCBhIGZ1bmN0aW9uJztcblxuLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdmFyaW91cyBgTnVtYmVyYCBjb25zdGFudHMuICovXG52YXIgTkFOID0gMCAvIDA7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBzeW1ib2xUYWcgPSAnW29iamVjdCBTeW1ib2xdJztcblxuLyoqIFVzZWQgdG8gbWF0Y2ggbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZS4gKi9cbnZhciByZVRyaW0gPSAvXlxccyt8XFxzKyQvZztcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IGJhZCBzaWduZWQgaGV4YWRlY2ltYWwgc3RyaW5nIHZhbHVlcy4gKi9cbnZhciByZUlzQmFkSGV4ID0gL15bLStdMHhbMC05YS1mXSskL2k7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBiaW5hcnkgc3RyaW5nIHZhbHVlcy4gKi9cbnZhciByZUlzQmluYXJ5ID0gL14wYlswMV0rJC9pO1xuXG4vKiogVXNlZCB0byBkZXRlY3Qgb2N0YWwgc3RyaW5nIHZhbHVlcy4gKi9cbnZhciByZUlzT2N0YWwgPSAvXjBvWzAtN10rJC9pO1xuXG4vKiogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgd2l0aG91dCBhIGRlcGVuZGVuY3kgb24gYHJvb3RgLiAqL1xudmFyIGZyZWVQYXJzZUludCA9IHBhcnNlSW50O1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGdsb2JhbGAgZnJvbSBOb2RlLmpzLiAqL1xudmFyIGZyZWVHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsID09ICdvYmplY3QnICYmIGdsb2JhbCAmJiBnbG9iYWwuT2JqZWN0ID09PSBPYmplY3QgJiYgZ2xvYmFsO1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYHNlbGZgLiAqL1xudmFyIGZyZWVTZWxmID0gdHlwZW9mIHNlbGYgPT0gJ29iamVjdCcgJiYgc2VsZiAmJiBzZWxmLk9iamVjdCA9PT0gT2JqZWN0ICYmIHNlbGY7XG5cbi8qKiBVc2VkIGFzIGEgcmVmZXJlbmNlIHRvIHRoZSBnbG9iYWwgb2JqZWN0LiAqL1xudmFyIHJvb3QgPSBmcmVlR2xvYmFsIHx8IGZyZWVTZWxmIHx8IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZVxuICogW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmplY3RUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWF4ID0gTWF0aC5tYXgsXG4gICAgbmF0aXZlTWluID0gTWF0aC5taW47XG5cbi8qKlxuICogR2V0cyB0aGUgdGltZXN0YW1wIG9mIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRoYXQgaGF2ZSBlbGFwc2VkIHNpbmNlXG4gKiB0aGUgVW5peCBlcG9jaCAoMSBKYW51YXJ5IDE5NzAgMDA6MDA6MDAgVVRDKS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDIuNC4wXG4gKiBAY2F0ZWdvcnkgRGF0ZVxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgdGltZXN0YW1wLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmRlZmVyKGZ1bmN0aW9uKHN0YW1wKSB7XG4gKiAgIGNvbnNvbGUubG9nKF8ubm93KCkgLSBzdGFtcCk7XG4gKiB9LCBfLm5vdygpKTtcbiAqIC8vID0+IExvZ3MgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgaXQgdG9vayBmb3IgdGhlIGRlZmVycmVkIGludm9jYXRpb24uXG4gKi9cbnZhciBub3cgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHJvb3QuRGF0ZS5ub3coKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIGRlYm91bmNlZCBmdW5jdGlvbiB0aGF0IGRlbGF5cyBpbnZva2luZyBgZnVuY2AgdW50aWwgYWZ0ZXIgYHdhaXRgXG4gKiBtaWxsaXNlY29uZHMgaGF2ZSBlbGFwc2VkIHNpbmNlIHRoZSBsYXN0IHRpbWUgdGhlIGRlYm91bmNlZCBmdW5jdGlvbiB3YXNcbiAqIGludm9rZWQuIFRoZSBkZWJvdW5jZWQgZnVuY3Rpb24gY29tZXMgd2l0aCBhIGBjYW5jZWxgIG1ldGhvZCB0byBjYW5jZWxcbiAqIGRlbGF5ZWQgYGZ1bmNgIGludm9jYXRpb25zIGFuZCBhIGBmbHVzaGAgbWV0aG9kIHRvIGltbWVkaWF0ZWx5IGludm9rZSB0aGVtLlxuICogUHJvdmlkZSBgb3B0aW9uc2AgdG8gaW5kaWNhdGUgd2hldGhlciBgZnVuY2Agc2hvdWxkIGJlIGludm9rZWQgb24gdGhlXG4gKiBsZWFkaW5nIGFuZC9vciB0cmFpbGluZyBlZGdlIG9mIHRoZSBgd2FpdGAgdGltZW91dC4gVGhlIGBmdW5jYCBpcyBpbnZva2VkXG4gKiB3aXRoIHRoZSBsYXN0IGFyZ3VtZW50cyBwcm92aWRlZCB0byB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uLiBTdWJzZXF1ZW50XG4gKiBjYWxscyB0byB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uIHJldHVybiB0aGUgcmVzdWx0IG9mIHRoZSBsYXN0IGBmdW5jYFxuICogaW52b2NhdGlvbi5cbiAqXG4gKiAqKk5vdGU6KiogSWYgYGxlYWRpbmdgIGFuZCBgdHJhaWxpbmdgIG9wdGlvbnMgYXJlIGB0cnVlYCwgYGZ1bmNgIGlzXG4gKiBpbnZva2VkIG9uIHRoZSB0cmFpbGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0IG9ubHkgaWYgdGhlIGRlYm91bmNlZCBmdW5jdGlvblxuICogaXMgaW52b2tlZCBtb3JlIHRoYW4gb25jZSBkdXJpbmcgdGhlIGB3YWl0YCB0aW1lb3V0LlxuICpcbiAqIElmIGB3YWl0YCBpcyBgMGAgYW5kIGBsZWFkaW5nYCBpcyBgZmFsc2VgLCBgZnVuY2AgaW52b2NhdGlvbiBpcyBkZWZlcnJlZFxuICogdW50aWwgdG8gdGhlIG5leHQgdGljaywgc2ltaWxhciB0byBgc2V0VGltZW91dGAgd2l0aCBhIHRpbWVvdXQgb2YgYDBgLlxuICpcbiAqIFNlZSBbRGF2aWQgQ29yYmFjaG8ncyBhcnRpY2xlXShodHRwczovL2Nzcy10cmlja3MuY29tL2RlYm91bmNpbmctdGhyb3R0bGluZy1leHBsYWluZWQtZXhhbXBsZXMvKVxuICogZm9yIGRldGFpbHMgb3ZlciB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiBgXy5kZWJvdW5jZWAgYW5kIGBfLnRocm90dGxlYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRlYm91bmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IFt3YWl0PTBdIFRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIGRlbGF5LlxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zPXt9XSBUaGUgb3B0aW9ucyBvYmplY3QuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmxlYWRpbmc9ZmFsc2VdXG4gKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgbGVhZGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLm1heFdhaXRdXG4gKiAgVGhlIG1heGltdW0gdGltZSBgZnVuY2AgaXMgYWxsb3dlZCB0byBiZSBkZWxheWVkIGJlZm9yZSBpdCdzIGludm9rZWQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnRyYWlsaW5nPXRydWVdXG4gKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGRlYm91bmNlZCBmdW5jdGlvbi5cbiAqIEBleGFtcGxlXG4gKlxuICogLy8gQXZvaWQgY29zdGx5IGNhbGN1bGF0aW9ucyB3aGlsZSB0aGUgd2luZG93IHNpemUgaXMgaW4gZmx1eC5cbiAqIGpRdWVyeSh3aW5kb3cpLm9uKCdyZXNpemUnLCBfLmRlYm91bmNlKGNhbGN1bGF0ZUxheW91dCwgMTUwKSk7XG4gKlxuICogLy8gSW52b2tlIGBzZW5kTWFpbGAgd2hlbiBjbGlja2VkLCBkZWJvdW5jaW5nIHN1YnNlcXVlbnQgY2FsbHMuXG4gKiBqUXVlcnkoZWxlbWVudCkub24oJ2NsaWNrJywgXy5kZWJvdW5jZShzZW5kTWFpbCwgMzAwLCB7XG4gKiAgICdsZWFkaW5nJzogdHJ1ZSxcbiAqICAgJ3RyYWlsaW5nJzogZmFsc2VcbiAqIH0pKTtcbiAqXG4gKiAvLyBFbnN1cmUgYGJhdGNoTG9nYCBpcyBpbnZva2VkIG9uY2UgYWZ0ZXIgMSBzZWNvbmQgb2YgZGVib3VuY2VkIGNhbGxzLlxuICogdmFyIGRlYm91bmNlZCA9IF8uZGVib3VuY2UoYmF0Y2hMb2csIDI1MCwgeyAnbWF4V2FpdCc6IDEwMDAgfSk7XG4gKiB2YXIgc291cmNlID0gbmV3IEV2ZW50U291cmNlKCcvc3RyZWFtJyk7XG4gKiBqUXVlcnkoc291cmNlKS5vbignbWVzc2FnZScsIGRlYm91bmNlZCk7XG4gKlxuICogLy8gQ2FuY2VsIHRoZSB0cmFpbGluZyBkZWJvdW5jZWQgaW52b2NhdGlvbi5cbiAqIGpRdWVyeSh3aW5kb3cpLm9uKCdwb3BzdGF0ZScsIGRlYm91bmNlZC5jYW5jZWwpO1xuICovXG5mdW5jdGlvbiBkZWJvdW5jZShmdW5jLCB3YWl0LCBvcHRpb25zKSB7XG4gIHZhciBsYXN0QXJncyxcbiAgICAgIGxhc3RUaGlzLFxuICAgICAgbWF4V2FpdCxcbiAgICAgIHJlc3VsdCxcbiAgICAgIHRpbWVySWQsXG4gICAgICBsYXN0Q2FsbFRpbWUsXG4gICAgICBsYXN0SW52b2tlVGltZSA9IDAsXG4gICAgICBsZWFkaW5nID0gZmFsc2UsXG4gICAgICBtYXhpbmcgPSBmYWxzZSxcbiAgICAgIHRyYWlsaW5nID0gdHJ1ZTtcblxuICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgfVxuICB3YWl0ID0gdG9OdW1iZXIod2FpdCkgfHwgMDtcbiAgaWYgKGlzT2JqZWN0KG9wdGlvbnMpKSB7XG4gICAgbGVhZGluZyA9ICEhb3B0aW9ucy5sZWFkaW5nO1xuICAgIG1heGluZyA9ICdtYXhXYWl0JyBpbiBvcHRpb25zO1xuICAgIG1heFdhaXQgPSBtYXhpbmcgPyBuYXRpdmVNYXgodG9OdW1iZXIob3B0aW9ucy5tYXhXYWl0KSB8fCAwLCB3YWl0KSA6IG1heFdhaXQ7XG4gICAgdHJhaWxpbmcgPSAndHJhaWxpbmcnIGluIG9wdGlvbnMgPyAhIW9wdGlvbnMudHJhaWxpbmcgOiB0cmFpbGluZztcbiAgfVxuXG4gIGZ1bmN0aW9uIGludm9rZUZ1bmModGltZSkge1xuICAgIHZhciBhcmdzID0gbGFzdEFyZ3MsXG4gICAgICAgIHRoaXNBcmcgPSBsYXN0VGhpcztcblxuICAgIGxhc3RBcmdzID0gbGFzdFRoaXMgPSB1bmRlZmluZWQ7XG4gICAgbGFzdEludm9rZVRpbWUgPSB0aW1lO1xuICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkodGhpc0FyZywgYXJncyk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGxlYWRpbmdFZGdlKHRpbWUpIHtcbiAgICAvLyBSZXNldCBhbnkgYG1heFdhaXRgIHRpbWVyLlxuICAgIGxhc3RJbnZva2VUaW1lID0gdGltZTtcbiAgICAvLyBTdGFydCB0aGUgdGltZXIgZm9yIHRoZSB0cmFpbGluZyBlZGdlLlxuICAgIHRpbWVySWQgPSBzZXRUaW1lb3V0KHRpbWVyRXhwaXJlZCwgd2FpdCk7XG4gICAgLy8gSW52b2tlIHRoZSBsZWFkaW5nIGVkZ2UuXG4gICAgcmV0dXJuIGxlYWRpbmcgPyBpbnZva2VGdW5jKHRpbWUpIDogcmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gcmVtYWluaW5nV2FpdCh0aW1lKSB7XG4gICAgdmFyIHRpbWVTaW5jZUxhc3RDYWxsID0gdGltZSAtIGxhc3RDYWxsVGltZSxcbiAgICAgICAgdGltZVNpbmNlTGFzdEludm9rZSA9IHRpbWUgLSBsYXN0SW52b2tlVGltZSxcbiAgICAgICAgcmVzdWx0ID0gd2FpdCAtIHRpbWVTaW5jZUxhc3RDYWxsO1xuXG4gICAgcmV0dXJuIG1heGluZyA/IG5hdGl2ZU1pbihyZXN1bHQsIG1heFdhaXQgLSB0aW1lU2luY2VMYXN0SW52b2tlKSA6IHJlc3VsdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNob3VsZEludm9rZSh0aW1lKSB7XG4gICAgdmFyIHRpbWVTaW5jZUxhc3RDYWxsID0gdGltZSAtIGxhc3RDYWxsVGltZSxcbiAgICAgICAgdGltZVNpbmNlTGFzdEludm9rZSA9IHRpbWUgLSBsYXN0SW52b2tlVGltZTtcblxuICAgIC8vIEVpdGhlciB0aGlzIGlzIHRoZSBmaXJzdCBjYWxsLCBhY3Rpdml0eSBoYXMgc3RvcHBlZCBhbmQgd2UncmUgYXQgdGhlXG4gICAgLy8gdHJhaWxpbmcgZWRnZSwgdGhlIHN5c3RlbSB0aW1lIGhhcyBnb25lIGJhY2t3YXJkcyBhbmQgd2UncmUgdHJlYXRpbmdcbiAgICAvLyBpdCBhcyB0aGUgdHJhaWxpbmcgZWRnZSwgb3Igd2UndmUgaGl0IHRoZSBgbWF4V2FpdGAgbGltaXQuXG4gICAgcmV0dXJuIChsYXN0Q2FsbFRpbWUgPT09IHVuZGVmaW5lZCB8fCAodGltZVNpbmNlTGFzdENhbGwgPj0gd2FpdCkgfHxcbiAgICAgICh0aW1lU2luY2VMYXN0Q2FsbCA8IDApIHx8IChtYXhpbmcgJiYgdGltZVNpbmNlTGFzdEludm9rZSA+PSBtYXhXYWl0KSk7XG4gIH1cblxuICBmdW5jdGlvbiB0aW1lckV4cGlyZWQoKSB7XG4gICAgdmFyIHRpbWUgPSBub3coKTtcbiAgICBpZiAoc2hvdWxkSW52b2tlKHRpbWUpKSB7XG4gICAgICByZXR1cm4gdHJhaWxpbmdFZGdlKHRpbWUpO1xuICAgIH1cbiAgICAvLyBSZXN0YXJ0IHRoZSB0aW1lci5cbiAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHJlbWFpbmluZ1dhaXQodGltZSkpO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJhaWxpbmdFZGdlKHRpbWUpIHtcbiAgICB0aW1lcklkID0gdW5kZWZpbmVkO1xuXG4gICAgLy8gT25seSBpbnZva2UgaWYgd2UgaGF2ZSBgbGFzdEFyZ3NgIHdoaWNoIG1lYW5zIGBmdW5jYCBoYXMgYmVlblxuICAgIC8vIGRlYm91bmNlZCBhdCBsZWFzdCBvbmNlLlxuICAgIGlmICh0cmFpbGluZyAmJiBsYXN0QXJncykge1xuICAgICAgcmV0dXJuIGludm9rZUZ1bmModGltZSk7XG4gICAgfVxuICAgIGxhc3RBcmdzID0gbGFzdFRoaXMgPSB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNhbmNlbCgpIHtcbiAgICBpZiAodGltZXJJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZXJJZCk7XG4gICAgfVxuICAgIGxhc3RJbnZva2VUaW1lID0gMDtcbiAgICBsYXN0QXJncyA9IGxhc3RDYWxsVGltZSA9IGxhc3RUaGlzID0gdGltZXJJZCA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZsdXNoKCkge1xuICAgIHJldHVybiB0aW1lcklkID09PSB1bmRlZmluZWQgPyByZXN1bHQgOiB0cmFpbGluZ0VkZ2Uobm93KCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gZGVib3VuY2VkKCkge1xuICAgIHZhciB0aW1lID0gbm93KCksXG4gICAgICAgIGlzSW52b2tpbmcgPSBzaG91bGRJbnZva2UodGltZSk7XG5cbiAgICBsYXN0QXJncyA9IGFyZ3VtZW50cztcbiAgICBsYXN0VGhpcyA9IHRoaXM7XG4gICAgbGFzdENhbGxUaW1lID0gdGltZTtcblxuICAgIGlmIChpc0ludm9raW5nKSB7XG4gICAgICBpZiAodGltZXJJZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBsZWFkaW5nRWRnZShsYXN0Q2FsbFRpbWUpO1xuICAgICAgfVxuICAgICAgaWYgKG1heGluZykge1xuICAgICAgICAvLyBIYW5kbGUgaW52b2NhdGlvbnMgaW4gYSB0aWdodCBsb29wLlxuICAgICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHdhaXQpO1xuICAgICAgICByZXR1cm4gaW52b2tlRnVuYyhsYXN0Q2FsbFRpbWUpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodGltZXJJZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHdhaXQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIGRlYm91bmNlZC5jYW5jZWwgPSBjYW5jZWw7XG4gIGRlYm91bmNlZC5mbHVzaCA9IGZsdXNoO1xuICByZXR1cm4gZGVib3VuY2VkO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSB0aHJvdHRsZWQgZnVuY3Rpb24gdGhhdCBvbmx5IGludm9rZXMgYGZ1bmNgIGF0IG1vc3Qgb25jZSBwZXJcbiAqIGV2ZXJ5IGB3YWl0YCBtaWxsaXNlY29uZHMuIFRoZSB0aHJvdHRsZWQgZnVuY3Rpb24gY29tZXMgd2l0aCBhIGBjYW5jZWxgXG4gKiBtZXRob2QgdG8gY2FuY2VsIGRlbGF5ZWQgYGZ1bmNgIGludm9jYXRpb25zIGFuZCBhIGBmbHVzaGAgbWV0aG9kIHRvXG4gKiBpbW1lZGlhdGVseSBpbnZva2UgdGhlbS4gUHJvdmlkZSBgb3B0aW9uc2AgdG8gaW5kaWNhdGUgd2hldGhlciBgZnVuY2BcbiAqIHNob3VsZCBiZSBpbnZva2VkIG9uIHRoZSBsZWFkaW5nIGFuZC9vciB0cmFpbGluZyBlZGdlIG9mIHRoZSBgd2FpdGBcbiAqIHRpbWVvdXQuIFRoZSBgZnVuY2AgaXMgaW52b2tlZCB3aXRoIHRoZSBsYXN0IGFyZ3VtZW50cyBwcm92aWRlZCB0byB0aGVcbiAqIHRocm90dGxlZCBmdW5jdGlvbi4gU3Vic2VxdWVudCBjYWxscyB0byB0aGUgdGhyb3R0bGVkIGZ1bmN0aW9uIHJldHVybiB0aGVcbiAqIHJlc3VsdCBvZiB0aGUgbGFzdCBgZnVuY2AgaW52b2NhdGlvbi5cbiAqXG4gKiAqKk5vdGU6KiogSWYgYGxlYWRpbmdgIGFuZCBgdHJhaWxpbmdgIG9wdGlvbnMgYXJlIGB0cnVlYCwgYGZ1bmNgIGlzXG4gKiBpbnZva2VkIG9uIHRoZSB0cmFpbGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0IG9ubHkgaWYgdGhlIHRocm90dGxlZCBmdW5jdGlvblxuICogaXMgaW52b2tlZCBtb3JlIHRoYW4gb25jZSBkdXJpbmcgdGhlIGB3YWl0YCB0aW1lb3V0LlxuICpcbiAqIElmIGB3YWl0YCBpcyBgMGAgYW5kIGBsZWFkaW5nYCBpcyBgZmFsc2VgLCBgZnVuY2AgaW52b2NhdGlvbiBpcyBkZWZlcnJlZFxuICogdW50aWwgdG8gdGhlIG5leHQgdGljaywgc2ltaWxhciB0byBgc2V0VGltZW91dGAgd2l0aCBhIHRpbWVvdXQgb2YgYDBgLlxuICpcbiAqIFNlZSBbRGF2aWQgQ29yYmFjaG8ncyBhcnRpY2xlXShodHRwczovL2Nzcy10cmlja3MuY29tL2RlYm91bmNpbmctdGhyb3R0bGluZy1leHBsYWluZWQtZXhhbXBsZXMvKVxuICogZm9yIGRldGFpbHMgb3ZlciB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiBgXy50aHJvdHRsZWAgYW5kIGBfLmRlYm91bmNlYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHRocm90dGxlLlxuICogQHBhcmFtIHtudW1iZXJ9IFt3YWl0PTBdIFRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIHRocm90dGxlIGludm9jYXRpb25zIHRvLlxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zPXt9XSBUaGUgb3B0aW9ucyBvYmplY3QuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmxlYWRpbmc9dHJ1ZV1cbiAqICBTcGVjaWZ5IGludm9raW5nIG9uIHRoZSBsZWFkaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnRyYWlsaW5nPXRydWVdXG4gKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHRocm90dGxlZCBmdW5jdGlvbi5cbiAqIEBleGFtcGxlXG4gKlxuICogLy8gQXZvaWQgZXhjZXNzaXZlbHkgdXBkYXRpbmcgdGhlIHBvc2l0aW9uIHdoaWxlIHNjcm9sbGluZy5cbiAqIGpRdWVyeSh3aW5kb3cpLm9uKCdzY3JvbGwnLCBfLnRocm90dGxlKHVwZGF0ZVBvc2l0aW9uLCAxMDApKTtcbiAqXG4gKiAvLyBJbnZva2UgYHJlbmV3VG9rZW5gIHdoZW4gdGhlIGNsaWNrIGV2ZW50IGlzIGZpcmVkLCBidXQgbm90IG1vcmUgdGhhbiBvbmNlIGV2ZXJ5IDUgbWludXRlcy5cbiAqIHZhciB0aHJvdHRsZWQgPSBfLnRocm90dGxlKHJlbmV3VG9rZW4sIDMwMDAwMCwgeyAndHJhaWxpbmcnOiBmYWxzZSB9KTtcbiAqIGpRdWVyeShlbGVtZW50KS5vbignY2xpY2snLCB0aHJvdHRsZWQpO1xuICpcbiAqIC8vIENhbmNlbCB0aGUgdHJhaWxpbmcgdGhyb3R0bGVkIGludm9jYXRpb24uXG4gKiBqUXVlcnkod2luZG93KS5vbigncG9wc3RhdGUnLCB0aHJvdHRsZWQuY2FuY2VsKTtcbiAqL1xuZnVuY3Rpb24gdGhyb3R0bGUoZnVuYywgd2FpdCwgb3B0aW9ucykge1xuICB2YXIgbGVhZGluZyA9IHRydWUsXG4gICAgICB0cmFpbGluZyA9IHRydWU7XG5cbiAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gIH1cbiAgaWYgKGlzT2JqZWN0KG9wdGlvbnMpKSB7XG4gICAgbGVhZGluZyA9ICdsZWFkaW5nJyBpbiBvcHRpb25zID8gISFvcHRpb25zLmxlYWRpbmcgOiBsZWFkaW5nO1xuICAgIHRyYWlsaW5nID0gJ3RyYWlsaW5nJyBpbiBvcHRpb25zID8gISFvcHRpb25zLnRyYWlsaW5nIDogdHJhaWxpbmc7XG4gIH1cbiAgcmV0dXJuIGRlYm91bmNlKGZ1bmMsIHdhaXQsIHtcbiAgICAnbGVhZGluZyc6IGxlYWRpbmcsXG4gICAgJ21heFdhaXQnOiB3YWl0LFxuICAgICd0cmFpbGluZyc6IHRyYWlsaW5nXG4gIH0pO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHRoZVxuICogW2xhbmd1YWdlIHR5cGVdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1lY21hc2NyaXB0LWxhbmd1YWdlLXR5cGVzKVxuICogb2YgYE9iamVjdGAuIChlLmcuIGFycmF5cywgZnVuY3Rpb25zLCBvYmplY3RzLCByZWdleGVzLCBgbmV3IE51bWJlcigwKWAsIGFuZCBgbmV3IFN0cmluZygnJylgKVxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzT2JqZWN0KHt9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChfLm5vb3ApO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QobnVsbCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkge1xuICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgcmV0dXJuICEhdmFsdWUgJiYgKHR5cGUgPT0gJ29iamVjdCcgfHwgdHlwZSA9PSAnZnVuY3Rpb24nKTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZS4gQSB2YWx1ZSBpcyBvYmplY3QtbGlrZSBpZiBpdCdzIG5vdCBgbnVsbGBcbiAqIGFuZCBoYXMgYSBgdHlwZW9mYCByZXN1bHQgb2YgXCJvYmplY3RcIi5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZSwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZSh7fSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdExpa2UoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShfLm5vb3ApO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShudWxsKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0TGlrZSh2YWx1ZSkge1xuICByZXR1cm4gISF2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCc7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBTeW1ib2xgIHByaW1pdGl2ZSBvciBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBzeW1ib2wsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc1N5bWJvbChTeW1ib2wuaXRlcmF0b3IpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNTeW1ib2woJ2FiYycpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3ltYm9sJyB8fFxuICAgIChpc09iamVjdExpa2UodmFsdWUpICYmIG9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpID09IHN5bWJvbFRhZyk7XG59XG5cbi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIG51bWJlci5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG51bWJlci5cbiAqIEBleGFtcGxlXG4gKlxuICogXy50b051bWJlcigzLjIpO1xuICogLy8gPT4gMy4yXG4gKlxuICogXy50b051bWJlcihOdW1iZXIuTUlOX1ZBTFVFKTtcbiAqIC8vID0+IDVlLTMyNFxuICpcbiAqIF8udG9OdW1iZXIoSW5maW5pdHkpO1xuICogLy8gPT4gSW5maW5pdHlcbiAqXG4gKiBfLnRvTnVtYmVyKCczLjInKTtcbiAqIC8vID0+IDMuMlxuICovXG5mdW5jdGlvbiB0b051bWJlcih2YWx1ZSkge1xuICBpZiAodHlwZW9mIHZhbHVlID09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIGlmIChpc1N5bWJvbCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gTkFOO1xuICB9XG4gIGlmIChpc09iamVjdCh2YWx1ZSkpIHtcbiAgICB2YXIgb3RoZXIgPSB0eXBlb2YgdmFsdWUudmFsdWVPZiA9PSAnZnVuY3Rpb24nID8gdmFsdWUudmFsdWVPZigpIDogdmFsdWU7XG4gICAgdmFsdWUgPSBpc09iamVjdChvdGhlcikgPyAob3RoZXIgKyAnJykgOiBvdGhlcjtcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiArdmFsdWU7XG4gIH1cbiAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKHJlVHJpbSwgJycpO1xuICB2YXIgaXNCaW5hcnkgPSByZUlzQmluYXJ5LnRlc3QodmFsdWUpO1xuICByZXR1cm4gKGlzQmluYXJ5IHx8IHJlSXNPY3RhbC50ZXN0KHZhbHVlKSlcbiAgICA/IGZyZWVQYXJzZUludCh2YWx1ZS5zbGljZSgyKSwgaXNCaW5hcnkgPyAyIDogOClcbiAgICA6IChyZUlzQmFkSGV4LnRlc3QodmFsdWUpID8gTkFOIDogK3ZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0aHJvdHRsZTtcbiIsInZhciBnO1xyXG5cclxuLy8gVGhpcyB3b3JrcyBpbiBub24tc3RyaWN0IG1vZGVcclxuZyA9IChmdW5jdGlvbigpIHtcclxuXHRyZXR1cm4gdGhpcztcclxufSkoKTtcclxuXHJcbnRyeSB7XHJcblx0Ly8gVGhpcyB3b3JrcyBpZiBldmFsIGlzIGFsbG93ZWQgKHNlZSBDU1ApXHJcblx0ZyA9IGcgfHwgRnVuY3Rpb24oXCJyZXR1cm4gdGhpc1wiKSgpIHx8ICgxLCBldmFsKShcInRoaXNcIik7XHJcbn0gY2F0Y2ggKGUpIHtcclxuXHQvLyBUaGlzIHdvcmtzIGlmIHRoZSB3aW5kb3cgcmVmZXJlbmNlIGlzIGF2YWlsYWJsZVxyXG5cdGlmICh0eXBlb2Ygd2luZG93ID09PSBcIm9iamVjdFwiKSBnID0gd2luZG93O1xyXG59XHJcblxyXG4vLyBnIGNhbiBzdGlsbCBiZSB1bmRlZmluZWQsIGJ1dCBub3RoaW5nIHRvIGRvIGFib3V0IGl0Li4uXHJcbi8vIFdlIHJldHVybiB1bmRlZmluZWQsIGluc3RlYWQgb2Ygbm90aGluZyBoZXJlLCBzbyBpdCdzXHJcbi8vIGVhc2llciB0byBoYW5kbGUgdGhpcyBjYXNlLiBpZighZ2xvYmFsKSB7IC4uLn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZztcclxuIiwiLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqICBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqICBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxuICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5pbXBvcnQgeyBnZXRFbGVtZW50c0ZvclNvdXJjZUxpbmUgfSBmcm9tICcuL3Njcm9sbC1zeW5jJztcblxuZXhwb3J0IGNsYXNzIEFjdGl2ZUxpbmVNYXJrZXIge1xuXHRwcml2YXRlIF9jdXJyZW50OiBhbnk7XG5cblx0b25EaWRDaGFuZ2VUZXh0RWRpdG9yU2VsZWN0aW9uKGxpbmU6IG51bWJlcikge1xuXHRcdGNvbnN0IHsgcHJldmlvdXMgfSA9IGdldEVsZW1lbnRzRm9yU291cmNlTGluZShsaW5lKTtcblx0XHR0aGlzLl91cGRhdGUocHJldmlvdXMgJiYgcHJldmlvdXMuZWxlbWVudCk7XG5cdH1cblxuXHRfdXBkYXRlKGJlZm9yZTogSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQpIHtcblx0XHR0aGlzLl91bm1hcmtBY3RpdmVFbGVtZW50KHRoaXMuX2N1cnJlbnQpO1xuXHRcdHRoaXMuX21hcmtBY3RpdmVFbGVtZW50KGJlZm9yZSk7XG5cdFx0dGhpcy5fY3VycmVudCA9IGJlZm9yZTtcblx0fVxuXG5cdF91bm1hcmtBY3RpdmVFbGVtZW50KGVsZW1lbnQ6IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkKSB7XG5cdFx0aWYgKCFlbGVtZW50KSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGVsZW1lbnQuY2xhc3NOYW1lID0gZWxlbWVudC5jbGFzc05hbWUucmVwbGFjZSgvXFxiY29kZS1hY3RpdmUtbGluZVxcYi9nLCAnJyk7XG5cdH1cblxuXHRfbWFya0FjdGl2ZUVsZW1lbnQoZWxlbWVudDogSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQpIHtcblx0XHRpZiAoIWVsZW1lbnQpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0ZWxlbWVudC5jbGFzc05hbWUgKz0gJyBjb2RlLWFjdGl2ZS1saW5lJztcblx0fVxufSIsIi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiAgQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiAgTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLiBTZWUgTGljZW5zZS50eHQgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cbiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5leHBvcnQgZnVuY3Rpb24gb25jZURvY3VtZW50TG9hZGVkKGY6ICgpID0+IHZvaWQpIHtcblx0aWYgKGRvY3VtZW50LnJlYWR5U3RhdGUgPT09ICdsb2FkaW5nJyB8fCBkb2N1bWVudC5yZWFkeVN0YXRlIGFzIHN0cmluZyA9PT0gJ3VuaW5pdGlhbGl6ZWQnKSB7XG5cdFx0ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsIGYpO1xuXHR9IGVsc2Uge1xuXHRcdGYoKTtcblx0fVxufSIsIi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiAgQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiAgTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLiBTZWUgTGljZW5zZS50eHQgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cbiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5pbXBvcnQgeyBBY3RpdmVMaW5lTWFya2VyIH0gZnJvbSAnLi9hY3RpdmVMaW5lTWFya2VyJztcbmltcG9ydCB7IG9uY2VEb2N1bWVudExvYWRlZCB9IGZyb20gJy4vZXZlbnRzJztcbmltcG9ydCB7IGNyZWF0ZVBvc3RlckZvclZzQ29kZSB9IGZyb20gJy4vbWVzc2FnaW5nJztcbmltcG9ydCB7IGdldEVkaXRvckxpbmVOdW1iZXJGb3JQYWdlT2Zmc2V0LCBzY3JvbGxUb1JldmVhbFNvdXJjZUxpbmUsIGdldExpbmVFbGVtZW50Rm9yRnJhZ21lbnQgfSBmcm9tICcuL3Njcm9sbC1zeW5jJztcbmltcG9ydCB7IGdldFNldHRpbmdzLCBnZXREYXRhIH0gZnJvbSAnLi9zZXR0aW5ncyc7XG5pbXBvcnQgdGhyb3R0bGUgPSByZXF1aXJlKCdsb2Rhc2gudGhyb3R0bGUnKTtcblxuZGVjbGFyZSB2YXIgYWNxdWlyZVZzQ29kZUFwaTogYW55O1xuXG5sZXQgc2Nyb2xsRGlzYWJsZWQgPSB0cnVlO1xuY29uc3QgbWFya2VyID0gbmV3IEFjdGl2ZUxpbmVNYXJrZXIoKTtcbmNvbnN0IHNldHRpbmdzID0gZ2V0U2V0dGluZ3MoKTtcblxuY29uc3QgdnNjb2RlID0gYWNxdWlyZVZzQ29kZUFwaSgpO1xuXG4vLyBTZXQgVlMgQ29kZSBzdGF0ZVxubGV0IHN0YXRlID0gZ2V0RGF0YTx7IGxpbmU6IG51bWJlciwgIGZyYWdtZW50OiBzdHJpbmcgfT4oJ2RhdGEtc3RhdGUnKTtcbnZzY29kZS5zZXRTdGF0ZShzdGF0ZSk7XG5cbmNvbnN0IG1lc3NhZ2luZyA9IGNyZWF0ZVBvc3RlckZvclZzQ29kZSh2c2NvZGUpO1xuXG53aW5kb3cuY3NwQWxlcnRlci5zZXRQb3N0ZXIobWVzc2FnaW5nKTtcbndpbmRvdy5zdHlsZUxvYWRpbmdNb25pdG9yLnNldFBvc3RlcihtZXNzYWdpbmcpO1xuXG53aW5kb3cub25sb2FkID0gKCkgPT4ge1xuXHR1cGRhdGVJbWFnZVNpemVzKCk7XG59O1xuXG5vbmNlRG9jdW1lbnRMb2FkZWQoKCkgPT4ge1xuXHRpZiAoc2V0dGluZ3Muc2Nyb2xsUHJldmlld1dpdGhFZGl0b3IpIHtcblx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdC8vIFRyeSB0byBzY3JvbGwgdG8gZnJhZ21lbnQgaWYgYXZhaWxhYmxlXG5cdFx0XHRpZiAoc3RhdGUuZnJhZ21lbnQpIHtcblx0XHRcdFx0Y29uc3QgZWxlbWVudCA9IGdldExpbmVFbGVtZW50Rm9yRnJhZ21lbnQoc3RhdGUuZnJhZ21lbnQpO1xuXHRcdFx0XHRpZiAoZWxlbWVudCkge1xuXHRcdFx0XHRcdHNjcm9sbERpc2FibGVkID0gdHJ1ZTtcblx0XHRcdFx0XHRzY3JvbGxUb1JldmVhbFNvdXJjZUxpbmUoZWxlbWVudC5saW5lKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y29uc3QgaW5pdGlhbExpbmUgPSArc2V0dGluZ3MubGluZTtcblx0XHRcdFx0aWYgKCFpc05hTihpbml0aWFsTGluZSkpIHtcblx0XHRcdFx0XHRzY3JvbGxEaXNhYmxlZCA9IHRydWU7XG5cdFx0XHRcdFx0c2Nyb2xsVG9SZXZlYWxTb3VyY2VMaW5lKGluaXRpYWxMaW5lKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0sIDApO1xuXHR9XG59KTtcblxuY29uc3Qgb25VcGRhdGVWaWV3ID0gKCgpID0+IHtcblx0Y29uc3QgZG9TY3JvbGwgPSB0aHJvdHRsZSgobGluZTogbnVtYmVyKSA9PiB7XG5cdFx0c2Nyb2xsRGlzYWJsZWQgPSB0cnVlO1xuXHRcdHNjcm9sbFRvUmV2ZWFsU291cmNlTGluZShsaW5lKTtcblx0fSwgNTApO1xuXG5cdHJldHVybiAobGluZTogbnVtYmVyLCBzZXR0aW5nczogYW55KSA9PiB7XG5cdFx0aWYgKCFpc05hTihsaW5lKSkge1xuXHRcdFx0c2V0dGluZ3MubGluZSA9IGxpbmU7XG5cdFx0XHRkb1Njcm9sbChsaW5lKTtcblx0XHR9XG5cdH07XG59KSgpO1xuXG5sZXQgdXBkYXRlSW1hZ2VTaXplcyA9IHRocm90dGxlKCgpID0+IHtcblx0Y29uc3QgaW1hZ2VJbmZvOiB7IGlkOiBzdHJpbmcsIGhlaWdodDogbnVtYmVyLCB3aWR0aDogbnVtYmVyIH1bXSA9IFtdO1xuXHRsZXQgaW1hZ2VzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2ltZycpO1xuXHRpZiAoaW1hZ2VzKSB7XG5cdFx0bGV0IGk7XG5cdFx0Zm9yIChpID0gMDsgaSA8IGltYWdlcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0Y29uc3QgaW1nID0gaW1hZ2VzW2ldO1xuXG5cdFx0XHRpZiAoaW1nLmNsYXNzTGlzdC5jb250YWlucygnbG9hZGluZycpKSB7XG5cdFx0XHRcdGltZy5jbGFzc0xpc3QucmVtb3ZlKCdsb2FkaW5nJyk7XG5cdFx0XHR9XG5cblx0XHRcdGltYWdlSW5mby5wdXNoKHtcblx0XHRcdFx0aWQ6IGltZy5pZCxcblx0XHRcdFx0aGVpZ2h0OiBpbWcuaGVpZ2h0LFxuXHRcdFx0XHR3aWR0aDogaW1nLndpZHRoXG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHRtZXNzYWdpbmcucG9zdE1lc3NhZ2UoJ2NhY2hlSW1hZ2VTaXplcycsIGltYWdlSW5mbyk7XG5cdH1cbn0sIDUwKTtcblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsICgpID0+IHtcblx0c2Nyb2xsRGlzYWJsZWQgPSB0cnVlO1xuXHR1cGRhdGVJbWFnZVNpemVzKCk7XG59LCB0cnVlKTtcblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBldmVudCA9PiB7XG5cdGlmIChldmVudC5kYXRhLnNvdXJjZSAhPT0gc2V0dGluZ3Muc291cmNlKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0c3dpdGNoIChldmVudC5kYXRhLnR5cGUpIHtcblx0XHRjYXNlICdvbkRpZENoYW5nZVRleHRFZGl0b3JTZWxlY3Rpb24nOlxuXHRcdFx0bWFya2VyLm9uRGlkQ2hhbmdlVGV4dEVkaXRvclNlbGVjdGlvbihldmVudC5kYXRhLmxpbmUpO1xuXHRcdFx0YnJlYWs7XG5cblx0XHRjYXNlICd1cGRhdGVWaWV3Jzpcblx0XHRcdG9uVXBkYXRlVmlldyhldmVudC5kYXRhLmxpbmUsIHNldHRpbmdzKTtcblx0XHRcdGJyZWFrO1xuXHR9XG59LCBmYWxzZSk7XG5cbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2RibGNsaWNrJywgZXZlbnQgPT4ge1xuXHRpZiAoIXNldHRpbmdzLmRvdWJsZUNsaWNrVG9Td2l0Y2hUb0VkaXRvcikge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdC8vIElnbm9yZSBjbGlja3Mgb24gbGlua3Ncblx0Zm9yIChsZXQgbm9kZSA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDsgbm9kZTsgbm9kZSA9IG5vZGUucGFyZW50Tm9kZSBhcyBIVE1MRWxlbWVudCkge1xuXHRcdGlmIChub2RlLnRhZ05hbWUgPT09ICdBJykge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0fVxuXG5cdGNvbnN0IG9mZnNldCA9IGV2ZW50LnBhZ2VZO1xuXHRjb25zdCBsaW5lID0gZ2V0RWRpdG9yTGluZU51bWJlckZvclBhZ2VPZmZzZXQob2Zmc2V0KTtcblx0aWYgKHR5cGVvZiBsaW5lID09PSAnbnVtYmVyJyAmJiAhaXNOYU4obGluZSkpIHtcblx0XHRtZXNzYWdpbmcucG9zdE1lc3NhZ2UoJ2RpZENsaWNrJywgeyBsaW5lOiBNYXRoLmZsb29yKGxpbmUpIH0pO1xuXHR9XG59KTtcblxuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBldmVudCA9PiB7XG5cdGlmICghZXZlbnQpIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHRsZXQgbm9kZTogYW55ID0gZXZlbnQudGFyZ2V0O1xuXHR3aGlsZSAobm9kZSkge1xuXHRcdGlmIChub2RlLnRhZ05hbWUgJiYgbm9kZS50YWdOYW1lID09PSAnQScgJiYgbm9kZS5ocmVmKSB7XG5cdFx0XHRpZiAobm9kZS5nZXRBdHRyaWJ1dGUoJ2hyZWYnKS5zdGFydHNXaXRoKCcjJykpIHtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRpZiAobm9kZS5ocmVmLnN0YXJ0c1dpdGgoJ2ZpbGU6Ly8nKSB8fCBub2RlLmhyZWYuc3RhcnRzV2l0aCgndnNjb2RlLXJlc291cmNlOicpIHx8IG5vZGUuaHJlZi5zdGFydHNXaXRoKHNldHRpbmdzLndlYnZpZXdSZXNvdXJjZVJvb3QpKSB7XG5cdFx0XHRcdGNvbnN0IFtwYXRoLCBmcmFnbWVudF0gPSBub2RlLmhyZWYucmVwbGFjZSgvXihmaWxlOlxcL1xcL3x2c2NvZGUtcmVzb3VyY2U6KS9pLCAnJykucmVwbGFjZShuZXcgUmVnRXhwKGBeJHtlc2NhcGVSZWdFeHAoc2V0dGluZ3Mud2Vidmlld1Jlc291cmNlUm9vdCl9YCkpLnNwbGl0KCcjJyk7XG5cdFx0XHRcdG1lc3NhZ2luZy5wb3N0TWVzc2FnZSgnY2xpY2tMaW5rJywgeyBwYXRoLCBmcmFnbWVudCB9KTtcblx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXHRcdG5vZGUgPSBub2RlLnBhcmVudE5vZGU7XG5cdH1cbn0sIHRydWUpO1xuXG5pZiAoc2V0dGluZ3Muc2Nyb2xsRWRpdG9yV2l0aFByZXZpZXcpIHtcblx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRocm90dGxlKCgpID0+IHtcblx0XHRpZiAoc2Nyb2xsRGlzYWJsZWQpIHtcblx0XHRcdHNjcm9sbERpc2FibGVkID0gZmFsc2U7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnN0IGxpbmUgPSBnZXRFZGl0b3JMaW5lTnVtYmVyRm9yUGFnZU9mZnNldCh3aW5kb3cuc2Nyb2xsWSk7XG5cdFx0XHRpZiAodHlwZW9mIGxpbmUgPT09ICdudW1iZXInICYmICFpc05hTihsaW5lKSkge1xuXHRcdFx0XHRtZXNzYWdpbmcucG9zdE1lc3NhZ2UoJ3JldmVhbExpbmUnLCB7IGxpbmUgfSk7XG5cdFx0XHRcdHN0YXRlLmxpbmUgPSBsaW5lO1xuXHRcdFx0XHR2c2NvZGUuc2V0U3RhdGUoc3RhdGUpO1xuXHRcdFx0fVxuXHRcdH1cblx0fSwgNTApKTtcbn1cblxuZnVuY3Rpb24gZXNjYXBlUmVnRXhwKHRleHQ6IHN0cmluZykge1xuXHRyZXR1cm4gdGV4dC5yZXBsYWNlKC9bLVtcXF17fSgpKis/LixcXFxcXiR8I1xcc10vZywgJ1xcXFwkJicpO1xufVxuIiwiLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqICBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqICBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxuICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbmltcG9ydCB7IGdldFNldHRpbmdzIH0gZnJvbSAnLi9zZXR0aW5ncyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWVzc2FnZVBvc3RlciB7XG5cdC8qKlxuXHQgKiBQb3N0IGEgbWVzc2FnZSB0byB0aGUgbWFya2Rvd24gZXh0ZW5zaW9uXG5cdCAqL1xuXHRwb3N0TWVzc2FnZSh0eXBlOiBzdHJpbmcsIGJvZHk6IG9iamVjdCk6IHZvaWQ7XG59XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVQb3N0ZXJGb3JWc0NvZGUgPSAodnNjb2RlOiBhbnkpID0+IHtcblx0cmV0dXJuIG5ldyBjbGFzcyBpbXBsZW1lbnRzIE1lc3NhZ2VQb3N0ZXIge1xuXHRcdHBvc3RNZXNzYWdlKHR5cGU6IHN0cmluZywgYm9keTogb2JqZWN0KTogdm9pZCB7XG5cdFx0XHR2c2NvZGUucG9zdE1lc3NhZ2Uoe1xuXHRcdFx0XHR0eXBlLFxuXHRcdFx0XHRzb3VyY2U6IGdldFNldHRpbmdzKCkuc291cmNlLFxuXHRcdFx0XHRib2R5XG5cdFx0XHR9KTtcblx0XHR9XG5cdH07XG59O1xuXG4iLCIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXG4gKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuaW1wb3J0IHsgZ2V0U2V0dGluZ3MgfSBmcm9tICcuL3NldHRpbmdzJztcblxuXG5mdW5jdGlvbiBjbGFtcChtaW46IG51bWJlciwgbWF4OiBudW1iZXIsIHZhbHVlOiBudW1iZXIpIHtcblx0cmV0dXJuIE1hdGgubWluKG1heCwgTWF0aC5tYXgobWluLCB2YWx1ZSkpO1xufVxuXG5mdW5jdGlvbiBjbGFtcExpbmUobGluZTogbnVtYmVyKSB7XG5cdHJldHVybiBjbGFtcCgwLCBnZXRTZXR0aW5ncygpLmxpbmVDb3VudCAtIDEsIGxpbmUpO1xufVxuXG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29kZUxpbmVFbGVtZW50IHtcblx0ZWxlbWVudDogSFRNTEVsZW1lbnQ7XG5cdGxpbmU6IG51bWJlcjtcbn1cblxuY29uc3QgZ2V0Q29kZUxpbmVFbGVtZW50cyA9ICgoKSA9PiB7XG5cdGxldCBlbGVtZW50czogQ29kZUxpbmVFbGVtZW50W107XG5cdHJldHVybiAoKSA9PiB7XG5cdFx0aWYgKCFlbGVtZW50cykge1xuXHRcdFx0ZWxlbWVudHMgPSBbeyBlbGVtZW50OiBkb2N1bWVudC5ib2R5LCBsaW5lOiAwIH1dO1xuXHRcdFx0Zm9yIChjb25zdCBlbGVtZW50IG9mIGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ2NvZGUtbGluZScpKSB7XG5cdFx0XHRcdGNvbnN0IGxpbmUgPSArZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtbGluZScpITtcblx0XHRcdFx0aWYgKCFpc05hTihsaW5lKSkge1xuXHRcdFx0XHRcdGVsZW1lbnRzLnB1c2goeyBlbGVtZW50OiBlbGVtZW50IGFzIEhUTUxFbGVtZW50LCBsaW5lIH0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBlbGVtZW50cztcblx0fTtcbn0pKCk7XG5cbi8qKlxuICogRmluZCB0aGUgaHRtbCBlbGVtZW50cyB0aGF0IG1hcCB0byBhIHNwZWNpZmljIHRhcmdldCBsaW5lIGluIHRoZSBlZGl0b3IuXG4gKlxuICogSWYgYW4gZXhhY3QgbWF0Y2gsIHJldHVybnMgYSBzaW5nbGUgZWxlbWVudC4gSWYgdGhlIGxpbmUgaXMgYmV0d2VlbiBlbGVtZW50cyxcbiAqIHJldHVybnMgdGhlIGVsZW1lbnQgcHJpb3IgdG8gYW5kIHRoZSBlbGVtZW50IGFmdGVyIHRoZSBnaXZlbiBsaW5lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RWxlbWVudHNGb3JTb3VyY2VMaW5lKHRhcmdldExpbmU6IG51bWJlcik6IHsgcHJldmlvdXM6IENvZGVMaW5lRWxlbWVudDsgbmV4dD86IENvZGVMaW5lRWxlbWVudDsgfSB7XG5cdGNvbnN0IGxpbmVOdW1iZXIgPSBNYXRoLmZsb29yKHRhcmdldExpbmUpO1xuXHRjb25zdCBsaW5lcyA9IGdldENvZGVMaW5lRWxlbWVudHMoKTtcblx0bGV0IHByZXZpb3VzID0gbGluZXNbMF0gfHwgbnVsbDtcblx0Zm9yIChjb25zdCBlbnRyeSBvZiBsaW5lcykge1xuXHRcdGlmIChlbnRyeS5saW5lID09PSBsaW5lTnVtYmVyKSB7XG5cdFx0XHRyZXR1cm4geyBwcmV2aW91czogZW50cnksIG5leHQ6IHVuZGVmaW5lZCB9O1xuXHRcdH0gZWxzZSBpZiAoZW50cnkubGluZSA+IGxpbmVOdW1iZXIpIHtcblx0XHRcdHJldHVybiB7IHByZXZpb3VzLCBuZXh0OiBlbnRyeSB9O1xuXHRcdH1cblx0XHRwcmV2aW91cyA9IGVudHJ5O1xuXHR9XG5cdHJldHVybiB7IHByZXZpb3VzIH07XG59XG5cbi8qKlxuICogRmluZCB0aGUgaHRtbCBlbGVtZW50cyB0aGF0IGFyZSBhdCBhIHNwZWNpZmljIHBpeGVsIG9mZnNldCBvbiB0aGUgcGFnZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldExpbmVFbGVtZW50c0F0UGFnZU9mZnNldChvZmZzZXQ6IG51bWJlcik6IHsgcHJldmlvdXM6IENvZGVMaW5lRWxlbWVudDsgbmV4dD86IENvZGVMaW5lRWxlbWVudDsgfSB7XG5cdGNvbnN0IGxpbmVzID0gZ2V0Q29kZUxpbmVFbGVtZW50cygpO1xuXHRjb25zdCBwb3NpdGlvbiA9IG9mZnNldCAtIHdpbmRvdy5zY3JvbGxZO1xuXHRsZXQgbG8gPSAtMTtcblx0bGV0IGhpID0gbGluZXMubGVuZ3RoIC0gMTtcblx0d2hpbGUgKGxvICsgMSA8IGhpKSB7XG5cdFx0Y29uc3QgbWlkID0gTWF0aC5mbG9vcigobG8gKyBoaSkgLyAyKTtcblx0XHRjb25zdCBib3VuZHMgPSBsaW5lc1ttaWRdLmVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cdFx0aWYgKGJvdW5kcy50b3AgKyBib3VuZHMuaGVpZ2h0ID49IHBvc2l0aW9uKSB7XG5cdFx0XHRoaSA9IG1pZDtcblx0XHR9XG5cdFx0ZWxzZSB7XG5cdFx0XHRsbyA9IG1pZDtcblx0XHR9XG5cdH1cblx0Y29uc3QgaGlFbGVtZW50ID0gbGluZXNbaGldO1xuXHRjb25zdCBoaUJvdW5kcyA9IGhpRWxlbWVudC5lbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXHRpZiAoaGkgPj0gMSAmJiBoaUJvdW5kcy50b3AgPiBwb3NpdGlvbikge1xuXHRcdGNvbnN0IGxvRWxlbWVudCA9IGxpbmVzW2xvXTtcblx0XHRyZXR1cm4geyBwcmV2aW91czogbG9FbGVtZW50LCBuZXh0OiBoaUVsZW1lbnQgfTtcblx0fVxuXHRyZXR1cm4geyBwcmV2aW91czogaGlFbGVtZW50IH07XG59XG5cbi8qKlxuICogQXR0ZW1wdCB0byByZXZlYWwgdGhlIGVsZW1lbnQgZm9yIGEgc291cmNlIGxpbmUgaW4gdGhlIGVkaXRvci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNjcm9sbFRvUmV2ZWFsU291cmNlTGluZShsaW5lOiBudW1iZXIpIHtcblx0aWYgKCFnZXRTZXR0aW5ncygpLnNjcm9sbFByZXZpZXdXaXRoRWRpdG9yKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0aWYgKGxpbmUgPD0gMCkge1xuXHRcdHdpbmRvdy5zY3JvbGwod2luZG93LnNjcm9sbFgsIDApO1xuXHRcdHJldHVybjtcblx0fVxuXG5cdGNvbnN0IHsgcHJldmlvdXMsIG5leHQgfSA9IGdldEVsZW1lbnRzRm9yU291cmNlTGluZShsaW5lKTtcblx0aWYgKCFwcmV2aW91cykge1xuXHRcdHJldHVybjtcblx0fVxuXHRsZXQgc2Nyb2xsVG8gPSAwO1xuXHRjb25zdCByZWN0ID0gcHJldmlvdXMuZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblx0Y29uc3QgcHJldmlvdXNUb3AgPSByZWN0LnRvcDtcblx0aWYgKG5leHQgJiYgbmV4dC5saW5lICE9PSBwcmV2aW91cy5saW5lKSB7XG5cdFx0Ly8gQmV0d2VlbiB0d28gZWxlbWVudHMuIEdvIHRvIHBlcmNlbnRhZ2Ugb2Zmc2V0IGJldHdlZW4gdGhlbS5cblx0XHRjb25zdCBiZXR3ZWVuUHJvZ3Jlc3MgPSAobGluZSAtIHByZXZpb3VzLmxpbmUpIC8gKG5leHQubGluZSAtIHByZXZpb3VzLmxpbmUpO1xuXHRcdGNvbnN0IGVsZW1lbnRPZmZzZXQgPSBuZXh0LmVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wIC0gcHJldmlvdXNUb3A7XG5cdFx0c2Nyb2xsVG8gPSBwcmV2aW91c1RvcCArIGJldHdlZW5Qcm9ncmVzcyAqIGVsZW1lbnRPZmZzZXQ7XG5cdH0gZWxzZSB7XG5cdFx0Y29uc3QgcHJvZ3Jlc3NJbkVsZW1lbnQgPSBsaW5lIC0gTWF0aC5mbG9vcihsaW5lKTtcblx0XHRzY3JvbGxUbyA9IHByZXZpb3VzVG9wICsgKHJlY3QuaGVpZ2h0ICogcHJvZ3Jlc3NJbkVsZW1lbnQpO1xuXHR9XG5cdHdpbmRvdy5zY3JvbGwod2luZG93LnNjcm9sbFgsIE1hdGgubWF4KDEsIHdpbmRvdy5zY3JvbGxZICsgc2Nyb2xsVG8pKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEVkaXRvckxpbmVOdW1iZXJGb3JQYWdlT2Zmc2V0KG9mZnNldDogbnVtYmVyKSB7XG5cdGNvbnN0IHsgcHJldmlvdXMsIG5leHQgfSA9IGdldExpbmVFbGVtZW50c0F0UGFnZU9mZnNldChvZmZzZXQpO1xuXHRpZiAocHJldmlvdXMpIHtcblx0XHRjb25zdCBwcmV2aW91c0JvdW5kcyA9IHByZXZpb3VzLmVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cdFx0Y29uc3Qgb2Zmc2V0RnJvbVByZXZpb3VzID0gKG9mZnNldCAtIHdpbmRvdy5zY3JvbGxZIC0gcHJldmlvdXNCb3VuZHMudG9wKTtcblx0XHRpZiAobmV4dCkge1xuXHRcdFx0Y29uc3QgcHJvZ3Jlc3NCZXR3ZWVuRWxlbWVudHMgPSBvZmZzZXRGcm9tUHJldmlvdXMgLyAobmV4dC5lbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcCAtIHByZXZpb3VzQm91bmRzLnRvcCk7XG5cdFx0XHRjb25zdCBsaW5lID0gcHJldmlvdXMubGluZSArIHByb2dyZXNzQmV0d2VlbkVsZW1lbnRzICogKG5leHQubGluZSAtIHByZXZpb3VzLmxpbmUpO1xuXHRcdFx0cmV0dXJuIGNsYW1wTGluZShsaW5lKTtcblx0XHR9XG5cdFx0ZWxzZSB7XG5cdFx0XHRjb25zdCBwcm9ncmVzc1dpdGhpbkVsZW1lbnQgPSBvZmZzZXRGcm9tUHJldmlvdXMgLyAocHJldmlvdXNCb3VuZHMuaGVpZ2h0KTtcblx0XHRcdGNvbnN0IGxpbmUgPSBwcmV2aW91cy5saW5lICsgcHJvZ3Jlc3NXaXRoaW5FbGVtZW50O1xuXHRcdFx0cmV0dXJuIGNsYW1wTGluZShsaW5lKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogVHJ5IHRvIGZpbmQgdGhlIGh0bWwgZWxlbWVudCBieSB1c2luZyBhIGZyYWdtZW50IGlkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRMaW5lRWxlbWVudEZvckZyYWdtZW50KGZyYWdtZW50OiBzdHJpbmcpOiBDb2RlTGluZUVsZW1lbnQgfCB1bmRlZmluZWQge1xuXHRyZXR1cm4gZ2V0Q29kZUxpbmVFbGVtZW50cygpLmZpbmQoKGVsZW1lbnQpID0+IHtcblx0XHRyZXR1cm4gZWxlbWVudC5lbGVtZW50LmlkID09PSBmcmFnbWVudDtcblx0fSk7XG59XG4iLCIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXG4gKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuZXhwb3J0IGludGVyZmFjZSBQcmV2aWV3U2V0dGluZ3Mge1xuXHRyZWFkb25seSBzb3VyY2U6IHN0cmluZztcblx0cmVhZG9ubHkgbGluZTogbnVtYmVyO1xuXHRyZWFkb25seSBsaW5lQ291bnQ6IG51bWJlcjtcblx0cmVhZG9ubHkgc2Nyb2xsUHJldmlld1dpdGhFZGl0b3I/OiBib29sZWFuO1xuXHRyZWFkb25seSBzY3JvbGxFZGl0b3JXaXRoUHJldmlldzogYm9vbGVhbjtcblx0cmVhZG9ubHkgZGlzYWJsZVNlY3VyaXR5V2FybmluZ3M6IGJvb2xlYW47XG5cdHJlYWRvbmx5IGRvdWJsZUNsaWNrVG9Td2l0Y2hUb0VkaXRvcjogYm9vbGVhbjtcblx0cmVhZG9ubHkgd2Vidmlld1Jlc291cmNlUm9vdDogc3RyaW5nO1xufVxuXG5sZXQgY2FjaGVkU2V0dGluZ3M6IFByZXZpZXdTZXR0aW5ncyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldERhdGE8VCA9IHt9PihrZXk6IHN0cmluZyk6IFQge1xuXHRjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3ZzY29kZS1tYXJrZG93bi1wcmV2aWV3LWRhdGEnKTtcblx0aWYgKGVsZW1lbnQpIHtcblx0XHRjb25zdCBkYXRhID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoa2V5KTtcblx0XHRpZiAoZGF0YSkge1xuXHRcdFx0cmV0dXJuIEpTT04ucGFyc2UoZGF0YSk7XG5cdFx0fVxuXHR9XG5cblx0dGhyb3cgbmV3IEVycm9yKGBDb3VsZCBub3QgbG9hZCBkYXRhIGZvciAke2tleX1gKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNldHRpbmdzKCk6IFByZXZpZXdTZXR0aW5ncyB7XG5cdGlmIChjYWNoZWRTZXR0aW5ncykge1xuXHRcdHJldHVybiBjYWNoZWRTZXR0aW5ncztcblx0fVxuXG5cdGNhY2hlZFNldHRpbmdzID0gZ2V0RGF0YSgnZGF0YS1zZXR0aW5ncycpO1xuXHRpZiAoY2FjaGVkU2V0dGluZ3MpIHtcblx0XHRyZXR1cm4gY2FjaGVkU2V0dGluZ3M7XG5cdH1cblxuXHR0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBsb2FkIHNldHRpbmdzJyk7XG59XG4iXSwic291cmNlUm9vdCI6IiJ9 \ No newline at end of file diff --git a/extensions/markdown-language-features/preview-src/index.ts b/extensions/markdown-language-features/preview-src/index.ts index f78ae2f7972..b12614fe9ec 100644 --- a/extensions/markdown-language-features/preview-src/index.ts +++ b/extensions/markdown-language-features/preview-src/index.ts @@ -6,7 +6,7 @@ import { ActiveLineMarker } from './activeLineMarker'; import { onceDocumentLoaded } from './events'; import { createPosterForVsCode } from './messaging'; -import { getEditorLineNumberForPageOffset, scrollToRevealSourceLine } from './scroll-sync'; +import { getEditorLineNumberForPageOffset, scrollToRevealSourceLine, getLineElementForFragment } from './scroll-sync'; import { getSettings, getData } from './settings'; import throttle = require('lodash.throttle'); @@ -19,7 +19,7 @@ const settings = getSettings(); const vscode = acquireVsCodeApi(); // Set VS Code state -let state = getData<{ line: number }>('data-state'); +let state = getData<{ line: number, fragment: string }>('data-state'); vscode.setState(state); const messaging = createPosterForVsCode(vscode); @@ -34,10 +34,19 @@ window.onload = () => { onceDocumentLoaded(() => { if (settings.scrollPreviewWithEditor) { setTimeout(() => { - const initialLine = +settings.line; - if (!isNaN(initialLine)) { - scrollDisabled = true; - scrollToRevealSourceLine(initialLine); + // Try to scroll to fragment if available + if (state.fragment) { + const element = getLineElementForFragment(state.fragment); + if (element) { + scrollDisabled = true; + scrollToRevealSourceLine(element.line); + } + } else { + const initialLine = +settings.line; + if (!isNaN(initialLine)) { + scrollDisabled = true; + scrollToRevealSourceLine(initialLine); + } } }, 0); } @@ -161,4 +170,4 @@ if (settings.scrollEditorWithPreview) { function escapeRegExp(text: string) { return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); -} \ No newline at end of file +} diff --git a/extensions/markdown-language-features/preview-src/scroll-sync.ts b/extensions/markdown-language-features/preview-src/scroll-sync.ts index 4fe8987f6cd..eee320ac8e7 100644 --- a/extensions/markdown-language-features/preview-src/scroll-sync.ts +++ b/extensions/markdown-language-features/preview-src/scroll-sync.ts @@ -134,3 +134,12 @@ export function getEditorLineNumberForPageOffset(offset: number) { } return null; } + +/** + * Try to find the html element by using a fragment id + */ +export function getLineElementForFragment(fragment: string): CodeLineElement | undefined { + return getCodeLineElements().find((element) => { + return element.element.id === fragment; + }); +} diff --git a/extensions/markdown-language-features/src/features/preview.ts b/extensions/markdown-language-features/src/features/preview.ts index c874f5791ed..694a4fbb13c 100644 --- a/extensions/markdown-language-features/src/features/preview.ts +++ b/extensions/markdown-language-features/src/features/preview.ts @@ -89,6 +89,7 @@ export class MarkdownPreview extends Disposable { private isScrolling = false; private _disposed: boolean = false; private imageInfo: { id: string, width: number, height: number }[] = []; + private scrollToFragment: string | undefined; public static async revive( webview: vscode.WebviewPanel, @@ -264,7 +265,8 @@ export class MarkdownPreview extends Disposable { locked: this._locked, line: this.line, resourceColumn: this.resourceColumn, - imageInfo: this.imageInfo + imageInfo: this.imageInfo, + fragment: this.scrollToFragment }; } @@ -284,8 +286,12 @@ export class MarkdownPreview extends Disposable { public update(resource: vscode.Uri) { const editor = vscode.window.activeTextEditor; + // Reposition scroll preview, position scroll to the top if active text editor + // doesn't corresponds with preview if (editor && editor.document.uri.fsPath === resource.fsPath) { this.line = getVisibleLine(editor); + } else { + this.line = 0; } // If we have changed resources, cancel any pending updates @@ -520,11 +526,15 @@ export class MarkdownPreview extends Disposable { } private async onDidClickPreviewLink(path: string, fragment: string | undefined) { + this.scrollToFragment = undefined; const config = vscode.workspace.getConfiguration('markdown', this.resource); const openLinks = config.get('preview.openMarkdownLinks', 'inPreview'); if (openLinks === 'inPreview') { const markdownLink = await resolveLinkToMarkdownFile(path); if (markdownLink) { + if (fragment) { + this.scrollToFragment = fragment; + } this.update(markdownLink); return; } From 9fed4cfd3e02eef6510414d793e14226fe2a801f Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 19 Aug 2019 17:10:39 +0200 Subject: [PATCH 782/861] #79429 --- src/vs/workbench/contrib/files/browser/views/emptyView.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/contrib/files/browser/views/emptyView.ts b/src/vs/workbench/contrib/files/browser/views/emptyView.ts index 8f097112f00..e7e9ecf5f61 100644 --- a/src/vs/workbench/contrib/files/browser/views/emptyView.ts +++ b/src/vs/workbench/contrib/files/browser/views/emptyView.ts @@ -59,7 +59,6 @@ export class EmptyView extends ViewletPanel { container.appendChild(titleContainer); this.titleElement = document.createElement('span'); - this.titleElement.textContent = name; titleContainer.appendChild(this.titleElement); } From 90a35ecc5d4c6b79b3083bcdb0c6430b8674cc1c Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 19 Aug 2019 17:13:18 +0200 Subject: [PATCH 783/861] TSLint: show a warning when accessing node.js globals in common|browser (#79222) * trivial first cut * document where globals are from * improve rule detection * fix "gulp tslint" task * share rules * enable more rules * also add a rule for DOM --- build/gulpfile.hygiene.js | 49 ++++++++++++++++++------ build/lib/tslint/abstractGlobalsRule.js | 40 +++++++++++++++++++ build/lib/tslint/abstractGlobalsRule.ts | 51 +++++++++++++++++++++++++ build/lib/tslint/noDOMGlobalsRule.js | 34 +++++++++++++++++ build/lib/tslint/noDOMGlobalsRule.ts | 45 ++++++++++++++++++++++ build/lib/tslint/noNodeJSGlobalsRule.js | 40 +++++++++++++++++++ build/lib/tslint/noNodeJSGlobalsRule.ts | 51 +++++++++++++++++++++++++ tslint.json | 44 +++++++++++++++++++++ 8 files changed, 343 insertions(+), 11 deletions(-) create mode 100644 build/lib/tslint/abstractGlobalsRule.js create mode 100644 build/lib/tslint/abstractGlobalsRule.ts create mode 100644 build/lib/tslint/noDOMGlobalsRule.js create mode 100644 build/lib/tslint/noDOMGlobalsRule.ts create mode 100644 build/lib/tslint/noNodeJSGlobalsRule.js create mode 100644 build/lib/tslint/noNodeJSGlobalsRule.ts diff --git a/build/gulpfile.hygiene.js b/build/gulpfile.hygiene.js index f6594804322..a05fff4a1bd 100644 --- a/build/gulpfile.hygiene.js +++ b/build/gulpfile.hygiene.js @@ -135,20 +135,39 @@ const eslintFilter = [ '!**/test/**' ]; -const tslintFilter = [ - 'src/**/*.ts', - 'test/**/*.ts', - 'extensions/**/*.ts', +const tslintBaseFilter = [ '!**/fixtures/**', '!**/typings/**', '!**/node_modules/**', - '!extensions/typescript/test/colorize-fixtures/**', + '!extensions/typescript-basics/test/colorize-fixtures/**', '!extensions/vscode-api-tests/testWorkspace/**', '!extensions/vscode-api-tests/testWorkspace2/**', '!extensions/**/*.test.ts', '!extensions/html-language-features/server/lib/jquery.d.ts' ]; +const tslintCoreFilter = [ + 'src/**/*.ts', + 'test/**/*.ts', + '!extensions/**/*.ts', + '!test/smoke/**', + ...tslintBaseFilter +]; + +const tslintExtensionsFilter = [ + 'extensions/**/*.ts', + '!src/**/*.ts', + '!test/**/*.ts', + ...tslintBaseFilter +]; + +const tslintHygieneFilter = [ + 'src/**/*.ts', + 'test/**/*.ts', + 'extensions/**/*.ts', + ...tslintBaseFilter +]; + const copyrightHeaderLines = [ '/*---------------------------------------------------------------------------------------------', ' * Copyright (c) Microsoft Corporation. All rights reserved.', @@ -165,12 +184,20 @@ gulp.task('eslint', () => { }); gulp.task('tslint', () => { - const options = { emitError: true }; + return es.merge([ - return vfs.src(all, { base: '.', follow: true, allowEmpty: true }) - .pipe(filter(tslintFilter)) - .pipe(gulptslint.default({ rulesDirectory: 'build/lib/tslint' })) - .pipe(gulptslint.default.report(options)); + // Core: include type information (required by certain rules like no-nodejs-globals) + vfs.src(all, { base: '.', follow: true, allowEmpty: true }) + .pipe(filter(tslintCoreFilter)) + .pipe(gulptslint.default({ rulesDirectory: 'build/lib/tslint', program: tslint.Linter.createProgram('src/tsconfig.json') })) + .pipe(gulptslint.default.report({ emitError: true })), + + // Exenstions: do not include type information + vfs.src(all, { base: '.', follow: true, allowEmpty: true }) + .pipe(filter(tslintExtensionsFilter)) + .pipe(gulptslint.default({ rulesDirectory: 'build/lib/tslint' })) + .pipe(gulptslint.default.report({ emitError: true })) + ]); }); function hygiene(some) { @@ -283,7 +310,7 @@ function hygiene(some) { .pipe(copyrights); const typescript = result - .pipe(filter(tslintFilter)) + .pipe(filter(tslintHygieneFilter)) .pipe(formatting) .pipe(tsl); diff --git a/build/lib/tslint/abstractGlobalsRule.js b/build/lib/tslint/abstractGlobalsRule.js new file mode 100644 index 00000000000..2aadf2c3bd9 --- /dev/null +++ b/build/lib/tslint/abstractGlobalsRule.js @@ -0,0 +1,40 @@ +"use strict"; +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +const Lint = require("tslint"); +class AbstractGlobalsRuleWalker extends Lint.RuleWalker { + constructor(file, program, opts, _config) { + super(file, opts); + this.program = program; + this._config = _config; + } + visitIdentifier(node) { + if (this.getDisallowedGlobals().some(disallowedGlobal => disallowedGlobal === node.text)) { + if (this._config.allowed && this._config.allowed.some(allowed => allowed === node.text)) { + return; // override + } + const checker = this.program.getTypeChecker(); + const symbol = checker.getSymbolAtLocation(node); + if (symbol) { + const valueDeclaration = symbol.valueDeclaration; + if (valueDeclaration) { + const parent = valueDeclaration.parent; + if (parent) { + const sourceFile = parent.getSourceFile(); + if (sourceFile) { + const fileName = sourceFile.fileName; + if (fileName && fileName.indexOf(this.getDefinitionPattern()) >= 0) { + this.addFailureAtNode(node, `Cannot use global '${node.text}' in '${this._config.target}'`); + } + } + } + } + } + } + super.visitIdentifier(node); + } +} +exports.AbstractGlobalsRuleWalker = AbstractGlobalsRuleWalker; diff --git a/build/lib/tslint/abstractGlobalsRule.ts b/build/lib/tslint/abstractGlobalsRule.ts new file mode 100644 index 00000000000..8c80b3e0cfd --- /dev/null +++ b/build/lib/tslint/abstractGlobalsRule.ts @@ -0,0 +1,51 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as ts from 'typescript'; +import * as Lint from 'tslint'; + +interface AbstractGlobalsRuleConfig { + target: string; + allowed: string[]; +} + +export abstract class AbstractGlobalsRuleWalker extends Lint.RuleWalker { + + constructor(file: ts.SourceFile, private program: ts.Program, opts: Lint.IOptions, private _config: AbstractGlobalsRuleConfig) { + super(file, opts); + } + + protected abstract getDisallowedGlobals(): string[]; + + protected abstract getDefinitionPattern(): string; + + visitIdentifier(node: ts.Identifier) { + if (this.getDisallowedGlobals().some(disallowedGlobal => disallowedGlobal === node.text)) { + if (this._config.allowed && this._config.allowed.some(allowed => allowed === node.text)) { + return; // override + } + + const checker = this.program.getTypeChecker(); + const symbol = checker.getSymbolAtLocation(node); + if (symbol) { + const valueDeclaration = symbol.valueDeclaration; + if (valueDeclaration) { + const parent = valueDeclaration.parent; + if (parent) { + const sourceFile = parent.getSourceFile(); + if (sourceFile) { + const fileName = sourceFile.fileName; + if (fileName && fileName.indexOf(this.getDefinitionPattern()) >= 0) { + this.addFailureAtNode(node, `Cannot use global '${node.text}' in '${this._config.target}'`); + } + } + } + } + } + } + + super.visitIdentifier(node); + } +} diff --git a/build/lib/tslint/noDOMGlobalsRule.js b/build/lib/tslint/noDOMGlobalsRule.js new file mode 100644 index 00000000000..a83ac8f7f59 --- /dev/null +++ b/build/lib/tslint/noDOMGlobalsRule.js @@ -0,0 +1,34 @@ +"use strict"; +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +const Lint = require("tslint"); +const minimatch = require("minimatch"); +const abstractGlobalsRule_1 = require("./abstractGlobalsRule"); +class Rule extends Lint.Rules.TypedRule { + applyWithProgram(sourceFile, program) { + const configs = this.getOptions().ruleArguments; + for (const config of configs) { + if (minimatch(sourceFile.fileName, config.target)) { + return this.applyWithWalker(new NoDOMGlobalsRuleWalker(sourceFile, program, this.getOptions(), config)); + } + } + return []; + } +} +exports.Rule = Rule; +class NoDOMGlobalsRuleWalker extends abstractGlobalsRule_1.AbstractGlobalsRuleWalker { + getDefinitionPattern() { + return 'lib.dom.d.ts'; + } + getDisallowedGlobals() { + // intentionally not complete + return [ + "window", + "document", + "HTMLElement" + ]; + } +} diff --git a/build/lib/tslint/noDOMGlobalsRule.ts b/build/lib/tslint/noDOMGlobalsRule.ts new file mode 100644 index 00000000000..df9e67bf78b --- /dev/null +++ b/build/lib/tslint/noDOMGlobalsRule.ts @@ -0,0 +1,45 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as ts from 'typescript'; +import * as Lint from 'tslint'; +import * as minimatch from 'minimatch'; +import { AbstractGlobalsRuleWalker } from './abstractGlobalsRule'; + +interface NoDOMGlobalsRuleConfig { + target: string; + allowed: string[]; +} + +export class Rule extends Lint.Rules.TypedRule { + + applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): Lint.RuleFailure[] { + const configs = this.getOptions().ruleArguments; + + for (const config of configs) { + if (minimatch(sourceFile.fileName, config.target)) { + return this.applyWithWalker(new NoDOMGlobalsRuleWalker(sourceFile, program, this.getOptions(), config)); + } + } + + return []; + } +} + +class NoDOMGlobalsRuleWalker extends AbstractGlobalsRuleWalker { + + getDefinitionPattern(): string { + return 'lib.dom.d.ts'; + } + + getDisallowedGlobals(): string[] { + // intentionally not complete + return [ + "window", + "document", + "HTMLElement" + ]; + } +} diff --git a/build/lib/tslint/noNodeJSGlobalsRule.js b/build/lib/tslint/noNodeJSGlobalsRule.js new file mode 100644 index 00000000000..1e955a41e1b --- /dev/null +++ b/build/lib/tslint/noNodeJSGlobalsRule.js @@ -0,0 +1,40 @@ +"use strict"; +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +const Lint = require("tslint"); +const minimatch = require("minimatch"); +const abstractGlobalsRule_1 = require("./abstractGlobalsRule"); +class Rule extends Lint.Rules.TypedRule { + applyWithProgram(sourceFile, program) { + const configs = this.getOptions().ruleArguments; + for (const config of configs) { + if (minimatch(sourceFile.fileName, config.target)) { + return this.applyWithWalker(new NoNodejsGlobalsRuleWalker(sourceFile, program, this.getOptions(), config)); + } + } + return []; + } +} +exports.Rule = Rule; +class NoNodejsGlobalsRuleWalker extends abstractGlobalsRule_1.AbstractGlobalsRuleWalker { + getDefinitionPattern() { + return '@types/node'; + } + getDisallowedGlobals() { + // https://nodejs.org/api/globals.html#globals_global_objects + return [ + "Buffer", + "__dirname", + "__filename", + "clearImmediate", + "exports", + "global", + "module", + "process", + "setImmediate" + ]; + } +} diff --git a/build/lib/tslint/noNodeJSGlobalsRule.ts b/build/lib/tslint/noNodeJSGlobalsRule.ts new file mode 100644 index 00000000000..48b229333e9 --- /dev/null +++ b/build/lib/tslint/noNodeJSGlobalsRule.ts @@ -0,0 +1,51 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as ts from 'typescript'; +import * as Lint from 'tslint'; +import * as minimatch from 'minimatch'; +import { AbstractGlobalsRuleWalker } from './abstractGlobalsRule'; + +interface NoNodejsGlobalsConfig { + target: string; + allowed: string[]; +} + +export class Rule extends Lint.Rules.TypedRule { + + applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): Lint.RuleFailure[] { + const configs = this.getOptions().ruleArguments; + + for (const config of configs) { + if (minimatch(sourceFile.fileName, config.target)) { + return this.applyWithWalker(new NoNodejsGlobalsRuleWalker(sourceFile, program, this.getOptions(), config)); + } + } + + return []; + } +} + +class NoNodejsGlobalsRuleWalker extends AbstractGlobalsRuleWalker { + + getDefinitionPattern(): string { + return '@types/node'; + } + + getDisallowedGlobals(): string[] { + // https://nodejs.org/api/globals.html#globals_global_objects + return [ + "Buffer", + "__dirname", + "__filename", + "clearImmediate", + "exports", + "global", + "module", + "process", + "setImmediate" + ]; + } +} diff --git a/tslint.json b/tslint.json index 059d2cea868..4cffe3e1c53 100644 --- a/tslint.json +++ b/tslint.json @@ -9,8 +9,10 @@ "no-duplicate-super": true, "no-duplicate-switch-case": true, "no-duplicate-variable": true, + "no-for-in-array": true, "no-eval": true, "no-redundant-jsdoc": true, + "no-restricted-globals": true, "no-sparse-arrays": true, "no-string-throw": true, "no-unsafe-finally": true, @@ -625,6 +627,48 @@ "restrictions": "**/vs/**" } ], + "no-nodejs-globals": [ + true, + { + "target": "**/vs/base/common/{path,process,platform}.ts", + "allowed": [ + "process" // -> defines safe access to process + ] + }, + { + "target": "**/vs/**/test/{common,browser}/**", + "allowed": [ + "process", + "Buffer", + "__filename", + "__dirname" + ] + }, + { + "target": "**/vs/workbench/api/common/extHostExtensionService.ts", + "allowed": [ + "global" // -> safe access to 'global' + ] + }, + { + "target": "**/vs/**/{common,browser}/**", + "allowed": [ /* none */] + } + ], + "no-dom-globals": [ + true, + { + "target": "**/vs/**/test/{common,node,electron-main}/**", + "allowed": [ + "document", + "HTMLElement" + ] + }, + { + "target": "**/vs/**/{common,node,electron-main}/**", + "allowed": [ /* none */] + } + ], "duplicate-imports": true, "no-new-buffer": true, "translation-remind": true, From af13ba22fbcafb02aa326c67e60ed09470e55179 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Mon, 19 Aug 2019 08:32:59 -0700 Subject: [PATCH 784/861] Update trustedDomain default config --- src/vs/platform/request/common/request.ts | 8 -------- src/vs/workbench/contrib/url/common/url.contribution.ts | 8 ++++++-- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/vs/platform/request/common/request.ts b/src/vs/platform/request/common/request.ts index 27601de0ef0..31e3c314242 100644 --- a/src/vs/platform/request/common/request.ts +++ b/src/vs/platform/request/common/request.ts @@ -117,14 +117,6 @@ Registry.as(Extensions.Configuration) type: 'boolean', default: true, description: localize('systemCertificates', "Controls whether CA certificates should be loaded from the OS. (On Windows and macOS a reload of the window is required after turning this off.)") - }, - 'http.trustedDomains': { - type: 'array', - default: ['https://code.visualstudio.com'], - description: localize('trustedDomains', "Controls whether a http/https link can be opened directly in browser.\n\nAdd `*` to the list to whitelist all domains."), - items: { - type: 'string' - } } } }); diff --git a/src/vs/workbench/contrib/url/common/url.contribution.ts b/src/vs/workbench/contrib/url/common/url.contribution.ts index b8f67e2e598..5fe78f41820 100644 --- a/src/vs/workbench/contrib/url/common/url.contribution.ts +++ b/src/vs/workbench/contrib/url/common/url.contribution.ts @@ -47,9 +47,13 @@ const configureTrustedDomainsHandler = ( storageService: IStorageService, domainToConfigure?: string ) => { - let trustedDomains: string[] = []; + let trustedDomains: string[] = ['https://code.visualstudio.com']; + try { - trustedDomains = JSON.parse(storageService.get('http.trustedDomains', StorageScope.GLOBAL, '[]')); + const trustedDomainsSrc = storageService.get('http.trustedDomains', StorageScope.GLOBAL); + if (trustedDomainsSrc) { + trustedDomains = JSON.parse(trustedDomainsSrc); + } } catch (err) { } const domainQuickPickItems: IQuickPickItem[] = trustedDomains From dc257921750737813d00123ca83c7c2cda409185 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 19 Aug 2019 17:41:36 +0200 Subject: [PATCH 785/861] tslint - disable some rules with comments (#79454) --- src/vs/base/parts/quickopen/common/quickOpen.ts | 4 +++- src/vs/platform/windows/common/windows.ts | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/vs/base/parts/quickopen/common/quickOpen.ts b/src/vs/base/parts/quickopen/common/quickOpen.ts index dd39a215ef1..d6039c68802 100644 --- a/src/vs/base/parts/quickopen/common/quickOpen.ts +++ b/src/vs/base/parts/quickopen/common/quickOpen.ts @@ -68,6 +68,8 @@ export interface IDataSource { export interface IRenderer { getHeight(entry: T): number; getTemplateId(entry: T): string; + // rationale: will be replaced by quickinput later + // tslint:disable-next-line: no-dom-globals renderTemplate(templateId: string, container: HTMLElement, styles: any): any; renderElement(entry: T, templateId: string, templateData: any, styles: any): void; disposeTemplate(templateId: string, templateData: any): void; @@ -92,4 +94,4 @@ export interface IModel { runner: IRunner; filter?: IFilter; accessibilityProvider?: IAccessiblityProvider; -} \ No newline at end of file +} diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index 7ac04663081..bca1181e591 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -240,6 +240,8 @@ export interface IWindowService { closeWorkspace(): Promise; updateTouchBar(items: ISerializableCommandAction[][]): Promise; enterWorkspace(path: URI): Promise; + // rationale: will eventually move to electron-browser + // tslint:disable-next-line: no-dom-globals toggleFullScreen(target?: HTMLElement): Promise; setRepresentedFilename(fileName: string): Promise; getRecentlyOpened(): Promise; From c0039fa3bda0417228b5a37442470d694301e5b1 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Mon, 19 Aug 2019 08:57:19 -0700 Subject: [PATCH 786/861] Drop unneeded action registration --- .../editor/browser/services/openerService.ts | 9 ++-- .../contrib/url/common/url.contribution.ts | 52 +++++++------------ 2 files changed, 24 insertions(+), 37 deletions(-) diff --git a/src/vs/editor/browser/services/openerService.ts b/src/vs/editor/browser/services/openerService.ts index c6aa9891cf5..60be6dadd59 100644 --- a/src/vs/editor/browser/services/openerService.ts +++ b/src/vs/editor/browser/services/openerService.ts @@ -67,9 +67,12 @@ export class OpenerService implements IOpenerService { } if (equalsIgnoreCase(scheme, Schemas.http) || equalsIgnoreCase(scheme, Schemas.https)) { - let trustedDomains: string[] = []; + let trustedDomains: string[] = ['https://code.visualstudio.com']; try { - trustedDomains = JSON.parse(this._storageService.get('http.trustedDomains', StorageScope.GLOBAL, '[]')); + const trustedDomainsSrc = this._storageService.get('http.trustedDomains', StorageScope.GLOBAL); + if (trustedDomainsSrc) { + trustedDomains = JSON.parse(trustedDomainsSrc); + } } catch (err) { } const domainToOpen = `${scheme}://${authority}`; @@ -96,7 +99,7 @@ export class OpenerService implements IOpenerService { if (choice === 0) { return this.openExternal(resource); } else if (choice === 2) { - return this._commandService.executeCommand('_workbench.action.configureTrustedDomains', domainToOpen).then((pickedDomains: string[]) => { + return this._commandService.executeCommand('workbench.action.configureTrustedDomains', domainToOpen).then((pickedDomains: string[]) => { if (pickedDomains.indexOf(domainToOpen) !== -1) { return this.openExternal(resource); } diff --git a/src/vs/workbench/contrib/url/common/url.contribution.ts b/src/vs/workbench/contrib/url/common/url.contribution.ts index 5fe78f41820..dc917095f0c 100644 --- a/src/vs/workbench/contrib/url/common/url.contribution.ts +++ b/src/vs/workbench/contrib/url/common/url.contribution.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { localize } from 'vs/nls'; -import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; +import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { Registry } from 'vs/platform/registry/common/platform'; import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions'; import { IURLService } from 'vs/platform/url/common/url'; @@ -13,6 +13,7 @@ import { URI } from 'vs/base/common/uri'; import { Action } from 'vs/base/common/actions'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; +import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; export class OpenUrlAction extends Action { @@ -42,12 +43,14 @@ Registry.as(ActionExtensions.WorkbenchActions).registe localize('developer', 'Developer') ); +const VSCODE_DOMAIN = 'https://code.visualstudio.com'; + const configureTrustedDomainsHandler = ( quickInputService: IQuickInputService, storageService: IStorageService, domainToConfigure?: string ) => { - let trustedDomains: string[] = ['https://code.visualstudio.com']; + let trustedDomains: string[] = [VSCODE_DOMAIN]; try { const trustedDomainsSrc = storageService.get('http.trustedDomains', StorageScope.GLOBAL); @@ -75,7 +78,7 @@ const configureTrustedDomainsHandler = ( ]; let domainToConfigureItem: IQuickPickItem | undefined = undefined; - if (domainToConfigure) { + if (domainToConfigure && trustedDomains.indexOf(domainToConfigure) === -1) { domainToConfigureItem = { type: 'item', label: domainToConfigure, @@ -104,43 +107,24 @@ const configureTrustedDomainsHandler = ( }); }; -export class ConfigureTrustedDomainsAction extends Action { - - static readonly ID = 'workbench.action.configureTrustedDomains'; - static readonly LABEL = localize('configureTrustedDomains', "Configure Trusted Domains"); - - constructor( - id: string, - label: string, - @IQuickInputService private readonly quickInputService: IQuickInputService, - @IStorageService private readonly storageService: IStorageService - ) { - super(id, label); - } - - run(): Promise { - return configureTrustedDomainsHandler(this.quickInputService, this.storageService); - } -} - -Registry.as(ActionExtensions.WorkbenchActions).registerWorkbenchAction( - new SyncActionDescriptor( - ConfigureTrustedDomainsAction, - ConfigureTrustedDomainsAction.ID, - ConfigureTrustedDomainsAction.LABEL - ), - 'Configure Trusted Domains' -); -CommandsRegistry.registerCommand({ - id: '_workbench.action.configureTrustedDomains', +const configureTrustedDomainCommand = { + id: 'workbench.action.configureTrustedDomains', description: { - description: 'Configure Trusted Domains', + description: localize('configureTrustedDomains', 'Configure Trusted Domains'), args: [{ name: 'domainToConfigure', schema: { type: 'string' } }] }, - handler: (accessor, domainToConfigure?: string) => { + handler: (accessor: ServicesAccessor, domainToConfigure?: string) => { const quickInputService = accessor.get(IQuickInputService); const storageService = accessor.get(IStorageService); return configureTrustedDomainsHandler(quickInputService, storageService, domainToConfigure); } +}; + +CommandsRegistry.registerCommand(configureTrustedDomainCommand); +MenuRegistry.appendMenuItem(MenuId.CommandPalette, { + command: { + id: configureTrustedDomainCommand.id, + title: configureTrustedDomainCommand.description.description + } }); From cea5cbd07df785ec48056eb0ce22b04a4cfe2df6 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 19 Aug 2019 18:14:23 +0200 Subject: [PATCH 787/861] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e01ec81fc97..0bcb75c265b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "79dcce2b3cd0772344a028cd703b7da03f3ffa83", + "distro": "5b190cd6f374ca91b14712a57cab6be8818f2a4a", "author": { "name": "Microsoft Corporation" }, From b9b5692e279699a5d2d1e1173098004a40408478 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 19 Aug 2019 09:09:08 -0700 Subject: [PATCH 788/861] Support using csharp in markdown preview to identify c# code blocks --- extensions/markdown-language-features/src/markdownEngine.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/markdown-language-features/src/markdownEngine.ts b/extensions/markdown-language-features/src/markdownEngine.ts index 0cc75bfe823..613d207712b 100644 --- a/extensions/markdown-language-features/src/markdownEngine.ts +++ b/extensions/markdown-language-features/src/markdownEngine.ts @@ -297,13 +297,13 @@ async function getMarkdownOptions(md: () => MarkdownIt) { html: true, highlight: (str: string, lang?: string) => { // Workaround for highlight not supporting tsx: https://github.com/isagalaev/highlight.js/issues/1155 - if (lang && ['tsx', 'typescriptreact'].indexOf(lang.toLocaleLowerCase()) >= 0) { + if (lang && ['tsx', 'typescriptreact'].includes(lang.toLocaleLowerCase())) { lang = 'jsx'; } if (lang && lang.toLocaleLowerCase() === 'json5') { lang = 'json'; } - if (lang && lang.toLocaleLowerCase() === 'c#') { + if (lang && ['c#', 'csharp'].includes(lang.toLocaleLowerCase())) { lang = 'cs'; } if (lang && hljs.getLanguage(lang)) { From 78d462bd86c0e75b6f7128f68ef450ad6cb53562 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 19 Aug 2019 18:27:22 +0200 Subject: [PATCH 789/861] sync diagnostics, fixes #47292 --- .../api/browser/mainThreadDiagnostics.ts | 21 +++++++++- .../workbench/api/common/extHost.protocol.ts | 2 +- .../api/common/extHostDiagnostics.ts | 38 +++++++++++++++---- .../api/common/extHostTypeConverters.ts | 18 +++++++++ .../api/extHostDiagnostics.test.ts | 36 ++++++++++++++++++ .../api/mainThreadDiagnostics.test.ts | 12 +++++- 6 files changed, 117 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadDiagnostics.ts b/src/vs/workbench/api/browser/mainThreadDiagnostics.ts index 801a17d89a7..eb26b62da3a 100644 --- a/src/vs/workbench/api/browser/mainThreadDiagnostics.ts +++ b/src/vs/workbench/api/browser/mainThreadDiagnostics.ts @@ -5,24 +5,43 @@ import { IMarkerService, IMarkerData } from 'vs/platform/markers/common/markers'; import { URI, UriComponents } from 'vs/base/common/uri'; -import { MainThreadDiagnosticsShape, MainContext, IExtHostContext } from '../common/extHost.protocol'; +import { MainThreadDiagnosticsShape, MainContext, IExtHostContext, ExtHostDiagnosticsShape, ExtHostContext } from '../common/extHost.protocol'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; +import { IDisposable } from 'vs/base/common/lifecycle'; @extHostNamedCustomer(MainContext.MainThreadDiagnostics) export class MainThreadDiagnostics implements MainThreadDiagnosticsShape { private readonly _activeOwners = new Set(); + + private readonly _proxy: ExtHostDiagnosticsShape; private readonly _markerService: IMarkerService; + private readonly _markerListener: IDisposable; constructor( extHostContext: IExtHostContext, @IMarkerService markerService: IMarkerService ) { + this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostDiagnostics); this._markerService = markerService; + this._markerListener = this._markerService.onMarkerChanged(this._forwardMarkers, this); } dispose(): void { + this._markerListener.dispose(); this._activeOwners.forEach(owner => this._markerService.changeAll(owner, [])); + this._activeOwners.clear(); + } + + private _forwardMarkers(resources: URI[]): void { + const data: [UriComponents, IMarkerData[]][] = []; + for (const resource of resources) { + data.push([ + resource, + this._markerService.read({ resource }).filter(marker => !this._activeOwners.has(marker.owner)) + ]); + } + this._proxy.$acceptMarkersChange(data); } $changeMany(owner: string, entries: [UriComponents, IMarkerData[]][]): void { diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 2b1f57a09d6..055786be742 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -741,7 +741,7 @@ export interface ExtHostConfigurationShape { } export interface ExtHostDiagnosticsShape { - + $acceptMarkersChange(data: [UriComponents, IMarkerData[]][]): void; } export interface ExtHostDocumentContentProvidersShape { diff --git a/src/vs/workbench/api/common/extHostDiagnostics.ts b/src/vs/workbench/api/common/extHostDiagnostics.ts index 60dae259b05..d654408346b 100644 --- a/src/vs/workbench/api/common/extHostDiagnostics.ts +++ b/src/vs/workbench/api/common/extHostDiagnostics.ts @@ -5,7 +5,7 @@ import { localize } from 'vs/nls'; import { IMarkerData, MarkerSeverity } from 'vs/platform/markers/common/markers'; -import { URI } from 'vs/base/common/uri'; +import { URI, UriComponents } from 'vs/base/common/uri'; import * as vscode from 'vscode'; import { MainContext, MainThreadDiagnosticsShape, ExtHostDiagnosticsShape, IMainContext } from './extHost.protocol'; import { DiagnosticSeverity } from './extHostTypes'; @@ -20,12 +20,12 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { private readonly _owner: string; private readonly _maxDiagnosticsPerFile: number; private readonly _onDidChangeDiagnostics: Emitter<(vscode.Uri | string)[]>; - private readonly _proxy: MainThreadDiagnosticsShape; + private readonly _proxy: MainThreadDiagnosticsShape | undefined; private _isDisposed = false; private _data = new Map(); - constructor(name: string, owner: string, maxDiagnosticsPerFile: number, proxy: MainThreadDiagnosticsShape, onDidChangeDiagnostics: Emitter<(vscode.Uri | string)[]>) { + constructor(name: string, owner: string, maxDiagnosticsPerFile: number, proxy: MainThreadDiagnosticsShape | undefined, onDidChangeDiagnostics: Emitter<(vscode.Uri | string)[]>) { this._name = name; this._owner = owner; this._maxDiagnosticsPerFile = maxDiagnosticsPerFile; @@ -36,7 +36,9 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { dispose(): void { if (!this._isDisposed) { this._onDidChangeDiagnostics.fire(keys(this._data)); - this._proxy.$clear(this._owner); + if (this._proxy) { + this._proxy.$clear(this._owner); + } this._data = undefined!; this._isDisposed = true; } @@ -112,6 +114,9 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { this._onDidChangeDiagnostics.fire(toSync); // compute change and send to main side + if (!this._proxy) { + return; + } const entries: [URI, IMarkerData[]][] = []; for (let uri of toSync) { let marker: IMarkerData[] = []; @@ -149,7 +154,6 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { entries.push([uri, marker]); } - this._proxy.$changeMany(this._owner, entries); } @@ -157,14 +161,18 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { this._checkDisposed(); this._onDidChangeDiagnostics.fire([uri]); this._data.delete(uri.toString()); - this._proxy.$changeMany(this._owner, [[uri, undefined]]); + if (this._proxy) { + this._proxy.$changeMany(this._owner, [[uri, undefined]]); + } } clear(): void { this._checkDisposed(); this._onDidChangeDiagnostics.fire(keys(this._data)); this._data.clear(); - this._proxy.$clear(this._owner); + if (this._proxy) { + this._proxy.$clear(this._owner); + } } forEach(callback: (uri: URI, diagnostics: ReadonlyArray, collection: DiagnosticCollection) => any, thisArg?: any): void { @@ -311,4 +319,20 @@ export class ExtHostDiagnostics implements ExtHostDiagnosticsShape { }); return res; } + + private _mirrorCollection: vscode.DiagnosticCollection | undefined; + + $acceptMarkersChange(data: [UriComponents, IMarkerData[]][]): void { + + if (!this._mirrorCollection) { + const name = '_generated_mirror'; + const collection = new DiagnosticCollection(name, name, ExtHostDiagnostics._maxDiagnosticsPerFile, undefined, this._onDidChangeDiagnostics); + this._collections.set(name, collection); + this._mirrorCollection = collection; + } + + for (const [uri, markers] of data) { + this._mirrorCollection.set(URI.revive(uri), markers.map(converter.Diagnostic.to)); + } + } } diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index f7827afe487..0fb461e8c97 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -113,6 +113,15 @@ export namespace DiagnosticTag { } return undefined; } + export function to(value: MarkerTag): vscode.DiagnosticTag | undefined { + switch (value) { + case MarkerTag.Unnecessary: + return types.DiagnosticTag.Unnecessary; + case MarkerTag.Deprecated: + return types.DiagnosticTag.Deprecated; + } + return undefined; + } } export namespace Diagnostic { @@ -127,6 +136,15 @@ export namespace Diagnostic { tags: Array.isArray(value.tags) ? coalesce(value.tags.map(DiagnosticTag.from)) : undefined, }; } + + export function to(value: IMarkerData): vscode.Diagnostic { + const res = new types.Diagnostic(Range.to(value), value.message, DiagnosticSeverity.to(value.severity)); + res.source = value.source; + res.code = value.code; + res.relatedInformation = value.relatedInformation && value.relatedInformation.map(DiagnosticRelatedInformation.to); + res.tags = value.tags && coalesce(value.tags.map(DiagnosticTag.to)); + return res; + } } export namespace DiagnosticRelatedInformation { diff --git a/src/vs/workbench/test/electron-browser/api/extHostDiagnostics.test.ts b/src/vs/workbench/test/electron-browser/api/extHostDiagnostics.test.ts index 4eca9307e09..60181c415f2 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostDiagnostics.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostDiagnostics.test.ts @@ -424,4 +424,40 @@ suite('ExtHostDiagnostics', () => { collection.set(URI.parse('test:me'), array); assert.equal(callCount, 3); // same but un-equal array }); + + test('Diagnostics created by tasks aren\'t accessible to extensions #47292', async function () { + const diags = new ExtHostDiagnostics(new class implements IMainContext { + getProxy(id: any): any { + return {}; + } + set(): any { + return null; + } + assertRegistered(): void { + + } + }); + + + // + const uri = URI.parse('foo:bar'); + const data: IMarkerData[] = [{ + message: 'message', + startLineNumber: 1, + startColumn: 1, + endLineNumber: 1, + endColumn: 1, + severity: 3 + }]; + + const p1 = Event.toPromise(diags.onDidChangeDiagnostics); + diags.$acceptMarkersChange([[uri, data]]); + await p1; + assert.equal(diags.getDiagnostics(uri).length, 1); + + const p2 = Event.toPromise(diags.onDidChangeDiagnostics); + diags.$acceptMarkersChange([[uri, []]]); + await p2; + assert.equal(diags.getDiagnostics(uri).length, 0); + }); }); diff --git a/src/vs/workbench/test/electron-browser/api/mainThreadDiagnostics.test.ts b/src/vs/workbench/test/electron-browser/api/mainThreadDiagnostics.test.ts index e01923222da..72f53943e04 100644 --- a/src/vs/workbench/test/electron-browser/api/mainThreadDiagnostics.test.ts +++ b/src/vs/workbench/test/electron-browser/api/mainThreadDiagnostics.test.ts @@ -7,6 +7,7 @@ import * as assert from 'assert'; import { MarkerService } from 'vs/platform/markers/common/markerService'; import { MainThreadDiagnostics } from 'vs/workbench/api/browser/mainThreadDiagnostics'; import { URI } from 'vs/base/common/uri'; +import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol'; suite('MainThreadDiagnostics', function () { @@ -19,7 +20,16 @@ suite('MainThreadDiagnostics', function () { test('clear markers on dispose', function () { - let diag = new MainThreadDiagnostics(null!, markerService); + let diag = new MainThreadDiagnostics(new class implements IExtHostContext { + remoteAuthority = ''; + assertRegistered() { } + set(v: any): any { return null; } + getProxy(): any { + return { + $acceptMarkersChange() { } + }; + } + }, markerService); diag.$changeMany('foo', [[URI.file('a'), [{ code: '666', From 997d73516c65afbbb9939ce6bf55a97a82a8bbc7 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Mon, 19 Aug 2019 10:09:13 -0700 Subject: [PATCH 790/861] fixes #79280 --- src/vs/base/browser/ui/splitview/splitview.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index b5102c9f9b3..81090f39c2c 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -117,12 +117,11 @@ abstract class ViewItem { if (typeof size === 'number') { this._size = size; this._cachedVisibleSize = undefined; + dom.addClass(container, 'visible'); } else { this._size = 0; this._cachedVisibleSize = size.cachedVisibleSize; } - - dom.addClass(container, 'visible'); } layout(_orthogonalSize: number | undefined): void { From 949ec731d8dd1b69fb9c84b6ba6b67cb1d714661 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 19 Aug 2019 19:11:31 +0200 Subject: [PATCH 791/861] tests - more diagnostics for getUntitledWorkspaceSync() random failures --- .../test/electron-main/workspacesMainService.test.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts b/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts index 395e709bd28..16b3f1d60d7 100644 --- a/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts +++ b/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts @@ -343,11 +343,12 @@ suite('WorkspacesMainService', () => { const untitledTwo = await createWorkspace([os.tmpdir(), process.cwd()]); assert.ok(fs.existsSync(untitledTwo.configPath.fsPath)); assert.ok(fs.existsSync(untitledOne.configPath.fsPath), `Unexpected workspaces count of 1 (expected 2): ${untitledOne.configPath.fsPath} does not exist anymore?`); + const untitledHome = dirname(dirname(untitledTwo.configPath)); + const beforeGettingUntitledWorkspaces = fs.readdirSync(untitledHome.fsPath).map(name => fs.readFileSync(joinPath(untitledHome, name, 'workspace.json').fsPath, 'utf8')); untitled = service.getUntitledWorkspacesSync(); assert.ok(fs.existsSync(untitledOne.configPath.fsPath), `Unexpected workspaces count of 1 (expected 2): ${untitledOne.configPath.fsPath} does not exist anymore?`); if (untitled.length === 1) { - const untitledHome = dirname(dirname(untitledTwo.configPath)); - assert.fail(`Unexpected workspaces count of 1 (expected 2), all workspaces:\n ${fs.readdirSync(untitledHome.fsPath).map(name => fs.readFileSync(joinPath(untitledHome, name, 'workspace.json').fsPath, 'utf8'))}`); + assert.fail(`Unexpected workspaces count of 1 (expected 2), all workspaces:\n ${fs.readdirSync(untitledHome.fsPath).map(name => fs.readFileSync(joinPath(untitledHome, name, 'workspace.json').fsPath, 'utf8'))}, before getUntitledWorkspacesSync: ${beforeGettingUntitledWorkspaces}`); } assert.equal(2, untitled.length); From 0361f77d9e5124841b83bd01ecabb4449fcb7b25 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 19 Aug 2019 19:21:25 +0200 Subject: [PATCH 792/861] debt - reduce dependencies diff to E6 branch --- package.json | 2 +- remote/package.json | 2 +- remote/yarn.lock | 12 +++++------- yarn.lock | 8 ++++---- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 0bcb75c265b..a9793ee759c 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "fast-plist": "0.1.2", "glob": "^5.0.13", "gulp": "^4.0.0", - "gulp-atom-electron": "^1.21.1", + "gulp-atom-electron": "^1.22.0", "gulp-azure-storage": "^0.10.0", "gulp-buffer": "0.0.2", "gulp-concat": "^2.6.1", diff --git a/remote/package.json b/remote/package.json index 9bbc0f44c5c..2e8ceed0809 100644 --- a/remote/package.json +++ b/remote/package.json @@ -29,6 +29,6 @@ }, "optionalDependencies": { "vscode-windows-ca-certs": "0.1.0", - "vscode-windows-registry": "1.0.1" + "vscode-windows-registry": "1.0.2" } } diff --git a/remote/yarn.lock b/remote/yarn.lock index 54e0619915e..dca0e2501f0 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -743,7 +743,7 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -nan@^2.0.0, nan@^2.12.1, nan@^2.13.2, nan@^2.14.0: +nan@^2.0.0, nan@^2.13.2, nan@^2.14.0: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== @@ -1210,12 +1210,10 @@ vscode-windows-ca-certs@0.1.0: dependencies: node-addon-api "1.6.2" -vscode-windows-registry@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/vscode-windows-registry/-/vscode-windows-registry-1.0.1.tgz#bc9f765563eb6dc1c9ad9a41f9eaacc84dfadc7c" - integrity sha512-q0aKXi9Py1OBdmXIJJFeJBzpPJMMUxMJNBU9FysWIXEwJyMQGEVevKzM2J3Qz/cHSc5LVqibmoUWzZ7g+97qRg== - dependencies: - nan "^2.12.1" +vscode-windows-registry@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/vscode-windows-registry/-/vscode-windows-registry-1.0.2.tgz#b863e704a6a69c50b3098a55fbddbe595b0c124a" + integrity sha512-/CLLvuOSM2Vme2z6aNyB+4Omd7hDxpf4Thrt8ImxnXeQtxzel2bClJpFQvQqK/s4oaXlkBKS7LqVLeZM+uSVIA== xterm-addon-search@0.2.0-beta5: version "0.2.0-beta5" diff --git a/yarn.lock b/yarn.lock index 5dfdc062d4f..78e871f843b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3831,10 +3831,10 @@ growl@1.9.2: resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" integrity sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8= -gulp-atom-electron@^1.21.1: - version "1.21.1" - resolved "https://registry.yarnpkg.com/gulp-atom-electron/-/gulp-atom-electron-1.21.1.tgz#4017144bf659fbbf7d0644664fcc47c64efac0f0" - integrity sha512-UHEf2pZrJD/u+AAzKCbhdPXaKrReFDa+OEJjBCAdN2SHnD+dfZqSJAz/u2OD6YR/eREuUbQOCw+VWUwex20klQ== +gulp-atom-electron@^1.22.0: + version "1.22.0" + resolved "https://registry.yarnpkg.com/gulp-atom-electron/-/gulp-atom-electron-1.22.0.tgz#0e2f4fe7c7310145c6c81d5660d0277cd8338d27" + integrity sha512-K13Ze2+iRIvC1igl+BIbZdF8M2ZzEIM6LF+/j83oWNGNhe7+en77qT9y9rs6SipYeOyoInlbly+pzbFgvwpSHA== dependencies: event-stream "3.3.4" github-releases-ms "^0.5.0" From 17f0eac6567f1ded08bdffb286bab17fbf406081 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 19 Aug 2019 19:38:09 +0200 Subject: [PATCH 793/861] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a9793ee759c..bfc482a9e1d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "5b190cd6f374ca91b14712a57cab6be8818f2a4a", + "distro": "448bb39d6aabd312c4a28393314e7e406c52acb8", "author": { "name": "Microsoft Corporation" }, From b9748c53f041b4b43f5f7828a08531a1d8d69bc3 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 19 Aug 2019 20:02:11 +0200 Subject: [PATCH 794/861] debt - menubar service should not live in common (#79181) --- src/vs/code/electron-main/app.ts | 2 +- .../electron-browser/menubarService.ts | 2 +- .../platform/menubar/electron-main/menubar.ts | 2 +- .../menubar/electron-main/menubarService.ts | 2 +- .../menubar/{common => node}/menubar.ts | 0 src/vs/platform/menubar/node/menubarIpc.ts | 2 +- .../browser/parts/titlebar/menubarControl.ts | 193 +--------------- .../browser/parts/titlebar/titlebarPart.ts | 25 +-- src/vs/workbench/electron-browser/window.ts | 212 +++++++++++++++++- src/vs/workbench/workbench.desktop.main.ts | 2 +- 10 files changed, 226 insertions(+), 216 deletions(-) rename src/vs/platform/menubar/{common => node}/menubar.ts (100%) diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 1953c269a6b..d269616e1b9 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -53,7 +53,7 @@ import { LogLevelSetterChannel } from 'vs/platform/log/common/logIpc'; import { setUnexpectedErrorHandler, onUnexpectedError } from 'vs/base/common/errors'; import { ElectronURLListener } from 'vs/platform/url/electron-main/electronUrlListener'; import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver'; -import { IMenubarService } from 'vs/platform/menubar/common/menubar'; +import { IMenubarService } from 'vs/platform/menubar/node/menubar'; import { MenubarService } from 'vs/platform/menubar/electron-main/menubarService'; import { MenubarChannel } from 'vs/platform/menubar/node/menubarIpc'; import { hasArgs } from 'vs/platform/environment/node/argv'; diff --git a/src/vs/platform/menubar/electron-browser/menubarService.ts b/src/vs/platform/menubar/electron-browser/menubarService.ts index 794d65de6a7..336330d1e6d 100644 --- a/src/vs/platform/menubar/electron-browser/menubarService.ts +++ b/src/vs/platform/menubar/electron-browser/menubarService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IChannel } from 'vs/base/parts/ipc/common/ipc'; -import { IMenubarService, IMenubarData } from 'vs/platform/menubar/common/menubar'; +import { IMenubarService, IMenubarData } from 'vs/platform/menubar/node/menubar'; import { IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService'; import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; diff --git a/src/vs/platform/menubar/electron-main/menubar.ts b/src/vs/platform/menubar/electron-main/menubar.ts index 01f781dd944..ff9d06a636b 100644 --- a/src/vs/platform/menubar/electron-main/menubar.ts +++ b/src/vs/platform/menubar/electron-main/menubar.ts @@ -17,7 +17,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { mnemonicMenuLabel as baseMnemonicLabel } from 'vs/base/common/labels'; import { IWindowsMainService, IWindowsCountChangedEvent } from 'vs/platform/windows/electron-main/windows'; import { IHistoryMainService } from 'vs/platform/history/common/history'; -import { IMenubarData, IMenubarKeybinding, MenubarMenuItem, isMenubarMenuItemSeparator, isMenubarMenuItemSubmenu, isMenubarMenuItemAction, IMenubarMenu, isMenubarMenuItemUriAction } from 'vs/platform/menubar/common/menubar'; +import { IMenubarData, IMenubarKeybinding, MenubarMenuItem, isMenubarMenuItemSeparator, isMenubarMenuItemSubmenu, isMenubarMenuItemAction, IMenubarMenu, isMenubarMenuItemUriAction } from 'vs/platform/menubar/node/menubar'; import { URI } from 'vs/base/common/uri'; import { IStateService } from 'vs/platform/state/common/state'; import { ILifecycleService } from 'vs/platform/lifecycle/electron-main/lifecycleMain'; diff --git a/src/vs/platform/menubar/electron-main/menubarService.ts b/src/vs/platform/menubar/electron-main/menubarService.ts index b4a8ed44ef4..f7abf2ee9f2 100644 --- a/src/vs/platform/menubar/electron-main/menubarService.ts +++ b/src/vs/platform/menubar/electron-main/menubarService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IMenubarService, IMenubarData } from 'vs/platform/menubar/common/menubar'; +import { IMenubarService, IMenubarData } from 'vs/platform/menubar/node/menubar'; import { Menubar } from 'vs/platform/menubar/electron-main/menubar'; import { ILogService } from 'vs/platform/log/common/log'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; diff --git a/src/vs/platform/menubar/common/menubar.ts b/src/vs/platform/menubar/node/menubar.ts similarity index 100% rename from src/vs/platform/menubar/common/menubar.ts rename to src/vs/platform/menubar/node/menubar.ts diff --git a/src/vs/platform/menubar/node/menubarIpc.ts b/src/vs/platform/menubar/node/menubarIpc.ts index 58f22e631b4..850a2542dd0 100644 --- a/src/vs/platform/menubar/node/menubarIpc.ts +++ b/src/vs/platform/menubar/node/menubarIpc.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IServerChannel } from 'vs/base/parts/ipc/common/ipc'; -import { IMenubarService } from 'vs/platform/menubar/common/menubar'; +import { IMenubarService } from 'vs/platform/menubar/node/menubar'; import { Event } from 'vs/base/common/event'; export class MenubarChannel implements IServerChannel { diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index bb5dda0c50f..0a45e07062e 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; -import { IMenubarMenu, IMenubarMenuItemAction, IMenubarMenuItemSubmenu, IMenubarKeybinding, IMenubarService, IMenubarData, MenubarMenuItem } from 'vs/platform/menubar/common/menubar'; import { IMenuService, MenuId, IMenu, SubmenuItemAction } from 'vs/platform/actions/common/actions'; import { registerThemingParticipant, ITheme, ICssStyleCollector, IThemeService } from 'vs/platform/theme/common/themeService'; import { IWindowService, MenuBarVisibility, IWindowsService, getTitleBarStyle, IURIToOpen } from 'vs/platform/windows/common/windows'; @@ -33,7 +32,6 @@ import { attachMenuStyler } from 'vs/platform/theme/common/styler'; import { assign } from 'vs/base/common/objects'; import { mnemonicMenuLabel, unmnemonicLabel } from 'vs/base/common/labels'; import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; -import { withNullAsUndefined } from 'vs/base/common/types'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { isFullscreen } from 'vs/base/browser/browser'; @@ -133,7 +131,7 @@ export abstract class MenubarControl extends Disposable { this.menuUpdater.schedule(); } - protected calculateActionLabel(action: IAction | IMenubarMenuItemAction): string { + protected calculateActionLabel(action: { id: string; label: string; }): string { let label = action.label; switch (action.id) { default: @@ -251,195 +249,6 @@ export abstract class MenubarControl extends Disposable { } } -export class NativeMenubarControl extends MenubarControl { - constructor( - @IMenuService menuService: IMenuService, - @IWindowService windowService: IWindowService, - @IWindowsService windowsService: IWindowsService, - @IContextKeyService contextKeyService: IContextKeyService, - @IKeybindingService keybindingService: IKeybindingService, - @IConfigurationService configurationService: IConfigurationService, - @ILabelService labelService: ILabelService, - @IUpdateService updateService: IUpdateService, - @IStorageService storageService: IStorageService, - @INotificationService notificationService: INotificationService, - @IPreferencesService preferencesService: IPreferencesService, - @IEnvironmentService environmentService: IEnvironmentService, - @IAccessibilityService accessibilityService: IAccessibilityService, - @IMenubarService private readonly menubarService: IMenubarService - ) { - super( - menuService, - windowService, - windowsService, - contextKeyService, - keybindingService, - configurationService, - labelService, - updateService, - storageService, - notificationService, - preferencesService, - environmentService, - accessibilityService); - - if (isMacintosh && !isWeb) { - this.menus['Preferences'] = this._register(this.menuService.createMenu(MenuId.MenubarPreferencesMenu, this.contextKeyService)); - this.topLevelTitles['Preferences'] = nls.localize('mPreferences', "Preferences"); - } - - for (const topLevelMenuName of Object.keys(this.topLevelTitles)) { - const menu = this.menus[topLevelMenuName]; - if (menu) { - this._register(menu.onDidChange(() => this.updateMenubar())); - } - } - - this.windowService.getRecentlyOpened().then((recentlyOpened) => { - this.recentlyOpened = recentlyOpened; - - this.doUpdateMenubar(true); - }); - - this.registerListeners(); - } - - protected doUpdateMenubar(firstTime: boolean): void { - // Send menus to main process to be rendered by Electron - const menubarData = { menus: {}, keybindings: {} }; - if (this.getMenubarMenus(menubarData)) { - this.menubarService.updateMenubar(this.windowService.windowId, menubarData); - } - } - - private getMenubarMenus(menubarData: IMenubarData): boolean { - if (!menubarData) { - return false; - } - - menubarData.keybindings = this.getAdditionalKeybindings(); - for (const topLevelMenuName of Object.keys(this.topLevelTitles)) { - const menu = this.menus[topLevelMenuName]; - if (menu) { - const menubarMenu: IMenubarMenu = { items: [] }; - this.populateMenuItems(menu, menubarMenu, menubarData.keybindings); - if (menubarMenu.items.length === 0) { - // Menus are incomplete - return false; - } - menubarData.menus[topLevelMenuName] = menubarMenu; - } - } - - return true; - } - - private populateMenuItems(menu: IMenu, menuToPopulate: IMenubarMenu, keybindings: { [id: string]: IMenubarKeybinding | undefined }) { - let groups = menu.getActions(); - for (let group of groups) { - const [, actions] = group; - - actions.forEach(menuItem => { - - if (menuItem instanceof SubmenuItemAction) { - const submenu = { items: [] }; - - if (!this.menus[menuItem.item.submenu]) { - this.menus[menuItem.item.submenu] = this.menuService.createMenu(menuItem.item.submenu, this.contextKeyService); - this._register(this.menus[menuItem.item.submenu]!.onDidChange(() => this.updateMenubar())); - } - - const menuToDispose = this.menuService.createMenu(menuItem.item.submenu, this.contextKeyService); - this.populateMenuItems(menuToDispose, submenu, keybindings); - - let menubarSubmenuItem: IMenubarMenuItemSubmenu = { - id: menuItem.id, - label: menuItem.label, - submenu: submenu - }; - - menuToPopulate.items.push(menubarSubmenuItem); - menuToDispose.dispose(); - } else { - if (menuItem.id === 'workbench.action.openRecent') { - const actions = this.getOpenRecentActions().map(this.transformOpenRecentAction); - menuToPopulate.items.push(...actions); - } - - let menubarMenuItem: IMenubarMenuItemAction = { - id: menuItem.id, - label: menuItem.label - }; - - if (menuItem.checked) { - menubarMenuItem.checked = true; - } - - if (!menuItem.enabled) { - menubarMenuItem.enabled = false; - } - - menubarMenuItem.label = this.calculateActionLabel(menubarMenuItem); - keybindings[menuItem.id] = this.getMenubarKeybinding(menuItem.id); - menuToPopulate.items.push(menubarMenuItem); - } - }); - - menuToPopulate.items.push({ id: 'vscode.menubar.separator' }); - } - - if (menuToPopulate.items.length > 0) { - menuToPopulate.items.pop(); - } - } - - private transformOpenRecentAction(action: Separator | (IAction & { uri: URI })): MenubarMenuItem { - if (action instanceof Separator) { - return { id: 'vscode.menubar.separator' }; - } - - return { - id: action.id, - uri: action.uri, - enabled: action.enabled, - label: action.label - }; - } - - private getAdditionalKeybindings(): { [id: string]: IMenubarKeybinding } { - const keybindings: { [id: string]: IMenubarKeybinding } = {}; - if (isMacintosh) { - const keybinding = this.getMenubarKeybinding('workbench.action.quit'); - if (keybinding) { - keybindings['workbench.action.quit'] = keybinding; - } - } - - return keybindings; - } - - private getMenubarKeybinding(id: string): IMenubarKeybinding | undefined { - const binding = this.keybindingService.lookupKeybinding(id); - if (!binding) { - return undefined; - } - - // first try to resolve a native accelerator - const electronAccelerator = binding.getElectronAccelerator(); - if (electronAccelerator) { - return { label: electronAccelerator, userSettingsLabel: withNullAsUndefined(binding.getUserSettingsLabel()) }; - } - - // we need this fallback to support keybindings that cannot show in electron menus (e.g. chords) - const acceleratorLabel = binding.getLabel(); - if (acceleratorLabel) { - return { label: acceleratorLabel, isNative: false, userSettingsLabel: withNullAsUndefined(binding.getUserSettingsLabel()) }; - } - - return undefined; - } -} - export class CustomMenubarControl extends MenubarControl { private menubar: MenuBar; private container: HTMLElement; diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 66bf29cdd22..fbf3423014f 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -27,7 +27,7 @@ import { URI } from 'vs/base/common/uri'; import { Color } from 'vs/base/common/color'; import { trim } from 'vs/base/common/strings'; import { EventType, EventHelper, Dimension, isAncestor, hide, show, removeClass, addClass, append, $, addDisposableListener, runAtThisOrScheduleAtNextAnimationFrame } from 'vs/base/browser/dom'; -import { MenubarControl, NativeMenubarControl, CustomMenubarControl } from 'vs/workbench/browser/parts/titlebar/menubarControl'; +import { CustomMenubarControl } from 'vs/workbench/browser/parts/titlebar/menubarControl'; import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { template, getBaseLabel } from 'vs/base/common/labels'; import { ILabelService } from 'vs/platform/label/common/label'; @@ -65,7 +65,7 @@ export class TitlebarPart extends Part implements ITitleService { private windowControls: HTMLElement; private maxRestoreControl: HTMLElement; private appIcon: HTMLElement; - private menubarPart: MenubarControl; + private customMenubar: CustomMenubarControl | undefined; private menubar: HTMLElement; private resizer: HTMLElement; private lastLayoutDimensions: Dimension; @@ -332,19 +332,16 @@ export class TitlebarPart extends Part implements ITitleService { }))); } - // Menubar: the menubar part which is responsible for populating both the custom and native menubars - if ((isMacintosh && !isWeb) || getTitleBarStyle(this.configurationService, this.environmentService) === 'native') { - this.menubarPart = this.instantiationService.createInstance(NativeMenubarControl); - } else { - const customMenubarControl = this.instantiationService.createInstance(CustomMenubarControl); - this.menubarPart = customMenubarControl; + // Menubar: install a custom menu bar depending on configuration + if (getTitleBarStyle(this.configurationService, this.environmentService) !== 'native' && (!isMacintosh || isWeb)) { + this.customMenubar = this._register(this.instantiationService.createInstance(CustomMenubarControl)); this.menubar = append(this.element, $('div.menubar')); this.menubar.setAttribute('role', 'menubar'); - customMenubarControl.create(this.menubar); + this.customMenubar.create(this.menubar); - this._register(customMenubarControl.onVisibilityChange(e => this.onMenubarVisibilityChanged(e))); - this._register(customMenubarControl.onFocusStateChange(e => this.onMenubarFocusChanged(e))); + this._register(this.customMenubar.onVisibilityChange(e => this.onMenubarVisibilityChanged(e))); + this._register(this.customMenubar.onFocusStateChange(e => this.onMenubarFocusChanged(e))); } // Title @@ -547,7 +544,7 @@ export class TitlebarPart extends Part implements ITitleService { } private adjustTitleMarginToCenter(): void { - if (this.menubarPart instanceof CustomMenubarControl) { + if (this.customMenubar) { const leftMarker = (this.appIcon ? this.appIcon.clientWidth : 0) + this.menubar.clientWidth + 10; const rightMarker = this.element.clientWidth - (this.windowControls ? this.windowControls.clientWidth : 0) - 10; @@ -588,9 +585,9 @@ export class TitlebarPart extends Part implements ITitleService { runAtThisOrScheduleAtNextAnimationFrame(() => this.adjustTitleMarginToCenter()); - if (this.menubarPart instanceof CustomMenubarControl) { + if (this.customMenubar) { const menubarDimension = new Dimension(0, dimension.height); - this.menubarPart.layout(menubarDimension); + this.customMenubar.layout(menubarDimension); } } } diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index bfc7916011e..57dd6170e9a 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -14,7 +14,7 @@ import { IFileService } from 'vs/platform/files/common/files'; import { toResource, IUntitledResourceInput, SideBySideEditor, pathsToEditors } from 'vs/workbench/common/editor'; import { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/common/editorService'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { IWindowsService, IWindowService, IWindowSettings, IOpenFileRequest, IWindowsConfiguration, IAddFoldersRequest, IRunActionInWindowRequest, IRunKeybindingInWindowRequest } from 'vs/platform/windows/common/windows'; +import { IWindowsService, IWindowService, IWindowSettings, IOpenFileRequest, IWindowsConfiguration, IAddFoldersRequest, IRunActionInWindowRequest, IRunKeybindingInWindowRequest, getTitleBarStyle } from 'vs/platform/windows/common/windows'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { ITitleService } from 'vs/workbench/services/title/common/titleService'; import { IWorkbenchThemeService, VS_HC_THEME } from 'vs/workbench/services/themes/common/workbenchThemeService'; @@ -24,7 +24,7 @@ import { IResourceInput } from 'vs/platform/editor/common/editor'; import { KeyboardMapperFactory } from 'vs/workbench/services/keybinding/electron-browser/nativeKeymapService'; import { ipcRenderer as ipc, webFrame, crashReporter, Event } from 'electron'; import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing'; -import { IMenuService, MenuId, IMenu, MenuItemAction, ICommandAction } from 'vs/platform/actions/common/actions'; +import { IMenuService, MenuId, IMenu, MenuItemAction, ICommandAction, SubmenuItemAction } from 'vs/platform/actions/common/actions'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; import { RunOnceScheduler } from 'vs/base/common/async'; @@ -32,7 +32,7 @@ import { IDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecyc import { LifecyclePhase, ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces'; import { IIntegrityService } from 'vs/workbench/services/integrity/common/integrity'; -import { isRootUser, isWindows, isMacintosh, isLinux } from 'vs/base/common/platform'; +import { isRootUser, isWindows, isMacintosh, isLinux, isWeb } from 'vs/base/common/platform'; import product from 'vs/platform/product/node/product'; import pkg from 'vs/platform/product/node/package'; import { INotificationService } from 'vs/platform/notification/common/notification'; @@ -45,6 +45,15 @@ import { coalesce } from 'vs/base/common/arrays'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { isEqual } from 'vs/base/common/resources'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { MenubarControl } from '../browser/parts/titlebar/menubarControl'; +import { ILabelService } from 'vs/platform/label/common/label'; +import { IUpdateService } from 'vs/platform/update/common/update'; +import { IStorageService } from 'vs/platform/storage/common/storage'; +import { IPreferencesService } from '../services/preferences/common/preferences'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IMenubarService, IMenubarData, IMenubarMenu, IMenubarKeybinding, IMenubarMenuItemSubmenu, IMenubarMenuItemAction, MenubarMenuItem } from 'vs/platform/menubar/node/menubar'; +import { withNullAsUndefined } from 'vs/base/common/types'; const TextInputActions: IAction[] = [ new Action('undo', nls.localize('undo', "Undo"), undefined, true, () => Promise.resolve(document.execCommand('undo'))), @@ -91,7 +100,8 @@ export class ElectronWindow extends Disposable { @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService, @IAccessibilityService private readonly accessibilityService: IAccessibilityService, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, - @ITextFileService private readonly textFileService: ITextFileService + @ITextFileService private readonly textFileService: ITextFileService, + @IInstantiationService private readonly instantiationService: IInstantiationService ) { super(); @@ -297,6 +307,11 @@ export class ElectronWindow extends Disposable { private create(): void { + // Native menu controller + if (isMacintosh || getTitleBarStyle(this.configurationService, this.environmentService) === 'native') { + this._register(this.instantiationService.createInstance(NativeMenubarControl)); + } + // Handle window.open() calls const $this = this; window.open = function (url: string, target: string, features: string, replace: boolean): Window | null { @@ -538,3 +553,192 @@ export class ElectronWindow extends Disposable { return this.editorService.openEditors(resources); } } + +class NativeMenubarControl extends MenubarControl { + constructor( + @IMenuService menuService: IMenuService, + @IWindowService windowService: IWindowService, + @IWindowsService windowsService: IWindowsService, + @IContextKeyService contextKeyService: IContextKeyService, + @IKeybindingService keybindingService: IKeybindingService, + @IConfigurationService configurationService: IConfigurationService, + @ILabelService labelService: ILabelService, + @IUpdateService updateService: IUpdateService, + @IStorageService storageService: IStorageService, + @INotificationService notificationService: INotificationService, + @IPreferencesService preferencesService: IPreferencesService, + @IEnvironmentService environmentService: IEnvironmentService, + @IAccessibilityService accessibilityService: IAccessibilityService, + @IMenubarService private readonly menubarService: IMenubarService + ) { + super( + menuService, + windowService, + windowsService, + contextKeyService, + keybindingService, + configurationService, + labelService, + updateService, + storageService, + notificationService, + preferencesService, + environmentService, + accessibilityService); + + if (isMacintosh && !isWeb) { + this.menus['Preferences'] = this._register(this.menuService.createMenu(MenuId.MenubarPreferencesMenu, this.contextKeyService)); + this.topLevelTitles['Preferences'] = nls.localize('mPreferences', "Preferences"); + } + + for (const topLevelMenuName of Object.keys(this.topLevelTitles)) { + const menu = this.menus[topLevelMenuName]; + if (menu) { + this._register(menu.onDidChange(() => this.updateMenubar())); + } + } + + this.windowService.getRecentlyOpened().then((recentlyOpened) => { + this.recentlyOpened = recentlyOpened; + + this.doUpdateMenubar(true); + }); + + this.registerListeners(); + } + + protected doUpdateMenubar(firstTime: boolean): void { + + // Send menus to main process to be rendered by Electron + const menubarData = { menus: {}, keybindings: {} }; + if (this.getMenubarMenus(menubarData)) { + this.menubarService.updateMenubar(this.windowService.windowId, menubarData); + } + } + + private getMenubarMenus(menubarData: IMenubarData): boolean { + if (!menubarData) { + return false; + } + + menubarData.keybindings = this.getAdditionalKeybindings(); + for (const topLevelMenuName of Object.keys(this.topLevelTitles)) { + const menu = this.menus[topLevelMenuName]; + if (menu) { + const menubarMenu: IMenubarMenu = { items: [] }; + this.populateMenuItems(menu, menubarMenu, menubarData.keybindings); + if (menubarMenu.items.length === 0) { + return false; // Menus are incomplete + } + menubarData.menus[topLevelMenuName] = menubarMenu; + } + } + + return true; + } + + private populateMenuItems(menu: IMenu, menuToPopulate: IMenubarMenu, keybindings: { [id: string]: IMenubarKeybinding | undefined }) { + let groups = menu.getActions(); + for (let group of groups) { + const [, actions] = group; + + actions.forEach(menuItem => { + + if (menuItem instanceof SubmenuItemAction) { + const submenu = { items: [] }; + + if (!this.menus[menuItem.item.submenu]) { + this.menus[menuItem.item.submenu] = this.menuService.createMenu(menuItem.item.submenu, this.contextKeyService); + this._register(this.menus[menuItem.item.submenu]!.onDidChange(() => this.updateMenubar())); + } + + const menuToDispose = this.menuService.createMenu(menuItem.item.submenu, this.contextKeyService); + this.populateMenuItems(menuToDispose, submenu, keybindings); + + let menubarSubmenuItem: IMenubarMenuItemSubmenu = { + id: menuItem.id, + label: menuItem.label, + submenu: submenu + }; + + menuToPopulate.items.push(menubarSubmenuItem); + menuToDispose.dispose(); + } else { + if (menuItem.id === 'workbench.action.openRecent') { + const actions = this.getOpenRecentActions().map(this.transformOpenRecentAction); + menuToPopulate.items.push(...actions); + } + + let menubarMenuItem: IMenubarMenuItemAction = { + id: menuItem.id, + label: menuItem.label + }; + + if (menuItem.checked) { + menubarMenuItem.checked = true; + } + + if (!menuItem.enabled) { + menubarMenuItem.enabled = false; + } + + menubarMenuItem.label = this.calculateActionLabel(menubarMenuItem); + keybindings[menuItem.id] = this.getMenubarKeybinding(menuItem.id); + menuToPopulate.items.push(menubarMenuItem); + } + }); + + menuToPopulate.items.push({ id: 'vscode.menubar.separator' }); + } + + if (menuToPopulate.items.length > 0) { + menuToPopulate.items.pop(); + } + } + + private transformOpenRecentAction(action: Separator | (IAction & { uri: URI })): MenubarMenuItem { + if (action instanceof Separator) { + return { id: 'vscode.menubar.separator' }; + } + + return { + id: action.id, + uri: action.uri, + enabled: action.enabled, + label: action.label + }; + } + + private getAdditionalKeybindings(): { [id: string]: IMenubarKeybinding } { + const keybindings: { [id: string]: IMenubarKeybinding } = {}; + if (isMacintosh) { + const keybinding = this.getMenubarKeybinding('workbench.action.quit'); + if (keybinding) { + keybindings['workbench.action.quit'] = keybinding; + } + } + + return keybindings; + } + + private getMenubarKeybinding(id: string): IMenubarKeybinding | undefined { + const binding = this.keybindingService.lookupKeybinding(id); + if (!binding) { + return undefined; + } + + // first try to resolve a native accelerator + const electronAccelerator = binding.getElectronAccelerator(); + if (electronAccelerator) { + return { label: electronAccelerator, userSettingsLabel: withNullAsUndefined(binding.getUserSettingsLabel()) }; + } + + // we need this fallback to support keybindings that cannot show in electron menus (e.g. chords) + const acceleratorLabel = binding.getLabel(); + if (acceleratorLabel) { + return { label: acceleratorLabel, isNative: false, userSettingsLabel: withNullAsUndefined(binding.getUserSettingsLabel()) }; + } + + return undefined; + } +} \ No newline at end of file diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index 04981fd3a82..7aa1334e1f4 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -69,7 +69,7 @@ import { IIssueService } from 'vs/platform/issue/node/issue'; import { IssueService } from 'vs/platform/issue/electron-browser/issueService'; import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces'; import { WorkspacesService } from 'vs/platform/workspaces/electron-browser/workspacesService'; -import { IMenubarService } from 'vs/platform/menubar/common/menubar'; +import { IMenubarService } from 'vs/platform/menubar/node/menubar'; import { MenubarService } from 'vs/platform/menubar/electron-browser/menubarService'; import { IURLService } from 'vs/platform/url/common/url'; import { RelayURLService } from 'vs/platform/url/electron-browser/urlService'; From 0fe953811068ffb98736c2f9c0de918ccd518f39 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 19 Aug 2019 20:17:32 +0200 Subject: [PATCH 795/861] distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bfc482a9e1d..b8ed8e8fea7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.38.0", - "distro": "448bb39d6aabd312c4a28393314e7e406c52acb8", + "distro": "2f7403275ca8931a7265b58ac35e33096ce0d074", "author": { "name": "Microsoft Corporation" }, From 69f99d3439df22ec5b07358594c7d2bc32e3eb2c Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Mon, 19 Aug 2019 11:17:22 -0700 Subject: [PATCH 796/861] Unify trusted domain language and use quick pick item id --- src/vs/editor/browser/services/openerService.ts | 2 +- src/vs/workbench/contrib/url/common/url.contribution.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/browser/services/openerService.ts b/src/vs/editor/browser/services/openerService.ts index 60be6dadd59..c92e5a70c76 100644 --- a/src/vs/editor/browser/services/openerService.ts +++ b/src/vs/editor/browser/services/openerService.ts @@ -91,7 +91,7 @@ export class OpenerService implements IOpenerService { [ localize('openLink', 'Open Link'), localize('cancel', 'Cancel'), - localize('configureLinkPermission', 'Configure Link Permission'), + localize('configureTrustedDomains', 'Configure Trusted Domains') ], { cancelId: 1 diff --git a/src/vs/workbench/contrib/url/common/url.contribution.ts b/src/vs/workbench/contrib/url/common/url.contribution.ts index dc917095f0c..475265542b1 100644 --- a/src/vs/workbench/contrib/url/common/url.contribution.ts +++ b/src/vs/workbench/contrib/url/common/url.contribution.ts @@ -65,6 +65,7 @@ const configureTrustedDomainsHandler = ( return { type: 'item', label: d, + id: d, picked: true, }; }); @@ -73,6 +74,7 @@ const configureTrustedDomainsHandler = ( { type: 'item', label: localize('openAllLinksWithoutPrompt', 'Open all links without prompt'), + id: '*', picked: trustedDomains.indexOf('*') !== -1 } ]; @@ -82,6 +84,7 @@ const configureTrustedDomainsHandler = ( domainToConfigureItem = { type: 'item', label: domainToConfigure, + id: domainToConfigure, picked: true, description: localize('trustDomainAndOpenLink', 'Trust domain and open link') }; @@ -97,7 +100,7 @@ const configureTrustedDomainsHandler = ( activeItem: domainToConfigureItem }).then(result => { if (result) { - const pickedDomains = result.map(r => r.label); + const pickedDomains = result.map(r => r.id); storageService.store('http.trustedDomains', JSON.stringify(pickedDomains), StorageScope.GLOBAL); return pickedDomains; From 94c6d0482f89e04f4aa7903f0ef1947316c7f3f9 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Mon, 19 Aug 2019 11:49:30 -0700 Subject: [PATCH 797/861] Update browser telemetry common properties --- src/vs/base/common/platform.ts | 14 ++++++-------- .../telemetry/browser/workbenchCommonProperties.ts | 7 ++++--- src/vs/workbench/browser/web.main.ts | 2 +- .../environment/browser/environmentService.ts | 2 ++ 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/vs/base/common/platform.ts b/src/vs/base/common/platform.ts index d7371552d30..07759dffe59 100644 --- a/src/vs/base/common/platform.ts +++ b/src/vs/base/common/platform.ts @@ -93,14 +93,12 @@ export function PlatformToString(platform: Platform) { } let _platform: Platform = Platform.Web; -if (_isNative) { - if (_isMacintosh) { - _platform = Platform.Mac; - } else if (_isWindows) { - _platform = Platform.Windows; - } else if (_isLinux) { - _platform = Platform.Linux; - } +if (_isMacintosh) { + _platform = Platform.Mac; +} else if (_isWindows) { + _platform = Platform.Windows; +} else if (_isLinux) { + _platform = Platform.Linux; } export const isWindows = _isWindows; diff --git a/src/vs/platform/telemetry/browser/workbenchCommonProperties.ts b/src/vs/platform/telemetry/browser/workbenchCommonProperties.ts index 8f2d2413061..ac0da4361f7 100644 --- a/src/vs/platform/telemetry/browser/workbenchCommonProperties.ts +++ b/src/vs/platform/telemetry/browser/workbenchCommonProperties.ts @@ -16,18 +16,19 @@ import { cleanRemoteAuthority } from 'vs/platform/telemetry/common/telemetryUtil export async function resolveWorkbenchCommonProperties(storageService: IStorageService, commit: string | undefined, version: string | undefined, machineId: string, remoteAuthority?: string): Promise<{ [name: string]: string | undefined }> { const result: { [name: string]: string | undefined; } = Object.create(null); - const instanceId = storageService.get(instanceStorageKey, StorageScope.GLOBAL)!; const firstSessionDate = storageService.get(firstSessionDateStorageKey, StorageScope.GLOBAL)!; const lastSessionDate = storageService.get(lastSessionDateStorageKey, StorageScope.GLOBAL)!; + /** + * Note: In the web, session date information is fetched from browser storage, so these dates are tied to a specific + * browser and not the machine overall. + */ // __GDPR__COMMON__ "common.firstSessionDate" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } result['common.firstSessionDate'] = firstSessionDate; // __GDPR__COMMON__ "common.lastSessionDate" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } result['common.lastSessionDate'] = lastSessionDate || ''; // __GDPR__COMMON__ "common.isNewSession" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } result['common.isNewSession'] = !lastSessionDate ? '1' : '0'; - // __GDPR__COMMON__ "common.instanceId" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } - result['common.instanceId'] = instanceId; // __GDPR__COMMON__ "common.remoteAuthority" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" } result['common.remoteAuthority'] = cleanRemoteAuthority(remoteAuthority); diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index e882484c10b..b4a31c9a356 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -204,7 +204,7 @@ class CodeRendererMain extends Disposable { version: '1.38.0-unknown', nameLong: 'Unknown', extensionAllowedProposedApi: [], - }, ...{ urlProtocol: '', enableTelemetry: false } + }, ...{ urlProtocol: ''} }; return { _serviceBrand: undefined, ...productConfiguration }; } diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts index 318caeb3d77..6cbe59689db 100644 --- a/src/vs/workbench/services/environment/browser/environmentService.ts +++ b/src/vs/workbench/services/environment/browser/environmentService.ts @@ -15,6 +15,7 @@ import { joinPath } from 'vs/base/common/resources'; import { Schemas } from 'vs/base/common/network'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IWorkbenchConstructionOptions } from 'vs/workbench/workbench.web.api'; +import { generateUuid } from 'vs/base/common/uuid'; export class BrowserWindowConfiguration implements IWindowConfiguration { @@ -80,6 +81,7 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment this.appNameLong = 'Visual Studio Code - Web'; this.configuration.remoteAuthority = options.remoteAuthority; + this.configuration.machineId = generateUuid(); this.userRoamingDataHome = URI.file('/User').with({ scheme: Schemas.userData }); this.settingsResource = joinPath(this.userRoamingDataHome, 'settings.json'); this.keybindingsResource = joinPath(this.userRoamingDataHome, 'keybindings.json'); From 8d67f9b13a0290c57a9ca13b150f752918cbebab Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 19 Aug 2019 21:05:28 +0200 Subject: [PATCH 798/861] #79454 Fix warnings --- src/vs/workbench/browser/parts/views/customView.ts | 4 +++- src/vs/workbench/common/views.ts | 2 -- .../contrib/preferences/browser/keybindingsEditor.ts | 2 +- src/vs/workbench/contrib/preferences/common/preferences.ts | 1 - 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/browser/parts/views/customView.ts b/src/vs/workbench/browser/parts/views/customView.ts index 7e98724953d..2fcbf196e0d 100644 --- a/src/vs/workbench/browser/parts/views/customView.ts +++ b/src/vs/workbench/browser/parts/views/customView.ts @@ -69,7 +69,9 @@ export class CustomTreeViewPanel extends ViewletPanel { } renderBody(container: HTMLElement): void { - this.treeView.show(container); + if (this.treeView instanceof CustomTreeView) { + this.treeView.show(container); + } } layoutBody(height: number, width: number): void { diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index ab8b188c72d..7306d530fcb 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -334,8 +334,6 @@ export interface ITreeView extends IDisposable { layout(height: number, width: number): void; - show(container: HTMLElement): void; - getOptimalWidth(): number; reveal(item: ITreeItem): Promise; diff --git a/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts b/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts index d83000eaaa4..a45a2680f32 100644 --- a/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts +++ b/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts @@ -789,7 +789,7 @@ class KeybindingItemRenderer implements IListRenderer; defineWhenExpression(keybindingEntry: IKeybindingItemEntry): void; From b3827c8b373ac1335e573ad8e6480fcc3a114b69 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 19 Aug 2019 21:08:33 +0200 Subject: [PATCH 799/861] Fix #79429 --- .../extensions/browser/extensionTipsService.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts b/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts index ebf0b5ba336..3e7884ae1f7 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts @@ -520,8 +520,8 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe return false; } - const id = recommendationsToSuggest[0]; - const tip = this._importantExeBasedRecommendations[id]; + const extensionId = recommendationsToSuggest[0]; + const tip = this._importantExeBasedRecommendations[extensionId]; const message = localize('exeRecommended', "The '{0}' extension is recommended as you have {1} installed on your system.", tip.friendlyName!, tip.exeFriendlyName || basename(tip.windowsPath!)); this.notificationService.prompt(Severity.Info, message, @@ -534,8 +534,8 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe "extensionId": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" } } */ - this.telemetryService.publicLog('exeExtensionRecommendations:popup', { userReaction: 'install', extensionId: name }); - this.instantiationService.createInstance(InstallRecommendedExtensionAction, id).run(); + this.telemetryService.publicLog('exeExtensionRecommendations:popup', { userReaction: 'install', extensionId }); + this.instantiationService.createInstance(InstallRecommendedExtensionAction, extensionId).run(); } }, { label: localize('showRecommendations', "Show Recommendations"), @@ -546,7 +546,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe "extensionId": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" } } */ - this.telemetryService.publicLog('exeExtensionRecommendations:popup', { userReaction: 'show', extensionId: name }); + this.telemetryService.publicLog('exeExtensionRecommendations:popup', { userReaction: 'show', extensionId }); const recommendationsAction = this.instantiationService.createInstance(ShowRecommendedExtensionsAction, ShowRecommendedExtensionsAction.ID, localize('showRecommendations', "Show Recommendations")); recommendationsAction.run(); @@ -556,14 +556,14 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe label: choiceNever, isSecondary: true, run: () => { - this.addToImportantRecommendationsIgnore(id); + this.addToImportantRecommendationsIgnore(extensionId); /* __GDPR__ "exeExtensionRecommendations:popup" : { "userReaction" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, "extensionId": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" } } */ - this.telemetryService.publicLog('exeExtensionRecommendations:popup', { userReaction: 'neverShowAgain', extensionId: name }); + this.telemetryService.publicLog('exeExtensionRecommendations:popup', { userReaction: 'neverShowAgain', extensionId }); this.notificationService.prompt( Severity.Info, localize('ignoreExtensionRecommendations', "Do you want to ignore all extension recommendations?"), @@ -586,7 +586,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe "extensionId": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" } } */ - this.telemetryService.publicLog('exeExtensionRecommendations:popup', { userReaction: 'cancelled', extensionId: name }); + this.telemetryService.publicLog('exeExtensionRecommendations:popup', { userReaction: 'cancelled', extensionId }); } } ); From 56b7625239e507ed274555495a2f2ca1a6595ffa Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Mon, 19 Aug 2019 12:58:51 -0700 Subject: [PATCH 800/861] Fix hygiene check --- src/vs/workbench/browser/web.main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index b4a31c9a356..dcb44e8c137 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -204,7 +204,7 @@ class CodeRendererMain extends Disposable { version: '1.38.0-unknown', nameLong: 'Unknown', extensionAllowedProposedApi: [], - }, ...{ urlProtocol: ''} + }, ...{ urlProtocol: '' } }; return { _serviceBrand: undefined, ...productConfiguration }; } From e9b4a91e4a735343faeaeeaf88aa2c65c6b7943a Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 19 Aug 2019 19:40:31 -0700 Subject: [PATCH 801/861] Pass rendered markdown through additional sanitizer Uses insane to process rendered markdown. Adds an additional level of protection for context injections --- build/gulpfile.hygiene.js | 2 + src/vs/base/browser/markdownRenderer.ts | 16 +- src/vs/base/common/insane/cgmanifest.json | 17 + src/vs/base/common/insane/insane.d.ts | 20 + src/vs/base/common/insane/insane.js | 478 +++++++++++++++++++ src/vs/base/common/insane/insane.license.txt | 20 + 6 files changed, 552 insertions(+), 1 deletion(-) create mode 100644 src/vs/base/common/insane/cgmanifest.json create mode 100644 src/vs/base/common/insane/insane.d.ts create mode 100644 src/vs/base/common/insane/insane.js create mode 100644 src/vs/base/common/insane/insane.license.txt diff --git a/build/gulpfile.hygiene.js b/build/gulpfile.hygiene.js index a05fff4a1bd..c065556dc09 100644 --- a/build/gulpfile.hygiene.js +++ b/build/gulpfile.hygiene.js @@ -50,6 +50,7 @@ const indentationFilter = [ '!src/vs/css.js', '!src/vs/css.build.js', '!src/vs/loader.js', + '!src/vs/base/common/insane/insane.js', '!src/vs/base/common/marked/marked.js', '!src/vs/base/node/terminateProcess.sh', '!src/vs/base/node/cpuUsage.sh', @@ -131,6 +132,7 @@ const eslintFilter = [ '!src/vs/nls.js', '!src/vs/css.build.js', '!src/vs/nls.build.js', + '!src/**/insane.js', '!src/**/marked.js', '!**/test/**' ]; diff --git a/src/vs/base/browser/markdownRenderer.ts b/src/vs/base/browser/markdownRenderer.ts index 493f60ef8a1..23a30ee9373 100644 --- a/src/vs/base/browser/markdownRenderer.ts +++ b/src/vs/base/browser/markdownRenderer.ts @@ -9,6 +9,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { IMarkdownString, parseHrefAndDimensions, removeMarkdownEscapes } from 'vs/base/common/htmlContent'; import { defaultGenerator } from 'vs/base/common/idGenerator'; import * as marked from 'vs/base/common/marked/marked'; +import * as insane from 'vs/base/common/insane/insane'; import { parse } from 'vs/base/common/marshalling'; import { cloneAndChange } from 'vs/base/common/objects'; import { escape } from 'vs/base/common/strings'; @@ -171,7 +172,20 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende renderer }; - element.innerHTML = marked.parse(markdown.value, markedOptions); + const allowedSchemes = ['http', 'https', 'mailto']; + if (markdown.isTrusted) { + allowedSchemes.push('command'); + } + + const renderedMarkdown = marked.parse(markdown.value, markedOptions); + element.innerHTML = insane(renderedMarkdown, { + allowedSchemes, + allowedAttributes: { + 'a': ['href', 'name', 'target', 'data-href'], + 'iframe': ['allowfullscreen', 'frameborder', 'src'], + 'img': ['src'] + } + }); signalInnerHTML!(); return element; diff --git a/src/vs/base/common/insane/cgmanifest.json b/src/vs/base/common/insane/cgmanifest.json new file mode 100644 index 00000000000..bb94b817088 --- /dev/null +++ b/src/vs/base/common/insane/cgmanifest.json @@ -0,0 +1,17 @@ +{ + "registrations": [ + { + "component": { + "type": "git", + "git": { + "name": "insane", + "repositoryUrl": "https://github.com/bevacqua/insane", + "commitHash": "7f5a809f44a37e7d11ee5343b2d8bca4be6ba4ae" + } + }, + "license": "MIT", + "version": "2.6.2" + } + ], + "version": 1 +} diff --git a/src/vs/base/common/insane/insane.d.ts b/src/vs/base/common/insane/insane.d.ts new file mode 100644 index 00000000000..def347529e9 --- /dev/null +++ b/src/vs/base/common/insane/insane.d.ts @@ -0,0 +1,20 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export as namespace insane; + +export = insane; + +declare function insane( + html: string, + options?: { + readonly allowedSchemes?: readonly string[], + readonly allowedTags?: readonly string[], + readonly allowedAttributes?: { readonly [key: string]: string[] }, + }, + strict?: boolean, +): string; + +declare namespace insane { } diff --git a/src/vs/base/common/insane/insane.js b/src/vs/base/common/insane/insane.js new file mode 100644 index 00000000000..3cfdf5886bb --- /dev/null +++ b/src/vs/base/common/insane/insane.js @@ -0,0 +1,478 @@ +/* +The MIT License (MIT) + +Copyright © 2015 Nicolas Bevacqua + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +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. +*/ + +// ESM-comment-begin +let __insane_exports; +// ESM-comment-end + + + +(function () { function r(e, n, t) { function o(i, f) { if (!n[i]) { if (!e[i]) { var c = "function" == typeof require && require; if (!f && c) return c(i, !0); if (u) return u(i, !0); var a = new Error("Cannot find module '" + i + "'"); throw a.code = "MODULE_NOT_FOUND", a } var p = n[i] = { exports: {} }; e[i][0].call(p.exports, function (r) { var n = e[i][1][r]; return o(n || r) }, p, p.exports, r, e, n, t) } return n[i].exports } for (var u = "function" == typeof require && require, i = 0; i < t.length; i++)o(t[i]); return o } return r })()({ + 1: [function (require, module, exports) { + 'use strict'; + + var toMap = require('./toMap'); + var uris = ['background', 'base', 'cite', 'href', 'longdesc', 'src', 'usemap']; + + module.exports = { + uris: toMap(uris) // attributes that have an href and hence need to be sanitized + }; + + }, { "./toMap": 10 }], 2: [function (require, module, exports) { + 'use strict'; + + var defaults = { + allowedAttributes: { + '*': ['title', 'accesskey'], + a: ['href', 'name', 'target', 'aria-label'], + iframe: ['allowfullscreen', 'frameborder', 'src'], + img: ['src', 'alt', 'title', 'aria-label'] + }, + allowedClasses: {}, + allowedSchemes: ['http', 'https', 'mailto'], + allowedTags: [ + 'a', 'abbr', 'article', 'b', 'blockquote', 'br', 'caption', 'code', 'del', 'details', 'div', 'em', + 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'ins', 'kbd', 'li', 'main', 'mark', + 'ol', 'p', 'pre', 'section', 'span', 'strike', 'strong', 'sub', 'summary', 'sup', 'table', + 'tbody', 'td', 'th', 'thead', 'tr', 'u', 'ul' + ], + filter: null + }; + + module.exports = defaults; + + }, {}], 3: [function (require, module, exports) { + 'use strict'; + + var toMap = require('./toMap'); + var voids = ['area', 'br', 'col', 'hr', 'img', 'wbr', 'input', 'base', 'basefont', 'link', 'meta']; + + module.exports = { + voids: toMap(voids) + }; + + }, { "./toMap": 10 }], 4: [function (require, module, exports) { + 'use strict'; + + var he = require('he'); + var assign = require('assignment'); + var parser = require('./parser'); + var sanitizer = require('./sanitizer'); + var defaults = require('./defaults'); + + function insane(html, options, strict) { + var buffer = []; + var configuration = strict === true ? options : assign({}, defaults, options); + var handler = sanitizer(buffer, configuration); + + parser(html, handler); + + return buffer.join(''); + } + + insane.defaults = defaults; + module.exports = insane; + __insane_exports = insane; + + }, { "./defaults": 2, "./parser": 7, "./sanitizer": 8, "assignment": 6, "he": 9 }], 5: [function (require, module, exports) { + 'use strict'; + + module.exports = function lowercase(string) { + return typeof string === 'string' ? string.toLowerCase() : string; + }; + + }, {}], 6: [function (require, module, exports) { + 'use strict'; + + function assignment(result) { + var stack = Array.prototype.slice.call(arguments, 1); + var item; + var key; + while (stack.length) { + item = stack.shift(); + for (key in item) { + if (item.hasOwnProperty(key)) { + if (Object.prototype.toString.call(result[key]) === '[object Object]') { + result[key] = assignment(result[key], item[key]); + } else { + result[key] = item[key]; + } + } + } + } + return result; + } + + module.exports = assignment; + + }, {}], 7: [function (require, module, exports) { + 'use strict'; + + var he = require('he'); + var lowercase = require('./lowercase'); + var attributes = require('./attributes'); + var elements = require('./elements'); + var rstart = /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/; + var rend = /^<\s*\/\s*([\w:-]+)[^>]*>/; + var rattrs = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g; + var rtag = /^'); + if (index >= 0) { + if (handler.comment) { + handler.comment(html.substring(4, index)); + } + html = html.substring(index + 3); + chars = false; + } + } + + function parseTagDecode() { + if (!chars) { + return; + } + var text; + var index = html.indexOf('<'); + if (index >= 0) { + text = html.substring(0, index); + html = html.substring(index); + } else { + text = html; + html = ''; + } + if (handler.chars) { + handler.chars(text); + } + } + + function parseStartTag(tag, tagName, rest, unary) { + var attrs = {}; + var low = lowercase(tagName); + var u = elements.voids[low] || !!unary; + + rest.replace(rattrs, attrReplacer); + + if (!u) { + stack.push(low); + } + if (handler.start) { + handler.start(low, attrs, u); + } + + function attrReplacer(match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) { + if (doubleQuotedValue === void 0 && singleQuotedValue === void 0 && unquotedValue === void 0) { + attrs[name] = void 0; // attribute is like + } else { + attrs[name] = he.decode(doubleQuotedValue || singleQuotedValue || unquotedValue || ''); + } + } + } + + function parseEndTag(tag, tagName) { + var i; + var pos = 0; + var low = lowercase(tagName); + if (low) { + for (pos = stack.length - 1; pos >= 0; pos--) { + if (stack[pos] === low) { + break; // find the closest opened tag of the same type + } + } + } + if (pos >= 0) { + for (i = stack.length - 1; i >= pos; i--) { + if (handler.end) { // close all the open elements, up the stack + handler.end(stack[i]); + } + } + stack.length = pos; + } + } + } + + module.exports = parser; + + }, { "./attributes": 1, "./elements": 3, "./lowercase": 5, "he": 9 }], 8: [function (require, module, exports) { + 'use strict'; + + var he = require('he'); + var lowercase = require('./lowercase'); + var attributes = require('./attributes'); + var elements = require('./elements'); + + function sanitizer(buffer, options) { + var last; + var context; + var o = options || {}; + + reset(); + + return { + start: start, + end: end, + chars: chars + }; + + function out(value) { + buffer.push(value); + } + + function start(tag, attrs, unary) { + var low = lowercase(tag); + + if (context.ignoring) { + ignore(low); return; + } + if ((o.allowedTags || []).indexOf(low) === -1) { + ignore(low); return; + } + if (o.filter && !o.filter({ tag: low, attrs: attrs })) { + ignore(low); return; + } + + out('<'); + out(low); + Object.keys(attrs).forEach(parse); + out(unary ? '/>' : '>'); + + function parse(key) { + var value = attrs[key]; + var classesOk = (o.allowedClasses || {})[low] || []; + var attrsOk = (o.allowedAttributes || {})[low] || []; + attrsOk = attrsOk.concat((o.allowedAttributes || {})['*'] || []); + var valid; + var lkey = lowercase(key); + if (lkey === 'class' && attrsOk.indexOf(lkey) === -1) { + value = value.split(' ').filter(isValidClass).join(' ').trim(); + valid = value.length; + } else { + valid = attrsOk.indexOf(lkey) !== -1 && (attributes.uris[lkey] !== true || testUrl(value)); + } + if (valid) { + out(' '); + out(key); + if (typeof value === 'string') { + out('="'); + out(he.encode(value)); + out('"'); + } + } + function isValidClass(className) { + return classesOk && classesOk.indexOf(className) !== -1; + } + } + } + + function end(tag) { + var low = lowercase(tag); + var allowed = (o.allowedTags || []).indexOf(low) !== -1; + if (allowed) { + if (context.ignoring === false) { + out(''); + } else { + unignore(low); + } + } else { + unignore(low); + } + } + + function testUrl(text) { + var start = text[0]; + if (start === '#' || start === '/') { + return true; + } + var colon = text.indexOf(':'); + if (colon === -1) { + return true; + } + var questionmark = text.indexOf('?'); + if (questionmark !== -1 && colon > questionmark) { + return true; + } + var hash = text.indexOf('#'); + if (hash !== -1 && colon > hash) { + return true; + } + return o.allowedSchemes.some(matches); + + function matches(scheme) { + return text.indexOf(scheme + ':') === 0; + } + } + + function chars(text) { + if (context.ignoring === false) { + out(o.transformText ? o.transformText(text) : text); + } + } + + function ignore(tag) { + if (elements.voids[tag]) { + return; + } + if (context.ignoring === false) { + context = { ignoring: tag, depth: 1 }; + } else if (context.ignoring === tag) { + context.depth++; + } + } + + function unignore(tag) { + if (context.ignoring === tag) { + if (--context.depth <= 0) { + reset(); + } + } + } + + function reset() { + context = { ignoring: false, depth: 0 }; + } + } + + module.exports = sanitizer; + + }, { "./attributes": 1, "./elements": 3, "./lowercase": 5, "he": 9 }], 9: [function (require, module, exports) { + 'use strict'; + + var escapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + var unescapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'" + }; + var rescaped = /(&|<|>|"|')/g; + var runescaped = /[&<>"']/g; + + function escapeHtmlChar(match) { + return escapes[match]; + } + function unescapeHtmlChar(match) { + return unescapes[match]; + } + + function escapeHtml(text) { + return text == null ? '' : String(text).replace(runescaped, escapeHtmlChar); + } + + function unescapeHtml(html) { + return html == null ? '' : String(html).replace(rescaped, unescapeHtmlChar); + } + + escapeHtml.options = unescapeHtml.options = {}; + + module.exports = { + encode: escapeHtml, + escape: escapeHtml, + decode: unescapeHtml, + unescape: unescapeHtml, + version: '1.0.0-browser' + }; + + }, {}], 10: [function (require, module, exports) { + 'use strict'; + + function toMap(list) { + return list.reduce(asKey, {}); + } + + function asKey(accumulator, item) { + accumulator[item] = true; + return accumulator; + } + + module.exports = toMap; + + }, {}] +}, {}, [4]); + +// BEGIN MONACOCHANGE +// __marked_exports = marked; +// }).call(this); + +// ESM-comment-begin +define(function() { return __insane_exports; }); +// ESM-comment-end diff --git a/src/vs/base/common/insane/insane.license.txt b/src/vs/base/common/insane/insane.license.txt new file mode 100644 index 00000000000..b980cef0bc7 --- /dev/null +++ b/src/vs/base/common/insane/insane.license.txt @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright © 2015 Nicolas Bevacqua + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +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. From bfda91410442d32601f2d760fa7e2f612df9f57f Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 19 Aug 2019 19:48:50 -0700 Subject: [PATCH 802/861] Update md grammar Fixes #https://github.com/microsoft/vscode/issues/79478 --- .../syntaxes/markdown.tmLanguage.json | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json index 6fb25ae6ce2..28c275a5c35 100644 --- a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json +++ b/extensions/markdown-basics/syntaxes/markdown.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/vscode-markdown-tm-grammar/commit/05ccfa3db6edbd357390431f9e316adb38ba41d8", + "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/d64818b45a51ad281d0eececa06fccb8c3767fe4", "name": "Markdown", "scopeName": "text.html.markdown", "patterns": [ @@ -122,7 +122,7 @@ "contentName": "meta.embedded.block.html", "patterns": [ { - "include": "text.html.basic" + "include": "text.html.derivative" } ] } @@ -386,7 +386,7 @@ "contentName": "meta.embedded.block.php", "patterns": [ { - "include": "text.html.basic" + "include": "text.html.derivative" }, { "include": "source.php" @@ -1993,7 +1993,7 @@ "1": { "patterns": [ { - "include": "text.html.basic" + "include": "text.html.derivative" } ] }, @@ -2015,7 +2015,7 @@ "begin": "(\\s*|$)", "patterns": [ { - "include": "text.html.basic" + "include": "text.html.derivative" } ], "while": "(?i)^(?!.*)" @@ -2023,10 +2023,10 @@ ] }, { - "begin": "(?i)(^|\\G)\\s*(?=))", + "begin": "(?i)(^|\\G)\\s*(?=]*(\\s|$|/?>))", "patterns": [ { - "include": "text.html.basic" + "include": "text.html.derivative" } ], "while": "^(?!\\s*$)" @@ -2035,7 +2035,7 @@ "begin": "(^|\\G)\\s*(?=(<[a-zA-Z0-9\\-](/?>|\\s.*?>)|)\\s*$)", "patterns": [ { - "include": "text.html.basic" + "include": "text.html.derivative" } ], "while": "^(?!\\s*$)" @@ -2095,7 +2095,7 @@ "include": "#inline" }, { - "include": "text.html.basic" + "include": "text.html.derivative" }, { "include": "#heading-setext" @@ -2152,7 +2152,7 @@ "include": "#inline" }, { - "include": "text.html.basic" + "include": "text.html.derivative" }, { "include": "#heading-setext" @@ -2246,7 +2246,7 @@ "end": "(?<=>)", "patterns": [ { - "include": "text.html.basic" + "include": "text.html.derivative" } ] }, @@ -2391,7 +2391,7 @@ "end": "(?<=>)", "patterns": [ { - "include": "text.html.basic" + "include": "text.html.derivative" } ] }, From abb946ccaa79ba4b17f1d2974ee273797ea0f569 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 19 Aug 2019 20:01:14 -0700 Subject: [PATCH 803/861] =?UTF-8?q?Whitelist=20a=20few=20additional=20attr?= =?UTF-8?q?ibutes=20for=20img=20elements=20in=20md=C3=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vs/base/browser/markdownRenderer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/browser/markdownRenderer.ts b/src/vs/base/browser/markdownRenderer.ts index 23a30ee9373..5d94200e15a 100644 --- a/src/vs/base/browser/markdownRenderer.ts +++ b/src/vs/base/browser/markdownRenderer.ts @@ -183,7 +183,7 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende allowedAttributes: { 'a': ['href', 'name', 'target', 'data-href'], 'iframe': ['allowfullscreen', 'frameborder', 'src'], - 'img': ['src'] + 'img': ['src', 'title', 'alt', 'width', 'height'] } }); signalInnerHTML!(); From 7af2ebb9fca2d021c1571d3c0983e39a1a7af028 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 19 Aug 2019 20:10:35 -0700 Subject: [PATCH 804/861] Update md grammar --- .../syntaxes/markdown.tmLanguage.json | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json index 28c275a5c35..3fe94d8cf7e 100644 --- a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json +++ b/extensions/markdown-basics/syntaxes/markdown.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/vscode-markdown-tm-grammar/commit/d64818b45a51ad281d0eececa06fccb8c3767fe4", + "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/eb3898715b50d7911377a650e383a768a3a21f25", "name": "Markdown", "scopeName": "text.html.markdown", "patterns": [ @@ -122,7 +122,7 @@ "contentName": "meta.embedded.block.html", "patterns": [ { - "include": "text.html.derivative" + "include": "text.html.basic" } ] } @@ -386,7 +386,7 @@ "contentName": "meta.embedded.block.php", "patterns": [ { - "include": "text.html.derivative" + "include": "text.html.basic" }, { "include": "source.php" @@ -1855,12 +1855,12 @@ "name": "markup.fenced_code.block.markdown" }, "heading": { - "match": "(?:^|\\G)[ ]{0,3}((#{1,6})\\s*(?=[\\S[^#]]).*?\\s*(#{1,6})?)$\\n?", + "match": "(?:^|\\G)[ ]{0,3}((#{1,6})\\s+(?=[\\S[^#]]).*?\\s*(#{1,6})?)$\\n?", "captures": { "1": { "patterns": [ { - "match": "(#{6})\\s*(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?", + "match": "(#{6})\\s+(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?", "name": "heading.6.markdown", "captures": { "1": { @@ -1875,7 +1875,7 @@ } }, { - "match": "(#{5})\\s*(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?", + "match": "(#{5})\\s+(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?", "name": "heading.5.markdown", "captures": { "1": { @@ -1890,7 +1890,7 @@ } }, { - "match": "(#{4})\\s*(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?", + "match": "(#{4})\\s+(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?", "name": "heading.4.markdown", "captures": { "1": { @@ -1905,7 +1905,7 @@ } }, { - "match": "(#{3})\\s*(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?", + "match": "(#{3})\\s+(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?", "name": "heading.3.markdown", "captures": { "1": { @@ -1920,7 +1920,7 @@ } }, { - "match": "(#{2})\\s*(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?", + "match": "(#{2})\\s+(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?", "name": "heading.2.markdown", "captures": { "1": { @@ -1935,7 +1935,7 @@ } }, { - "match": "(#{1})\\s*(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?", + "match": "(#{1})\\s+(?=[\\S[^#]])(.*?)\\s*(\\s+#+)?$\\n?", "name": "heading.1.markdown", "captures": { "1": { @@ -2023,7 +2023,7 @@ ] }, { - "begin": "(?i)(^|\\G)\\s*(?=]*(\\s|$|/?>))", + "begin": "(?i)(^|\\G)\\s*(?=))", "patterns": [ { "include": "text.html.derivative" From c5dc9d16be5cbd18b4a1bc44941ef8a1b16cf983 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 19 Aug 2019 20:18:26 -0700 Subject: [PATCH 805/861] Finalize asWebviewUri api Fixes #79242 As discussed, renames `toWebviewResource` to `asWebviewUri` to be consistent with the `asAbsolutePath` api naming --- .../src/features/preview.ts | 4 +-- .../src/features/previewContentProvider.ts | 16 +++++----- .../src/util/resources.ts | 4 +-- .../src/singlefolder-tests/webview.test.ts | 8 ++--- src/vs/vscode.d.ts | 24 ++++++++++++++ src/vs/vscode.proposed.d.ts | 31 ------------------- .../workbench/api/common/extHostCodeInsets.ts | 6 ++-- src/vs/workbench/api/common/extHostWebview.ts | 6 ++-- src/vs/workbench/api/common/shared/webview.ts | 2 +- .../api/extHostWebview.test.ts | 24 +++++++------- 10 files changed, 59 insertions(+), 66 deletions(-) diff --git a/extensions/markdown-language-features/src/features/preview.ts b/extensions/markdown-language-features/src/features/preview.ts index 694a4fbb13c..775734d1140 100644 --- a/extensions/markdown-language-features/src/features/preview.ts +++ b/extensions/markdown-language-features/src/features/preview.ts @@ -439,8 +439,8 @@ export class MarkdownPreview extends Disposable { if (this._resource === markdownResource) { const self = this; const resourceProvider: WebviewResourceProvider = { - toWebviewResource: (resource) => { - return this.editor.webview.toWebviewResource(normalizeResource(markdownResource, resource)); + asWebviewUri: (resource) => { + return this.editor.webview.asWebviewUri(normalizeResource(markdownResource, resource)); }, get cspSource() { return self.editor.webview.cspSource; } }; diff --git a/extensions/markdown-language-features/src/features/previewContentProvider.ts b/extensions/markdown-language-features/src/features/previewContentProvider.ts index 9b70fe3beb3..0be66d1d630 100644 --- a/extensions/markdown-language-features/src/features/previewContentProvider.ts +++ b/extensions/markdown-language-features/src/features/previewContentProvider.ts @@ -65,7 +65,7 @@ export class MarkdownContentProvider { scrollEditorWithPreview: config.scrollEditorWithPreview, doubleClickToSwitchToEditor: config.doubleClickToSwitchToEditor, disableSecurityWarnings: this.cspArbiter.shouldDisableSecurityWarnings(), - webviewResourceRoot: resourceProvider.toWebviewResource(markdownDocument.uri).toString(), + webviewResourceRoot: resourceProvider.asWebviewUri(markdownDocument.uri).toString(), }; this.logger.log('provideTextDocumentContent', initialData); @@ -86,7 +86,7 @@ export class MarkdownContentProvider { data-state="${escapeAttribute(JSON.stringify(state || {}))}"> ${this.getStyles(resourceProvider, sourceUri, config, state)} - + ${body} @@ -110,7 +110,7 @@ export class MarkdownContentProvider { } private extensionResourcePath(resourceProvider: WebviewResourceProvider, mediaFile: string): string { - const webviewResource = resourceProvider.toWebviewResource( + const webviewResource = resourceProvider.asWebviewUri( vscode.Uri.file(this.context.asAbsolutePath(path.join('media', mediaFile)))); return webviewResource.toString(); } @@ -126,17 +126,17 @@ export class MarkdownContentProvider { // Assume it must be a local file if (path.isAbsolute(href)) { - return resourceProvider.toWebviewResource(vscode.Uri.file(href)).toString(); + return resourceProvider.asWebviewUri(vscode.Uri.file(href)).toString(); } // Use a workspace relative path if there is a workspace const root = vscode.workspace.getWorkspaceFolder(resource); if (root) { - return resourceProvider.toWebviewResource(vscode.Uri.file(path.join(root.uri.fsPath, href))).toString(); + return resourceProvider.asWebviewUri(vscode.Uri.file(path.join(root.uri.fsPath, href))).toString(); } // Otherwise look relative to the markdown file - return resourceProvider.toWebviewResource(vscode.Uri.file(path.join(path.dirname(resource.fsPath), href))).toString(); + return resourceProvider.asWebviewUri(vscode.Uri.file(path.join(path.dirname(resource.fsPath), href))).toString(); } private computeCustomStyleSheetIncludes(resourceProvider: WebviewResourceProvider, resource: vscode.Uri, config: MarkdownPreviewConfiguration): string { @@ -176,7 +176,7 @@ export class MarkdownContentProvider { private getStyles(resourceProvider: WebviewResourceProvider, resource: vscode.Uri, config: MarkdownPreviewConfiguration, state?: any): string { const baseStyles: string[] = []; for (const resource of this.contributionProvider.contributions.previewStyles) { - baseStyles.push(``); + baseStyles.push(``); } return `${baseStyles.join('\n')} @@ -188,7 +188,7 @@ export class MarkdownContentProvider { const out: string[] = []; for (const resource of this.contributionProvider.contributions.previewScripts) { out.push(``); } diff --git a/extensions/markdown-language-features/src/util/resources.ts b/extensions/markdown-language-features/src/util/resources.ts index 1def7adcce0..063c410b39e 100644 --- a/extensions/markdown-language-features/src/util/resources.ts +++ b/extensions/markdown-language-features/src/util/resources.ts @@ -6,7 +6,7 @@ import * as vscode from 'vscode'; export interface WebviewResourceProvider { - toWebviewResource(resource: vscode.Uri): vscode.Uri; + asWebviewUri(resource: vscode.Uri): vscode.Uri; readonly cspSource: string; } @@ -30,4 +30,4 @@ export function normalizeResource( } } return resource; -} \ No newline at end of file +} diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts index 4be0218ab64..e785f1d4afb 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts @@ -251,18 +251,18 @@ suite('Webview tests', () => { }); `); - async function toWebviewResource(path: string) { - const root = await webview.webview.toWebviewResource(vscode.Uri.file(vscode.workspace.rootPath!)); + async function asWebviewUri(path: string) { + const root = await webview.webview.asWebviewUri(vscode.Uri.file(vscode.workspace.rootPath!)); return root.toString() + path; } { - const imagePath = await toWebviewResource('/image.png'); + const imagePath = await asWebviewUri('/image.png'); const response = sendRecieveMessage(webview, { src: imagePath }); assert.strictEqual((await response).value, true); } { - const imagePath = await toWebviewResource('/no-such-image.png'); + const imagePath = await asWebviewUri('/no-such-image.png'); const response = sendRecieveMessage(webview, { src: imagePath }); assert.strictEqual((await response).value, false); } diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index bdef68b2eca..3611c2746ab 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -5923,6 +5923,30 @@ declare module 'vscode' { * @param message Body of the message. */ postMessage(message: any): Thenable; + + /** + * Convert a uri for the local file system to one that can be used inside webviews. + * + * Webviews cannot directly load resoruces from the workspace or local file system using `file:` uris. The + * `asWebviewUri` function takes a local `file:` uri and converts it into a uri that can be used inside of + * a webview to load the same resource: + * + * ```ts + * webview.html = `` + * ``` + */ + asWebviewUri(localResource: Uri): Uri; + + /** + * Content security policy source for webview resources. + * + * This is the origin that should be used in a content security policy rule: + * + * ``` + * img-src https: ${webview.cspSource} ...; + * ``` + */ + readonly cspSource: string; } /** diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 5284711d6e1..9dcf41062f4 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1141,35 +1141,4 @@ declare module 'vscode' { } //#endregion - - //#region Webview Resource Roots - - export interface Webview { - /** - * Convert a uri for the local file system to one that can be used inside webviews. - * - * Webviews cannot directly load resoruces from the workspace or local file system using `file:` uris. The - * `toWebviewResource` function takes a local `file:` uri and converts it into a uri that can be used inside of - * a webview to load the same resource: - * - * ```ts - * webview.html = `` - * ``` - */ - toWebviewResource(localResource: Uri): Uri; - - /** - * Content security policy source for webview resources. - * - * This is the origin that should be used in a content security policy rule: - * - * ``` - * img-src https: ${webview.cspSource} ...; - * ``` - */ - readonly cspSource: string; - } - - //#endregion - } diff --git a/src/vs/workbench/api/common/extHostCodeInsets.ts b/src/vs/workbench/api/common/extHostCodeInsets.ts index 066b25f2b02..769e4de2a7a 100644 --- a/src/vs/workbench/api/common/extHostCodeInsets.ts +++ b/src/vs/workbench/api/common/extHostCodeInsets.ts @@ -10,7 +10,7 @@ import { ExtHostTextEditor } from 'vs/workbench/api/common/extHostTextEditor'; import { ExtHostEditors } from 'vs/workbench/api/common/extHostTextEditors'; import * as vscode from 'vscode'; import { ExtHostEditorInsetsShape, MainThreadEditorInsetsShape } from './extHost.protocol'; -import { toWebviewResource, WebviewInitData } from 'vs/workbench/api/common/shared/webview'; +import { asWebviewUri, WebviewInitData } from 'vs/workbench/api/common/shared/webview'; import { generateUuid } from 'vs/base/common/uuid'; export class ExtHostEditorInsets implements ExtHostEditorInsetsShape { @@ -65,8 +65,8 @@ export class ExtHostEditorInsets implements ExtHostEditorInsetsShape { private _html: string = ''; private _options: vscode.WebviewOptions = Object.create(null); - toWebviewResource(resource: vscode.Uri): vscode.Uri { - return toWebviewResource(that._initData, this._uuid, resource); + asWebviewUri(resource: vscode.Uri): vscode.Uri { + return asWebviewUri(that._initData, this._uuid, resource); } get cspSource(): string { diff --git a/src/vs/workbench/api/common/extHostWebview.ts b/src/vs/workbench/api/common/extHostWebview.ts index aaa6a49734c..44b99bcbd4c 100644 --- a/src/vs/workbench/api/common/extHostWebview.ts +++ b/src/vs/workbench/api/common/extHostWebview.ts @@ -12,7 +12,7 @@ import { ExtHostWebviewsShape, IMainContext, MainContext, MainThreadWebviewsShap import { Disposable } from './extHostTypes'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import * as modes from 'vs/editor/common/modes'; -import { WebviewInitData, toWebviewResource } from 'vs/workbench/api/common/shared/webview'; +import { WebviewInitData, asWebviewUri } from 'vs/workbench/api/common/shared/webview'; import { generateUuid } from 'vs/base/common/uuid'; type IconPath = URI | { light: URI, dark: URI }; @@ -35,8 +35,8 @@ export class ExtHostWebview implements vscode.Webview { this._onMessageEmitter.dispose(); } - public toWebviewResource(resource: vscode.Uri): vscode.Uri { - return toWebviewResource(this._initData, this._handle, resource); + public asWebviewUri(resource: vscode.Uri): vscode.Uri { + return asWebviewUri(this._initData, this._handle, resource); } public get cspSource(): string { diff --git a/src/vs/workbench/api/common/shared/webview.ts b/src/vs/workbench/api/common/shared/webview.ts index 3969d74dbe1..9740cd21a6f 100644 --- a/src/vs/workbench/api/common/shared/webview.ts +++ b/src/vs/workbench/api/common/shared/webview.ts @@ -11,7 +11,7 @@ export interface WebviewInitData { readonly webviewCspSource: string; } -export function toWebviewResource( +export function asWebviewUri( initData: WebviewInitData, uuid: string, resource: vscode.Uri diff --git a/src/vs/workbench/test/electron-browser/api/extHostWebview.test.ts b/src/vs/workbench/test/electron-browser/api/extHostWebview.test.ts index 8a121279041..fb75ee14a20 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostWebview.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostWebview.test.ts @@ -48,7 +48,7 @@ suite('ExtHostWebview', () => { assert.strictEqual(lastInvokedDeserializer, serializerB); }); - test('toWebviewResource for desktop vscode-resource scheme', () => { + test('asWebviewUri for desktop vscode-resource scheme', () => { const shape = createNoopMainThreadWebviews(); const extHostWebviews = new ExtHostWebviews(SingleProxyRPCProtocol(shape), { webviewCspSource: '', @@ -57,37 +57,37 @@ suite('ExtHostWebview', () => { const webview = extHostWebviews.createWebviewPanel({} as any, 'type', 'title', 1, {}); assert.strictEqual( - webview.webview.toWebviewResource(URI.parse('file:///Users/codey/file.html')).toString(), + webview.webview.asWebviewUri(URI.parse('file:///Users/codey/file.html')).toString(), 'vscode-resource:/Users/codey/file.html', 'Unix basic' ); assert.strictEqual( - webview.webview.toWebviewResource(URI.parse('file:///Users/codey/file.html#frag')).toString(), + webview.webview.asWebviewUri(URI.parse('file:///Users/codey/file.html#frag')).toString(), 'vscode-resource:/Users/codey/file.html#frag', 'Unix should preserve fragment' ); assert.strictEqual( - webview.webview.toWebviewResource(URI.parse('file:///Users/codey/f%20ile.html')).toString(), + webview.webview.asWebviewUri(URI.parse('file:///Users/codey/f%20ile.html')).toString(), 'vscode-resource:/Users/codey/f%20ile.html', 'Unix with encoding' ); assert.strictEqual( - webview.webview.toWebviewResource(URI.parse('file://localhost/Users/codey/file.html')).toString(), + webview.webview.asWebviewUri(URI.parse('file://localhost/Users/codey/file.html')).toString(), 'vscode-resource://localhost/Users/codey/file.html', 'Unix should preserve authority' ); assert.strictEqual( - webview.webview.toWebviewResource(URI.parse('file:///c:/codey/file.txt')).toString(), + webview.webview.asWebviewUri(URI.parse('file:///c:/codey/file.txt')).toString(), 'vscode-resource:/c%3A/codey/file.txt', 'Windows C drive' ); }); - test('toWebviewResource for web endpoint', () => { + test('asWebviewUri for web endpoint', () => { const shape = createNoopMainThreadWebviews(); const extHostWebviews = new ExtHostWebviews(SingleProxyRPCProtocol(shape), { @@ -101,31 +101,31 @@ suite('ExtHostWebview', () => { } assert.strictEqual( - stripEndpointUuid(webview.webview.toWebviewResource(URI.parse('file:///Users/codey/file.html')).toString()), + stripEndpointUuid(webview.webview.asWebviewUri(URI.parse('file:///Users/codey/file.html')).toString()), 'webview.contoso.com/commit///Users/codey/file.html', 'Unix basic' ); assert.strictEqual( - stripEndpointUuid(webview.webview.toWebviewResource(URI.parse('file:///Users/codey/file.html#frag')).toString()), + stripEndpointUuid(webview.webview.asWebviewUri(URI.parse('file:///Users/codey/file.html#frag')).toString()), 'webview.contoso.com/commit///Users/codey/file.html#frag', 'Unix should preserve fragment' ); assert.strictEqual( - stripEndpointUuid(webview.webview.toWebviewResource(URI.parse('file:///Users/codey/f%20ile.html')).toString()), + stripEndpointUuid(webview.webview.asWebviewUri(URI.parse('file:///Users/codey/f%20ile.html')).toString()), 'webview.contoso.com/commit///Users/codey/f%20ile.html', 'Unix with encoding' ); assert.strictEqual( - stripEndpointUuid(webview.webview.toWebviewResource(URI.parse('file://localhost/Users/codey/file.html')).toString()), + stripEndpointUuid(webview.webview.asWebviewUri(URI.parse('file://localhost/Users/codey/file.html')).toString()), 'webview.contoso.com/commit//localhost/Users/codey/file.html', 'Unix should preserve authority' ); assert.strictEqual( - stripEndpointUuid(webview.webview.toWebviewResource(URI.parse('file:///c:/codey/file.txt')).toString()), + stripEndpointUuid(webview.webview.asWebviewUri(URI.parse('file:///c:/codey/file.txt')).toString()), 'webview.contoso.com/commit///c%3A/codey/file.txt', 'Windows C drive' ); From df0dd2edc279af12fdf6140bb4362231fa8dc8a3 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 19 Aug 2019 21:06:47 -0700 Subject: [PATCH 806/861] Move webview into browser Fixes #79424 This file depends on dom api so it should live in browser instead of common --- src/vs/workbench/api/browser/mainThreadCodeInsets.ts | 2 +- src/vs/workbench/api/browser/mainThreadWebview.ts | 2 +- .../workbench/contrib/extensions/browser/extensionEditor.ts | 2 +- .../contrib/webview/browser/dynamicWebviewEditorOverlay.ts | 2 +- .../workbench/contrib/webview/browser/webview.contribution.ts | 2 +- .../workbench/contrib/webview/{common => browser}/webview.ts | 0 src/vs/workbench/contrib/webview/browser/webviewEditor.ts | 2 +- .../workbench/contrib/webview/browser/webviewEditorInput.ts | 2 +- .../workbench/contrib/webview/browser/webviewEditorService.ts | 2 +- src/vs/workbench/contrib/webview/browser/webviewElement.ts | 2 +- src/vs/workbench/contrib/webview/browser/webviewService.ts | 2 +- .../contrib/webview/electron-browser/webview.contribution.ts | 4 ++-- .../contrib/webview/electron-browser/webviewCommands.ts | 4 ++-- .../contrib/webview/electron-browser/webviewElement.ts | 2 +- .../contrib/webview/electron-browser/webviewService.ts | 4 ++-- 15 files changed, 17 insertions(+), 17 deletions(-) rename src/vs/workbench/contrib/webview/{common => browser}/webview.ts (100%) diff --git a/src/vs/workbench/api/browser/mainThreadCodeInsets.ts b/src/vs/workbench/api/browser/mainThreadCodeInsets.ts index bb42627961d..053217cda52 100644 --- a/src/vs/workbench/api/browser/mainThreadCodeInsets.ts +++ b/src/vs/workbench/api/browser/mainThreadCodeInsets.ts @@ -8,7 +8,7 @@ import * as modes from 'vs/editor/common/modes'; import { MainContext, MainThreadEditorInsetsShape, IExtHostContext, ExtHostEditorInsetsShape, ExtHostContext } from 'vs/workbench/api/common/extHost.protocol'; import { extHostNamedCustomer } from '../common/extHostCustomers'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; -import { IWebviewService, WebviewElement } from 'vs/workbench/contrib/webview/common/webview'; +import { IWebviewService, WebviewElement } from 'vs/workbench/contrib/webview/browser/webview'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { IActiveCodeEditor, IViewZone } from 'vs/editor/browser/editorBrowser'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; diff --git a/src/vs/workbench/api/browser/mainThreadWebview.ts b/src/vs/workbench/api/browser/mainThreadWebview.ts index 90bdeb5ea74..d4beebbd5ff 100644 --- a/src/vs/workbench/api/browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/browser/mainThreadWebview.ts @@ -22,7 +22,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { extHostNamedCustomer } from '../common/extHostCustomers'; import { IProductService } from 'vs/platform/product/common/product'; import { startsWith } from 'vs/base/common/strings'; -import { Webview } from 'vs/workbench/contrib/webview/common/webview'; +import { Webview } from 'vs/workbench/contrib/webview/browser/webview'; interface OldMainThreadWebviewState { readonly viewType: string; diff --git a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index d4a6e6f60ac..dc9e6489cd7 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -50,7 +50,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { getDefaultValue } from 'vs/platform/configuration/common/configurationRegistry'; import { isUndefined } from 'vs/base/common/types'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; -import { IWebviewService, Webview } from 'vs/workbench/contrib/webview/common/webview'; +import { IWebviewService, Webview } from 'vs/workbench/contrib/webview/browser/webview'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { generateUuid } from 'vs/base/common/uuid'; import { platform } from 'vs/base/common/process'; diff --git a/src/vs/workbench/contrib/webview/browser/dynamicWebviewEditorOverlay.ts b/src/vs/workbench/contrib/webview/browser/dynamicWebviewEditorOverlay.ts index c86d25f7724..94d8bfa1f36 100644 --- a/src/vs/workbench/contrib/webview/browser/dynamicWebviewEditorOverlay.ts +++ b/src/vs/workbench/contrib/webview/browser/dynamicWebviewEditorOverlay.ts @@ -6,7 +6,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, DisposableStore, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; -import { IWebviewService, Webview, WebviewContentOptions, WebviewEditorOverlay, WebviewElement, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview'; +import { IWebviewService, Webview, WebviewContentOptions, WebviewEditorOverlay, WebviewElement, WebviewOptions } from 'vs/workbench/contrib/webview/browser/webview'; import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService'; import { memoize } from 'vs/base/common/decorators'; diff --git a/src/vs/workbench/contrib/webview/browser/webview.contribution.ts b/src/vs/workbench/contrib/webview/browser/webview.contribution.ts index 40dac14b615..56017d4348f 100644 --- a/src/vs/workbench/contrib/webview/browser/webview.contribution.ts +++ b/src/vs/workbench/contrib/webview/browser/webview.contribution.ts @@ -15,7 +15,7 @@ import { EditorDescriptor, Extensions as EditorExtensions, IEditorRegistry } fro import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions'; import { Extensions as EditorInputExtensions, IEditorInputFactoryRegistry } from 'vs/workbench/common/editor'; import { WebviewEditorInputFactory } from 'vs/workbench/contrib/webview/browser/webviewEditorInputFactory'; -import { KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE, webviewDeveloperCategory } from 'vs/workbench/contrib/webview/common/webview'; +import { KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE, webviewDeveloperCategory } from 'vs/workbench/contrib/webview/browser/webview'; import { HideWebViewEditorFindCommand, ReloadWebviewAction, ShowWebViewEditorFindWidgetCommand } from '../browser/webviewCommands'; import { WebviewEditor } from '../browser/webviewEditor'; import { WebviewEditorInput } from '../browser/webviewEditorInput'; diff --git a/src/vs/workbench/contrib/webview/common/webview.ts b/src/vs/workbench/contrib/webview/browser/webview.ts similarity index 100% rename from src/vs/workbench/contrib/webview/common/webview.ts rename to src/vs/workbench/contrib/webview/browser/webview.ts diff --git a/src/vs/workbench/contrib/webview/browser/webviewEditor.ts b/src/vs/workbench/contrib/webview/browser/webviewEditor.ts index d01dc751d00..b8d7c6dd48e 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewEditor.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewEditor.ts @@ -15,7 +15,7 @@ import { IWindowService } from 'vs/platform/windows/common/windows'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorOptions } from 'vs/workbench/common/editor'; import { WebviewEditorInput } from 'vs/workbench/contrib/webview/browser/webviewEditorInput'; -import { KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE, Webview, WebviewEditorOverlay } from 'vs/workbench/contrib/webview/common/webview'; +import { KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE, Webview, WebviewEditorOverlay } from 'vs/workbench/contrib/webview/browser/webview'; import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; diff --git a/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts b/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts index 614097c5ba9..316c112a8bd 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts @@ -8,7 +8,7 @@ import { URI } from 'vs/base/common/uri'; import { IEditorModel } from 'vs/platform/editor/common/editor'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { EditorInput, EditorModel, GroupIdentifier, IEditorInput } from 'vs/workbench/common/editor'; -import { WebviewEditorOverlay } from 'vs/workbench/contrib/webview/common/webview'; +import { WebviewEditorOverlay } from 'vs/workbench/contrib/webview/browser/webview'; import { UnownedDisposable as Unowned } from 'vs/base/common/lifecycle'; class WebviewIconsManager { diff --git a/src/vs/workbench/contrib/webview/browser/webviewEditorService.ts b/src/vs/workbench/contrib/webview/browser/webviewEditorService.ts index c17d203aed3..6fdda6cfb1c 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewEditorService.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewEditorService.ts @@ -10,7 +10,7 @@ import { URI } from 'vs/base/common/uri'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { GroupIdentifier } from 'vs/workbench/common/editor'; -import { IWebviewService, WebviewOptions, WebviewContentOptions } from 'vs/workbench/contrib/webview/common/webview'; +import { IWebviewService, WebviewOptions, WebviewContentOptions } from 'vs/workbench/contrib/webview/browser/webview'; import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { ACTIVE_GROUP_TYPE, IEditorService, SIDE_GROUP_TYPE } from 'vs/workbench/services/editor/common/editorService'; import { RevivedWebviewEditorInput, WebviewEditorInput } from './webviewEditorInput'; diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index 6eb2d99a7b0..65b09a14dde 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -5,7 +5,7 @@ import { Emitter } from 'vs/base/common/event'; import { URI } from 'vs/base/common/uri'; -import { Webview, WebviewContentOptions, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview'; +import { Webview, WebviewContentOptions, WebviewOptions } from 'vs/workbench/contrib/webview/browser/webview'; import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; diff --git a/src/vs/workbench/contrib/webview/browser/webviewService.ts b/src/vs/workbench/contrib/webview/browser/webviewService.ts index 44ef4a15f1e..eed1445c492 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewService.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewService.ts @@ -5,7 +5,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IFrameWebview } from 'vs/workbench/contrib/webview/browser/webviewElement'; -import { IWebviewService, WebviewContentOptions, WebviewEditorOverlay, WebviewElement, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview'; +import { IWebviewService, WebviewContentOptions, WebviewEditorOverlay, WebviewElement, WebviewOptions } from 'vs/workbench/contrib/webview/browser/webview'; import { DynamicWebviewEditorOverlay } from './dynamicWebviewEditorOverlay'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; diff --git a/src/vs/workbench/contrib/webview/electron-browser/webview.contribution.ts b/src/vs/workbench/contrib/webview/electron-browser/webview.contribution.ts index 084163f0459..627d57bd3fd 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webview.contribution.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webview.contribution.ts @@ -13,7 +13,7 @@ import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegis import { Registry } from 'vs/platform/registry/common/platform'; import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions'; import { WebviewEditor } from 'vs/workbench/contrib/webview/browser/webviewEditor'; -import { IWebviewService, webviewDeveloperCategory } from 'vs/workbench/contrib/webview/common/webview'; +import { IWebviewService, webviewDeveloperCategory } from 'vs/workbench/contrib/webview/browser/webview'; import * as webviewCommands from 'vs/workbench/contrib/webview/electron-browser/webviewCommands'; import { ElectronWebviewService } from 'vs/workbench/contrib/webview/electron-browser/webviewService'; @@ -89,4 +89,4 @@ function registerWebViewCommands(editorId: string): void { } } -registerWebViewCommands(WebviewEditor.ID); \ No newline at end of file +registerWebViewCommands(WebviewEditor.ID); diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewCommands.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewCommands.ts index a1d8ecda01a..066dbbecf5e 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewCommands.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewCommands.ts @@ -9,7 +9,7 @@ import { Command, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { WebviewEditor } from 'vs/workbench/contrib/webview/browser/webviewEditor'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { ElectronWebviewBasedWebview } from 'vs/workbench/contrib/webview/electron-browser/webviewElement'; -import { WebviewEditorOverlay } from 'vs/workbench/contrib/webview/common/webview'; +import { WebviewEditorOverlay } from 'vs/workbench/contrib/webview/browser/webview'; export class OpenWebviewDeveloperToolsAction extends Action { static readonly ID = 'workbench.action.webview.openDeveloperTools'; @@ -101,4 +101,4 @@ function withActiveWebviewBasedWebview(accessor: ServicesAccessor, f: (webview: } }); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts index 4002461cae2..68ad466ee19 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts @@ -20,7 +20,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITheme, IThemeService } from 'vs/platform/theme/common/themeService'; import { WebviewPortMappingManager } from 'vs/workbench/contrib/webview/common/portMapping'; import { getWebviewThemeData } from 'vs/workbench/contrib/webview/common/themeing'; -import { Webview, WebviewContentOptions, WebviewOptions, WebviewResourceScheme } from 'vs/workbench/contrib/webview/common/webview'; +import { Webview, WebviewContentOptions, WebviewOptions, WebviewResourceScheme } from 'vs/workbench/contrib/webview/browser/webview'; import { registerFileProtocol } from 'vs/workbench/contrib/webview/electron-browser/webviewProtocols'; import { areWebviewInputOptionsEqual } from '../browser/webviewEditorService'; import { WebviewFindWidget } from '../browser/webviewFindWidget'; diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewService.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewService.ts index ae8eb72d06f..dedb445ab5c 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewService.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewService.ts @@ -7,7 +7,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { DynamicWebviewEditorOverlay } from 'vs/workbench/contrib/webview/browser/dynamicWebviewEditorOverlay'; import { IFrameWebview } from 'vs/workbench/contrib/webview/browser/webviewElement'; -import { IWebviewService, WebviewContentOptions, WebviewEditorOverlay, WebviewElement, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview'; +import { IWebviewService, WebviewContentOptions, WebviewEditorOverlay, WebviewElement, WebviewOptions } from 'vs/workbench/contrib/webview/browser/webview'; import { ElectronWebviewBasedWebview } from 'vs/workbench/contrib/webview/electron-browser/webviewElement'; export class ElectronWebviewService implements IWebviewService { @@ -38,4 +38,4 @@ export class ElectronWebviewService implements IWebviewService { ): WebviewEditorOverlay { return this._instantiationService.createInstance(DynamicWebviewEditorOverlay, id, options, contentOptions); } -} \ No newline at end of file +} From d5026ed3fbf84acec67bb8be933060bedd46a97e Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 20 Aug 2019 11:01:07 +0200 Subject: [PATCH 807/861] fix #79453 --- .../editor/browser/services/openerService.ts | 19 ++++---- src/vs/platform/opener/common/opener.ts | 10 +--- .../url/electron-browser/urlService.ts | 10 ++-- .../workbench/api/browser/mainThreadWindow.ts | 2 +- .../files/browser/editors/binaryFileEditor.ts | 2 +- src/vs/workbench/electron-browser/window.ts | 45 ++++++++++++++---- .../services/files/common/workspaceWatcher.ts | 4 +- .../integrity/node/integrityService.ts | 2 +- .../opener/electron-browser/openerService.ts | 46 ------------------- src/vs/workbench/workbench.common.main.ts | 3 ++ src/vs/workbench/workbench.desktop.main.ts | 1 - src/vs/workbench/workbench.web.main.ts | 3 -- 12 files changed, 63 insertions(+), 84 deletions(-) delete mode 100644 src/vs/workbench/services/opener/electron-browser/openerService.ts diff --git a/src/vs/editor/browser/services/openerService.ts b/src/vs/editor/browser/services/openerService.ts index c92e5a70c76..7632af1b45c 100644 --- a/src/vs/editor/browser/services/openerService.ts +++ b/src/vs/editor/browser/services/openerService.ts @@ -19,10 +19,11 @@ import { localize } from 'vs/nls'; import { IProductService } from 'vs/platform/product/common/product'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import Severity from 'vs/base/common/severity'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; export class OpenerService implements IOpenerService { - _serviceBrand: any; + _serviceBrand!: ServiceIdentifier; private readonly _opener = new LinkedList(); @@ -41,7 +42,7 @@ export class OpenerService implements IOpenerService { return { dispose: remove }; } - async open(resource: URI, options?: { openToSide?: boolean }): Promise { + async open(resource: URI, options?: { openToSide?: boolean, openExternal?: boolean }): Promise { // no scheme ?!? if (!resource.scheme) { return Promise.resolve(false); @@ -57,13 +58,13 @@ export class OpenerService implements IOpenerService { return this._doOpen(resource, options); } - private _doOpen(resource: URI, options?: { openToSide?: boolean }): Promise { + private _doOpen(resource: URI, options?: { openToSide?: boolean, openExternal?: boolean }): Promise { const { scheme, authority, path, query, fragment } = resource; - if (equalsIgnoreCase(scheme, Schemas.mailto)) { + if (equalsIgnoreCase(scheme, Schemas.mailto) || (options && options.openExternal)) { // open default mail application - return this.openExternal(resource); + return this._doOpenExternal(resource); } if (equalsIgnoreCase(scheme, Schemas.http) || equalsIgnoreCase(scheme, Schemas.https)) { @@ -78,7 +79,7 @@ export class OpenerService implements IOpenerService { const domainToOpen = `${scheme}://${authority}`; if (isDomainTrusted(domainToOpen, trustedDomains)) { - return this.openExternal(resource); + return this._doOpenExternal(resource); } else { return this._dialogService.show( Severity.Info, @@ -97,11 +98,11 @@ export class OpenerService implements IOpenerService { cancelId: 1 }).then((choice) => { if (choice === 0) { - return this.openExternal(resource); + return this._doOpenExternal(resource); } else if (choice === 2) { return this._commandService.executeCommand('workbench.action.configureTrustedDomains', domainToOpen).then((pickedDomains: string[]) => { if (pickedDomains.indexOf(domainToOpen) !== -1) { - return this.openExternal(resource); + return this._doOpenExternal(resource); } return Promise.resolve(false); }); @@ -152,7 +153,7 @@ export class OpenerService implements IOpenerService { } } - openExternal(resource: URI): Promise { + private _doOpenExternal(resource: URI): Promise { dom.windowOpenNoOpener(encodeURI(resource.toString(true))); return Promise.resolve(true); diff --git a/src/vs/platform/opener/common/opener.ts b/src/vs/platform/opener/common/opener.ts index c8336fc712c..17cea7f5b3a 100644 --- a/src/vs/platform/opener/common/opener.ts +++ b/src/vs/platform/opener/common/opener.ts @@ -11,6 +11,7 @@ export const IOpenerService = createDecorator('openerService'); export interface IOpener { open(resource: URI, options?: { openToSide?: boolean }): Promise; + open(resource: URI, options?: { openExternal?: boolean }): Promise; } export interface IOpenerService { @@ -29,18 +30,11 @@ export interface IOpenerService { * @return A promise that resolves when the opening is done. */ open(resource: URI, options?: { openToSide?: boolean }): Promise; - - /** - * Opens a URL externally. - * - * @param url A resource to open externally. - */ - openExternal(resource: URI): Promise; + open(resource: URI, options?: { openExternal?: boolean }): Promise; } export const NullOpenerService: IOpenerService = Object.freeze({ _serviceBrand: undefined, registerOpener() { return { dispose() { } }; }, open() { return Promise.resolve(false); }, - openExternal() { return Promise.resolve(false); } }); diff --git a/src/vs/platform/url/electron-browser/urlService.ts b/src/vs/platform/url/electron-browser/urlService.ts index 06b5d7c31f0..1b1c88721b7 100644 --- a/src/vs/platform/url/electron-browser/urlService.ts +++ b/src/vs/platform/url/electron-browser/urlService.ts @@ -27,12 +27,16 @@ export class RelayURLService extends URLService implements IURLHandler { openerService.registerOpener(this); } - async open(uri: URI): Promise { - if (uri.scheme !== product.urlProtocol) { + async open(resource: URI, options?: { openToSide?: boolean, openExternal?: boolean }): Promise { + if (options && options.openExternal) { return false; } - return await this.urlService.open(uri); + if (resource.scheme !== product.urlProtocol) { + return false; + } + + return await this.urlService.open(resource); } handleURL(uri: URI): Promise { diff --git a/src/vs/workbench/api/browser/mainThreadWindow.ts b/src/vs/workbench/api/browser/mainThreadWindow.ts index acbb5c6f306..df059758f65 100644 --- a/src/vs/workbench/api/browser/mainThreadWindow.ts +++ b/src/vs/workbench/api/browser/mainThreadWindow.ts @@ -59,7 +59,7 @@ export class MainThreadWindow implements MainThreadWindowShape { } } - return this.openerService.openExternal(uri); + return this.openerService.open(uri, { openExternal: true }); } private getOrCreateTunnel(remotePort: number): Promise | undefined { diff --git a/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts b/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts index d6ce1130e86..9c0808d9ad1 100644 --- a/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts +++ b/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts @@ -38,7 +38,7 @@ export class BinaryFileEditor extends BaseBinaryResourceEditor { BinaryFileEditor.ID, { openInternal: (input, options) => this.openInternal(input, options), - openExternal: resource => this.openerService.openExternal(resource) + openExternal: resource => this.openerService.open(resource, { openExternal: true }) }, telemetryService, themeService, diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index 57dd6170e9a..a2ee3629a46 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -54,6 +54,8 @@ import { IPreferencesService } from '../services/preferences/common/preferences' import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IMenubarService, IMenubarData, IMenubarMenu, IMenubarKeybinding, IMenubarMenuItemSubmenu, IMenubarMenuItemAction, MenubarMenuItem } from 'vs/platform/menubar/node/menubar'; import { withNullAsUndefined } from 'vs/base/common/types'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { Schemas } from 'vs/base/common/network'; const TextInputActions: IAction[] = [ new Action('undo', nls.localize('undo', "Undo"), undefined, true, () => Promise.resolve(document.execCommand('undo'))), @@ -101,7 +103,8 @@ export class ElectronWindow extends Disposable { @IAccessibilityService private readonly accessibilityService: IAccessibilityService, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, @ITextFileService private readonly textFileService: ITextFileService, - @IInstantiationService private readonly instantiationService: IInstantiationService + @IInstantiationService private readonly instantiationService: IInstantiationService, + @IOpenerService private readonly openerService: IOpenerService ) { super(); @@ -312,13 +315,8 @@ export class ElectronWindow extends Disposable { this._register(this.instantiationService.createInstance(NativeMenubarControl)); } - // Handle window.open() calls - const $this = this; - window.open = function (url: string, target: string, features: string, replace: boolean): Window | null { - $this.windowsService.openExternal(url); - - return null; - }; + // Handle open calls + this.setupOpenHandlers(); // Emit event when vscode is ready this.lifecycleService.when(LifecyclePhase.Ready).then(() => ipc.send('vscode:workbenchReady', this.windowService.windowId)); @@ -356,6 +354,35 @@ export class ElectronWindow extends Disposable { } } + private setupOpenHandlers(): void { + + // Handle window.open() calls + const $this = this; + window.open = function (url: string, target: string, features: string, replace: boolean): Window | null { + $this.windowsService.openExternal(url); + + return null; + }; + + // Handle external open calls + this.openerService.registerOpener({ + async open(resource: URI, options?: { openToSide?: boolean; openExternal?: boolean; } | undefined): Promise { + if (!options || !options.openExternal) { + return false; // only override behaviour for external open() + } + + const success = await $this.windowsService.openExternal(encodeURI(resource.toString(true))); + if (!success && resource.scheme === Schemas.file) { + await $this.windowsService.showItemInFolder(resource); + + return true; + } + + return success; + } + }); + } + private updateTouchbarMenu(): void { if (!isMacintosh) { return; // macOS only @@ -741,4 +768,4 @@ class NativeMenubarControl extends MenubarControl { return undefined; } -} \ No newline at end of file +} diff --git a/src/vs/workbench/services/files/common/workspaceWatcher.ts b/src/vs/workbench/services/files/common/workspaceWatcher.ts index 1f9049858d3..da8c120643a 100644 --- a/src/vs/workbench/services/files/common/workspaceWatcher.ts +++ b/src/vs/workbench/services/files/common/workspaceWatcher.ts @@ -79,7 +79,7 @@ export class WorkspaceWatcher extends Disposable { localize('netVersionError', "The Microsoft .NET Framework 4.5 is required. Please follow the link to install it."), [{ label: localize('installNet', "Download .NET Framework 4.5"), - run: () => this.openerService.openExternal(URI.parse('https://go.microsoft.com/fwlink/?LinkId=786533')) + run: () => this.openerService.open(URI.parse('https://go.microsoft.com/fwlink/?LinkId=786533')) }], { sticky: true, @@ -95,7 +95,7 @@ export class WorkspaceWatcher extends Disposable { localize('enospcError', "Unable to watch for file changes in this large workspace. Please follow the instructions link to resolve this issue."), [{ label: localize('learnMore', "Instructions"), - run: () => this.openerService.openExternal(URI.parse('https://go.microsoft.com/fwlink/?linkid=867693')) + run: () => this.openerService.open(URI.parse('https://go.microsoft.com/fwlink/?linkid=867693')) }], { sticky: true, diff --git a/src/vs/workbench/services/integrity/node/integrityService.ts b/src/vs/workbench/services/integrity/node/integrityService.ts index 81f5317fe99..36c80d8c148 100644 --- a/src/vs/workbench/services/integrity/node/integrityService.ts +++ b/src/vs/workbench/services/integrity/node/integrityService.ts @@ -93,7 +93,7 @@ export class IntegrityServiceImpl implements IIntegrityService { [ { label: nls.localize('integrity.moreInformation', "More Information"), - run: () => this.openerService.openExternal(URI.parse(product.checksumFailMoreInfoUrl)) + run: () => this.openerService.open(URI.parse(product.checksumFailMoreInfoUrl)) }, { label: nls.localize('integrity.dontShowAgain', "Don't Show Again"), diff --git a/src/vs/workbench/services/opener/electron-browser/openerService.ts b/src/vs/workbench/services/opener/electron-browser/openerService.ts deleted file mode 100644 index d6cc8bb5bec..00000000000 --- a/src/vs/workbench/services/opener/electron-browser/openerService.ts +++ /dev/null @@ -1,46 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; -import { OpenerService as BaseOpenerService } from 'vs/editor/browser/services/openerService'; -import { IWindowsService } from 'vs/platform/windows/common/windows'; -import { ICommandService } from 'vs/platform/commands/common/commands'; -import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; -import { Schemas } from 'vs/base/common/network'; -import { URI } from 'vs/base/common/uri'; -import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; -import { IProductService } from 'vs/platform/product/common/product'; -import { IStorageService } from 'vs/platform/storage/common/storage'; - -export class OpenerService extends BaseOpenerService { - - _serviceBrand!: ServiceIdentifier; - - constructor( - @ICodeEditorService codeEditorService: ICodeEditorService, - @ICommandService commandService: ICommandService, - @IWindowsService private readonly windowsService: IWindowsService, - @IStorageService readonly storageService: IStorageService, - @IDialogService readonly dialogService: IDialogService, - @IProductService readonly productService: IProductService - ) { - super(codeEditorService, commandService, storageService, dialogService, productService); - } - - async openExternal(resource: URI): Promise { - const success = this.windowsService.openExternal(encodeURI(resource.toString(true))); - if (!success && resource.scheme === Schemas.file) { - await this.windowsService.showItemInFolder(resource); - - return true; - } - - return success; - } -} - -registerSingleton(IOpenerService, OpenerService, true); diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index e58f7058329..198e68e65bb 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -96,6 +96,8 @@ import { IMenuService } from 'vs/platform/actions/common/actions'; import { MenuService } from 'vs/platform/actions/common/menuService'; import { IDownloadService } from 'vs/platform/download/common/download'; import { DownloadService } from 'vs/platform/download/common/downloadService'; +import { OpenerService } from 'vs/editor/browser/services/openerService'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; registerSingleton(IExtensionGalleryService, ExtensionGalleryService, true); registerSingleton(IContextViewService, ContextViewService, true); @@ -108,6 +110,7 @@ registerSingleton(IModelService, ModelServiceImpl, true); registerSingleton(ITextResourceConfigurationService, TextResourceConfigurationService); registerSingleton(IMenuService, MenuService, true); registerSingleton(IDownloadService, DownloadService, true); +registerSingleton(IOpenerService, OpenerService, true); //#endregion diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index 7aa1334e1f4..b44e341f9c1 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -48,7 +48,6 @@ import 'vs/workbench/services/extensionManagement/node/extensionManagementServic import 'vs/workbench/services/accessibility/node/accessibilityService'; import 'vs/workbench/services/remote/node/tunnelService'; import 'vs/workbench/services/backup/node/backupFileService'; -import 'vs/workbench/services/opener/electron-browser/openerService'; import 'vs/workbench/services/credentials/node/credentialsService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 40384b249b0..20db7d07378 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -56,8 +56,6 @@ import { ContextMenuService } from 'vs/platform/contextview/browser/contextMenuS import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; import { BackupFileService } from 'vs/workbench/services/backup/common/backupFileService'; import { ExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagementService'; -import { OpenerService } from 'vs/editor/browser/services/openerService'; -import { IOpenerService } from 'vs/platform/opener/common/opener'; registerSingleton(IRequestService, RequestService, true); registerSingleton(IExtensionManagementService, ExtensionManagementService); @@ -67,7 +65,6 @@ registerSingleton(IClipboardService, BrowserClipboardService, true); registerSingleton(IAccessibilityService, BrowserAccessibilityService, true); registerSingleton(ILifecycleService, BrowserLifecycleService); registerSingleton(IContextMenuService, ContextMenuService); -registerSingleton(IOpenerService, OpenerService, true); //#endregion From 711faedf570d735f32b580a1ad3adf5ff37318d9 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 20 Aug 2019 11:17:59 +0200 Subject: [PATCH 808/861] allow https: as 'script-src' --- src/vs/code/browser/workbench/workbench.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index 9b8e42d3a3b..45a9d6d13fe 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -10,7 +10,7 @@ + content="default-src 'none'; img-src 'self' https: data: blob: vscode-remote:; media-src 'none'; frame-src 'self' {{WEBVIEW_ENDPOINT}} https://*.vscode-webview-test.com; script-src 'self' https://az416426.vo.msecnd.net 'unsafe-eval' https:; style-src 'self' 'unsafe-inline'; connect-src 'self' ws: wss: https:; font-src 'self' blob: vscode-remote:;"> From 0f338d93b5b384bb575d195c1b3119eadaf8e170 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Wed, 14 Aug 2019 12:02:07 +0200 Subject: [PATCH 809/861] node-debug@1.38.3 --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index 27467db5743..664ef4bba18 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -1,7 +1,7 @@ [ { "name": "ms-vscode.node-debug", - "version": "1.38.2", + "version": "1.38.3", "repo": "https://github.com/Microsoft/vscode-node-debug", "metadata": { "id": "b6ded8fb-a0a0-4c1c-acbd-ab2a3bc995a6", From 6aa2a756b04ffbffd3632c0896cb37fbf9875d49 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Tue, 20 Aug 2019 11:21:41 +0200 Subject: [PATCH 810/861] use latest DAP --- .../contrib/debug/common/debugProtocol.d.ts | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/contrib/debug/common/debugProtocol.d.ts b/src/vs/workbench/contrib/debug/common/debugProtocol.d.ts index 39fbff2964f..8854146a484 100644 --- a/src/vs/workbench/contrib/debug/common/debugProtocol.d.ts +++ b/src/vs/workbench/contrib/debug/common/debugProtocol.d.ts @@ -168,7 +168,7 @@ declare module DebugProtocol { category?: string; /** The output to report. */ output: string; - /** If an attribute 'variablesReference' exists and its value is > 0, the output contains objects which can be retrieved by passing 'variablesReference' to the 'variables' request. */ + /** If an attribute 'variablesReference' exists and its value is > 0, the output contains objects which can be retrieved by passing 'variablesReference' to the 'variables' request. The value should be less than or equal to 2147483647 (2^31 - 1). */ variablesReference?: number; /** An optional source location where the output was produced. */ source?: Source; @@ -284,9 +284,9 @@ declare module DebugProtocol { /** Response to 'runInTerminal' request. */ export interface RunInTerminalResponse extends Response { body: { - /** The process ID. */ + /** The process ID. The value should be less than or equal to 2147483647 (2^31 - 1). */ processId?: number; - /** The process ID of the terminal shell. */ + /** The process ID of the terminal shell. The value should be less than or equal to 2147483647 (2^31 - 1). */ shellProcessId?: number; }; } @@ -757,7 +757,7 @@ declare module DebugProtocol { } /** Pause request; value of command field is 'pause'. - The request suspenses the debuggee. + The request suspends the debuggee. The debug adapter first sends the response and then a 'stopped' event (with reason 'pause') after the thread has been paused successfully. */ export interface PauseRequest extends Request { @@ -842,7 +842,7 @@ declare module DebugProtocol { export interface VariablesArguments { /** The Variable reference. */ variablesReference: number; - /** Optional filter to limit the child variables to either named or indexed. If ommited, both types are fetched. */ + /** Optional filter to limit the child variables to either named or indexed. If omitted, both types are fetched. */ filter?: 'indexed' | 'named'; /** The index of the first variable to return; if omitted children start at 0. */ start?: number; @@ -887,14 +887,14 @@ declare module DebugProtocol { value: string; /** The type of the new value. Typically shown in the UI when hovering over the value. */ type?: string; - /** If variablesReference is > 0, the new value is structured and its children can be retrieved by passing variablesReference to the VariablesRequest. */ + /** If variablesReference is > 0, the new value is structured and its children can be retrieved by passing variablesReference to the VariablesRequest. The value should be less than or equal to 2147483647 (2^31 - 1). */ variablesReference?: number; /** The number of named child variables. - The client can use this optional information to present the variables in a paged UI and fetch them in chunks. + The client can use this optional information to present the variables in a paged UI and fetch them in chunks. The value should be less than or equal to 2147483647 (2^31 - 1). */ namedVariables?: number; /** The number of indexed child variables. - The client can use this optional information to present the variables in a paged UI and fetch them in chunks. + The client can use this optional information to present the variables in a paged UI and fetch them in chunks. The value should be less than or equal to 2147483647 (2^31 - 1). */ indexedVariables?: number; }; @@ -1041,14 +1041,14 @@ declare module DebugProtocol { type?: string; /** Properties of a evaluate result that can be used to determine how to render the result in the UI. */ presentationHint?: VariablePresentationHint; - /** If variablesReference is > 0, the evaluate result is structured and its children can be retrieved by passing variablesReference to the VariablesRequest. */ + /** If variablesReference is > 0, the evaluate result is structured and its children can be retrieved by passing variablesReference to the VariablesRequest. The value should be less than or equal to 2147483647 (2^31 - 1). */ variablesReference: number; /** The number of named child variables. - The client can use this optional information to present the variables in a paged UI and fetch them in chunks. + The client can use this optional information to present the variables in a paged UI and fetch them in chunks. The value should be less than or equal to 2147483647 (2^31 - 1). */ namedVariables?: number; /** The number of indexed child variables. - The client can use this optional information to present the variables in a paged UI and fetch them in chunks. + The client can use this optional information to present the variables in a paged UI and fetch them in chunks. The value should be less than or equal to 2147483647 (2^31 - 1). */ indexedVariables?: number; /** Memory reference to a location appropriate for this result. For pointer type eval results, this is generally a reference to the memory address contained in the pointer. */ @@ -1086,14 +1086,14 @@ declare module DebugProtocol { type?: string; /** Properties of a value that can be used to determine how to render the result in the UI. */ presentationHint?: VariablePresentationHint; - /** If variablesReference is > 0, the value is structured and its children can be retrieved by passing variablesReference to the VariablesRequest. */ + /** If variablesReference is > 0, the value is structured and its children can be retrieved by passing variablesReference to the VariablesRequest. The value should be less than or equal to 2147483647 (2^31 - 1). */ variablesReference?: number; /** The number of named child variables. - The client can use this optional information to present the variables in a paged UI and fetch them in chunks. + The client can use this optional information to present the variables in a paged UI and fetch them in chunks. The value should be less than or equal to 2147483647 (2^31 - 1). */ namedVariables?: number; /** The number of indexed child variables. - The client can use this optional information to present the variables in a paged UI and fetch them in chunks. + The client can use this optional information to present the variables in a paged UI and fetch them in chunks. The value should be less than or equal to 2147483647 (2^31 - 1). */ indexedVariables?: number; }; @@ -1294,6 +1294,8 @@ declare module DebugProtocol { supportsStepInTargetsRequest?: boolean; /** The debug adapter supports the 'completions' request. */ supportsCompletionsRequest?: boolean; + /** The set of characters that should trigger completion in a REPL. If not specified, the UI should assume the '.' character. */ + completionTriggerCharacters?: string[]; /** The debug adapter supports the 'modules' request. */ supportsModulesRequest?: boolean; /** The set of additional module information exposed by the debug adapter. */ @@ -1433,7 +1435,7 @@ declare module DebugProtocol { name?: string; /** The path of the source to be shown in the UI. It is only used to locate and load the content of the source if no sourceReference is specified (or its value is 0). */ path?: string; - /** If sourceReference > 0 the contents of the source must be retrieved through the SourceRequest (even if a path is specified). A sourceReference is only valid for a session, so it must not be used to persist a source. */ + /** If sourceReference > 0 the contents of the source must be retrieved through the SourceRequest (even if a path is specified). A sourceReference is only valid for a session, so it must not be used to persist a source. The value should be less than or equal to 2147483647 (2^31 - 1). */ sourceReference?: number; /** An optional hint for how to present the source in the UI. A value of 'deemphasize' can be used to indicate that the source is not available or that it is skipped on stepping. */ presentationHint?: 'normal' | 'emphasize' | 'deemphasize'; @@ -1668,6 +1670,8 @@ declare module DebugProtocol { label: string; /** If text is not falsy then it is inserted instead of the label. */ text?: string; + /** A string that should be used when comparing this item with other items. When `falsy` the label is used. */ + sortText?: string; /** The item's type. Typically the client uses this information to render the item in the UI with an icon. */ type?: CompletionItemType; /** This value determines the location (in the CompletionsRequest's 'text' attribute) where the completion text is added. @@ -1729,7 +1733,7 @@ declare module DebugProtocol { /** This enumeration defines all possible conditions when a thrown exception should result in a break. never: never breaks, always: always breaks, - unhandled: breaks when excpetion unhandled, + unhandled: breaks when exception unhandled, userUnhandled: breaks if the exception is not handled by user code. */ export type ExceptionBreakMode = 'never' | 'always' | 'unhandled' | 'userUnhandled'; @@ -1766,7 +1770,7 @@ declare module DebugProtocol { instructionBytes?: string; /** Text representing the instruction and its operands, in an implementation-defined format. */ instruction: string; - /** Name of the symbol that correponds with the location of this instruction, if any. */ + /** Name of the symbol that corresponds with the location of this instruction, if any. */ symbol?: string; /** Source location that corresponds to this instruction, if any. Should always be set (if available) on the first instruction returned, but can be omitted afterwards if this instruction maps to the same source file as the previous instruction. */ location?: Source; From b0d58e4fe6327250ef912a2ff8ea7e07251a54c5 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 20 Aug 2019 11:28:55 +0200 Subject: [PATCH 811/861] debt - prefer opener service over window.open(). Block window.open() --- .../contrib/debug/browser/debugSession.ts | 6 ++- .../contrib/debug/browser/rawDebugSession.ts | 6 ++- .../debug/test/browser/debugModel.test.ts | 5 +- .../experiments/browser/experimentalPrompt.ts | 7 ++- .../extensions/browser/extensionEditor.ts | 11 +++-- .../electron-browser/extensionsSlowActions.ts | 7 ++- .../runtimeExtensionsEditor.ts | 13 +++-- .../contrib/feedback/browser/feedback.ts | 8 +-- .../feedback/browser/feedbackStatusbarItem.ts | 6 ++- .../electron-browser/startupProfiler.ts | 4 +- .../contrib/search/browser/searchView.ts | 4 +- .../languageSurveys.contribution.ts | 12 +++-- .../electron-browser/nps.contribution.ts | 9 ++-- .../tasks/browser/abstractTaskService.ts | 2 +- .../electron-browser/gettingStarted.ts | 7 ++- .../electron-browser/actions/helpActions.ts | 49 ++++++++++++------- src/vs/workbench/electron-browser/window.ts | 28 ++++++----- 17 files changed, 117 insertions(+), 67 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugSession.ts b/src/vs/workbench/contrib/debug/browser/debugSession.ts index b0f361a4872..24b9b18c788 100644 --- a/src/vs/workbench/contrib/debug/browser/debugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/debugSession.ts @@ -31,6 +31,7 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { ReplModel } from 'vs/workbench/contrib/debug/common/replModel'; import { onUnexpectedError } from 'vs/base/common/errors'; import { INotificationService } from 'vs/platform/notification/common/notification'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; export class DebugSession implements IDebugSession { @@ -66,7 +67,8 @@ export class DebugSession implements IDebugSession { @IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService, @INotificationService private readonly notificationService: INotificationService, @IProductService private readonly productService: IProductService, - @IWindowsService private readonly windowsService: IWindowsService + @IWindowsService private readonly windowsService: IWindowsService, + @IOpenerService private readonly openerService: IOpenerService ) { this.id = generateUuid(); this.repl = new ReplModel(this); @@ -167,7 +169,7 @@ export class DebugSession implements IDebugSession { return dbgr.createDebugAdapter(this).then(debugAdapter => { - this.raw = new RawDebugSession(debugAdapter, dbgr, this.telemetryService, customTelemetryService, this.windowsService); + this.raw = new RawDebugSession(debugAdapter, dbgr, this.telemetryService, customTelemetryService, this.windowsService, this.openerService); return this.raw.start().then(() => { diff --git a/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts b/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts index fe5e98b83dd..d8ad2212ace 100644 --- a/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts @@ -17,6 +17,7 @@ import { IWindowsService } from 'vs/platform/windows/common/windows'; import { URI } from 'vs/base/common/uri'; import { IProcessEnvironment } from 'vs/base/common/platform'; import { env as processEnv } from 'vs/base/common/process'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; /** * This interface represents a single command line argument split into a "prefix" and a "path" half. @@ -74,7 +75,8 @@ export class RawDebugSession { dbgr: IDebugger, private readonly telemetryService: ITelemetryService, public readonly customTelemetryService: ITelemetryService | undefined, - private readonly windowsService: IWindowsService + private readonly windowsService: IWindowsService, + private readonly openerService: IOpenerService ) { this.debugAdapter = debugAdapter; @@ -652,7 +654,7 @@ export class RawDebugSession { const label = error.urlLabel ? error.urlLabel : nls.localize('moreInfo', "More Info"); return createErrorWithActions(userMessage, { actions: [new Action('debug.moreInfo', label, undefined, true, () => { - window.open(error.url); + this.openerService.open(URI.parse(error.url)); return Promise.resolve(null); })] }); diff --git a/src/vs/workbench/contrib/debug/test/browser/debugModel.test.ts b/src/vs/workbench/contrib/debug/test/browser/debugModel.test.ts index d6ebbfd721b..d967dce1868 100644 --- a/src/vs/workbench/contrib/debug/test/browser/debugModel.test.ts +++ b/src/vs/workbench/contrib/debug/test/browser/debugModel.test.ts @@ -13,9 +13,10 @@ import { Source } from 'vs/workbench/contrib/debug/common/debugSource'; import { DebugSession } from 'vs/workbench/contrib/debug/browser/debugSession'; import { ReplModel } from 'vs/workbench/contrib/debug/common/replModel'; import { IBreakpointUpdateData } from 'vs/workbench/contrib/debug/common/debug'; +import { NullOpenerService } from 'vs/platform/opener/common/opener'; function createMockSession(model: DebugModel, name = 'mockSession', parentSession?: DebugSession | undefined): DebugSession { - return new DebugSession({ resolved: { name, type: 'node', request: 'launch' }, unresolved: undefined }, undefined!, model, parentSession, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!); + return new DebugSession({ resolved: { name, type: 'node', request: 'launch' }, unresolved: undefined }, undefined!, model, parentSession, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!, NullOpenerService); } suite('Debug - Model', () => { @@ -427,7 +428,7 @@ suite('Debug - Model', () => { // Repl output test('repl output', () => { - const session = new DebugSession({ resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, undefined!, model, undefined, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!); + const session = new DebugSession({ resolved: { name: 'mockSession', type: 'node', request: 'launch' }, unresolved: undefined }, undefined!, model, undefined, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!, NullOpenerService); const repl = new ReplModel(session); repl.appendToRepl('first line\n', severity.Error); repl.appendToRepl('second line ', severity.Error); diff --git a/src/vs/workbench/contrib/experiments/browser/experimentalPrompt.ts b/src/vs/workbench/contrib/experiments/browser/experimentalPrompt.ts index 97f55700a40..b8ded4b910a 100644 --- a/src/vs/workbench/contrib/experiments/browser/experimentalPrompt.ts +++ b/src/vs/workbench/contrib/experiments/browser/experimentalPrompt.ts @@ -11,6 +11,8 @@ import { IExtensionsViewlet } from 'vs/workbench/contrib/extensions/common/exten import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { Disposable } from 'vs/base/common/lifecycle'; import { language } from 'vs/base/common/platform'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { URI } from 'vs/base/common/uri'; export class ExperimentalPrompts extends Disposable implements IWorkbenchContribution { @@ -18,7 +20,8 @@ export class ExperimentalPrompts extends Disposable implements IWorkbenchContrib @IExperimentService private readonly experimentService: IExperimentService, @IViewletService private readonly viewletService: IViewletService, @INotificationService private readonly notificationService: INotificationService, - @ITelemetryService private readonly telemetryService: ITelemetryService + @ITelemetryService private readonly telemetryService: ITelemetryService, + @IOpenerService private readonly openerService: IOpenerService ) { super(); @@ -65,7 +68,7 @@ export class ExperimentalPrompts extends Disposable implements IWorkbenchContrib run: () => { logTelemetry(commandText); if (command.externalLink) { - window.open(command.externalLink); + this.openerService.open(URI.parse(command.externalLink)); } else if (command.curatedExtensionsKey && Array.isArray(command.curatedExtensionsList)) { this.viewletService.openViewlet('workbench.view.extensions', true) .then(viewlet => viewlet as IExtensionsViewlet) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index dc9e6489cd7..272fa9d0591 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -54,6 +54,7 @@ import { IWebviewService, Webview } from 'vs/workbench/contrib/webview/browser/w import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { generateUuid } from 'vs/base/common/uuid'; import { platform } from 'vs/base/common/process'; +import { URI } from 'vs/base/common/uri'; function removeEmbeddedSVGs(documentContent: string): string { const newDocument = new DOMParser().parseFromString(documentContent, 'text/html'); @@ -185,7 +186,7 @@ export class ExtensionEditor extends BaseEditor { @IStorageService storageService: IStorageService, @IExtensionService private readonly extensionService: IExtensionService, @IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService, - @IWebviewService private readonly webviewService: IWebviewService, + @IWebviewService private readonly webviewService: IWebviewService ) { super(ExtensionEditor.ID, telemetryService, themeService, storageService); this.extensionReadme = null; @@ -354,8 +355,8 @@ export class ExtensionEditor extends BaseEditor { toggleClass(template.publisher, 'clickable', !!extension.url); toggleClass(template.rating, 'clickable', !!extension.url); if (extension.url) { - this.transientDisposables.add(this.onClick(template.name, () => window.open(extension.url))); - this.transientDisposables.add(this.onClick(template.rating, () => window.open(`${extension.url}#review-details`))); + this.transientDisposables.add(this.onClick(template.name, () => this.openerService.open(URI.parse(extension.url!)))); + this.transientDisposables.add(this.onClick(template.rating, () => this.openerService.open(URI.parse(`${extension.url}#review-details`)))); this.transientDisposables.add(this.onClick(template.publisher, () => { this.viewletService.openViewlet(VIEWLET_ID, true) .then(viewlet => viewlet as IExtensionsViewlet) @@ -363,7 +364,7 @@ export class ExtensionEditor extends BaseEditor { })); if (extension.licenseUrl) { - this.transientDisposables.add(this.onClick(template.license, () => window.open(extension.licenseUrl))); + this.transientDisposables.add(this.onClick(template.license, () => this.openerService.open(URI.parse(extension.licenseUrl!)))); template.license.style.display = 'initial'; } else { template.license.style.display = 'none'; @@ -373,7 +374,7 @@ export class ExtensionEditor extends BaseEditor { } if (extension.repository) { - this.transientDisposables.add(this.onClick(template.repository, () => window.open(extension.repository))); + this.transientDisposables.add(this.onClick(template.repository, () => this.openerService.open(URI.parse(extension.repository!)))); template.repository.style.display = 'initial'; } else { diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsSlowActions.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionsSlowActions.ts index 11aacd06955..e7e9842b027 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionsSlowActions.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionsSlowActions.ts @@ -17,6 +17,7 @@ import { join } from 'vs/base/common/path'; import { onUnexpectedError } from 'vs/base/common/errors'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import Severity from 'vs/base/common/severity'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; abstract class RepoInfo { abstract get base(): string; @@ -117,6 +118,7 @@ class ReportExtensionSlowAction extends Action { readonly repoInfo: RepoInfo, readonly profile: IExtensionHostProfile, @IDialogService private readonly _dialogService: IDialogService, + @IOpenerService private readonly _openerService: IOpenerService ) { super('report.slow', localize('cmd.report', "Report Issue")); } @@ -140,7 +142,7 @@ class ReportExtensionSlowAction extends Action { - VSCode version: \`${pkg.version}\`\n\n${message}`); const url = `${this.repoInfo.base}/${this.repoInfo.owner}/${this.repoInfo.repo}/issues/new/?body=${body}&title=${title}`; - window.open(url); + this._openerService.open(URI.parse(url)); this._dialogService.show( Severity.Info, @@ -158,6 +160,7 @@ class ShowExtensionSlowAction extends Action { readonly repoInfo: RepoInfo, readonly profile: IExtensionHostProfile, @IDialogService private readonly _dialogService: IDialogService, + @IOpenerService private readonly _openerService: IOpenerService ) { super('show.slow', localize('cmd.show', "Show Issues")); } @@ -172,7 +175,7 @@ class ShowExtensionSlowAction extends Action { // show issues const url = `${this.repoInfo.base}/${this.repoInfo.owner}/${this.repoInfo.repo}/issues?utf8=✓&q=is%3Aissue+state%3Aopen+%22Extension+causes+high+cpu+load%22`; - window.open(url); + this._openerService.open(URI.parse(url)); this._dialogService.show( Severity.Info, diff --git a/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts b/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts index 1cc01b85802..b6ac536b089 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts @@ -44,6 +44,8 @@ import { ExtensionIdentifier, ExtensionType, IExtensionDescription } from 'vs/pl import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts'; import { SlowExtensionAction } from 'vs/workbench/contrib/extensions/electron-browser/extensionsSlowActions'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { URI } from 'vs/base/common/uri'; export const IExtensionHostProfileService = createDecorator('extensionHostProfileService'); export const CONTEXT_PROFILE_SESSION_STATE = new RawContextKey('profileSessionState', 'none'); @@ -120,7 +122,8 @@ export class RuntimeExtensionsEditor extends BaseEditor { @IExtensionHostProfileService private readonly _extensionHostProfileService: IExtensionHostProfileService, @IStorageService storageService: IStorageService, @ILabelService private readonly _labelService: ILabelService, - @IWorkbenchEnvironmentService private readonly _environmentService: IWorkbenchEnvironmentService + @IWorkbenchEnvironmentService private readonly _environmentService: IWorkbenchEnvironmentService, + @IOpenerService private readonly _openerService: IOpenerService ) { super(RuntimeExtensionsEditor.ID, telemetryService, themeService, storageService); @@ -312,7 +315,7 @@ export class RuntimeExtensionsEditor extends BaseEditor { data.actionbar.push(this._instantiationService.createInstance(SlowExtensionAction, element.description, element.unresponsiveProfile), { icon: true, label: true }); } if (isNonEmptyArray(element.status.runtimeErrors)) { - data.actionbar.push(new ReportExtensionIssueAction(element), { icon: true, label: true }); + data.actionbar.push(new ReportExtensionIssueAction(element, this._openerService), { icon: true, label: true }); } let title: string; @@ -416,7 +419,7 @@ export class RuntimeExtensionsEditor extends BaseEditor { const actions: IAction[] = []; - actions.push(new ReportExtensionIssueAction(e.element)); + actions.push(new ReportExtensionIssueAction(e.element, this._openerService)); actions.push(new Separator()); if (e.element.marketplaceInfo) { @@ -480,7 +483,7 @@ export class ReportExtensionIssueAction extends Action { marketplaceInfo: IExtension; status?: IExtensionsStatus; unresponsiveProfile?: IExtensionHostProfile - }) { + }, @IOpenerService private readonly openerService: IOpenerService) { super(ReportExtensionIssueAction._id, ReportExtensionIssueAction._label, 'extension-action report-issue'); this.enabled = extension.marketplaceInfo && extension.marketplaceInfo.type === ExtensionType.User @@ -490,7 +493,7 @@ export class ReportExtensionIssueAction extends Action { } async run(): Promise { - window.open(this._url); + this.openerService.open(URI.parse(this._url)); } private static _generateNewIssueUrl(extension: { diff --git a/src/vs/workbench/contrib/feedback/browser/feedback.ts b/src/vs/workbench/contrib/feedback/browser/feedback.ts index 618dc7edaa9..ef308647b8d 100644 --- a/src/vs/workbench/contrib/feedback/browser/feedback.ts +++ b/src/vs/workbench/contrib/feedback/browser/feedback.ts @@ -20,6 +20,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification } from 'vs/base/common/actions'; import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar'; import { IProductService } from 'vs/platform/product/common/product'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; export interface IFeedback { feedback: string; @@ -27,7 +28,7 @@ export interface IFeedback { } export interface IFeedbackDelegate { - submitFeedback(feedback: IFeedback): void; + submitFeedback(feedback: IFeedback, openerService: IOpenerService): void; getCharacterLimit(sentiment: number): number; } @@ -66,7 +67,8 @@ export class FeedbackDropdown extends Dropdown { @IIntegrityService private readonly integrityService: IIntegrityService, @IThemeService private readonly themeService: IThemeService, @IStatusbarService private readonly statusbarService: IStatusbarService, - @IProductService productService: IProductService + @IProductService productService: IProductService, + @IOpenerService private readonly openerService: IOpenerService ) { super(container, options); @@ -415,7 +417,7 @@ export class FeedbackDropdown extends Dropdown { this.feedbackDelegate.submitFeedback({ feedback: this.feedbackDescriptionInput.value, sentiment: this.sentiment - }); + }, this.openerService); this.hide(); } diff --git a/src/vs/workbench/contrib/feedback/browser/feedbackStatusbarItem.ts b/src/vs/workbench/contrib/feedback/browser/feedbackStatusbarItem.ts index c609aa4132f..9eda590df6f 100644 --- a/src/vs/workbench/contrib/feedback/browser/feedbackStatusbarItem.ts +++ b/src/vs/workbench/contrib/feedback/browser/feedbackStatusbarItem.ts @@ -12,6 +12,8 @@ import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { IStatusbarService, StatusbarAlignment, IStatusbarEntry, IStatusbarEntryAccessor } from 'vs/platform/statusbar/common/statusbar'; import { localize } from 'vs/nls'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { URI } from 'vs/base/common/uri'; class TwitterFeedbackService implements IFeedbackDelegate { @@ -23,11 +25,11 @@ class TwitterFeedbackService implements IFeedbackDelegate { return TwitterFeedbackService.HASHTAGS.join(','); } - submitFeedback(feedback: IFeedback): void { + submitFeedback(feedback: IFeedback, openerService: IOpenerService): void { const queryString = `?${feedback.sentiment === 1 ? `hashtags=${this.combineHashTagsAsString()}&` : null}ref_src=twsrc%5Etfw&related=twitterapi%2Ctwitter&text=${encodeURIComponent(feedback.feedback)}&tw_p=tweetbutton&via=${TwitterFeedbackService.VIA_NAME}`; const url = TwitterFeedbackService.TWITTER_URL + queryString; - window.open(url); + openerService.open(URI.parse(url)); } getCharacterLimit(sentiment: number): number { diff --git a/src/vs/workbench/contrib/performance/electron-browser/startupProfiler.ts b/src/vs/workbench/contrib/performance/electron-browser/startupProfiler.ts index ecfdd8e2ea0..9c8fe678aed 100644 --- a/src/vs/workbench/contrib/performance/electron-browser/startupProfiler.ts +++ b/src/vs/workbench/contrib/performance/electron-browser/startupProfiler.ts @@ -17,6 +17,7 @@ import { PerfviewInput } from 'vs/workbench/contrib/performance/electron-browser import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { URI } from 'vs/base/common/uri'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; export class StartupProfiler implements IWorkbenchContribution { @@ -28,6 +29,7 @@ export class StartupProfiler implements IWorkbenchContribution { @IClipboardService private readonly _clipboardService: IClipboardService, @ILifecycleService lifecycleService: ILifecycleService, @IExtensionService extensionService: IExtensionService, + @IOpenerService private readonly _openerService: IOpenerService ) { // wait for everything to be ready Promise.all([ @@ -116,6 +118,6 @@ export class StartupProfiler implements IWorkbenchContribution { const baseUrl = product.reportIssueUrl; const queryStringPrefix = baseUrl.indexOf('?') === -1 ? '?' : '&'; - window.open(`${baseUrl}${queryStringPrefix}body=${encodeURIComponent(body)}`); + this._openerService.open(URI.parse(`${baseUrl}${queryStringPrefix}body=${encodeURIComponent(body)}`)); } } diff --git a/src/vs/workbench/contrib/search/browser/searchView.ts b/src/vs/workbench/contrib/search/browser/searchView.ts index 4174d8137f6..33e16e9f22d 100644 --- a/src/vs/workbench/contrib/search/browser/searchView.ts +++ b/src/vs/workbench/contrib/search/browser/searchView.ts @@ -61,6 +61,7 @@ import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/v import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { Memento, MementoObject } from 'vs/workbench/common/memento'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; const $ = dom.$; @@ -153,6 +154,7 @@ export class SearchView extends ViewletPanel { @IAccessibilityService private readonly accessibilityService: IAccessibilityService, @IKeybindingService keybindingService: IKeybindingService, @IStorageService storageService: IStorageService, + @IOpenerService private readonly openerService: IOpenerService ) { super({ ...(options as IViewletPanelOptions), id: VIEW_ID, ariaHeaderLabel: nls.localize('searchView', "Search") }, keybindingService, contextMenuService, configurationService, contextKeyService); @@ -1473,7 +1475,7 @@ export class SearchView extends ViewletPanel { private onLearnMore = (e: MouseEvent): void => { dom.EventHelper.stop(e, false); - window.open('https://go.microsoft.com/fwlink/?linkid=853977'); + this.openerService.open(URI.parse('https://go.microsoft.com/fwlink/?linkid=853977')); } private updateSearchResultCount(disregardExcludesAndIgnores?: boolean): void { diff --git a/src/vs/workbench/contrib/surveys/electron-browser/languageSurveys.contribution.ts b/src/vs/workbench/contrib/surveys/electron-browser/languageSurveys.contribution.ts index ec9ac3fb2b7..44cf53887ff 100644 --- a/src/vs/workbench/contrib/surveys/electron-browser/languageSurveys.contribution.ts +++ b/src/vs/workbench/contrib/surveys/electron-browser/languageSurveys.contribution.ts @@ -16,6 +16,8 @@ import { ISurveyData } from 'vs/platform/product/common/product'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { Severity, INotificationService } from 'vs/platform/notification/common/notification'; import { ITextFileService, StateChange } from 'vs/workbench/services/textfile/common/textfiles'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { URI } from 'vs/base/common/uri'; class LanguageSurvey { @@ -25,7 +27,8 @@ class LanguageSurvey { notificationService: INotificationService, telemetryService: ITelemetryService, modelService: IModelService, - textFileService: ITextFileService + textFileService: ITextFileService, + openerService: IOpenerService ) { const SESSION_COUNT_KEY = `${data.surveyId}.sessionCount`; const LAST_SESSION_DATE_KEY = `${data.surveyId}.lastSessionDate`; @@ -94,7 +97,7 @@ class LanguageSurvey { run: () => { telemetryService.publicLog(`${data.surveyId}.survey/takeShortSurvey`); telemetryService.getTelemetryInfo().then(info => { - window.open(`${data.surveyUrl}?o=${encodeURIComponent(process.platform)}&v=${encodeURIComponent(pkg.version)}&m=${encodeURIComponent(info.machineId)}`); + openerService.open(URI.parse(`${data.surveyUrl}?o=${encodeURIComponent(process.platform)}&v=${encodeURIComponent(pkg.version)}&m=${encodeURIComponent(info.machineId)}`)); storageService.store(IS_CANDIDATE_KEY, false, StorageScope.GLOBAL); storageService.store(SKIP_VERSION_KEY, pkg.version, StorageScope.GLOBAL); }); @@ -126,11 +129,12 @@ class LanguageSurveysContribution implements IWorkbenchContribution { @INotificationService notificationService: INotificationService, @ITelemetryService telemetryService: ITelemetryService, @IModelService modelService: IModelService, - @ITextFileService textFileService: ITextFileService + @ITextFileService textFileService: ITextFileService, + @IOpenerService openerService: IOpenerService ) { product.surveys .filter(surveyData => surveyData.surveyId && surveyData.editCount && surveyData.languageId && surveyData.surveyUrl && surveyData.userProbability) - .map(surveyData => new LanguageSurvey(surveyData, storageService, notificationService, telemetryService, modelService, textFileService)); + .map(surveyData => new LanguageSurvey(surveyData, storageService, notificationService, telemetryService, modelService, textFileService, openerService)); } } diff --git a/src/vs/workbench/contrib/surveys/electron-browser/nps.contribution.ts b/src/vs/workbench/contrib/surveys/electron-browser/nps.contribution.ts index c11fd38db20..5e4433ce2ad 100644 --- a/src/vs/workbench/contrib/surveys/electron-browser/nps.contribution.ts +++ b/src/vs/workbench/contrib/surveys/electron-browser/nps.contribution.ts @@ -13,6 +13,8 @@ import pkg from 'vs/platform/product/node/package'; import product from 'vs/platform/product/node/product'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { Severity, INotificationService } from 'vs/platform/notification/common/notification'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { URI } from 'vs/base/common/uri'; const PROBABILITY = 0.15; const SESSION_COUNT_KEY = 'nps/sessionCount'; @@ -25,7 +27,8 @@ class NPSContribution implements IWorkbenchContribution { constructor( @IStorageService storageService: IStorageService, @INotificationService notificationService: INotificationService, - @ITelemetryService telemetryService: ITelemetryService + @ITelemetryService telemetryService: ITelemetryService, + @IOpenerService openerService: IOpenerService ) { const skipVersion = storageService.get(SKIP_VERSION_KEY, StorageScope.GLOBAL, ''); if (skipVersion) { @@ -64,7 +67,7 @@ class NPSContribution implements IWorkbenchContribution { label: nls.localize('takeSurvey', "Take Survey"), run: () => { telemetryService.getTelemetryInfo().then(info => { - window.open(`${product.npsSurveyUrl}?o=${encodeURIComponent(process.platform)}&v=${encodeURIComponent(pkg.version)}&m=${encodeURIComponent(info.machineId)}`); + openerService.open(URI.parse(`${product.npsSurveyUrl}?o=${encodeURIComponent(process.platform)}&v=${encodeURIComponent(pkg.version)}&m=${encodeURIComponent(info.machineId)}`)); storageService.store(IS_CANDIDATE_KEY, false, StorageScope.GLOBAL); storageService.store(SKIP_VERSION_KEY, pkg.version, StorageScope.GLOBAL); }); @@ -87,4 +90,4 @@ class NPSContribution implements IWorkbenchContribution { if (language === 'en' && product.npsSurveyUrl) { const workbenchRegistry = Registry.as(WorkbenchExtensions.Workbench); workbenchRegistry.registerWorkbenchContribution(NPSContribution, LifecyclePhase.Restored); -} \ No newline at end of file +} diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts index 17e62768740..461797d862c 100644 --- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts +++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts @@ -1620,7 +1620,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer nls.localize('TaskService.noWorkspace', "Tasks are only available on a workspace folder."), [{ label: nls.localize('TaskService.learnMore', "Learn More"), - run: () => window.open('https://code.visualstudio.com/docs/editor/tasks') + run: () => this.openerService.open(URI.parse('https://code.visualstudio.com/docs/editor/tasks')) }] ); return false; diff --git a/src/vs/workbench/contrib/welcome/gettingStarted/electron-browser/gettingStarted.ts b/src/vs/workbench/contrib/welcome/gettingStarted/electron-browser/gettingStarted.ts index 2c0d6778d39..200de4fa5c9 100644 --- a/src/vs/workbench/contrib/welcome/gettingStarted/electron-browser/gettingStarted.ts +++ b/src/vs/workbench/contrib/welcome/gettingStarted/electron-browser/gettingStarted.ts @@ -9,6 +9,8 @@ import { ITelemetryService, ITelemetryInfo } from 'vs/platform/telemetry/common/ import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import * as platform from 'vs/base/common/platform'; import product from 'vs/platform/product/node/product'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { URI } from 'vs/base/common/uri'; export class GettingStarted implements IWorkbenchContribution { @@ -20,7 +22,8 @@ export class GettingStarted implements IWorkbenchContribution { constructor( @IStorageService private readonly storageService: IStorageService, @IEnvironmentService environmentService: IEnvironmentService, - @ITelemetryService private readonly telemetryService: ITelemetryService + @ITelemetryService private readonly telemetryService: ITelemetryService, + @IOpenerService private readonly openerService: IOpenerService ) { this.appName = product.nameLong; @@ -50,7 +53,7 @@ export class GettingStarted implements IWorkbenchContribution { if (platform.isLinux && platform.isRootUser()) { return; } - window.open(url); + this.openerService.open(URI.parse(url)); } private handleWelcome(): void { diff --git a/src/vs/workbench/electron-browser/actions/helpActions.ts b/src/vs/workbench/electron-browser/actions/helpActions.ts index 3c5d242f92f..ce5e237ef08 100644 --- a/src/vs/workbench/electron-browser/actions/helpActions.ts +++ b/src/vs/workbench/electron-browser/actions/helpActions.ts @@ -8,6 +8,8 @@ import * as nls from 'vs/nls'; import product from 'vs/platform/product/node/product'; import { isMacintosh, isLinux, language } from 'vs/base/common/platform'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { URI } from 'vs/base/common/uri'; export class KeybindingsReferenceAction extends Action { @@ -19,13 +21,14 @@ export class KeybindingsReferenceAction extends Action { constructor( id: string, - label: string + label: string, + @IOpenerService private readonly openerService: IOpenerService ) { super(id, label); } run(): Promise { - window.open(KeybindingsReferenceAction.URL); + this.openerService.open(URI.parse(KeybindingsReferenceAction.URL)); return Promise.resolve(); } @@ -41,13 +44,14 @@ export class OpenDocumentationUrlAction extends Action { constructor( id: string, - label: string + label: string, + @IOpenerService private readonly openerService: IOpenerService ) { super(id, label); } run(): Promise { - window.open(OpenDocumentationUrlAction.URL); + this.openerService.open(URI.parse(OpenDocumentationUrlAction.URL)); return Promise.resolve(); } @@ -63,13 +67,14 @@ export class OpenIntroductoryVideosUrlAction extends Action { constructor( id: string, - label: string + label: string, + @IOpenerService private readonly openerService: IOpenerService ) { super(id, label); } run(): Promise { - window.open(OpenIntroductoryVideosUrlAction.URL); + this.openerService.open(URI.parse(OpenIntroductoryVideosUrlAction.URL)); return Promise.resolve(); } @@ -85,13 +90,14 @@ export class OpenTipsAndTricksUrlAction extends Action { constructor( id: string, - label: string + label: string, + @IOpenerService private readonly openerService: IOpenerService ) { super(id, label); } run(): Promise { - window.open(OpenTipsAndTricksUrlAction.URL); + this.openerService.open(URI.parse(OpenTipsAndTricksUrlAction.URL)); return Promise.resolve(); } } @@ -107,6 +113,7 @@ export class OpenNewsletterSignupUrlAction extends Action { constructor( id: string, label: string, + @IOpenerService private readonly openerService: IOpenerService, @ITelemetryService telemetryService: ITelemetryService ) { super(id, label); @@ -116,7 +123,7 @@ export class OpenNewsletterSignupUrlAction extends Action { async run(): Promise { const info = await this.telemetryService.getTelemetryInfo(); - window.open(`${OpenNewsletterSignupUrlAction.URL}?machineId=${encodeURIComponent(info.machineId)}`); + this.openerService.open(URI.parse(`${OpenNewsletterSignupUrlAction.URL}?machineId=${encodeURIComponent(info.machineId)}`)); } } @@ -127,14 +134,15 @@ export class OpenTwitterUrlAction extends Action { constructor( id: string, - label: string + label: string, + @IOpenerService private readonly openerService: IOpenerService ) { super(id, label); } run(): Promise { if (product.twitterUrl) { - window.open(product.twitterUrl); + this.openerService.open(URI.parse(product.twitterUrl)); } return Promise.resolve(); @@ -148,14 +156,15 @@ export class OpenRequestFeatureUrlAction extends Action { constructor( id: string, - label: string + label: string, + @IOpenerService private readonly openerService: IOpenerService ) { super(id, label); } run(): Promise { if (product.requestFeatureUrl) { - window.open(product.requestFeatureUrl); + this.openerService.open(URI.parse(product.requestFeatureUrl)); } return Promise.resolve(); @@ -169,7 +178,8 @@ export class OpenLicenseUrlAction extends Action { constructor( id: string, - label: string + label: string, + @IOpenerService private readonly openerService: IOpenerService ) { super(id, label); } @@ -178,9 +188,9 @@ export class OpenLicenseUrlAction extends Action { if (product.licenseUrl) { if (language) { const queryArgChar = product.licenseUrl.indexOf('?') > 0 ? '&' : '?'; - window.open(`${product.licenseUrl}${queryArgChar}lang=${language}`); + this.openerService.open(URI.parse(`${product.licenseUrl}${queryArgChar}lang=${language}`)); } else { - window.open(product.licenseUrl); + this.openerService.open(URI.parse(product.licenseUrl)); } } @@ -195,7 +205,8 @@ export class OpenPrivacyStatementUrlAction extends Action { constructor( id: string, - label: string + label: string, + @IOpenerService private readonly openerService: IOpenerService ) { super(id, label); } @@ -204,9 +215,9 @@ export class OpenPrivacyStatementUrlAction extends Action { if (product.privacyStatementUrl) { if (language) { const queryArgChar = product.privacyStatementUrl.indexOf('?') > 0 ? '&' : '?'; - window.open(`${product.privacyStatementUrl}${queryArgChar}lang=${language}`); + this.openerService.open(URI.parse(`${product.privacyStatementUrl}${queryArgChar}lang=${language}`)); } else { - window.open(product.privacyStatementUrl); + this.openerService.open(URI.parse(product.privacyStatementUrl)); } } diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index a2ee3629a46..a9c2344af12 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -356,29 +356,35 @@ export class ElectronWindow extends Disposable { private setupOpenHandlers(): void { - // Handle window.open() calls + // Block window.open() calls const $this = this; - window.open = function (url: string, target: string, features: string, replace: boolean): Window | null { - $this.windowsService.openExternal(url); + window.open = function (): Window | null { + console.error(new Error('Prevented call to window.open(). Use IOpenerService instead!')); return null; }; - // Handle external open calls + // Handle internal open() calls this.openerService.registerOpener({ async open(resource: URI, options?: { openToSide?: boolean; openExternal?: boolean; } | undefined): Promise { - if (!options || !options.openExternal) { - return false; // only override behaviour for external open() - } - const success = await $this.windowsService.openExternal(encodeURI(resource.toString(true))); - if (!success && resource.scheme === Schemas.file) { - await $this.windowsService.showItemInFolder(resource); + // If either the caller wants to open externally or the + // scheme is one where we prefer to open externally + // we handle this resource by delegating the opening to + // the main process to prevent window focus issues. + const scheme = resource.scheme.toLowerCase(); + const preferOpenExternal = (scheme === Schemas.mailto || scheme === Schemas.http || scheme === Schemas.https); + if ((options && options.openExternal) || preferOpenExternal) { + const success = await $this.windowsService.openExternal(encodeURI(resource.toString(true))); + if (!success && resource.scheme === Schemas.file) { + // if opening failed, and this is a file, we can still try to reveal it + await $this.windowsService.showItemInFolder(resource); + } return true; } - return success; + return false; // not handled by us } }); } From 97e60d9f1ccb40afcd7244387018dfb2ba3afd33 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Tue, 20 Aug 2019 12:19:02 +0200 Subject: [PATCH 812/861] History Main Service: bad reference to 'window'? Fixes #79426 --- src/vs/platform/history/common/historyStorage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/history/common/historyStorage.ts b/src/vs/platform/history/common/historyStorage.ts index 089d73ec313..b026460963d 100644 --- a/src/vs/platform/history/common/historyStorage.ts +++ b/src/vs/platform/history/common/historyStorage.ts @@ -71,7 +71,7 @@ export function restoreRecentlyOpened(data: RecentlyOpenedStorageData | undefine result.workspaces.push({ folderUri: URI.file(workspace) }); } else if (isLegacySerializedWorkspace(workspace)) { result.workspaces.push({ workspace: { id: workspace.id, configPath: URI.file(workspace.configPath) } }); - } else if (isUriComponents(window)) { + } else if (isUriComponents(workspace)) { // added by 1.26-insiders result.workspaces.push({ folderUri: URI.revive(workspace) }); } From 3a6099cab3b9b17a47c2a045ceb3914930f9a75a Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 20 Aug 2019 12:19:22 +0200 Subject: [PATCH 813/861] repl: support completionTriggerCharacters #79195 --- .../workbench/contrib/debug/browser/repl.ts | 55 +++++++++---------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/repl.ts b/src/vs/workbench/contrib/debug/browser/repl.ts index 938d2c6477c..2328778efd0 100644 --- a/src/vs/workbench/contrib/debug/browser/repl.ts +++ b/src/vs/workbench/contrib/debug/browser/repl.ts @@ -104,6 +104,7 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati private scopedInstantiationService!: IInstantiationService; private replElementsChangeListener: IDisposable | undefined; private styleElement: HTMLStyleElement | undefined; + private completionItemProvider: IDisposable | undefined; constructor( @IDebugService private readonly debugService: IDebugService, @@ -131,7 +132,33 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati this._register(this.debugService.getViewModel().onDidFocusSession(session => { if (session) { sessionsToIgnore.delete(session); + if (this.completionItemProvider) { + this.completionItemProvider.dispose(); + } + if (session.capabilities.supportsCompletionsRequest) { + this.completionItemProvider = CompletionProviderRegistry.register({ scheme: DEBUG_SCHEME, pattern: '**/replinput', hasAccessToAllModels: true }, { + triggerCharacters: session.capabilities.completionTriggerCharacters || ['.'], + provideCompletionItems: async (_: ITextModel, position: Position, _context: CompletionContext, token: CancellationToken): Promise => { + // Disable history navigation because up and down are used to navigate through the suggest widget + this.historyNavigationEnablement.set(false); + + const model = this.replInput.getModel(); + if (model) { + const word = model.getWordAtPosition(position); + const overwriteBefore = word ? word.word.length : 0; + const text = model.getLineContent(position.lineNumber); + const focusedStackFrame = this.debugService.getViewModel().focusedStackFrame; + const frameId = focusedStackFrame ? focusedStackFrame.frameId : undefined; + const suggestions = await session.completions(frameId, text, position, overwriteBefore); + return { suggestions }; + } + + return Promise.resolve({ suggestions: [] }); + } + }); + } } + this.selectSession(); })); this._register(this.debugService.onWillNewSession(newSession => { @@ -430,34 +457,6 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati options.readOnly = true; this.replInput = this.scopedInstantiationService.createInstance(CodeEditorWidget, this.replInputContainer, options, getSimpleCodeEditorWidgetOptions()); - CompletionProviderRegistry.register({ scheme: DEBUG_SCHEME, pattern: '**/replinput', hasAccessToAllModels: true }, { - triggerCharacters: ['.'], - provideCompletionItems: (model: ITextModel, position: Position, _context: CompletionContext, token: CancellationToken): Promise => { - // Disable history navigation because up and down are used to navigate through the suggest widget - this.historyNavigationEnablement.set(false); - - const focusedSession = this.debugService.getViewModel().focusedSession; - if (focusedSession && focusedSession.capabilities.supportsCompletionsRequest) { - - const model = this.replInput.getModel(); - if (model) { - const word = model.getWordAtPosition(position); - const overwriteBefore = word ? word.word.length : 0; - const text = model.getLineContent(position.lineNumber); - const focusedStackFrame = this.debugService.getViewModel().focusedStackFrame; - const frameId = focusedStackFrame ? focusedStackFrame.frameId : undefined; - - return focusedSession.completions(frameId, text, position, overwriteBefore).then(suggestions => { - return { suggestions }; - }, err => { - return { suggestions: [] }; - }); - } - } - return Promise.resolve({ suggestions: [] }); - } - }); - this._register(this.replInput.onDidScrollChange(e => { if (!e.scrollHeightChanged) { return; From 1271e25f4fceb332c6e4dd2d56f3f30f7bae9f99 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Tue, 20 Aug 2019 12:28:26 +0200 Subject: [PATCH 814/861] update DAP to 1.36.0-pre.0 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index b8ed8e8fea7..559c11a1763 100644 --- a/package.json +++ b/package.json @@ -139,7 +139,7 @@ "vinyl": "^2.0.0", "vinyl-fs": "^3.0.0", "vsce": "1.48.0", - "vscode-debugprotocol": "1.35.0", + "vscode-debugprotocol": "1.36.0-pre.0", "vscode-nls-dev": "^3.3.1", "webpack": "^4.16.5", "webpack-cli": "^3.1.0", diff --git a/yarn.lock b/yarn.lock index 78e871f843b..90211b1e515 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9631,10 +9631,10 @@ vscode-chokidar@2.1.7: optionalDependencies: vscode-fsevents "1.2.12" -vscode-debugprotocol@1.35.0: - version "1.35.0" - resolved "https://registry.yarnpkg.com/vscode-debugprotocol/-/vscode-debugprotocol-1.35.0.tgz#565140cd42945e30c6c85cafb38c631457d4a46c" - integrity sha512-+OMm11R1bGYbpIJ5eQIkwoDGFF4GvBz3Ztl6/VM+/RNNb2Gjk2c0Ku+oMmfhlTmTlPCpgHBsH4JqVCbUYhu5bA== +vscode-debugprotocol@1.36.0-pre.0: + version "1.36.0-pre.0" + resolved "https://registry.yarnpkg.com/vscode-debugprotocol/-/vscode-debugprotocol-1.36.0-pre.0.tgz#4f998e143acae9e3ce13c308d4ad322f96841926" + integrity sha512-nQhImfsUJFfr73JqA2Uc1bjTvpgZRabqkkKQWUbmrrnTLCPKRCr9AgE44Ehb/vkLXNdo+vPnWjJXWnPGjT10mA== vscode-fsevents@1.2.12: version "1.2.12" From 37981d8fd5d4ba1619f69dc8a0f4670543d39650 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Tue, 20 Aug 2019 12:33:58 +0200 Subject: [PATCH 815/861] Fixes #79430: Bring all auto-closing logic in one place which can now also handle multi-character auto-closing pairs --- src/vs/editor/common/controller/cursor.ts | 26 +- .../editor/common/controller/cursorCommon.ts | 29 +- .../controller/cursorDeleteOperations.ts | 12 +- .../common/controller/cursorTypeOperations.ts | 272 ++++++++---------- .../common/modes/languageConfiguration.ts | 8 +- .../modes/languageConfigurationRegistry.ts | 25 +- .../common/modes/supports/characterPair.ts | 27 +- .../modes/supports/electricCharacter.ts | 68 +---- .../test/browser/controller/cursor.test.ts | 47 +-- .../modes/supports/characterPair.test.ts | 16 +- .../modes/supports/electricCharacter.test.ts | 77 +---- src/vs/monaco.d.ts | 8 +- 12 files changed, 246 insertions(+), 369 deletions(-) diff --git a/src/vs/editor/common/controller/cursor.ts b/src/vs/editor/common/controller/cursor.ts index fefca3cd9b5..1b448239065 100644 --- a/src/vs/editor/common/controller/cursor.ts +++ b/src/vs/editor/common/controller/cursor.ts @@ -86,6 +86,14 @@ export class CursorModelState { class AutoClosedAction { + public static getAllAutoClosedCharacters(autoClosedActions: AutoClosedAction[]): Range[] { + let autoClosedCharacters: Range[] = []; + for (const autoClosedAction of autoClosedActions) { + autoClosedCharacters = autoClosedCharacters.concat(autoClosedAction.getAutoClosedCharactersRanges()); + } + return autoClosedCharacters; + } + private readonly _model: ITextModel; private _autoClosedCharactersDecorations: string[]; @@ -593,11 +601,12 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors { } const closeChar = m[1]; - const openChar = this.context.config.autoClosingPairsClose[closeChar]; - if (!openChar) { + const autoClosingPairsCandidates = this.context.config.autoClosingPairsClose2.get(closeChar); + if (!autoClosingPairsCandidates || autoClosingPairsCandidates.length !== 1) { return null; } + const openChar = autoClosingPairsCandidates[0].open; const closeCharIndex = edit.text.length - m[2].length - 1; const openCharIndex = edit.text.lastIndexOf(openChar, closeCharIndex - 1); if (openCharIndex === -1) { @@ -738,7 +747,8 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors { private _interpretCompositionEnd(source: string) { if (!this._isDoingComposition && source === 'keyboard') { // composition finishes, let's check if we need to auto complete if necessary. - this._executeEditOperation(TypeOperations.compositionEndWithInterceptors(this._prevEditOperationType, this.context.config, this.context.model, this.getSelections())); + const autoClosedCharacters = AutoClosedAction.getAllAutoClosedCharacters(this._autoClosedActions); + this._executeEditOperation(TypeOperations.compositionEndWithInterceptors(this._prevEditOperationType, this.context.config, this.context.model, this.getSelections(), autoClosedCharacters)); } } @@ -756,14 +766,8 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors { chr = text.charAt(i); } - let autoClosedCharacters: Range[] = []; - if (this._autoClosedActions.length > 0) { - for (let i = 0, len = this._autoClosedActions.length; i < len; i++) { - autoClosedCharacters = autoClosedCharacters.concat(this._autoClosedActions[i].getAutoClosedCharactersRanges()); - } - } - - // Here we must interpret each typed character individually, that's why we create a new context + // Here we must interpret each typed character individually + const autoClosedCharacters = AutoClosedAction.getAllAutoClosedCharacters(this._autoClosedActions); this._executeEditOperation(TypeOperations.typeWithInterceptors(this._prevEditOperationType, this.context.config, this.context.model, this.getSelections(), autoClosedCharacters, chr)); } diff --git a/src/vs/editor/common/controller/cursorCommon.ts b/src/vs/editor/common/controller/cursorCommon.ts index 844387516d6..f459e61735f 100644 --- a/src/vs/editor/common/controller/cursorCommon.ts +++ b/src/vs/editor/common/controller/cursorCommon.ts @@ -15,7 +15,7 @@ import { ICommand, IConfiguration, ScrollType } from 'vs/editor/common/editorCom import { ITextModel, TextModelResolvedOptions } from 'vs/editor/common/model'; import { TextModel } from 'vs/editor/common/model/textModel'; import { LanguageIdentifier } from 'vs/editor/common/modes'; -import { IAutoClosingPair } from 'vs/editor/common/modes/languageConfiguration'; +import { IAutoClosingPair, StandardAutoClosingPairConditional } from 'vs/editor/common/modes/languageConfiguration'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; import { VerticalRevealType } from 'vs/editor/common/view/viewEvents'; import { IViewModel } from 'vs/editor/common/viewModel/viewModel'; @@ -67,11 +67,22 @@ export interface ICursors { export interface CharacterMap { [char: string]: string; } +export interface MultipleCharacterMap { + [char: string]: string[]; +} const autoCloseAlways = () => true; const autoCloseNever = () => false; const autoCloseBeforeWhitespace = (chr: string) => (chr === ' ' || chr === '\t'); +function appendEntry(target: Map, key: K, value: V): void { + if (target.has(key)) { + target.get(key)!.push(value); + } else { + target.set(key, [value]); + } +} + export class CursorConfiguration { _cursorMoveConfigurationBrand: void; @@ -90,8 +101,8 @@ export class CursorConfiguration { public readonly autoClosingQuotes: EditorAutoClosingStrategy; public readonly autoSurround: EditorAutoSurroundStrategy; public readonly autoIndent: boolean; - public readonly autoClosingPairsOpen: CharacterMap; - public readonly autoClosingPairsClose: CharacterMap; + public readonly autoClosingPairsOpen2: Map; + public readonly autoClosingPairsClose2: Map; public readonly surroundingPairs: CharacterMap; public readonly shouldAutoCloseBefore: { quote: (ch: string) => boolean, bracket: (ch: string) => boolean }; @@ -138,8 +149,8 @@ export class CursorConfiguration { this.autoSurround = c.autoSurround; this.autoIndent = c.autoIndent; - this.autoClosingPairsOpen = {}; - this.autoClosingPairsClose = {}; + this.autoClosingPairsOpen2 = new Map(); + this.autoClosingPairsClose2 = new Map(); this.surroundingPairs = {}; this._electricChars = null; @@ -151,8 +162,10 @@ export class CursorConfiguration { let autoClosingPairs = CursorConfiguration._getAutoClosingPairs(languageIdentifier); if (autoClosingPairs) { for (const pair of autoClosingPairs) { - this.autoClosingPairsOpen[pair.open] = pair.close; - this.autoClosingPairsClose[pair.close] = pair.open; + appendEntry(this.autoClosingPairsOpen2, pair.open.charAt(pair.open.length - 1), pair); + if (pair.close.length === 1) { + appendEntry(this.autoClosingPairsClose2, pair.close, pair); + } } } @@ -190,7 +203,7 @@ export class CursorConfiguration { } } - private static _getAutoClosingPairs(languageIdentifier: LanguageIdentifier): IAutoClosingPair[] | null { + private static _getAutoClosingPairs(languageIdentifier: LanguageIdentifier): StandardAutoClosingPairConditional[] | null { try { return LanguageConfigurationRegistry.getAutoClosingPairs(languageIdentifier.id); } catch (e) { diff --git a/src/vs/editor/common/controller/cursorDeleteOperations.ts b/src/vs/editor/common/controller/cursorDeleteOperations.ts index 5a7830e26b3..3f5e80a3ee9 100644 --- a/src/vs/editor/common/controller/cursorDeleteOperations.ts +++ b/src/vs/editor/common/controller/cursorDeleteOperations.ts @@ -63,7 +63,8 @@ export class DeleteOperations { const lineText = model.getLineContent(position.lineNumber); const character = lineText[position.column - 2]; - if (!config.autoClosingPairsOpen.hasOwnProperty(character)) { + const autoClosingPairCandidates = config.autoClosingPairsOpen2.get(character); + if (!autoClosingPairCandidates) { return false; } @@ -78,9 +79,14 @@ export class DeleteOperations { } const afterCharacter = lineText[position.column - 1]; - const closeCharacter = config.autoClosingPairsOpen[character]; - if (afterCharacter !== closeCharacter) { + let foundAutoClosingPair = false; + for (const autoClosingPairCandidate of autoClosingPairCandidates) { + if (autoClosingPairCandidate.open === character && autoClosingPairCandidate.close === afterCharacter) { + foundAutoClosingPair = true; + } + } + if (!foundAutoClosingPair) { return false; } } diff --git a/src/vs/editor/common/controller/cursorTypeOperations.ts b/src/vs/editor/common/controller/cursorTypeOperations.ts index 7ea1d26dffd..aa6b5747420 100644 --- a/src/vs/editor/common/controller/cursorTypeOperations.ts +++ b/src/vs/editor/common/controller/cursorTypeOperations.ts @@ -13,9 +13,10 @@ import { CursorColumns, CursorConfiguration, EditOperationResult, EditOperationT import { WordCharacterClass, getMapForWordSeparators } from 'vs/editor/common/controller/wordCharacterClassifier'; import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; +import { Position } from 'vs/editor/common/core/position'; import { ICommand, ICursorStateComputerData } from 'vs/editor/common/editorCommon'; import { ITextModel } from 'vs/editor/common/model'; -import { EnterAction, IndentAction } from 'vs/editor/common/modes/languageConfiguration'; +import { EnterAction, IndentAction, StandardAutoClosingPairConditional } from 'vs/editor/common/modes/languageConfiguration'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; import { IElectricAction } from 'vs/editor/common/modes/supports/electricCharacter'; @@ -433,7 +434,11 @@ export class TypeOperations { private static _isAutoClosingCloseCharType(config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): boolean { const autoCloseConfig = isQuote(ch) ? config.autoClosingQuotes : config.autoClosingBrackets; - if (autoCloseConfig === 'never' || !config.autoClosingPairsClose.hasOwnProperty(ch)) { + if (autoCloseConfig === 'never') { + return false; + } + + if (!config.autoClosingPairsClose2.has(ch)) { return false; } @@ -469,15 +474,6 @@ export class TypeOperations { return true; } - private static _countNeedlesInHaystack(haystack: string, needle: string): number { - let cnt = 0; - let lastIndex = -1; - while ((lastIndex = haystack.indexOf(needle, lastIndex + 1)) !== -1) { - cnt++; - } - return cnt; - } - private static _runAutoClosingCloseCharType(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): EditOperationResult { let commands: ICommand[] = []; for (let i = 0, len = selections.length; i < len; i++) { @@ -492,65 +488,98 @@ export class TypeOperations { }); } - private static _isBeforeClosingBrace(config: CursorConfiguration, ch: string, characterAfter: string) { - const thisBraceIsSymmetric = (config.autoClosingPairsOpen[ch] === ch); - let isBeforeCloseBrace = false; - for (let otherCloseBrace in config.autoClosingPairsClose) { - const otherBraceIsSymmetric = (config.autoClosingPairsOpen[otherCloseBrace] === otherCloseBrace); - if (!thisBraceIsSymmetric && otherBraceIsSymmetric) { - continue; - } - if (characterAfter === otherCloseBrace) { - isBeforeCloseBrace = true; - break; - } - } - - return isBeforeCloseBrace; - } - - private static _isAutoClosingOpenCharType(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): boolean { - const chIsQuote = isQuote(ch); - const autoCloseConfig = chIsQuote ? config.autoClosingQuotes : config.autoClosingBrackets; - - if (autoCloseConfig === 'never' || !config.autoClosingPairsOpen.hasOwnProperty(ch)) { + private static _isBeforeClosingBrace(config: CursorConfiguration, autoClosingPair: StandardAutoClosingPairConditional, characterAfter: string) { + const otherAutoClosingPairs = config.autoClosingPairsClose2.get(characterAfter); + if (!otherAutoClosingPairs) { return false; } - let shouldAutoCloseBefore = chIsQuote ? config.shouldAutoCloseBefore.quote : config.shouldAutoCloseBefore.bracket; + const thisBraceIsSymmetric = (autoClosingPair.open === autoClosingPair.close); + for (const otherAutoClosingPair of otherAutoClosingPairs) { + const otherBraceIsSymmetric = (otherAutoClosingPair.open === otherAutoClosingPair.close); + if (!thisBraceIsSymmetric && otherBraceIsSymmetric) { + continue; + } + return true; + } + + return false; + } + + private static _findAutoClosingPairOpen(config: CursorConfiguration, model: ITextModel, positions: Position[], ch: string): StandardAutoClosingPairConditional | null { + const autoClosingPairCandidates = config.autoClosingPairsOpen2.get(ch); + if (!autoClosingPairCandidates) { + return null; + } + + // Determine which auto-closing pair it is + let autoClosingPair: StandardAutoClosingPairConditional | null = null; + for (const autoClosingPairCandidate of autoClosingPairCandidates) { + if (autoClosingPair === null || autoClosingPairCandidate.open.length > autoClosingPair.open.length) { + let candidateIsMatch = true; + for (const position of positions) { + const relevantText = model.getValueInRange(new Range(position.lineNumber, position.column - autoClosingPairCandidate.open.length + 1, position.lineNumber, position.column)); + if (relevantText + ch !== autoClosingPairCandidate.open) { + candidateIsMatch = false; + break; + } + } + + if (candidateIsMatch) { + autoClosingPair = autoClosingPairCandidate; + } + } + } + return autoClosingPair; + } + + private static _isAutoClosingOpenCharType(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, insertOpenCharacter: boolean): StandardAutoClosingPairConditional | null { + const chIsQuote = isQuote(ch); + const autoCloseConfig = chIsQuote ? config.autoClosingQuotes : config.autoClosingBrackets; + if (autoCloseConfig === 'never') { + return null; + } + + const autoClosingPair = this._findAutoClosingPairOpen(config, model, selections.map(s => s.getPosition()), ch); + if (!autoClosingPair) { + return null; + } + + const shouldAutoCloseBefore = chIsQuote ? config.shouldAutoCloseBefore.quote : config.shouldAutoCloseBefore.bracket; for (let i = 0, len = selections.length; i < len; i++) { const selection = selections[i]; if (!selection.isEmpty()) { - return false; + return null; } const position = selection.getPosition(); const lineText = model.getLineContent(position.lineNumber); - // Do not auto-close ' or " after a word character - if ((chIsQuote && position.column > 1) && autoCloseConfig !== 'always') { - const wordSeparators = getMapForWordSeparators(config.wordSeparators); - const characterBeforeCode = lineText.charCodeAt(position.column - 2); - const characterBeforeType = wordSeparators.get(characterBeforeCode); - if (characterBeforeType === WordCharacterClass.Regular) { - return false; - } - } - // Only consider auto closing the pair if a space follows or if another autoclosed pair follows - const characterAfter = lineText.charAt(position.column - 1); - if (characterAfter) { - let isBeforeCloseBrace = TypeOperations._isBeforeClosingBrace(config, ch, characterAfter); + if (lineText.length > position.column - 1) { + const characterAfter = lineText.charAt(position.column - 1); + const isBeforeCloseBrace = TypeOperations._isBeforeClosingBrace(config, autoClosingPair, characterAfter); if (!isBeforeCloseBrace && !shouldAutoCloseBefore(characterAfter)) { - return false; + return null; } } if (!model.isCheapToTokenize(position.lineNumber)) { // Do not force tokenization - return false; + return null; + } + + // Do not auto-close ' or " after a word character + if (autoClosingPair.open.length === 1 && chIsQuote && autoCloseConfig !== 'always') { + const wordSeparators = getMapForWordSeparators(config.wordSeparators); + if (insertOpenCharacter && position.column > 1 && wordSeparators.get(lineText.charCodeAt(position.column - 2)) === WordCharacterClass.Regular) { + return null; + } + if (!insertOpenCharacter && position.column > 2 && wordSeparators.get(lineText.charCodeAt(position.column - 3)) === WordCharacterClass.Regular) { + return null; + } } model.forceTokenization(position.lineNumber); @@ -558,25 +587,24 @@ export class TypeOperations { let shouldAutoClosePair = false; try { - shouldAutoClosePair = LanguageConfigurationRegistry.shouldAutoClosePair(ch, lineTokens, position.column); + shouldAutoClosePair = LanguageConfigurationRegistry.shouldAutoClosePair(autoClosingPair, lineTokens, insertOpenCharacter ? position.column : position.column - 1); } catch (e) { onUnexpectedError(e); } if (!shouldAutoClosePair) { - return false; + return null; } } - return true; + return autoClosingPair; } - private static _runAutoClosingOpenCharType(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): EditOperationResult { + private static _runAutoClosingOpenCharType(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, insertOpenCharacter: boolean, autoClosingPair: StandardAutoClosingPairConditional): EditOperationResult { let commands: ICommand[] = []; for (let i = 0, len = selections.length; i < len; i++) { const selection = selections[i]; - const closeCharacter = config.autoClosingPairsOpen[ch]; - commands[i] = new TypeWithAutoClosingCommand(selection, ch, closeCharacter); + commands[i] = new TypeWithAutoClosingCommand(selection, ch, insertOpenCharacter, autoClosingPair.close); } return new EditOperationResult(EditOperationType.Typing, commands, { shouldPushStackElementBefore: true, @@ -679,14 +707,6 @@ export class TypeOperations { return null; } - if (electricAction.appendText) { - const command = new ReplaceCommandWithOffsetCursorState(selection, ch + electricAction.appendText, 0, -electricAction.appendText.length); - return new EditOperationResult(EditOperationType.Typing, [command], { - shouldPushStackElementBefore: false, - shouldPushStackElementAfter: true - }); - } - if (electricAction.matchOpenBracket) { let endColumn = (lineTokens.getLineContent() + ch).lastIndexOf(electricAction.matchOpenBracket) + 1; let match = model.findMatchingBracketUp(electricAction.matchOpenBracket, { @@ -722,87 +742,44 @@ export class TypeOperations { return null; } - public static compositionEndWithInterceptors(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[]): EditOperationResult | null { - if (config.autoClosingQuotes === 'never') { + /** + * This is very similar with typing, but the character is already in the text buffer! + */ + public static compositionEndWithInterceptors(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[]): EditOperationResult | null { + let ch: string | null = null; + // extract last typed character + for (const selection of selections) { + if (!selection.isEmpty()) { + return null; + } + const position = selection.getPosition(); + const currentChar = model.getValueInRange(new Range(position.lineNumber, position.column - 1, position.lineNumber, position.column)); + if (ch === null) { + ch = currentChar; + } else if (ch !== currentChar) { + return null; + } + } + + if (!ch) { return null; } - let commands: ICommand[] = []; - - for (let i = 0; i < selections.length; i++) { - if (!selections[i].isEmpty()) { - continue; - } - const position = selections[i].getPosition(); - const lineText = model.getLineContent(position.lineNumber); - const ch = lineText.charAt(position.column - 2); - - if (config.autoClosingPairsClose.hasOwnProperty(ch)) { // first of all, it's a closing tag - if (ch === config.autoClosingPairsClose[ch] /** isEqualPair */) { - const lineTextBeforeCursor = lineText.substr(0, position.column - 2); - const chCntBefore = this._countNeedlesInHaystack(lineTextBeforeCursor, ch); - - if (chCntBefore % 2 === 1) { - continue; // it pairs with the opening tag. - } - } - } - - // As we are not typing in a new character, so we don't need to run `_runAutoClosingCloseCharType` - // Next step, let's try to check if it's an open char. - if (config.autoClosingPairsOpen.hasOwnProperty(ch)) { - if (isQuote(ch) && position.column > 2) { - const wordSeparators = getMapForWordSeparators(config.wordSeparators); - const characterBeforeCode = lineText.charCodeAt(position.column - 3); - const characterBeforeType = wordSeparators.get(characterBeforeCode); - if (characterBeforeType === WordCharacterClass.Regular) { - continue; - } - } - - const characterAfter = lineText.charAt(position.column - 1); - - if (characterAfter) { - let isBeforeCloseBrace = TypeOperations._isBeforeClosingBrace(config, ch, characterAfter); - let shouldAutoCloseBefore = isQuote(ch) ? config.shouldAutoCloseBefore.quote : config.shouldAutoCloseBefore.bracket; - if (isBeforeCloseBrace) { - // In normal auto closing logic, we will auto close if the cursor is even before a closing brace intentionally. - // However for composition mode, we do nothing here as users might clear all the characters for composition and we don't want to do a unnecessary auto close. - // Related: microsoft/vscode#57250. - continue; - } - if (!shouldAutoCloseBefore(characterAfter)) { - continue; - } - } - - if (!model.isCheapToTokenize(position.lineNumber)) { - // Do not force tokenization - continue; - } - - model.forceTokenization(position.lineNumber); - const lineTokens = model.getLineTokens(position.lineNumber); - - let shouldAutoClosePair = false; - - try { - shouldAutoClosePair = LanguageConfigurationRegistry.shouldAutoClosePair(ch, lineTokens, position.column - 1); - } catch (e) { - onUnexpectedError(e); - } - - if (shouldAutoClosePair) { - const closeCharacter = config.autoClosingPairsOpen[ch]; - commands[i] = new ReplaceCommandWithOffsetCursorState(selections[i], closeCharacter, 0, -closeCharacter.length); - } - } + if (this._isAutoClosingCloseCharType(config, model, selections, autoClosedCharacters, ch)) { + // Unfortunately, the close character is at this point "doubled", so we need to delete it... + const commands = selections.map(s => new ReplaceCommand(new Range(s.positionLineNumber, s.positionColumn, s.positionLineNumber, s.positionColumn + 1), '', false)); + return new EditOperationResult(EditOperationType.Typing, commands, { + shouldPushStackElementBefore: true, + shouldPushStackElementAfter: false + }); } - return new EditOperationResult(EditOperationType.Typing, commands, { - shouldPushStackElementBefore: true, - shouldPushStackElementAfter: false - }); + const autoClosingPairOpenCharType = this._isAutoClosingOpenCharType(config, model, selections, ch, false); + if (autoClosingPairOpenCharType) { + return this._runAutoClosingOpenCharType(prevEditOperationType, config, model, selections, ch, false, autoClosingPairOpenCharType); + } + + return null; } public static typeWithInterceptors(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult { @@ -840,8 +817,9 @@ export class TypeOperations { return this._runAutoClosingCloseCharType(prevEditOperationType, config, model, selections, ch); } - if (this._isAutoClosingOpenCharType(config, model, selections, ch)) { - return this._runAutoClosingOpenCharType(prevEditOperationType, config, model, selections, ch); + const autoClosingPairOpenCharType = this._isAutoClosingOpenCharType(config, model, selections, ch, true); + if (autoClosingPairOpenCharType) { + return this._runAutoClosingOpenCharType(prevEditOperationType, config, model, selections, ch, true, autoClosingPairOpenCharType); } if (this._isSurroundSelectionType(config, model, selections, ch)) { @@ -929,12 +907,14 @@ export class TypeOperations { export class TypeWithAutoClosingCommand extends ReplaceCommandWithOffsetCursorState { - private _closeCharacter: string; + private readonly _openCharacter: string; + private readonly _closeCharacter: string; public closeCharacterRange: Range | null; public enclosingRange: Range | null; - constructor(selection: Selection, openCharacter: string, closeCharacter: string) { - super(selection, openCharacter + closeCharacter, 0, -closeCharacter.length); + constructor(selection: Selection, openCharacter: string, insertOpenCharacter: boolean, closeCharacter: string) { + super(selection, (insertOpenCharacter ? openCharacter : '') + closeCharacter, 0, -closeCharacter.length); + this._openCharacter = openCharacter; this._closeCharacter = closeCharacter; this.closeCharacterRange = null; this.enclosingRange = null; @@ -944,7 +924,7 @@ export class TypeWithAutoClosingCommand extends ReplaceCommandWithOffsetCursorSt let inverseEditOperations = helper.getInverseEditOperations(); let range = inverseEditOperations[0].range; this.closeCharacterRange = new Range(range.startLineNumber, range.endColumn - this._closeCharacter.length, range.endLineNumber, range.endColumn); - this.enclosingRange = range; + this.enclosingRange = new Range(range.startLineNumber, range.endColumn - this._openCharacter.length - this._closeCharacter.length, range.endLineNumber, range.endColumn); return super.computeCursorState(model, helper); } } diff --git a/src/vs/editor/common/modes/languageConfiguration.ts b/src/vs/editor/common/modes/languageConfiguration.ts index 4bca048eec1..ed8d2fdb4ae 100644 --- a/src/vs/editor/common/modes/languageConfiguration.ts +++ b/src/vs/editor/common/modes/languageConfiguration.ts @@ -78,7 +78,9 @@ export interface LanguageConfiguration { * * @deprecated Will be replaced by a better API soon. */ - __electricCharacterSupport?: IBracketElectricCharacterContribution; + __electricCharacterSupport?: { + docComment?: IDocComment; + }; } /** @@ -155,10 +157,6 @@ export interface OnEnterRule { action: EnterAction; } -export interface IBracketElectricCharacterContribution { - docComment?: IDocComment; -} - /** * Definition of documentation comments (e.g. Javadoc/JSdoc) */ diff --git a/src/vs/editor/common/modes/languageConfigurationRegistry.ts b/src/vs/editor/common/modes/languageConfigurationRegistry.ts index baf47379af9..cee0469e30e 100644 --- a/src/vs/editor/common/modes/languageConfigurationRegistry.ts +++ b/src/vs/editor/common/modes/languageConfigurationRegistry.ts @@ -12,7 +12,7 @@ import { Range } from 'vs/editor/common/core/range'; import { ITextModel } from 'vs/editor/common/model'; import { DEFAULT_WORD_REGEXP, ensureValidWordDefinition } from 'vs/editor/common/model/wordHelper'; import { LanguageId, LanguageIdentifier } from 'vs/editor/common/modes'; -import { EnterAction, FoldingRules, IAutoClosingPair, IAutoClosingPairConditional, IndentAction, IndentationRule, LanguageConfiguration } from 'vs/editor/common/modes/languageConfiguration'; +import { EnterAction, FoldingRules, IAutoClosingPair, IndentAction, IndentationRule, LanguageConfiguration, StandardAutoClosingPairConditional } from 'vs/editor/common/modes/languageConfiguration'; import { createScopedLineTokens } from 'vs/editor/common/modes/supports'; import { CharacterPairSupport } from 'vs/editor/common/modes/supports/characterPair'; import { BracketElectricCharacterSupport, IElectricAction } from 'vs/editor/common/modes/supports/electricCharacter'; @@ -97,16 +97,7 @@ export class RichEditSupport { public get electricCharacter(): BracketElectricCharacterSupport | null { if (!this._electricCharacter) { - let autoClosingPairs: IAutoClosingPairConditional[] = []; - if (this._conf.autoClosingPairs) { - autoClosingPairs = this._conf.autoClosingPairs; - } else if (this._conf.brackets) { - autoClosingPairs = this._conf.brackets.map(b => { - return { open: b[0], close: b[1] }; - }); - } - - this._electricCharacter = new BracketElectricCharacterSupport(this.brackets, autoClosingPairs, this._conf.__electricCharacterSupport); + this._electricCharacter = new BracketElectricCharacterSupport(this.brackets); } return this._electricCharacter; } @@ -261,7 +252,7 @@ export class LanguageConfigurationRegistryImpl { return value.characterPair || null; } - public getAutoClosingPairs(languageId: LanguageId): IAutoClosingPair[] { + public getAutoClosingPairs(languageId: LanguageId): StandardAutoClosingPairConditional[] { let characterPairSupport = this._getCharacterPairSupport(languageId); if (!characterPairSupport) { return []; @@ -285,13 +276,9 @@ export class LanguageConfigurationRegistryImpl { return characterPairSupport.getSurroundingPairs(); } - public shouldAutoClosePair(character: string, context: LineTokens, column: number): boolean { - let scopedLineTokens = createScopedLineTokens(context, column - 1); - let characterPairSupport = this._getCharacterPairSupport(scopedLineTokens.languageId); - if (!characterPairSupport) { - return false; - } - return characterPairSupport.shouldAutoClosePair(character, scopedLineTokens, column - scopedLineTokens.firstCharOffset); + public shouldAutoClosePair(autoClosingPair: StandardAutoClosingPairConditional, context: LineTokens, column: number): boolean { + const scopedLineTokens = createScopedLineTokens(context, column - 1); + return CharacterPairSupport.shouldAutoClosePair(autoClosingPair, scopedLineTokens, column - scopedLineTokens.firstCharOffset); } // end characterPair diff --git a/src/vs/editor/common/modes/supports/characterPair.ts b/src/vs/editor/common/modes/supports/characterPair.ts index bb8ecd4980e..b7cfa2ecdd7 100644 --- a/src/vs/editor/common/modes/supports/characterPair.ts +++ b/src/vs/editor/common/modes/supports/characterPair.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { CharacterPair, IAutoClosingPair, IAutoClosingPairConditional, StandardAutoClosingPairConditional } from 'vs/editor/common/modes/languageConfiguration'; +import { IAutoClosingPair, StandardAutoClosingPairConditional, LanguageConfiguration } from 'vs/editor/common/modes/languageConfiguration'; import { ScopedLineTokens } from 'vs/editor/common/modes/supports'; export class CharacterPairSupport { @@ -15,7 +15,7 @@ export class CharacterPairSupport { private readonly _surroundingPairs: IAutoClosingPair[]; private readonly _autoCloseBefore: string; - constructor(config: { brackets?: CharacterPair[]; autoClosingPairs?: IAutoClosingPairConditional[], surroundingPairs?: IAutoClosingPair[], autoCloseBefore?: string }) { + constructor(config: LanguageConfiguration) { if (config.autoClosingPairs) { this._autoClosingPairs = config.autoClosingPairs.map(el => new StandardAutoClosingPairConditional(el)); } else if (config.brackets) { @@ -24,12 +24,18 @@ export class CharacterPairSupport { this._autoClosingPairs = []; } + if (config.__electricCharacterSupport && config.__electricCharacterSupport.docComment) { + const docComment = config.__electricCharacterSupport.docComment; + // IDocComment is legacy, only partially supported + this._autoClosingPairs.push(new StandardAutoClosingPairConditional({ open: docComment.open, close: docComment.close || '' })); + } + this._autoCloseBefore = typeof config.autoCloseBefore === 'string' ? config.autoCloseBefore : CharacterPairSupport.DEFAULT_AUTOCLOSE_BEFORE_LANGUAGE_DEFINED; this._surroundingPairs = config.surroundingPairs || this._autoClosingPairs; } - public getAutoClosingPairs(): IAutoClosingPair[] { + public getAutoClosingPairs(): StandardAutoClosingPairConditional[] { return this._autoClosingPairs; } @@ -37,22 +43,15 @@ export class CharacterPairSupport { return this._autoCloseBefore; } - public shouldAutoClosePair(character: string, context: ScopedLineTokens, column: number): boolean { + public static shouldAutoClosePair(autoClosingPair: StandardAutoClosingPairConditional, context: ScopedLineTokens, column: number): boolean { // Always complete on empty line if (context.getTokenCount() === 0) { return true; } - let tokenIndex = context.findTokenIndexAtOffset(column - 2); - let standardTokenType = context.getStandardTokenType(tokenIndex); - - for (const autoClosingPair of this._autoClosingPairs) { - if (autoClosingPair.open === character) { - return autoClosingPair.isOK(standardTokenType); - } - } - - return false; + const tokenIndex = context.findTokenIndexAtOffset(column - 2); + const standardTokenType = context.getStandardTokenType(tokenIndex); + return autoClosingPair.isOK(standardTokenType); } public getSurroundingPairs(): IAutoClosingPair[] { diff --git a/src/vs/editor/common/modes/supports/electricCharacter.ts b/src/vs/editor/common/modes/supports/electricCharacter.ts index 878ef492e12..387994c28a4 100644 --- a/src/vs/editor/common/modes/supports/electricCharacter.ts +++ b/src/vs/editor/common/modes/supports/electricCharacter.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IAutoClosingPairConditional, IBracketElectricCharacterContribution, StandardAutoClosingPairConditional } from 'vs/editor/common/modes/languageConfiguration'; import { ScopedLineTokens, ignoreBracketsInToken } from 'vs/editor/common/modes/supports'; import { BracketsUtils, RichEditBrackets } from 'vs/editor/common/modes/supports/richEditBrackets'; @@ -12,29 +11,17 @@ import { BracketsUtils, RichEditBrackets } from 'vs/editor/common/modes/supports * @internal */ export interface IElectricAction { - // Only one of the following properties should be defined: - // The line will be indented at the same level of the line // which contains the matching given bracket type. - matchOpenBracket?: string; - - // The text will be appended after the electric character. - appendText?: string; + matchOpenBracket: string; } export class BracketElectricCharacterSupport { private readonly _richEditBrackets: RichEditBrackets | null; - private readonly _complexAutoClosePairs: StandardAutoClosingPairConditional[]; - constructor(richEditBrackets: RichEditBrackets | null, autoClosePairs: IAutoClosingPairConditional[], contribution: IBracketElectricCharacterContribution | null | undefined) { - contribution = contribution || {}; + constructor(richEditBrackets: RichEditBrackets | null) { this._richEditBrackets = richEditBrackets; - this._complexAutoClosePairs = autoClosePairs.filter(pair => pair.open.length > 1 && !!pair.close).map(el => new StandardAutoClosingPairConditional(el)); - if (contribution.docComment) { - // IDocComment is legacy, only partially supported - this._complexAutoClosePairs.push(new StandardAutoClosingPairConditional({ open: contribution.docComment.open, close: contribution.docComment.close || '' })); - } } public getElectricCharacters(): string[] { @@ -48,11 +35,6 @@ export class BracketElectricCharacterSupport { } } - // auto close - for (let pair of this._complexAutoClosePairs) { - result.push(pair.open.charAt(pair.open.length - 1)); - } - // Filter duplicate entries result = result.filter((item, pos, array) => { return array.indexOf(item) === pos; @@ -62,12 +44,6 @@ export class BracketElectricCharacterSupport { } public onElectricCharacter(character: string, context: ScopedLineTokens, column: number): IElectricAction | null { - return (this._onElectricAutoClose(character, context, column) || - this._onElectricAutoIndent(character, context, column)); - } - - private _onElectricAutoIndent(character: string, context: ScopedLineTokens, column: number): IElectricAction | null { - if (!this._richEditBrackets || this._richEditBrackets.brackets.length === 0) { return null; } @@ -103,44 +79,4 @@ export class BracketElectricCharacterSupport { matchOpenBracket: bracketText }; } - - private _onElectricAutoClose(character: string, context: ScopedLineTokens, column: number): IElectricAction | null { - if (!this._complexAutoClosePairs.length) { - return null; - } - - let line = context.getLineContent(); - - for (let i = 0, len = this._complexAutoClosePairs.length; i < len; i++) { - let pair = this._complexAutoClosePairs[i]; - - // See if the right electric character was pressed - if (character !== pair.open.charAt(pair.open.length - 1)) { - continue; - } - - // check if the full open bracket matches - let start = column - pair.open.length + 1; - let actual = line.substring(start - 1, column - 1) + character; - if (actual !== pair.open) { - continue; - } - - let lastTokenIndex = context.findTokenIndexAtOffset(column - 1); - let lastTokenStandardType = context.getStandardTokenType(lastTokenIndex); - // If we're in a scope listed in 'notIn', do nothing - if (!pair.isOK(lastTokenStandardType)) { - continue; - } - - // If this line already contains the closing tag, do nothing. - if (line.indexOf(pair.close, column - 1) >= 0) { - continue; - } - - return { appendText: pair.close }; - } - - return null; - } } diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index e925406c1b4..59e221a8c2f 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -3998,8 +3998,12 @@ suite('autoClosingPairs', () => { { open: '\'', close: '\'', notIn: ['string', 'comment'] }, { open: '\"', close: '\"', notIn: ['string'] }, { open: '`', close: '`', notIn: ['string', 'comment'] }, - { open: '/**', close: ' */', notIn: ['string'] } + { open: '/**', close: ' */', notIn: ['string'] }, + { open: 'begin', close: 'end', notIn: ['string'] } ], + __electricCharacterSupport: { + docComment: { open: '/**', close: ' */' } + } })); } @@ -4439,6 +4443,28 @@ suite('autoClosingPairs', () => { mode.dispose(); }); + test('multi-character autoclose', () => { + let mode = new AutoClosingMode(); + usingCursor({ + text: [ + '', + ], + languageIdentifier: mode.getLanguageIdentifier() + }, (model, cursor) => { + + model.setValue('begi'); + cursor.setSelections('test', [new Selection(1, 5, 1, 5)]); + cursorCommand(cursor, H.Type, { text: 'n' }, 'keyboard'); + assert.strictEqual(model.getLineContent(1), 'beginend'); + + model.setValue('/*'); + cursor.setSelections('test', [new Selection(1, 3, 1, 3)]); + cursorCommand(cursor, H.Type, { text: '*' }, 'keyboard'); + assert.strictEqual(model.getLineContent(1), '/** */'); + }); + mode.dispose(); + }); + test('issue #55314: Do not auto-close when ending with open', () => { const languageId = new LanguageIdentifier('myElectricMode', 5); class ElectricMode extends MockMode { @@ -4477,7 +4503,7 @@ suite('autoClosingPairs', () => { model.forceTokenization(model.getLineCount()); assertType(model, cursor, 3, 4, '"', '"', `does not double quote when ending with open`); model.forceTokenization(model.getLineCount()); - assertType(model, cursor, 4, 2, '"', '""', `double quote when ending with open`); + assertType(model, cursor, 4, 2, '"', '"', `does not double quote when ending with open`); model.forceTokenization(model.getLineCount()); assertType(model, cursor, 4, 3, '"', '"', `does not double quote when ending with open`); }); @@ -4772,31 +4798,18 @@ suite('autoClosingPairs', () => { // on the mac US intl kb layout - // Typing ` + space + // Typing ' + space cursorCommand(cursor, H.CompositionStart, null, 'keyboard'); cursorCommand(cursor, H.Type, { text: '\'' }, 'keyboard'); cursorCommand(cursor, H.ReplacePreviousChar, { replaceCharCnt: 1, text: '\'' }, 'keyboard'); cursorCommand(cursor, H.CompositionEnd, null, 'keyboard'); - assert.equal(model.getValue(), '\'\''); - // Typing " + space within string - cursor.setSelections('test', [new Selection(1, 2, 1, 2)]); - cursorCommand(cursor, H.CompositionStart, null, 'keyboard'); - cursorCommand(cursor, H.Type, { text: '"' }, 'keyboard'); - cursorCommand(cursor, H.ReplacePreviousChar, { replaceCharCnt: 1, text: '"' }, 'keyboard'); - cursorCommand(cursor, H.CompositionEnd, null, 'keyboard'); - - assert.equal(model.getValue(), '\'"\''); - - // Typing ' + space after ' - model.setValue('\''); - cursor.setSelections('test', [new Selection(1, 2, 1, 2)]); + // Typing one more ' + space cursorCommand(cursor, H.CompositionStart, null, 'keyboard'); cursorCommand(cursor, H.Type, { text: '\'' }, 'keyboard'); cursorCommand(cursor, H.ReplacePreviousChar, { replaceCharCnt: 1, text: '\'' }, 'keyboard'); cursorCommand(cursor, H.CompositionEnd, null, 'keyboard'); - assert.equal(model.getValue(), '\'\''); // Typing ' as a closing tag diff --git a/src/vs/editor/test/common/modes/supports/characterPair.test.ts b/src/vs/editor/test/common/modes/supports/characterPair.test.ts index ba9aa15f503..3f3f6880450 100644 --- a/src/vs/editor/test/common/modes/supports/characterPair.test.ts +++ b/src/vs/editor/test/common/modes/supports/characterPair.test.ts @@ -7,6 +7,7 @@ import * as assert from 'assert'; import { StandardTokenType } from 'vs/editor/common/modes'; import { CharacterPairSupport } from 'vs/editor/common/modes/supports/characterPair'; import { TokenText, createFakeScopedLineTokens } from 'vs/editor/test/common/modesTestUtils'; +import { StandardAutoClosingPairConditional } from 'vs/editor/common/modes/languageConfiguration'; suite('CharacterPairSupport', () => { @@ -52,8 +53,21 @@ suite('CharacterPairSupport', () => { assert.deepEqual(characaterPairSupport.getSurroundingPairs(), []); }); + function findAutoClosingPair(characterPairSupport: CharacterPairSupport, character: string): StandardAutoClosingPairConditional | null { + for (const autoClosingPair of characterPairSupport.getAutoClosingPairs()) { + if (autoClosingPair.open === character) { + return autoClosingPair; + } + } + return null; + } + function testShouldAutoClose(characterPairSupport: CharacterPairSupport, line: TokenText[], character: string, column: number): boolean { - return characterPairSupport.shouldAutoClosePair(character, createFakeScopedLineTokens(line), column); + const autoClosingPair = findAutoClosingPair(characterPairSupport, character); + if (!autoClosingPair) { + return false; + } + return CharacterPairSupport.shouldAutoClosePair(autoClosingPair, createFakeScopedLineTokens(line), column); } test('shouldAutoClosePair in empty line', () => { diff --git a/src/vs/editor/test/common/modes/supports/electricCharacter.test.ts b/src/vs/editor/test/common/modes/supports/electricCharacter.test.ts index 6035379e05a..22b818c6b67 100644 --- a/src/vs/editor/test/common/modes/supports/electricCharacter.test.ts +++ b/src/vs/editor/test/common/modes/supports/electricCharacter.test.ts @@ -21,86 +21,20 @@ suite('Editor Modes - Auto Indentation', () => { assert.deepEqual(actual, null); } - function testAppends(electricCharacterSupport: BracketElectricCharacterSupport, line: TokenText[], character: string, offset: number, appendText: string): void { - let actual = _testOnElectricCharacter(electricCharacterSupport, line, character, offset); - assert.deepEqual(actual, { appendText: appendText }); - } - function testMatchBracket(electricCharacterSupport: BracketElectricCharacterSupport, line: TokenText[], character: string, offset: number, matchOpenBracket: string): void { let actual = _testOnElectricCharacter(electricCharacterSupport, line, character, offset); assert.deepEqual(actual, { matchOpenBracket: matchOpenBracket }); } - test('Doc comments', () => { - let brackets = new BracketElectricCharacterSupport(null, [{ open: '/**', close: ' */' }], null); - - testAppends(brackets, [ - { text: '/*', type: StandardTokenType.Other }, - ], '*', 3, ' */'); - - testDoesNothing(brackets, [ - { text: '/*', type: StandardTokenType.Other }, - { text: ' ', type: StandardTokenType.Other }, - { text: '*/', type: StandardTokenType.Other }, - ], '*', 3); - }); - test('getElectricCharacters uses all sources and dedups', () => { let sup = new BracketElectricCharacterSupport( new RichEditBrackets(fakeLanguageIdentifier, [ ['{', '}'], ['(', ')'] - ]), [ - { open: '{', close: '}', notIn: ['string', 'comment'] }, - { open: '"', close: '"', notIn: ['string', 'comment'] }, - { open: 'begin', close: 'end', notIn: ['string'] } - ], - { docComment: { open: '/**', close: ' */' } } + ]) ); - assert.deepEqual(sup.getElectricCharacters(), ['}', ')', 'n', '*']); - }); - - test('auto-close', () => { - let sup = new BracketElectricCharacterSupport( - new RichEditBrackets(fakeLanguageIdentifier, [ - ['{', '}'], - ['(', ')'] - ]), [ - { open: '{', close: '}', notIn: ['string', 'comment'] }, - { open: '"', close: '"', notIn: ['string', 'comment'] }, - { open: 'begin', close: 'end', notIn: ['string'] } - ], - { docComment: { open: '/**', close: ' */' } } - ); - - testDoesNothing(sup, [], 'a', 0); - - testDoesNothing(sup, [{ text: 'egi', type: StandardTokenType.Other }], 'b', 1); - testDoesNothing(sup, [{ text: 'bgi', type: StandardTokenType.Other }], 'e', 2); - testDoesNothing(sup, [{ text: 'bei', type: StandardTokenType.Other }], 'g', 3); - testDoesNothing(sup, [{ text: 'beg', type: StandardTokenType.Other }], 'i', 4); - - testDoesNothing(sup, [{ text: 'egin', type: StandardTokenType.Other }], 'b', 1); - testDoesNothing(sup, [{ text: 'bgin', type: StandardTokenType.Other }], 'e', 2); - testDoesNothing(sup, [{ text: 'bein', type: StandardTokenType.Other }], 'g', 3); - testDoesNothing(sup, [{ text: 'begn', type: StandardTokenType.Other }], 'i', 4); - testAppends(sup, [{ text: 'begi', type: StandardTokenType.Other }], 'n', 5, 'end'); - - testDoesNothing(sup, [{ text: '3gin', type: StandardTokenType.Other }], 'b', 1); - testDoesNothing(sup, [{ text: 'bgin', type: StandardTokenType.Other }], '3', 2); - testDoesNothing(sup, [{ text: 'b3in', type: StandardTokenType.Other }], 'g', 3); - testDoesNothing(sup, [{ text: 'b3gn', type: StandardTokenType.Other }], 'i', 4); - testDoesNothing(sup, [{ text: 'b3gi', type: StandardTokenType.Other }], 'n', 5); - - testDoesNothing(sup, [{ text: 'begi', type: StandardTokenType.String }], 'n', 5); - - testAppends(sup, [{ text: '"', type: StandardTokenType.String }, { text: 'begi', type: StandardTokenType.Other }], 'n', 6, 'end'); - testDoesNothing(sup, [{ text: '"', type: StandardTokenType.String }, { text: 'begi', type: StandardTokenType.String }], 'n', 6); - - testAppends(sup, [{ text: '/*', type: StandardTokenType.String }], '*', 3, ' */'); - - testDoesNothing(sup, [{ text: 'begi', type: StandardTokenType.Other }, { text: 'end', type: StandardTokenType.Other }], 'n', 5); + assert.deepEqual(sup.getElectricCharacters(), ['}', ')']); }); test('matchOpenBracket', () => { @@ -108,12 +42,7 @@ suite('Editor Modes - Auto Indentation', () => { new RichEditBrackets(fakeLanguageIdentifier, [ ['{', '}'], ['(', ')'] - ]), [ - { open: '{', close: '}', notIn: ['string', 'comment'] }, - { open: '"', close: '"', notIn: ['string', 'comment'] }, - { open: 'begin', close: 'end', notIn: ['string'] } - ], - { docComment: { open: '/**', close: ' */' } } + ]) ); testDoesNothing(sup, [{ text: '\t{', type: StandardTokenType.Other }], '\t', 1); diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 222b9e84666..9845081a9e9 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -4561,7 +4561,9 @@ declare namespace monaco.languages { * * @deprecated Will be replaced by a better API soon. */ - __electricCharacterSupport?: IBracketElectricCharacterContribution; + __electricCharacterSupport?: { + docComment?: IDocComment; + }; } /** @@ -4636,10 +4638,6 @@ declare namespace monaco.languages { action: EnterAction; } - export interface IBracketElectricCharacterContribution { - docComment?: IDocComment; - } - /** * Definition of documentation comments (e.g. Javadoc/JSdoc) */ From 606987ec3ddc24d5ceefb41d1d0f8fa301d041f2 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 20 Aug 2019 12:35:46 +0200 Subject: [PATCH 816/861] debugSession: respect sortText fixes #78408 --- src/vs/workbench/contrib/debug/browser/debugSession.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugSession.ts b/src/vs/workbench/contrib/debug/browser/debugSession.ts index 24b9b18c788..ccee3cee540 100644 --- a/src/vs/workbench/contrib/debug/browser/debugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/debugSession.ts @@ -554,7 +554,8 @@ export class DebugSession implements IDebugSession { insertText: item.text || item.label, kind: completionKindFromString(item.type || 'property'), filterText: (item.start && item.length) ? text.substr(item.start, item.length).concat(item.label) : undefined, - range: Range.fromPositions(position.delta(0, -(item.length || overwriteBefore)), position) + range: Range.fromPositions(position.delta(0, -(item.length || overwriteBefore)), position), + sortText: item.sortText }); } }); From bb384a83e586dda0e42227d55813c7ce744fc99b Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Tue, 20 Aug 2019 12:51:49 +0200 Subject: [PATCH 817/861] Remove for-in usages (#79432) --- .../common/monarch/monarchCompile.ts | 158 ++++++++---------- .../standalone/common/monarch/monarchLexer.ts | 53 +++--- 2 files changed, 96 insertions(+), 115 deletions(-) diff --git a/src/vs/editor/standalone/common/monarch/monarchCompile.ts b/src/vs/editor/standalone/common/monarch/monarchCompile.ts index f056854e44a..2c98c6ba429 100644 --- a/src/vs/editor/standalone/common/monarch/monarchCompile.ts +++ b/src/vs/editor/standalone/common/monarch/monarchCompile.ts @@ -27,11 +27,9 @@ function isArrayOf(elemType: (x: any) => boolean, obj: any): boolean { if (!(Array.isArray(obj))) { return false; } - for (let idx in obj) { - if (obj.hasOwnProperty(idx)) { - if (!(elemType(obj[idx]))) { - return false; - } + for (const el of obj) { + if (!(elemType(el))) { + return false; } } return true; @@ -298,10 +296,8 @@ function compileAction(lexer: monarchCommon.ILexerMin, ruleName: string, action: } else if (Array.isArray(action)) { let results: monarchCommon.FuzzyAction[] = []; - for (let idx in action) { - if (action.hasOwnProperty(idx)) { - results[idx] = compileAction(lexer, ruleName, action[idx]); - } + for (let i = 0, len = action.length; i < len; i++) { + results[i] = compileAction(lexer, ruleName, action[i]); } return { group: results }; } @@ -331,13 +327,10 @@ function compileAction(lexer: monarchCommon.ILexerMin, ruleName: string, action: const def = lexer.defaultToken; return { test: function (id, matches, state, eos) { - for (let idx in cases) { - if (cases.hasOwnProperty(idx)) { - const _case = cases[idx]; - const didmatch = (!_case.test || _case.test(id, matches, state, eos)); - if (didmatch) { - return _case.value; - } + for (const _case of cases) { + const didmatch = (!_case.test || _case.test(id, matches, state, eos)); + if (didmatch) { + return _case.value; } } return def; @@ -425,64 +418,61 @@ export function compile(languageId: string, json: IMonarchLanguage): monarchComm // Compile an array of rules into newrules where RegExp objects are created. function addRules(state: string, newrules: monarchCommon.IRule[], rules: any[]) { - for (let idx in rules) { - if (rules.hasOwnProperty(idx)) { - const rule = rules[idx]; - let include = rule.include; - if (include) { - if (typeof (include) !== 'string') { - throw monarchCommon.createError(lexer, 'an \'include\' attribute must be a string at: ' + state); - } - if (include[0] === '@') { - include = include.substr(1); // peel off starting @ - } - if (!json.tokenizer[include]) { - throw monarchCommon.createError(lexer, 'include target \'' + include + '\' is not defined at: ' + state); - } - addRules(state + '.' + include, newrules, json.tokenizer[include]); + for (const rule of rules) { + + let include = rule.include; + if (include) { + if (typeof (include) !== 'string') { + throw monarchCommon.createError(lexer, 'an \'include\' attribute must be a string at: ' + state); } - else { - const newrule = new Rule(state); + if (include[0] === '@') { + include = include.substr(1); // peel off starting @ + } + if (!json.tokenizer[include]) { + throw monarchCommon.createError(lexer, 'include target \'' + include + '\' is not defined at: ' + state); + } + addRules(state + '.' + include, newrules, json.tokenizer[include]); + } + else { + const newrule = new Rule(state); - - // Set up new rule attributes - if (Array.isArray(rule) && rule.length >= 1 && rule.length <= 3) { - newrule.setRegex(lexerMin, rule[0]); - if (rule.length >= 3) { - if (typeof (rule[1]) === 'string') { - newrule.setAction(lexerMin, { token: rule[1], next: rule[2] }); - } - else if (typeof (rule[1]) === 'object') { - const rule1 = rule[1]; - rule1.next = rule[2]; - newrule.setAction(lexerMin, rule1); - } - else { - throw monarchCommon.createError(lexer, 'a next state as the last element of a rule can only be given if the action is either an object or a string, at: ' + state); - } + // Set up new rule attributes + if (Array.isArray(rule) && rule.length >= 1 && rule.length <= 3) { + newrule.setRegex(lexerMin, rule[0]); + if (rule.length >= 3) { + if (typeof (rule[1]) === 'string') { + newrule.setAction(lexerMin, { token: rule[1], next: rule[2] }); + } + else if (typeof (rule[1]) === 'object') { + const rule1 = rule[1]; + rule1.next = rule[2]; + newrule.setAction(lexerMin, rule1); } else { - newrule.setAction(lexerMin, rule[1]); + throw monarchCommon.createError(lexer, 'a next state as the last element of a rule can only be given if the action is either an object or a string, at: ' + state); } } else { - if (!rule.regex) { - throw monarchCommon.createError(lexer, 'a rule must either be an array, or an object with a \'regex\' or \'include\' field at: ' + state); - } - if (rule.name) { - if (typeof rule.name === 'string') { - newrule.name = rule.name; - } - } - if (rule.matchOnlyAtStart) { - newrule.matchOnlyAtLineStart = bool(rule.matchOnlyAtLineStart, false); - } - newrule.setRegex(lexerMin, rule.regex); - newrule.setAction(lexerMin, rule.action); + newrule.setAction(lexerMin, rule[1]); } - - newrules.push(newrule); } + else { + if (!rule.regex) { + throw monarchCommon.createError(lexer, 'a rule must either be an array, or an object with a \'regex\' or \'include\' field at: ' + state); + } + if (rule.name) { + if (typeof rule.name === 'string') { + newrule.name = rule.name; + } + } + if (rule.matchOnlyAtStart) { + newrule.matchOnlyAtLineStart = bool(rule.matchOnlyAtLineStart, false); + } + newrule.setRegex(lexerMin, rule.regex); + newrule.setAction(lexerMin, rule.action); + } + + newrules.push(newrule); } } } @@ -520,26 +510,24 @@ export function compile(languageId: string, json: IMonarchLanguage): monarchComm { open: '<', close: '>', token: 'delimiter.angle' }]; } let brackets: IMonarchLanguageBracket[] = []; - for (let bracketIdx in json.brackets) { - if (json.brackets.hasOwnProperty(bracketIdx)) { - let desc = json.brackets[bracketIdx]; - if (desc && Array.isArray(desc) && desc.length === 3) { - desc = { token: desc[2], open: desc[0], close: desc[1] }; - } - if (desc.open === desc.close) { - throw monarchCommon.createError(lexer, 'open and close brackets in a \'brackets\' attribute must be different: ' + desc.open + - '\n hint: use the \'bracket\' attribute if matching on equal brackets is required.'); - } - if (typeof desc.open === 'string' && typeof desc.token === 'string' && typeof desc.close === 'string') { - brackets.push({ - token: desc.token + lexer.tokenPostfix, - open: monarchCommon.fixCase(lexer, desc.open), - close: monarchCommon.fixCase(lexer, desc.close) - }); - } - else { - throw monarchCommon.createError(lexer, 'every element in the \'brackets\' array must be a \'{open,close,token}\' object or array'); - } + for (let el of json.brackets) { + let desc: any = el; + if (desc && Array.isArray(desc) && desc.length === 3) { + desc = { token: desc[2], open: desc[0], close: desc[1] }; + } + if (desc.open === desc.close) { + throw monarchCommon.createError(lexer, 'open and close brackets in a \'brackets\' attribute must be different: ' + desc.open + + '\n hint: use the \'bracket\' attribute if matching on equal brackets is required.'); + } + if (typeof desc.open === 'string' && typeof desc.token === 'string' && typeof desc.close === 'string') { + brackets.push({ + token: desc.token + lexer.tokenPostfix, + open: monarchCommon.fixCase(lexer, desc.open), + close: monarchCommon.fixCase(lexer, desc.close) + }); + } + else { + throw monarchCommon.createError(lexer, 'every element in the \'brackets\' array must be a \'{open,close,token}\' object or array'); } } lexer.brackets = brackets; diff --git a/src/vs/editor/standalone/common/monarch/monarchLexer.ts b/src/vs/editor/standalone/common/monarch/monarchLexer.ts index a5c97ad6f28..39642a4d6e6 100644 --- a/src/vs/editor/standalone/common/monarch/monarchLexer.ts +++ b/src/vs/editor/standalone/common/monarch/monarchLexer.ts @@ -228,8 +228,6 @@ class MonarchLineState implements modes.IState { } } -const hasOwnProperty = Object.hasOwnProperty; - interface IMonarchTokensCollector { enterMode(startOffset: number, modeId: string): void; emit(startOffset: number, type: string): void; @@ -423,22 +421,24 @@ export class MonarchTokenizer implements modes.ITokenizationSupport { public getLoadStatus(): ILoadStatus { let promises: Thenable[] = []; for (let nestedModeId in this._embeddedModes) { - const tokenizationSupport = modes.TokenizationRegistry.get(nestedModeId); - if (tokenizationSupport) { - // The nested mode is already loaded - if (tokenizationSupport instanceof MonarchTokenizer) { - const nestedModeStatus = tokenizationSupport.getLoadStatus(); - if (nestedModeStatus.loaded === false) { - promises.push(nestedModeStatus.promise); + if (this._embeddedModes.hasOwnProperty(nestedModeId)) { + const tokenizationSupport = modes.TokenizationRegistry.get(nestedModeId); + if (tokenizationSupport) { + // The nested mode is already loaded + if (tokenizationSupport instanceof MonarchTokenizer) { + const nestedModeStatus = tokenizationSupport.getLoadStatus(); + if (nestedModeStatus.loaded === false) { + promises.push(nestedModeStatus.promise); + } } + continue; } - continue; - } - const tokenizationSupportPromise = modes.TokenizationRegistry.getPromise(nestedModeId); - if (tokenizationSupportPromise) { - // The nested mode is in the process of being loaded - promises.push(tokenizationSupportPromise); + const tokenizationSupportPromise = modes.TokenizationRegistry.getPromise(nestedModeId); + if (tokenizationSupportPromise) { + // The nested mode is in the process of being loaded + promises.push(tokenizationSupportPromise); + } } } @@ -490,11 +490,7 @@ export class MonarchTokenizer implements modes.ITokenizationSupport { let popOffset = -1; let hasEmbeddedPopRule = false; - for (let idx in rules) { - if (!hasOwnProperty.call(rules, idx)) { - continue; - } - let rule: monarchCommon.IRule = rules[idx]; + for (const rule of rules) { if (!monarchCommon.isIAction(rule.action) || rule.action.nextEmbedded !== '@pop') { continue; } @@ -619,16 +615,13 @@ export class MonarchTokenizer implements modes.ITokenizationSupport { // try each rule until we match let restOfLine = line.substr(pos); - for (let idx in rules) { - if (hasOwnProperty.call(rules, idx)) { - let rule: monarchCommon.IRule = rules[idx]; - if (pos === 0 || !rule.matchOnlyAtLineStart) { - matches = restOfLine.match(rule.regex); - if (matches) { - matched = matches[0]; - action = rule.action; - break; - } + for (const rule of rules) { + if (pos === 0 || !rule.matchOnlyAtLineStart) { + matches = restOfLine.match(rule.regex); + if (matches) { + matched = matches[0]; + action = rule.action; + break; } } } From 25c9b4bf6a32ab4f233e5168c5a0d3cbded351cd Mon Sep 17 00:00:00 2001 From: Belskiy Maksim Andreevich Date: Tue, 20 Aug 2019 15:02:32 +0300 Subject: [PATCH 818/861] Polish breadcrumbs icons spacing (#79005) --- .../browser/parts/editor/media/breadcrumbscontrol.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css b/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css index d3850e29307..1e6e29ee935 100644 --- a/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css +++ b/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css @@ -17,6 +17,10 @@ text-decoration-line: underline; } +.monaco-workbench .monaco-breadcrumb-item.shows-symbol-icon .symbol-icon.block { + padding-right: 6px; +} + /* todo@joh move somewhere else */ .monaco-workbench .monaco-breadcrumbs-picker .arrow { From ea7f62fa08586faad64007fde11dfe7d281b5f6d Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Tue, 20 Aug 2019 14:28:46 +0200 Subject: [PATCH 819/861] Fixes #79496: Always go through the protocol handler --- src/vs/base/common/network.ts | 7 ++++--- src/vs/code/browser/workbench/workbench.html | 2 +- src/vs/code/electron-browser/workbench/workbench.html | 2 +- src/vs/code/electron-main/app.ts | 4 ++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/vs/base/common/network.ts b/src/vs/base/common/network.ts index bccc2153602..9c83d42dc7c 100644 --- a/src/vs/base/common/network.ts +++ b/src/vs/base/common/network.ts @@ -49,6 +49,8 @@ export namespace Schemas { export const vscodeRemote: string = 'vscode-remote'; + export const vscodeRemoteResource: string = 'vscode-remote-resource'; + export const userData: string = 'vscode-userdata'; } @@ -64,7 +66,7 @@ class RemoteAuthoritiesImpl { } public set(authority: string, host: string, port: number): void { - this._hosts[authority] = (host === 'localhost' ? '127.0.0.1' : host); + this._hosts[authority] = host; this._ports[authority] = port; } @@ -76,9 +78,8 @@ class RemoteAuthoritiesImpl { const host = this._hosts[authority]; const port = this._ports[authority]; const connectionToken = this._connectionTokens[authority]; - const scheme = (host === '127.0.0.1' ? Schemas.http : Schemas.vscodeRemote); return URI.from({ - scheme: scheme, + scheme: Schemas.vscodeRemoteResource, authority: `${host}:${port}`, path: `/vscode-remote2`, query: `path=${encodeURIComponent(path)}&tkn=${encodeURIComponent(connectionToken)}` diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index 45a9d6d13fe..8f8f45fb15f 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -10,7 +10,7 @@ + content="default-src 'none'; img-src 'self' https: data: blob:; media-src 'none'; frame-src 'self' {{WEBVIEW_ENDPOINT}} https://*.vscode-webview-test.com; script-src 'self' https://az416426.vo.msecnd.net 'unsafe-eval' https:; style-src 'self' 'unsafe-inline'; connect-src 'self' ws: wss: https:; font-src 'self' blob:;"> diff --git a/src/vs/code/electron-browser/workbench/workbench.html b/src/vs/code/electron-browser/workbench/workbench.html index bef3d951473..693082bb9ed 100644 --- a/src/vs/code/electron-browser/workbench/workbench.html +++ b/src/vs/code/electron-browser/workbench/workbench.html @@ -3,7 +3,7 @@ - + diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index d269616e1b9..6d43b392dfb 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -688,9 +688,9 @@ export class CodeApplication extends Disposable { } private handleRemoteAuthorities(): void { - protocol.registerHttpProtocol(Schemas.vscodeRemote, (request, callback) => { + protocol.registerHttpProtocol(Schemas.vscodeRemoteResource, (request, callback) => { callback({ - url: request.url.replace(/^vscode-remote:/, 'http:'), + url: request.url.replace(/^vscode-remote-resource:/, 'http:'), method: request.method }); }); From a6cc555ddafc34163bc3f1eb588004199ca680e3 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 20 Aug 2019 14:38:01 +0200 Subject: [PATCH 820/861] window.open throws --- src/vs/workbench/electron-browser/window.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index a9c2344af12..7f13270ca83 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -359,9 +359,7 @@ export class ElectronWindow extends Disposable { // Block window.open() calls const $this = this; window.open = function (): Window | null { - console.error(new Error('Prevented call to window.open(). Use IOpenerService instead!')); - - return null; + throw new Error('Prevented call to window.open(). Use IOpenerService instead!'); }; // Handle internal open() calls From 63fe017c5a4af7db96b78d7bd9ccc762ece02816 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 20 Aug 2019 14:38:42 +0200 Subject: [PATCH 821/861] make extensionService fit for running without remote connection --- .../extensions/browser/extensionService.ts | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/services/extensions/browser/extensionService.ts b/src/vs/workbench/services/extensions/browser/extensionService.ts index 59e7baf1a17..e76e4044f5f 100644 --- a/src/vs/workbench/services/extensions/browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/browser/extensionService.ts @@ -27,6 +27,7 @@ import { FetchFileSystemProvider } from 'vs/workbench/services/extensions/browse import { Schemas } from 'vs/base/common/network'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { IStaticExtensionsService } from 'vs/workbench/services/extensions/common/staticExtensions'; +import { DeltaExtensionsResult } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; export class ExtensionService extends AbstractExtensionService implements IExtensionService { @@ -81,21 +82,22 @@ export class ExtensionService extends AbstractExtensionService implements IExten }; } - protected _createExtensionHosts(isInitialStart: boolean, initialActivationEvents: string[]): ExtensionHostProcessManager[] { + protected _createExtensionHosts(_isInitialStart: boolean, initialActivationEvents: string[]): ExtensionHostProcessManager[] { const result: ExtensionHostProcessManager[] = []; - const remoteAgentConnection = this._remoteAgentService.getConnection()!; + const remoteAgentConnection = this._remoteAgentService.getConnection(); const webExtensions = this.getExtensions().then(extensions => extensions.filter(ext => isWebExtension(ext, this._configService))); - const remoteExtensions = this.getExtensions().then(extensions => extensions.filter(ext => !isWebExtension(ext, this._configService))); - const webHostProcessWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, true, webExtensions, URI.parse('empty:value')); //todo@joh - const webHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, webHostProcessWorker, remoteAgentConnection.remoteAuthority, initialActivationEvents); + const webHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, webHostProcessWorker, remoteAgentConnection ? remoteAgentConnection.remoteAuthority : null, initialActivationEvents); result.push(webHostProcessManager); - const remoteExtHostProcessWorker = this._instantiationService.createInstance(RemoteExtensionHostClient, remoteExtensions, this._createProvider(remoteAgentConnection.remoteAuthority), this._remoteAgentService.socketFactory); - const remoteExtHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, remoteExtHostProcessWorker, remoteAgentConnection.remoteAuthority, initialActivationEvents); - result.push(remoteExtHostProcessManager); + if (remoteAgentConnection) { + const remoteExtensions = this.getExtensions().then(extensions => extensions.filter(ext => !isWebExtension(ext, this._configService))); + const remoteExtHostProcessWorker = this._instantiationService.createInstance(RemoteExtensionHostClient, remoteExtensions, this._createProvider(remoteAgentConnection.remoteAuthority), this._remoteAgentService.socketFactory); + const remoteExtHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, remoteExtHostProcessWorker, remoteAgentConnection.remoteAuthority, initialActivationEvents); + result.push(remoteExtHostProcessManager); + } return result; } @@ -103,27 +105,35 @@ export class ExtensionService extends AbstractExtensionService implements IExten protected async _scanAndHandleExtensions(): Promise { // fetch the remote environment let [remoteEnv, localExtensions] = await Promise.all([ - >this._remoteAgentService.getEnvironment(), + this._remoteAgentService.getEnvironment(), this._staticExtensions.getExtensions() ]); + let result: DeltaExtensionsResult; + // local: only enabled and web'ish extension localExtensions = localExtensions.filter(ext => this._isEnabled(ext) && isWebExtension(ext, this._configService)); this._checkEnableProposedApi(localExtensions); - // remote: only enabled and none-web'ish extension - remoteEnv.extensions = remoteEnv.extensions.filter(extension => this._isEnabled(extension) && !isWebExtension(extension, this._configService)); - this._checkEnableProposedApi(remoteEnv.extensions); + if (!remoteEnv) { + result = this._registry.deltaExtensions(localExtensions, []); - // in case of overlap, the remote wins - const isRemoteExtension = new Set(); - remoteEnv.extensions.forEach(extension => isRemoteExtension.add(ExtensionIdentifier.toKey(extension.identifier))); - localExtensions = localExtensions.filter(extension => !isRemoteExtension.has(ExtensionIdentifier.toKey(extension.identifier))); + } else { + // remote: only enabled and none-web'ish extension + remoteEnv.extensions = remoteEnv.extensions.filter(extension => this._isEnabled(extension) && !isWebExtension(extension, this._configService)); + this._checkEnableProposedApi(remoteEnv.extensions); - // save for remote extension's init data - this._remoteExtensionsEnvironmentData = remoteEnv; + // in case of overlap, the remote wins + const isRemoteExtension = new Set(); + remoteEnv.extensions.forEach(extension => isRemoteExtension.add(ExtensionIdentifier.toKey(extension.identifier))); + localExtensions = localExtensions.filter(extension => !isRemoteExtension.has(ExtensionIdentifier.toKey(extension.identifier))); + + // save for remote extension's init data + this._remoteExtensionsEnvironmentData = remoteEnv; + + result = this._registry.deltaExtensions(remoteEnv.extensions.concat(localExtensions), []); + } - const result = this._registry.deltaExtensions(remoteEnv.extensions.concat(localExtensions), []); if (result.removedDueToLooping.length > 0) { this._logOrShowMessage(Severity.Error, nls.localize('looping', "The following extensions contain dependency loops and have been disabled: {0}", result.removedDueToLooping.map(e => `'${e.identifier.value}'`).join(', '))); } From 26a8fa55d40a7748678b61b5e0aee3e2671d3275 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 20 Aug 2019 15:12:41 +0200 Subject: [PATCH 822/861] debug: data breakpoints that can not be persisted should be cleared when a session ends --- src/vs/workbench/contrib/debug/browser/debugService.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugService.ts b/src/vs/workbench/contrib/debug/browser/debugService.ts index 8b139d2a3e3..7a0b0fe82c4 100644 --- a/src/vs/workbench/contrib/debug/browser/debugService.ts +++ b/src/vs/workbench/contrib/debug/browser/debugService.ts @@ -404,7 +404,7 @@ export class DebugService implements IDebugService { .then(() => false); } - return launch && launch.openConfigFile(false, true, undefined, this.initCancellationToken ? this.initCancellationToken.token : undefined).then(() => false); + return !!launch && launch.openConfigFile(false, true, undefined, this.initCancellationToken ? this.initCancellationToken.token : undefined).then(() => false); }); } @@ -542,6 +542,10 @@ export class DebugService implements IDebugService { if (this.layoutService.isVisible(Parts.SIDEBAR_PART) && this.configurationService.getValue('debug').openExplorerOnEnd) { this.viewletService.openViewlet(EXPLORER_VIEWLET_ID); } + + // Data breakpoints that can not be persisted should be cleared when a session ends + const dataBreakpoints = this.model.getDataBreakpoints().filter(dbp => !dbp.canPersist); + dataBreakpoints.forEach(dbp => this.model.removeDataBreakpoints(dbp.getId())); } })); From ba00f5ff80cfdc7ae94c3bc74b897a9767ffd018 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Tue, 20 Aug 2019 15:14:55 +0200 Subject: [PATCH 823/861] Folding last item inside #region hides all blank lines up to #endregion Fixes #79359 --- .../contrib/folding/indentRangeProvider.ts | 31 ++++++++++++------- .../folding/test/indentRangeProvider.test.ts | 14 ++++++++- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/vs/editor/contrib/folding/indentRangeProvider.ts b/src/vs/editor/contrib/folding/indentRangeProvider.ts index f13ed98e9af..68a3a366faa 100644 --- a/src/vs/editor/contrib/folding/indentRangeProvider.ts +++ b/src/vs/editor/contrib/folding/indentRangeProvider.ts @@ -105,7 +105,11 @@ export class RangesCollector { } -interface PreviousRegion { indent: number; line: number; marker: boolean; } +interface PreviousRegion { + indent: number; // indent or -2 if a marker + endAbove: number; // end line number for the region above + line: number; // start line of the region. Only used for marker regions. +} export function computeRanges(model: ITextModel, offSide: boolean, markers?: FoldingMarkers, foldingRangesLimit = MAX_FOLDING_REGIONS_FOR_INDENT_LIMIT): FoldingRegions { const tabSize = model.getOptions().tabSize; @@ -117,16 +121,19 @@ export function computeRanges(model: ITextModel, offSide: boolean, markers?: Fol } let previousRegions: PreviousRegion[] = []; - previousRegions.push({ indent: -1, line: model.getLineCount() + 1, marker: false }); // sentinel, to make sure there's at least one entry + let line = model.getLineCount() + 1; + previousRegions.push({ indent: -1, endAbove: line, line }); // sentinel, to make sure there's at least one entry for (let line = model.getLineCount(); line > 0; line--) { let lineContent = model.getLineContent(line); let indent = TextModel.computeIndentLevel(lineContent, tabSize); let previous = previousRegions[previousRegions.length - 1]; if (indent === -1) { - if (offSide && !previous.marker) { - // for offSide languages, empty lines are associated to the next block - previous.line = line; + if (offSide) { + // for offSide languages, empty lines are associated to the previous block + // note: the next block is already written to the results, so this only + // impacts the end position of the block before + previous.endAbove = line; } continue; // only whitespace } @@ -136,7 +143,7 @@ export function computeRanges(model: ITextModel, offSide: boolean, markers?: Fol if (m[1]) { // start pattern match // discard all regions until the folding pattern let i = previousRegions.length - 1; - while (i > 0 && !previousRegions[i].marker) { + while (i > 0 && previousRegions[i].indent !== -2) { i--; } if (i > 0) { @@ -145,15 +152,15 @@ export function computeRanges(model: ITextModel, offSide: boolean, markers?: Fol // new folding range from pattern, includes the end line result.insertFirst(line, previous.line, indent); - previous.marker = false; - previous.indent = indent; previous.line = line; + previous.indent = indent; + previous.endAbove = line; continue; } else { // no end marker found, treat line as a regular line } } else { // end pattern match - previousRegions.push({ indent: -2, line, marker: true }); + previousRegions.push({ indent: -2, endAbove: line, line }); continue; } } @@ -165,16 +172,16 @@ export function computeRanges(model: ITextModel, offSide: boolean, markers?: Fol } while (previous.indent > indent); // new folding range - let endLineNumber = previous.line - 1; + let endLineNumber = previous.endAbove - 1; if (endLineNumber - line >= 1) { // needs at east size 1 result.insertFirst(line, endLineNumber, indent); } } if (previous.indent === indent) { - previous.line = line; + previous.endAbove = line; } else { // previous.indent < indent // new region with a bigger indent - previousRegions.push({ indent, line, marker: false }); + previousRegions.push({ indent, endAbove: line, line }); } } return result.toIndentRanges(model); diff --git a/src/vs/editor/contrib/folding/test/indentRangeProvider.test.ts b/src/vs/editor/contrib/folding/test/indentRangeProvider.test.ts index 882c097104d..07e20256667 100644 --- a/src/vs/editor/contrib/folding/test/indentRangeProvider.test.ts +++ b/src/vs/editor/contrib/folding/test/indentRangeProvider.test.ts @@ -316,5 +316,17 @@ suite('Folding with regions', () => { /* 8*/ '#endregionff', ], [], true, markers); }); - + test('Issue 79359', () => { + assertRanges([ + /* 1*/ '#region', + /* 2*/ '', + /* 3*/ 'class A', + /* 4*/ ' foo', + /* 5*/ '', + /* 6*/ 'class A', + /* 7*/ ' foo', + /* 8*/ '', + /* 9*/ '#endregion', + ], [r(1, 9, -1, true), r(3, 4, 0), r(6, 7, 0)], true, markers); + }); }); From e1f96ca53fb2e7210fdb2008c64414cf1b2d5917 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 20 Aug 2019 15:35:15 +0200 Subject: [PATCH 824/861] debug: refresh variables when selection added to repl fixes #78299 --- .../contrib/debug/browser/debugEditorActions.ts | 7 +++---- .../workbench/contrib/debug/browser/debugSession.ts | 12 +++++++----- src/vs/workbench/contrib/debug/browser/repl.ts | 3 +-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts b/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts index bf802266912..b7f89249ad9 100644 --- a/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts +++ b/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts @@ -169,7 +169,7 @@ class SelectionToReplAction extends EditorAction { }); } - public run(accessor: ServicesAccessor, editor: ICodeEditor): Promise { + public async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise { const debugService = accessor.get(IDebugService); const panelService = accessor.get(IPanelService); const viewModel = debugService.getViewModel(); @@ -179,9 +179,8 @@ class SelectionToReplAction extends EditorAction { } const text = editor.getModel().getValueInRange(editor.getSelection()); - return session.addReplExpression(viewModel.focusedStackFrame!, text) - .then(() => panelService.openPanel(REPL_ID, true)) - .then(_ => undefined); + await session.addReplExpression(viewModel.focusedStackFrame!, text); + await panelService.openPanel(REPL_ID, true); } } diff --git a/src/vs/workbench/contrib/debug/browser/debugSession.ts b/src/vs/workbench/contrib/debug/browser/debugSession.ts index ccee3cee540..01151248238 100644 --- a/src/vs/workbench/contrib/debug/browser/debugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/debugSession.ts @@ -32,6 +32,7 @@ import { ReplModel } from 'vs/workbench/contrib/debug/common/replModel'; import { onUnexpectedError } from 'vs/base/common/errors'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { variableSetEmitter } from 'vs/workbench/contrib/debug/browser/variablesView'; export class DebugSession implements IDebugSession { @@ -906,12 +907,13 @@ export class DebugSession implements IDebugSession { this._onDidChangeREPLElements.fire(); } - addReplExpression(stackFrame: IStackFrame | undefined, name: string): Promise { + async addReplExpression(stackFrame: IStackFrame | undefined, name: string): Promise { const viewModel = this.debugService.getViewModel(); - return this.repl.addReplExpression(stackFrame, name) - .then(() => this._onDidChangeREPLElements.fire()) - // Evaluate all watch expressions and fetch variables again since repl evaluation might have changed some. - .then(() => this.debugService.focusStackFrame(viewModel.focusedStackFrame, viewModel.focusedThread, viewModel.focusedSession)); + await this.repl.addReplExpression(stackFrame, name); + this._onDidChangeREPLElements.fire(); + // Evaluate all watch expressions and fetch variables again since repl evaluation might have changed some. + this.debugService.focusStackFrame(viewModel.focusedStackFrame, viewModel.focusedThread, viewModel.focusedSession); + variableSetEmitter.fire(); } appendToRepl(data: string | IExpression, severity: severity, source?: IReplElementSource): void { diff --git a/src/vs/workbench/contrib/debug/browser/repl.ts b/src/vs/workbench/contrib/debug/browser/repl.ts index 2328778efd0..0fe9ac036b1 100644 --- a/src/vs/workbench/contrib/debug/browser/repl.ts +++ b/src/vs/workbench/contrib/debug/browser/repl.ts @@ -62,7 +62,7 @@ import { RunOnceScheduler } from 'vs/base/common/async'; import { FuzzyScore, createMatches } from 'vs/base/common/filters'; import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; -import { VariablesRenderer, variableSetEmitter } from 'vs/workbench/contrib/debug/browser/variablesView'; +import { VariablesRenderer } from 'vs/workbench/contrib/debug/browser/variablesView'; const $ = dom.$; @@ -301,7 +301,6 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati revealLastElement(this.tree); this.history.add(this.replInput.getValue()); this.replInput.setValue(''); - variableSetEmitter.fire(); const shouldRelayout = this.replInputHeight > Repl.REPL_INPUT_INITIAL_HEIGHT; this.replInputHeight = Repl.REPL_INPUT_INITIAL_HEIGHT; if (shouldRelayout) { From 71c1fe1f3fd7d9c3b9dbb8abcedd370605659de4 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 20 Aug 2019 15:39:22 +0200 Subject: [PATCH 825/861] fix #79469 --- src/vs/workbench/browser/labels.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/labels.ts b/src/vs/workbench/browser/labels.ts index 7216a12b82f..35a19a119b4 100644 --- a/src/vs/workbench/browser/labels.ts +++ b/src/vs/workbench/browser/labels.ts @@ -321,14 +321,17 @@ class ResourceLabelWidget extends IconLabel { } setResource(label: IResourceLabelProps, options?: IResourceLabelOptions): void { + const hasPathLabelChanged = this.hasPathLabelChanged(label, options); + const clearIconCache = this.clearIconCache(label, options); + this.label = label; this.options = options; - if (this.hasPathLabelChanged(label, options)) { + if (hasPathLabelChanged) { this.computedPathLabel = undefined; // reset path label due to resource change } - this.render(this.clearIconCache(label, options)); + this.render(clearIconCache); } private clearIconCache(newLabel: IResourceLabelProps, newOptions?: IResourceLabelOptions): boolean { @@ -457,6 +460,7 @@ class ResourceLabelWidget extends IconLabel { } iconLabelOptions.extraClasses = this.computedIconClasses.slice(0); } + if (this.options && this.options.extraClasses) { iconLabelOptions.extraClasses!.push(...this.options.extraClasses); } From d746dccedab9233d24f1cac2e131e8aca8b4d263 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 20 Aug 2019 15:55:56 +0200 Subject: [PATCH 826/861] fix #79501 --- .../browser/parts/notifications/media/notificationsActions.css | 2 +- .../browser/parts/notifications/media/notificationsList.css | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/notifications/media/notificationsActions.css b/src/vs/workbench/browser/parts/notifications/media/notificationsActions.css index d5b23828af9..7f59f8471fb 100644 --- a/src/vs/workbench/browser/parts/notifications/media/notificationsActions.css +++ b/src/vs/workbench/browser/parts/notifications/media/notificationsActions.css @@ -66,4 +66,4 @@ .vs .monaco-workbench > .notifications-center > .notifications-center-header .hide-all-notifications-action { background-image: url('tree-expanded-light.svg'); -} \ No newline at end of file +} diff --git a/src/vs/workbench/browser/parts/notifications/media/notificationsList.css b/src/vs/workbench/browser/parts/notifications/media/notificationsList.css index f97e52b3507..719b6265b00 100644 --- a/src/vs/workbench/browser/parts/notifications/media/notificationsList.css +++ b/src/vs/workbench/browser/parts/notifications/media/notificationsList.css @@ -91,6 +91,7 @@ .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container { display: none; + height: 22px; } .monaco-workbench .notifications-list-container .notification-list-item:hover .notification-list-item-toolbar-container, @@ -142,4 +143,4 @@ .monaco-workbench .notifications-list-container .progress-bit { height: 2px; bottom: 0; -} \ No newline at end of file +} From 3d5238589ece772a028a79611422a92f0f6caea7 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 20 Aug 2019 16:06:50 +0200 Subject: [PATCH 827/861] debounce outline requests based on average reply duration, #77096 --- .../contrib/documentSymbols/outlineModel.ts | 48 +++++++++++++++++-- .../browser/parts/editor/breadcrumbsModel.ts | 11 ++++- .../contrib/outline/browser/outlinePanel.ts | 3 +- 3 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/vs/editor/contrib/documentSymbols/outlineModel.ts b/src/vs/editor/contrib/documentSymbols/outlineModel.ts index 180b0d5a55c..e5004629993 100644 --- a/src/vs/editor/contrib/documentSymbols/outlineModel.ts +++ b/src/vs/editor/contrib/documentSymbols/outlineModel.ts @@ -202,16 +202,33 @@ export class OutlineGroup extends TreeElement { } } +class MovingAverage { + + private _n = 1; + private _val = 0; + + update(value: number): this { + this._val = this._val + (value - this._val) / this._n; + this._n += 1; + return this; + } + + get value(): number { + return this._val; + } +} + export class OutlineModel extends TreeElement { + private static readonly _requestDurations = new LRUCache(50, 0.7); private static readonly _requests = new LRUCache, model: OutlineModel | undefined }>(9, 0.75); private static readonly _keys = new class { private _counter = 1; private _data = new WeakMap(); - for(textModel: ITextModel): string { - return `${textModel.id}/${textModel.getVersionId()}/${this._hash(DocumentSymbolProviderRegistry.all(textModel))}`; + for(textModel: ITextModel, version: boolean): string { + return `${textModel.id}/${version ? textModel.getVersionId() : ''}/${this._hash(DocumentSymbolProviderRegistry.all(textModel))}`; } private _hash(providers: DocumentSymbolProvider[]): string { @@ -231,7 +248,7 @@ export class OutlineModel extends TreeElement { static create(textModel: ITextModel, token: CancellationToken): Promise { - let key = this._keys.for(textModel); + let key = this._keys.for(textModel, true); let data = OutlineModel._requests.get(key); if (!data) { @@ -243,6 +260,18 @@ export class OutlineModel extends TreeElement { model: undefined, }; OutlineModel._requests.set(key, data); + + // keep moving average of request durations + const now = Date.now(); + data.promise.then(() => { + let key = this._keys.for(textModel, false); + let avg = this._requestDurations.get(key); + if (!avg) { + avg = new MovingAverage(); + this._requestDurations.set(key, avg); + } + avg.update(Date.now() - now); + }); } if (data!.model) { @@ -272,7 +301,18 @@ export class OutlineModel extends TreeElement { }); } - static _create(textModel: ITextModel, token: CancellationToken): Promise { + static getRequestDelay(textModel: ITextModel | null): number { + if (!textModel) { + return 350; + } + const avg = this._requestDurations.get(this._keys.for(textModel, false)); + if (!avg) { + return 350; + } + return Math.max(350, Math.floor(1.3 * avg.value)); + } + + private static _create(textModel: ITextModel, token: CancellationToken): Promise { const cts = new CancellationTokenSource(token); const result = new OutlineModel(textModel); diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts index 1c4f92cd459..43faa87a617 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts @@ -133,11 +133,18 @@ export class EditorBreadcrumbsModel { if (!this._editor) { return; } - // update as model changes + // update as language, model, providers changes this._disposables.push(DocumentSymbolProviderRegistry.onDidChange(_ => this._updateOutline())); this._disposables.push(this._editor.onDidChangeModel(_ => this._updateOutline())); this._disposables.push(this._editor.onDidChangeModelLanguage(_ => this._updateOutline())); - this._disposables.push(Event.debounce(this._editor.onDidChangeModelContent, _ => _, 350)(_ => this._updateOutline(true))); + + // update soon'ish as model content change + const updateSoon = new TimeoutTimer(); + this._disposables.push(updateSoon); + this._disposables.push(this._editor.onDidChangeModelContent(_ => { + const timeout = OutlineModel.getRequestDelay(this._editor!.getModel()); + updateSoon.cancelAndSet(() => this._updateOutline(true), timeout); + })); this._updateOutline(); // stop when editor dies diff --git a/src/vs/workbench/contrib/outline/browser/outlinePanel.ts b/src/vs/workbench/contrib/outline/browser/outlinePanel.ts index 00152554349..90dfc9732bf 100644 --- a/src/vs/workbench/contrib/outline/browser/outlinePanel.ts +++ b/src/vs/workbench/contrib/outline/browser/outlinePanel.ts @@ -122,7 +122,8 @@ class RequestOracle { let handle: any; let contentListener = codeEditor.onDidChangeModelContent(event => { clearTimeout(handle); - handle = setTimeout(() => this._callback(codeEditor!, event), 350); + const timeout = OutlineModel.getRequestDelay(codeEditor!.getModel()); + handle = setTimeout(() => this._callback(codeEditor!, event), timeout); }); let modeListener = codeEditor.onDidChangeModelLanguage(_ => { this._callback(codeEditor!, undefined); From ed576d082aa9b8a8f252db5ccb0361898541aec0 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 20 Aug 2019 16:19:56 +0200 Subject: [PATCH 828/861] no remote authority for worker process manager --- .../services/extensions/browser/extensionService.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/services/extensions/browser/extensionService.ts b/src/vs/workbench/services/extensions/browser/extensionService.ts index e76e4044f5f..78076e31480 100644 --- a/src/vs/workbench/services/extensions/browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/browser/extensionService.ts @@ -85,13 +85,12 @@ export class ExtensionService extends AbstractExtensionService implements IExten protected _createExtensionHosts(_isInitialStart: boolean, initialActivationEvents: string[]): ExtensionHostProcessManager[] { const result: ExtensionHostProcessManager[] = []; - const remoteAgentConnection = this._remoteAgentService.getConnection(); - const webExtensions = this.getExtensions().then(extensions => extensions.filter(ext => isWebExtension(ext, this._configService))); const webHostProcessWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, true, webExtensions, URI.parse('empty:value')); //todo@joh - const webHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, webHostProcessWorker, remoteAgentConnection ? remoteAgentConnection.remoteAuthority : null, initialActivationEvents); + const webHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, webHostProcessWorker, null, initialActivationEvents); result.push(webHostProcessManager); + const remoteAgentConnection = this._remoteAgentService.getConnection(); if (remoteAgentConnection) { const remoteExtensions = this.getExtensions().then(extensions => extensions.filter(ext => !isWebExtension(ext, this._configService))); const remoteExtHostProcessWorker = this._instantiationService.createInstance(RemoteExtensionHostClient, remoteExtensions, this._createProvider(remoteAgentConnection.remoteAuthority), this._remoteAgentService.socketFactory); From bab821e05833a2136f8243a867faeb11db288ba8 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 20 Aug 2019 16:24:04 +0200 Subject: [PATCH 829/861] Make custom tree view registration wait until extensions are registered --- .../api/browser/mainThreadTreeViews.ts | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTreeViews.ts b/src/vs/workbench/api/browser/mainThreadTreeViews.ts index 3e42831d23f..3c2e1c70801 100644 --- a/src/vs/workbench/api/browser/mainThreadTreeViews.ts +++ b/src/vs/workbench/api/browser/mainThreadTreeViews.ts @@ -11,6 +11,7 @@ import { distinct } from 'vs/base/common/arrays'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { isUndefinedOrNull, isNumber } from 'vs/base/common/types'; import { Registry } from 'vs/platform/registry/common/platform'; +import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; @extHostNamedCustomer(MainContext.MainThreadTreeViews) export class MainThreadTreeViews extends Disposable implements MainThreadTreeViewsShape { @@ -21,25 +22,28 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie constructor( extHostContext: IExtHostContext, @IViewsService private readonly viewsService: IViewsService, - @INotificationService private readonly notificationService: INotificationService + @INotificationService private readonly notificationService: INotificationService, + @IExtensionService private readonly extensionService: IExtensionService ) { super(); this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTreeViews); } $registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean, canSelectMany: boolean }): void { - const dataProvider = new TreeViewDataProvider(treeViewId, this._proxy, this.notificationService); - this._dataProviders.set(treeViewId, dataProvider); - const viewer = this.getTreeView(treeViewId); - if (viewer) { - viewer.dataProvider = dataProvider; - viewer.showCollapseAllAction = !!options.showCollapseAll; - viewer.canSelectMany = !!options.canSelectMany; - this.registerListeners(treeViewId, viewer); - this._proxy.$setVisible(treeViewId, viewer.visible); - } else { - this.notificationService.error('No view is registered with id: ' + treeViewId); - } + this.extensionService.whenInstalledExtensionsRegistered().then(() => { + const dataProvider = new TreeViewDataProvider(treeViewId, this._proxy, this.notificationService); + this._dataProviders.set(treeViewId, dataProvider); + const viewer = this.getTreeView(treeViewId); + if (viewer) { + viewer.dataProvider = dataProvider; + viewer.showCollapseAllAction = !!options.showCollapseAll; + viewer.canSelectMany = !!options.canSelectMany; + this.registerListeners(treeViewId, viewer); + this._proxy.$setVisible(treeViewId, viewer.visible); + } else { + this.notificationService.error('No view is registered with id: ' + treeViewId); + } + }); } $reveal(treeViewId: string, item: ITreeItem, parentChain: ITreeItem[], options: IRevealOptions): Promise { From c763a0e5bc519e0728b4b956dba2380e458faf50 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 20 Aug 2019 16:47:56 +0200 Subject: [PATCH 830/861] goto line announce column #78220 --- .../contrib/quickopen/browser/gotoLineHandler.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/quickopen/browser/gotoLineHandler.ts b/src/vs/workbench/contrib/quickopen/browser/gotoLineHandler.ts index 724509b2d05..19e76cbf3b7 100644 --- a/src/vs/workbench/contrib/quickopen/browser/gotoLineHandler.ts +++ b/src/vs/workbench/contrib/quickopen/browser/gotoLineHandler.ts @@ -99,18 +99,17 @@ class GotoLineEntry extends EditorQuickOpenEntry { if (this.editorService.activeTextEditorWidget && this.invalidRange(maxLineNumber)) { const position = this.editorService.activeTextEditorWidget.getPosition(); if (position) { - const currentLine = position.lineNumber; if (maxLineNumber > 0) { - return nls.localize('gotoLineLabelEmptyWithLimit', "Current Line: {0}. Type a line number between 1 and {1} to navigate to.", currentLine, maxLineNumber); + return nls.localize('gotoLineLabelEmptyWithLimit', "Current Line: {0}, Column: {1}. Type a line number between 1 and {2} to navigate to.", position.lineNumber, position.column, maxLineNumber); } - return nls.localize('gotoLineLabelEmpty', "Current Line: {0}. Type a line number to navigate to.", currentLine); + return nls.localize('gotoLineLabelEmpty', "Current Line: {0}, Column: {1}. Type a line number to navigate to.", position.lineNumber, position.column); } } // Input valid, indicate action - return this.column ? nls.localize('gotoLineColumnLabel', "Go to line {0} and character {1}.", this.line, this.column) : nls.localize('gotoLineLabel', "Go to line {0}.", this.line); + return this.column ? nls.localize('gotoLineColumnLabel', "Go to line {0} and column {1}.", this.line, this.column) : nls.localize('gotoLineLabel', "Go to line {0}.", this.line); } private invalidRange(maxLineNumber: number = this.getMaxLineNumber()): boolean { @@ -229,8 +228,7 @@ export class GotoLineHandler extends QuickOpenHandler { if (this.editorService.activeTextEditorWidget) { const position = this.editorService.activeTextEditorWidget.getPosition(); if (position) { - const currentLine = position.lineNumber; - return nls.localize('gotoLineLabelEmpty', "Current Line: {0}. Type a line number to navigate to.", currentLine); + return nls.localize('gotoLineLabelEmpty', "Current Line: {0}, Column: {1}. Type a line number to navigate to.", position.lineNumber, position.column); } } From 0cec0816d0c69782c402d20d91ab6a62626be00f Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 20 Aug 2019 17:09:46 +0200 Subject: [PATCH 831/861] debt - use DisposableStore --- .../browser/parts/editor/breadcrumbsModel.ts | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts index 43faa87a617..73b3e5f7664 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsModel.ts @@ -9,7 +9,7 @@ import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { size } from 'vs/base/common/collections'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; -import { dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { DisposableStore } from 'vs/base/common/lifecycle'; import { isEqual, dirname } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; @@ -36,14 +36,14 @@ type FileInfo = { path: FileElement[], folder?: IWorkspaceFolder }; export class EditorBreadcrumbsModel { - private readonly _disposables: IDisposable[] = []; + private readonly _disposables = new DisposableStore(); private readonly _fileInfo: FileInfo; private readonly _cfgFilePath: BreadcrumbsConfig<'on' | 'off' | 'last'>; private readonly _cfgSymbolPath: BreadcrumbsConfig<'on' | 'off' | 'last'>; private _outlineElements: Array = []; - private _outlineDisposables: IDisposable[] = []; + private _outlineDisposables = new DisposableStore(); private _onDidUpdate = new Emitter(); readonly onDidUpdate: Event = this._onDidUpdate.event; @@ -58,8 +58,8 @@ export class EditorBreadcrumbsModel { this._cfgFilePath = BreadcrumbsConfig.FilePath.bindTo(configurationService); this._cfgSymbolPath = BreadcrumbsConfig.SymbolPath.bindTo(configurationService); - this._disposables.push(this._cfgFilePath.onDidChange(_ => this._onDidUpdate.fire(this))); - this._disposables.push(this._cfgSymbolPath.onDidChange(_ => this._onDidUpdate.fire(this))); + this._disposables.add(this._cfgFilePath.onDidChange(_ => this._onDidUpdate.fire(this))); + this._disposables.add(this._cfgSymbolPath.onDidChange(_ => this._onDidUpdate.fire(this))); this._fileInfo = EditorBreadcrumbsModel._initFilePathInfo(this._uri, workspaceService); this._bindToEditor(); @@ -69,7 +69,7 @@ export class EditorBreadcrumbsModel { dispose(): void { this._cfgFilePath.dispose(); this._cfgSymbolPath.dispose(); - dispose(this._disposables); + this._disposables.dispose(); } isRelative(): boolean { @@ -134,26 +134,26 @@ export class EditorBreadcrumbsModel { return; } // update as language, model, providers changes - this._disposables.push(DocumentSymbolProviderRegistry.onDidChange(_ => this._updateOutline())); - this._disposables.push(this._editor.onDidChangeModel(_ => this._updateOutline())); - this._disposables.push(this._editor.onDidChangeModelLanguage(_ => this._updateOutline())); + this._disposables.add(DocumentSymbolProviderRegistry.onDidChange(_ => this._updateOutline())); + this._disposables.add(this._editor.onDidChangeModel(_ => this._updateOutline())); + this._disposables.add(this._editor.onDidChangeModelLanguage(_ => this._updateOutline())); // update soon'ish as model content change const updateSoon = new TimeoutTimer(); - this._disposables.push(updateSoon); - this._disposables.push(this._editor.onDidChangeModelContent(_ => { + this._disposables.add(updateSoon); + this._disposables.add(this._editor.onDidChangeModelContent(_ => { const timeout = OutlineModel.getRequestDelay(this._editor!.getModel()); updateSoon.cancelAndSet(() => this._updateOutline(true), timeout); })); this._updateOutline(); // stop when editor dies - this._disposables.push(this._editor.onDidDispose(() => this._outlineDisposables = dispose(this._outlineDisposables))); + this._disposables.add(this._editor.onDidDispose(() => this._outlineDisposables.clear())); } private _updateOutline(didChangeContent?: boolean): void { - this._outlineDisposables = dispose(this._outlineDisposables); + this._outlineDisposables.clear(); if (!didChangeContent) { this._updateOutlineElements([]); } @@ -169,7 +169,7 @@ export class EditorBreadcrumbsModel { const versionIdThen = buffer.getVersionId(); const timeout = new TimeoutTimer(); - this._outlineDisposables.push({ + this._outlineDisposables.add({ dispose: () => { source.cancel(); source.dispose(); @@ -187,7 +187,7 @@ export class EditorBreadcrumbsModel { model = model.adopt(); this._updateOutlineElements(this._getOutlineElements(model, editor.getPosition())); - this._outlineDisposables.push(editor.onDidChangeCursorPosition(_ => { + this._outlineDisposables.add(editor.onDidChangeCursorPosition(_ => { timeout.cancelAndSet(() => { if (!buffer.isDisposed() && versionIdThen === buffer.getVersionId() && editor.getModel()) { this._updateOutlineElements(this._getOutlineElements(model, editor.getPosition())); From d0e60e01add52d2ed931be5e17d0a3f1d09a8805 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 20 Aug 2019 17:30:57 +0200 Subject: [PATCH 832/861] fixes #77063 --- src/vs/workbench/contrib/debug/browser/repl.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/debug/browser/repl.ts b/src/vs/workbench/contrib/debug/browser/repl.ts index 0fe9ac036b1..96bb2f8da9d 100644 --- a/src/vs/workbench/contrib/debug/browser/repl.ts +++ b/src/vs/workbench/contrib/debug/browser/repl.ts @@ -444,6 +444,7 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati private createReplInput(container: HTMLElement): void { this.replInputContainer = dom.append(container, $('.repl-input-wrapper')); + this.replInputContainer.title = nls.localize('debugConsole', "Debug Console"); const { scopedContextKeyService, historyNavigationEnablement } = createAndBindHistoryNavigationWidgetScopedContextKeyService(this.contextKeyService, { target: this.replInputContainer, historyNavigator: this }); this.historyNavigationEnablement = historyNavigationEnablement; From 78d48a09cda49d4e4fc6462432457a4a21986867 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 20 Aug 2019 17:37:29 +0200 Subject: [PATCH 833/861] Get recently opened --- src/vs/workbench/api/common/apiCommands.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/api/common/apiCommands.ts b/src/vs/workbench/api/common/apiCommands.ts index 0c5b098cd6a..28bbc68d9bf 100644 --- a/src/vs/workbench/api/common/apiCommands.ts +++ b/src/vs/workbench/api/common/apiCommands.ts @@ -175,6 +175,11 @@ CommandsRegistry.registerCommand('_workbench.addToRecentlyOpened', async functio return windowService.addRecentlyOpened([recent]); }); +CommandsRegistry.registerCommand('_workbench.getRecentlyOpened', async function (accessor: ServicesAccessor) { + const windowService = accessor.get(IWindowService); + return windowService.getRecentlyOpened(); +}); + export class SetEditorLayoutAPICommand { public static ID = 'vscode.setEditorLayout'; public static execute(executor: ICommandsExecutor, layout: EditorGroupLayout): Promise { @@ -205,4 +210,4 @@ CommandsRegistry.registerCommand({ } }] } -}); \ No newline at end of file +}); From f9ee50e910f10a2259098b6ee992a4cdd7051b1d Mon Sep 17 00:00:00 2001 From: skprabhanjan Date: Tue, 20 Aug 2019 21:16:13 +0530 Subject: [PATCH 834/861] Added try catch for CustomEvent treated as MouseEvent --- .../electron-browser/webviewElement.ts | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts index 68ad466ee19..ce80556e0d6 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts @@ -327,12 +327,19 @@ export class ElectronWebviewBasedWebview extends Disposable implements Webview { { const rawEvent = event.args[0]; const bounds = this._webview.getBoundingClientRect(); - window.dispatchEvent(new MouseEvent(rawEvent.type, { - ...rawEvent, - clientX: rawEvent.clientX + bounds.left, - clientY: rawEvent.clientY + bounds.top, - })); - return; + try { + window.dispatchEvent(new MouseEvent(rawEvent.type, { + ...rawEvent, + clientX: rawEvent.clientX + bounds.left, + clientY: rawEvent.clientY + bounds.top, + })); + return; + } + catch (TypeError) { + //CustomEvent was treated as MouseEvent - https://github.com/microsoft/vscode/issues/78915 + return; + } + } case 'did-set-content': From 3dcdba53d62f7fa37a7c51a09202903dff8ad577 Mon Sep 17 00:00:00 2001 From: skprabhanjan Date: Tue, 20 Aug 2019 21:22:31 +0530 Subject: [PATCH 835/861] Changed comment message --- .../contrib/webview/electron-browser/webviewElement.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts index ce80556e0d6..830fd2effc8 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts @@ -336,7 +336,7 @@ export class ElectronWebviewBasedWebview extends Disposable implements Webview { return; } catch (TypeError) { - //CustomEvent was treated as MouseEvent - https://github.com/microsoft/vscode/issues/78915 + // CustomEvent was treated as MouseEvent so don't do anything - https://github.com/microsoft/vscode/issues/78915 return; } From 0f7db00b939f9c28ccf9fab8c9d2eb12165c714e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 20 Aug 2019 09:45:54 -0700 Subject: [PATCH 836/861] Add experimental terminal title event option This lets you use \[\033]0;\w\a\] in PS1 to set the dropdown value to the cwd for example Part of #22325 --- .../terminal/browser/terminal.contribution.ts | 5 ++ .../terminal/browser/terminalActions.ts | 4 +- .../terminal/browser/terminalInstance.ts | 58 +++++++++++++------ .../contrib/terminal/common/terminal.ts | 12 +++- .../contrib/terminal/node/terminalRemote.ts | 4 +- .../terminal/node/windowsShellHelper.ts | 4 +- 6 files changed, 61 insertions(+), 26 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts index 2a343f63b05..99c526eedca 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts @@ -298,6 +298,11 @@ configurationRegistry.registerConfiguration({ description: nls.localize('terminal.integrated.experimentalRefreshOnResume', "An experimental setting that will refresh the terminal renderer when the system is resumed."), type: 'boolean', default: false + }, + 'terminal.integrated.experimentalUseTitleEvent': { + description: nls.localize('terminal.integrated.experimentalUseTitleEvent', "An experimental setting that will use the terminal title event for the dropdown title. This setting will only apply to new terminals."), + type: 'boolean', + default: false } } }); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 4d07f85dc15..2492bd58041 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import { Action, IAction } from 'vs/base/common/actions'; import { EndOfLinePreference } from 'vs/editor/common/model'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; -import { ITerminalService, TERMINAL_PANEL_ID, ITerminalInstance, Direction, ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalService, TERMINAL_PANEL_ID, ITerminalInstance, Direction, ITerminalConfigHelper, TitleEventSource } from 'vs/workbench/contrib/terminal/common/terminal'; import { SelectActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar'; import { TogglePanelAction } from 'vs/workbench/browser/panel'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; @@ -1034,7 +1034,7 @@ export class RenameTerminalAction extends Action { prompt: nls.localize('workbench.action.terminal.rename.prompt', "Enter terminal name"), }).then(name => { if (name) { - terminalInstance.setTitle(name, false); + terminalInstance.setTitle(name, TitleEventSource.Api); } }); } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 9ca4fa8fb71..9ab3aa21384 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -25,7 +25,7 @@ import { activeContrastBorder, scrollbarSliderActiveBackground, scrollbarSliderB import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { PANEL_BACKGROUND } from 'vs/workbench/common/theme'; import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/terminalWidgetManager'; -import { IShellLaunchConfig, ITerminalDimensions, ITerminalInstance, ITerminalProcessManager, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, NEVER_MEASURE_RENDER_TIME_STORAGE_KEY, ProcessState, TERMINAL_PANEL_ID, IWindowsShellHelper, SHELL_PATH_INVALID_EXIT_CODE, SHELL_PATH_DIRECTORY_EXIT_CODE, SHELL_CWD_INVALID_EXIT_CODE, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, INavigationMode } from 'vs/workbench/contrib/terminal/common/terminal'; +import { IShellLaunchConfig, ITerminalDimensions, ITerminalInstance, ITerminalProcessManager, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, NEVER_MEASURE_RENDER_TIME_STORAGE_KEY, ProcessState, TERMINAL_PANEL_ID, IWindowsShellHelper, SHELL_PATH_INVALID_EXIT_CODE, SHELL_PATH_DIRECTORY_EXIT_CODE, SHELL_CWD_INVALID_EXIT_CODE, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, INavigationMode, TitleEventSource } from 'vs/workbench/contrib/terminal/common/terminal'; import { ansiColorIdentifiers, TERMINAL_BACKGROUND_COLOR, TERMINAL_CURSOR_BACKGROUND_COLOR, TERMINAL_CURSOR_FOREGROUND_COLOR, TERMINAL_FOREGROUND_COLOR, TERMINAL_SELECTION_BACKGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; import { TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/terminalCommands'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; @@ -973,11 +973,22 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this._processManager.onProcessResolvedShellLaunchConfig(e => this._setResolvedShellLaunchConfig(e)); if (this._shellLaunchConfig.name) { - this.setTitle(this._shellLaunchConfig.name, false); + this.setTitle(this._shellLaunchConfig.name, TitleEventSource.Api); } else { // Only listen for process title changes when a name is not provided - this.setTitle(this._shellLaunchConfig.executable, true); - this._messageTitleDisposable = this._processManager.onProcessTitle(title => this.setTitle(title ? title : '', true)); + if (this._configHelper.config.experimentalUseTitleEvent) { + this._processManager.ptyProcessReady.then(() => { + this._terminalInstanceService.getDefaultShellAndArgs(false).then(e => { + this.setTitle(e.shell, TitleEventSource.Sequence); + }); + this._xtermReadyPromise.then(xterm => { + this._messageTitleDisposable = xterm.onTitleChange(e => this._onTitleChange(e)); + }); + }); + } else { + this.setTitle(this._shellLaunchConfig.executable, TitleEventSource.Process); + this._messageTitleDisposable = this._processManager.onProcessTitle(title => this.setTitle(title ? title : '', TitleEventSource.Process)); + } } if (platform.isWindows) { @@ -1149,7 +1160,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this._createProcess(); if (oldTitle !== this._title) { - this.setTitle(this._title, true); + this.setTitle(this._title, TitleEventSource.Process); } this._processManager.onProcessData(data => this._onProcessData(data)); @@ -1168,6 +1179,12 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this._sendLineData(buffer, buffer.baseY + buffer.cursorY); } + private _onTitleChange(title: string): void { + if (this.isTitleSetByProcess) { + this.setTitle(title, TitleEventSource.Sequence); + } + } + private _sendLineData(buffer: IBuffer, lineIndex: number): void { let line = buffer.getLine(lineIndex); if (!line) { @@ -1348,23 +1365,26 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this._processManager.ptyProcessReady.then(() => this._processManager.setDimensions(cols, rows)); } - public setTitle(title: string | undefined, eventFromProcess: boolean): void { + public setTitle(title: string | undefined, eventSource: TitleEventSource): void { if (!title) { return; } - if (eventFromProcess) { - title = path.basename(title); - if (platform.isWindows) { - // Remove the .exe extension - title = title.split('.exe')[0]; - } - } else { - // If the title has not been set by the API or the rename command, unregister the handler that - // automatically updates the terminal name - dispose(this._messageTitleDisposable); - this._messageTitleDisposable = undefined; - dispose(this._windowsShellHelper); - this._windowsShellHelper = undefined; + switch (eventSource) { + case TitleEventSource.Process: + title = path.basename(title); + if (platform.isWindows) { + // Remove the .exe extension + title = title.split('.exe')[0]; + } + break; + case TitleEventSource.Api: + // If the title has not been set by the API or the rename command, unregister the handler that + // automatically updates the terminal name + dispose(this._messageTitleDisposable); + this._messageTitleDisposable = undefined; + dispose(this._windowsShellHelper); + this._windowsShellHelper = undefined; + break; } const didTitleChange = title !== this._title; this._title = title; diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 4383fb9c82b..48698da20ee 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -117,6 +117,7 @@ export interface ITerminalConfiguration { splitCwd: 'workspaceRoot' | 'initial' | 'inherited'; windowsEnableConpty: boolean; experimentalRefreshOnResume: boolean; + experimentalUseTitleEvent: boolean; } export interface ITerminalConfigHelper { @@ -636,7 +637,7 @@ export interface ITerminalInstance { /** * Sets the title of the terminal instance. */ - setTitle(title: string, eventFromProcess: boolean): void; + setTitle(title: string, eventSource: TitleEventSource): void; waitForTitle(): Promise; @@ -769,6 +770,15 @@ export enum LinuxDistro { Unknown } +export enum TitleEventSource { + /** From the API or the rename command that overrides any other type */ + Api, + /** From the process name property*/ + Process, + /** From the VT sequence */ + Sequence +} + export interface IWindowsShellHelper extends IDisposable { getShellName(): Promise; } diff --git a/src/vs/workbench/contrib/terminal/node/terminalRemote.ts b/src/vs/workbench/contrib/terminal/node/terminalRemote.ts index e264cdfdd5d..3ebea6304cf 100644 --- a/src/vs/workbench/contrib/terminal/node/terminalRemote.ts +++ b/src/vs/workbench/contrib/terminal/node/terminalRemote.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import { Registry } from 'vs/platform/registry/common/platform'; import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions'; import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; -import { TERMINAL_ACTION_CATEGORY, ITerminalService } from 'vs/workbench/contrib/terminal/common/terminal'; +import { TERMINAL_ACTION_CATEGORY, ITerminalService, TitleEventSource } from 'vs/workbench/contrib/terminal/common/terminal'; import { TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/terminalCommands'; import { Action } from 'vs/base/common/actions'; import { URI } from 'vs/base/common/uri'; @@ -39,7 +39,7 @@ export class CreateNewLocalTerminalAction extends Action { const disposable = instance.onTitleChanged(() => { if (instance.title && instance.title.trim().length > 0) { disposable.dispose(); - instance.setTitle(`${instance.title} (Local)`, false); + instance.setTitle(`${instance.title} (Local)`, TitleEventSource.Api); } }); diff --git a/src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts b/src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts index 46a2661d1ff..0b20c735a89 100644 --- a/src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts +++ b/src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts @@ -5,7 +5,7 @@ import * as platform from 'vs/base/common/platform'; import { Emitter, Event } from 'vs/base/common/event'; -import { ITerminalInstance, IWindowsShellHelper } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalInstance, IWindowsShellHelper, TitleEventSource } from 'vs/workbench/contrib/terminal/common/terminal'; import { Terminal as XTermTerminal } from 'xterm'; import * as WindowsProcessTreeType from 'windows-process-tree'; import { Disposable } from 'vs/base/common/lifecycle'; @@ -80,7 +80,7 @@ export class WindowsShellHelper extends Disposable implements IWindowsShellHelpe if (platform.isWindows && this._terminalInstance.isTitleSetByProcess) { this.getShellName().then(title => { if (!this._isDisposed) { - this._terminalInstance.setTitle(title, true); + this._terminalInstance.setTitle(title, TitleEventSource.Process); } }); } From 64716dd3b0a94133ab7e0e9a591e58f3e4a0ca76 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 20 Aug 2019 10:17:37 -0700 Subject: [PATCH 837/861] Fix smoke test driver types --- test/smoke/src/vscode/puppeteerDriver.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/smoke/src/vscode/puppeteerDriver.ts b/test/smoke/src/vscode/puppeteerDriver.ts index 955460f9d0a..88cb471bdd0 100644 --- a/test/smoke/src/vscode/puppeteerDriver.ts +++ b/test/smoke/src/vscode/puppeteerDriver.ts @@ -26,7 +26,7 @@ const vscodeToPuppeteerKey = { }; function buildDriver(browser: puppeteer.Browser, page: puppeteer.Page): IDriver { - const driver = { + const driver: IDriver = { _serviceBrand: undefined, getWindowIds: () => { return Promise.resolve([1]); @@ -180,7 +180,7 @@ export interface IDriver { getTitle(windowId: number): Promise; isActiveElement(windowId: number, selector: string): Promise; getElements(windowId: number, selector: string, recursive?: boolean): Promise; - getElementXY(selector: string, xoffset?: number, yoffset?: number): Promise<{ x: number; y: number; }>; + getElementXY(windowId: number, selector: string, xoffset?: number, yoffset?: number): Promise<{ x: number; y: number; }>; typeInEditor(windowId: number, selector: string, text: string): Promise; getTerminalBuffer(windowId: number, selector: string): Promise; writeInTerminal(windowId: number, selector: string, text: string): Promise; From 68660775ab49b500c91a3d02112d3a0ab503793b Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 20 Aug 2019 10:17:50 -0700 Subject: [PATCH 838/861] Teardown server on SIGTERM --- test/smoke/src/vscode/puppeteerDriver.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/smoke/src/vscode/puppeteerDriver.ts b/test/smoke/src/vscode/puppeteerDriver.ts index 88cb471bdd0..e7ae860b551 100644 --- a/test/smoke/src/vscode/puppeteerDriver.ts +++ b/test/smoke/src/vscode/puppeteerDriver.ts @@ -98,6 +98,7 @@ export async function launch(_args: string[]): Promise { server.stdout.on('data', e => console.log('Server stdout: ' + e)); process.on('exit', teardown); process.on('SIGINT', teardown); + process.on('SIGTERM', teardown); endpoint = await waitForEndpoint(); } From 5c2738521209c6f026ce349495843f008c9a7d50 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 20 Aug 2019 10:34:21 -0700 Subject: [PATCH 839/861] Restrict which subsets of the markdown grammar the js/ts injection eagerly loads Fixes #77990 --- .../syntaxes/jsdoc.injection.tmLanguage.json | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/extensions/typescript-basics/syntaxes/jsdoc.injection.tmLanguage.json b/extensions/typescript-basics/syntaxes/jsdoc.injection.tmLanguage.json index b7b4db2d2a5..02053ebab13 100644 --- a/extensions/typescript-basics/syntaxes/jsdoc.injection.tmLanguage.json +++ b/extensions/typescript-basics/syntaxes/jsdoc.injection.tmLanguage.json @@ -11,10 +11,13 @@ "while": "(^|\\G)\\s*\\*(?!/)(?=([^*]|[*](?!/))*$)", "patterns": [ { - "include": "text.html.markdown#fenced_code_block" + "include": "text.html.markdown#fenced_code_block_js" }, { - "include": "text.html.markdown#lists" + "include": "text.html.markdown#fenced_code_block_ts" + }, + { + "include": "text.html.markdown#fenced_code_block_unknown" }, { "include": "#example" @@ -47,4 +50,4 @@ } }, "scopeName": "documentation.injection" -} \ No newline at end of file +} From 0b4c4dc892cc52a9a1b42d41579299d6a4ddbe92 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 20 Aug 2019 11:02:16 -0700 Subject: [PATCH 840/861] Ensure resolved cwd is passed back to window Fixes #1109 --- src/vs/workbench/api/node/extHostTerminalService.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 99a7cc8309c..5c5d76564f8 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -497,6 +497,7 @@ export class ExtHostTerminalService implements IExtHostTerminalService, ExtHostT const terminalConfig = configProvider.getConfiguration('terminal.integrated'); const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, os.homedir(), lastActiveWorkspace ? lastActiveWorkspace : undefined, this._variableResolver, activeWorkspaceRootUri, terminalConfig.cwd, this._logService); + shellLaunchConfig.cwd = initialCwd; const envFromConfig = this._apiInspectConfigToPlain(configProvider.getConfiguration('terminal.integrated').inspect(`env.${platformKey}`)); const baseEnv = terminalConfig.get('inheritEnv', true) ? process.env as platform.IProcessEnvironment : await this._getNonInheritedEnv(); From 1429e8182ff283ef5927aecd7ee7da96ab9fc715 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 20 Aug 2019 11:21:23 -0700 Subject: [PATCH 841/861] Enable "restart ts server" command in js/tsconfig files Fixes #79530 --- .../src/features/task.ts | 5 +++-- .../src/utils/languageDescription.ts | 10 ++++++++++ .../src/utils/managedFileContext.ts | 18 +++++++++++++++--- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/extensions/typescript-language-features/src/features/task.ts b/extensions/typescript-language-features/src/features/task.ts index e47ee6d7fdc..64057555d5f 100644 --- a/extensions/typescript-language-features/src/features/task.ts +++ b/extensions/typescript-language-features/src/features/task.ts @@ -4,11 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import * as fs from 'fs'; +import * as jsonc from 'jsonc-parser'; import * as path from 'path'; import * as vscode from 'vscode'; import * as nls from 'vscode-nls'; -import * as jsonc from 'jsonc-parser'; import { ITypeScriptServiceClient } from '../typescriptService'; +import { isTsConfigFileName } from '../utils/languageDescription'; import { Lazy } from '../utils/lazy'; import { isImplicitProjectConfigFile } from '../utils/tsconfig'; import TsConfigProvider, { TSConfig } from '../utils/tsconfigProvider'; @@ -113,7 +114,7 @@ export default class TscTaskProvider implements vscode.TaskProvider { private async getTsConfigForActiveFile(token: vscode.CancellationToken): Promise { const editor = vscode.window.activeTextEditor; if (editor) { - if (path.basename(editor.document.fileName).match(/^tsconfig\.(.\.)?json$/)) { + if (isTsConfigFileName(editor.document.fileName)) { const uri = editor.document.uri; return [{ path: uri.fsPath, diff --git a/extensions/typescript-language-features/src/utils/languageDescription.ts b/extensions/typescript-language-features/src/utils/languageDescription.ts index 79f9ce9f47b..f6b066bd400 100644 --- a/extensions/typescript-language-features/src/utils/languageDescription.ts +++ b/extensions/typescript-language-features/src/utils/languageDescription.ts @@ -2,6 +2,8 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ + +import { basename } from 'path'; import * as languageModeIds from './languageModeIds'; export const enum DiagnosticLanguage { @@ -38,3 +40,11 @@ export const standardLanguageDescriptions: LanguageDescription[] = [ configFilePattern: /^jsconfig(\..*)?\.json$/gi } ]; + +export function isTsConfigFileName(fileName: string): boolean { + return /^tsconfig\.(.+\.)?json$/i.test(basename(fileName)); +} + +export function isJsConfigOrTsConfigFileName(fileName: string): boolean { + return /^[jt]sconfig\.(.+\.)?json$/i.test(basename(fileName)); +} diff --git a/extensions/typescript-language-features/src/utils/managedFileContext.ts b/extensions/typescript-language-features/src/utils/managedFileContext.ts index 81acf9ad505..481f2482d26 100644 --- a/extensions/typescript-language-features/src/utils/managedFileContext.ts +++ b/extensions/typescript-language-features/src/utils/managedFileContext.ts @@ -4,8 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { isSupportedLanguageMode } from './languageModeIds'; import { Disposable } from './dispose'; +import { isJsConfigOrTsConfigFileName } from './languageDescription'; +import { isSupportedLanguageMode } from './languageModeIds'; /** * When clause context set when the current file is managed by vscode's built-in typescript extension. @@ -26,8 +27,7 @@ export default class ManagedFileContextManager extends Disposable { private onDidChangeActiveTextEditor(editor?: vscode.TextEditor): any { if (editor) { - const isManagedFile = isSupportedLanguageMode(editor.document) && this.normalizePath(editor.document.uri) !== null; - this.updateContext(isManagedFile); + this.updateContext(this.isManagedFile(editor)); } } @@ -39,4 +39,16 @@ export default class ManagedFileContextManager extends Disposable { vscode.commands.executeCommand('setContext', ManagedFileContextManager.contextName, newValue); this.isInManagedFileContext = newValue; } + + private isManagedFile(editor: vscode.TextEditor): boolean { + return this.isManagedScriptFile(editor) || this.isManagedConfigFile(editor); + } + + private isManagedScriptFile(editor: vscode.TextEditor): boolean { + return isSupportedLanguageMode(editor.document) && this.normalizePath(editor.document.uri) !== null; + } + + private isManagedConfigFile(editor: vscode.TextEditor): boolean { + return isJsConfigOrTsConfigFileName(editor.document.fileName); + } } From f509f7f141192052b64d020038da19ec4244b289 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 20 Aug 2019 11:25:42 -0700 Subject: [PATCH 842/861] Rename command #75612 --- extensions/markdown-language-features/package.json | 2 +- .../markdown-language-features/src/commands/renderDocument.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/markdown-language-features/package.json b/extensions/markdown-language-features/package.json index 4a6c326c19e..7bcf7ca8641 100644 --- a/extensions/markdown-language-features/package.json +++ b/extensions/markdown-language-features/package.json @@ -24,7 +24,7 @@ "onCommand:markdown.showLockedPreviewToSide", "onCommand:markdown.showSource", "onCommand:markdown.showPreviewSecuritySelector", - "onCommand:markdown.render", + "onCommand:markdown.api.render", "onWebviewPanel:markdown.preview" ], "contributes": { diff --git a/extensions/markdown-language-features/src/commands/renderDocument.ts b/extensions/markdown-language-features/src/commands/renderDocument.ts index 3d7a0bc29a0..a55da6ddbc1 100644 --- a/extensions/markdown-language-features/src/commands/renderDocument.ts +++ b/extensions/markdown-language-features/src/commands/renderDocument.ts @@ -10,7 +10,7 @@ import { MarkdownEngine } from '../markdownEngine'; import { SkinnyTextDocument } from '../tableOfContentsProvider'; export class RenderDocument implements Command { - public readonly id = 'markdown.render'; + public readonly id = 'markdown.api.render'; public constructor( private readonly engine: MarkdownEngine From 1802be3b703f242352a71a5e75b298eb1c8ccca7 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 20 Aug 2019 11:26:49 -0700 Subject: [PATCH 843/861] Always require an argument to command #75612 --- .../src/commands/renderDocument.ts | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/extensions/markdown-language-features/src/commands/renderDocument.ts b/extensions/markdown-language-features/src/commands/renderDocument.ts index a55da6ddbc1..f9ec89fce3d 100644 --- a/extensions/markdown-language-features/src/commands/renderDocument.ts +++ b/extensions/markdown-language-features/src/commands/renderDocument.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as vscode from 'vscode'; - import { Command } from '../commandManager'; import { MarkdownEngine } from '../markdownEngine'; import { SkinnyTextDocument } from '../tableOfContentsProvider'; @@ -16,15 +14,7 @@ export class RenderDocument implements Command { private readonly engine: MarkdownEngine ) { } - public async execute(document?: SkinnyTextDocument | string): Promise { - if (!document) { - if (!vscode.window.activeTextEditor) { - return; - } - - document = vscode.window.activeTextEditor.document; - } - + public async execute(document: SkinnyTextDocument | string): Promise { return this.engine.render(document); } } From e44d9a2888d818b9e472df3198ec9187874bb7e0 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 20 Aug 2019 11:28:31 -0700 Subject: [PATCH 844/861] Rename parameter --- .../markdown-language-features/src/markdownEngine.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/extensions/markdown-language-features/src/markdownEngine.ts b/extensions/markdown-language-features/src/markdownEngine.ts index 9b51dc06b86..bcd7dc43ff4 100644 --- a/extensions/markdown-language-features/src/markdownEngine.ts +++ b/extensions/markdown-language-features/src/markdownEngine.ts @@ -140,12 +140,12 @@ export class MarkdownEngine { return engine.parse(text.replace(UNICODE_NEWLINE_REGEX, ''), {}); } - public async render(document: SkinnyTextDocument | string): Promise { - const config = this.getConfig(typeof document === 'string' ? undefined : document.uri); + public async render(input: SkinnyTextDocument | string): Promise { + const config = this.getConfig(typeof input === 'string' ? undefined : input.uri); const engine = await this.getEngine(config); - const tokens = typeof document === 'string' - ? this.tokenizeString(document, engine) - : this.tokenizeDocument(document, config, engine); + const tokens = typeof input === 'string' + ? this.tokenizeString(input, engine) + : this.tokenizeDocument(input, config, engine); return engine.renderer.render(tokens, { ...(engine as any).options, From 67145b273200c4025dfb239b8ce17850b90ad064 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 20 Aug 2019 11:49:59 -0700 Subject: [PATCH 845/861] update replace input box size when resizing and display preserve case button properly --- src/vs/base/browser/ui/findinput/findInput.ts | 9 +- .../base/browser/ui/findinput/replaceInput.ts | 378 ++++++++++++++++++ src/vs/base/browser/ui/inputbox/inputBox.ts | 33 +- src/vs/editor/contrib/find/findWidget.css | 19 +- src/vs/editor/contrib/find/findWidget.ts | 107 ++--- .../browser/contextScopedHistoryWidget.ts | 11 + 6 files changed, 476 insertions(+), 81 deletions(-) create mode 100644 src/vs/base/browser/ui/findinput/replaceInput.ts diff --git a/src/vs/base/browser/ui/findinput/findInput.ts b/src/vs/base/browser/ui/findinput/findInput.ts index 0c64d37c49e..fcc27e402a7 100644 --- a/src/vs/base/browser/ui/findinput/findInput.ts +++ b/src/vs/base/browser/ui/findinput/findInput.ts @@ -24,6 +24,7 @@ export interface IFindInputOptions extends IFindInputStyles { readonly validation?: IInputValidator; readonly label: string; readonly flexibleHeight?: boolean; + readonly flexibleWidth?: boolean; readonly flexibleMaxHeight?: number; readonly appendCaseSensitiveLabel?: string; @@ -120,6 +121,7 @@ export class FindInput extends Widget { const appendRegexLabel = options.appendRegexLabel || ''; const history = options.history || []; const flexibleHeight = !!options.flexibleHeight; + const flexibleWidth = !!options.flexibleWidth; const flexibleMaxHeight = options.flexibleMaxHeight; this.domNode = document.createElement('div'); @@ -145,6 +147,7 @@ export class FindInput extends Widget { inputValidationErrorBorder: this.inputValidationErrorBorder, history, flexibleHeight, + flexibleWidth, flexibleMaxHeight })); @@ -197,11 +200,7 @@ export class FindInput extends Widget { })); if (this._showOptionButtons) { - const paddingRight = (this.caseSensitive.width() + this.wholeWords.width() + this.regex.width()) + 'px'; - this.inputBox.inputElement.style.paddingRight = paddingRight; - if (this.inputBox.mirrorElement) { - this.inputBox.mirrorElement.style.paddingRight = paddingRight; - } + this.inputBox.paddingRight = this.caseSensitive.width() + this.wholeWords.width() + this.regex.width(); } // Arrow-Key support to navigate between options diff --git a/src/vs/base/browser/ui/findinput/replaceInput.ts b/src/vs/base/browser/ui/findinput/replaceInput.ts new file mode 100644 index 00000000000..db0c44edf2e --- /dev/null +++ b/src/vs/base/browser/ui/findinput/replaceInput.ts @@ -0,0 +1,378 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import 'vs/css!./findInput'; + +import * as nls from 'vs/nls'; +import * as dom from 'vs/base/browser/dom'; +import { IMessage as InputBoxMessage, IInputValidator, IInputBoxStyles, HistoryInputBox } from 'vs/base/browser/ui/inputbox/inputBox'; +import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview'; +import { Widget } from 'vs/base/browser/ui/widget'; +import { Event, Emitter } from 'vs/base/common/event'; +import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; +import { IMouseEvent } from 'vs/base/browser/mouseEvent'; +import { KeyCode } from 'vs/base/common/keyCodes'; +import { Color } from 'vs/base/common/color'; +import { ICheckboxStyles, Checkbox } from 'vs/base/browser/ui/checkbox/checkbox'; +import { IFindInputCheckboxOpts } from 'vs/base/browser/ui/findinput/findInputCheckboxes'; + +export interface IReplaceInputOptions extends IReplaceInputStyles { + readonly placeholder?: string; + readonly width?: number; + readonly validation?: IInputValidator; + readonly label: string; + readonly flexibleHeight?: boolean; + readonly flexibleWidth?: boolean; + readonly flexibleMaxHeight?: number; + + readonly history?: string[]; +} + +export interface IReplaceInputStyles extends IInputBoxStyles { + inputActiveOptionBorder?: Color; +} + +const NLS_DEFAULT_LABEL = nls.localize('defaultLabel', "input"); +const NLS_PRESERVE_CASE_LABEL = nls.localize('label.preserveCaseCheckbox', "Preserve Case"); + +export class PreserveCaseCheckbox extends Checkbox { + constructor(opts: IFindInputCheckboxOpts) { + super({ + // TODO: does this need its own icon? + actionClassName: 'monaco-case-sensitive', + title: NLS_PRESERVE_CASE_LABEL + opts.appendTitle, + isChecked: opts.isChecked, + inputActiveOptionBorder: opts.inputActiveOptionBorder + }); + } +} + +export class ReplaceInput extends Widget { + + static readonly OPTION_CHANGE: string = 'optionChange'; + + private contextViewProvider: IContextViewProvider | undefined; + private placeholder: string; + private validation?: IInputValidator; + private label: string; + private fixFocusOnOptionClickEnabled = true; + + private inputActiveOptionBorder?: Color; + private inputBackground?: Color; + private inputForeground?: Color; + private inputBorder?: Color; + + private inputValidationInfoBorder?: Color; + private inputValidationInfoBackground?: Color; + private inputValidationInfoForeground?: Color; + private inputValidationWarningBorder?: Color; + private inputValidationWarningBackground?: Color; + private inputValidationWarningForeground?: Color; + private inputValidationErrorBorder?: Color; + private inputValidationErrorBackground?: Color; + private inputValidationErrorForeground?: Color; + + private preserveCase: PreserveCaseCheckbox; + private cachedOptionsWidth: number = 0; + public domNode: HTMLElement; + public inputBox: HistoryInputBox; + + private readonly _onDidOptionChange = this._register(new Emitter()); + public readonly onDidOptionChange: Event = this._onDidOptionChange.event; + + private readonly _onKeyDown = this._register(new Emitter()); + public readonly onKeyDown: Event = this._onKeyDown.event; + + private readonly _onMouseDown = this._register(new Emitter()); + public readonly onMouseDown: Event = this._onMouseDown.event; + + private readonly _onInput = this._register(new Emitter()); + public readonly onInput: Event = this._onInput.event; + + private readonly _onKeyUp = this._register(new Emitter()); + public readonly onKeyUp: Event = this._onKeyUp.event; + + private _onPreserveCaseKeyDown = this._register(new Emitter()); + public readonly onPreserveCaseKeyDown: Event = this._onPreserveCaseKeyDown.event; + + constructor(parent: HTMLElement | null, contextViewProvider: IContextViewProvider | undefined, private readonly _showOptionButtons: boolean, options: IReplaceInputOptions) { + super(); + this.contextViewProvider = contextViewProvider; + this.placeholder = options.placeholder || ''; + this.validation = options.validation; + this.label = options.label || NLS_DEFAULT_LABEL; + + this.inputActiveOptionBorder = options.inputActiveOptionBorder; + this.inputBackground = options.inputBackground; + this.inputForeground = options.inputForeground; + this.inputBorder = options.inputBorder; + + this.inputValidationInfoBorder = options.inputValidationInfoBorder; + this.inputValidationInfoBackground = options.inputValidationInfoBackground; + this.inputValidationInfoForeground = options.inputValidationInfoForeground; + this.inputValidationWarningBorder = options.inputValidationWarningBorder; + this.inputValidationWarningBackground = options.inputValidationWarningBackground; + this.inputValidationWarningForeground = options.inputValidationWarningForeground; + this.inputValidationErrorBorder = options.inputValidationErrorBorder; + this.inputValidationErrorBackground = options.inputValidationErrorBackground; + this.inputValidationErrorForeground = options.inputValidationErrorForeground; + + const flexibleHeight = !!options.flexibleHeight; + const flexibleWidth = !!options.flexibleWidth; + const flexibleMaxHeight = options.flexibleMaxHeight; + + this.buildDomNode(options.history || [], flexibleHeight, flexibleWidth, flexibleMaxHeight); + + if (parent) { + parent.appendChild(this.domNode); + } + + this.onkeydown(this.inputBox.inputElement, (e) => this._onKeyDown.fire(e)); + this.onkeyup(this.inputBox.inputElement, (e) => this._onKeyUp.fire(e)); + this.oninput(this.inputBox.inputElement, (e) => this._onInput.fire()); + this.onmousedown(this.inputBox.inputElement, (e) => this._onMouseDown.fire(e)); + } + + public enable(): void { + dom.removeClass(this.domNode, 'disabled'); + this.inputBox.enable(); + this.preserveCase.enable(); + } + + public disable(): void { + dom.addClass(this.domNode, 'disabled'); + this.inputBox.disable(); + this.preserveCase.disable(); + } + + public setFocusInputOnOptionClick(value: boolean): void { + this.fixFocusOnOptionClickEnabled = value; + } + + public setEnabled(enabled: boolean): void { + if (enabled) { + this.enable(); + } else { + this.disable(); + } + } + + public clear(): void { + this.clearValidation(); + this.setValue(''); + this.focus(); + } + + public getValue(): string { + return this.inputBox.value; + } + + public setValue(value: string): void { + if (this.inputBox.value !== value) { + this.inputBox.value = value; + } + } + + public onSearchSubmit(): void { + this.inputBox.addToHistory(); + } + + public style(styles: IReplaceInputStyles): void { + this.inputActiveOptionBorder = styles.inputActiveOptionBorder; + this.inputBackground = styles.inputBackground; + this.inputForeground = styles.inputForeground; + this.inputBorder = styles.inputBorder; + + this.inputValidationInfoBackground = styles.inputValidationInfoBackground; + this.inputValidationInfoForeground = styles.inputValidationInfoForeground; + this.inputValidationInfoBorder = styles.inputValidationInfoBorder; + this.inputValidationWarningBackground = styles.inputValidationWarningBackground; + this.inputValidationWarningForeground = styles.inputValidationWarningForeground; + this.inputValidationWarningBorder = styles.inputValidationWarningBorder; + this.inputValidationErrorBackground = styles.inputValidationErrorBackground; + this.inputValidationErrorForeground = styles.inputValidationErrorForeground; + this.inputValidationErrorBorder = styles.inputValidationErrorBorder; + + this.applyStyles(); + } + + protected applyStyles(): void { + if (this.domNode) { + const checkBoxStyles: ICheckboxStyles = { + inputActiveOptionBorder: this.inputActiveOptionBorder, + }; + this.preserveCase.style(checkBoxStyles); + + const inputBoxStyles: IInputBoxStyles = { + inputBackground: this.inputBackground, + inputForeground: this.inputForeground, + inputBorder: this.inputBorder, + inputValidationInfoBackground: this.inputValidationInfoBackground, + inputValidationInfoForeground: this.inputValidationInfoForeground, + inputValidationInfoBorder: this.inputValidationInfoBorder, + inputValidationWarningBackground: this.inputValidationWarningBackground, + inputValidationWarningForeground: this.inputValidationWarningForeground, + inputValidationWarningBorder: this.inputValidationWarningBorder, + inputValidationErrorBackground: this.inputValidationErrorBackground, + inputValidationErrorForeground: this.inputValidationErrorForeground, + inputValidationErrorBorder: this.inputValidationErrorBorder + }; + this.inputBox.style(inputBoxStyles); + } + } + + public select(): void { + this.inputBox.select(); + } + + public focus(): void { + this.inputBox.focus(); + } + + public getPreserveCase(): boolean { + return this.preserveCase.checked; + } + + public setPreserveCase(value: boolean): void { + this.preserveCase.checked = value; + } + + public focusOnPreserve(): void { + this.preserveCase.focus(); + } + + private _lastHighlightFindOptions: number = 0; + public highlightFindOptions(): void { + dom.removeClass(this.domNode, 'highlight-' + (this._lastHighlightFindOptions)); + this._lastHighlightFindOptions = 1 - this._lastHighlightFindOptions; + dom.addClass(this.domNode, 'highlight-' + (this._lastHighlightFindOptions)); + } + + private buildDomNode(history: string[], flexibleHeight: boolean, flexibleWidth: boolean, flexibleMaxHeight: number | undefined): void { + this.domNode = document.createElement('div'); + dom.addClass(this.domNode, 'monaco-findInput'); + + this.inputBox = this._register(new HistoryInputBox(this.domNode, this.contextViewProvider, { + ariaLabel: this.label || '', + placeholder: this.placeholder || '', + validationOptions: { + validation: this.validation + }, + inputBackground: this.inputBackground, + inputForeground: this.inputForeground, + inputBorder: this.inputBorder, + inputValidationInfoBackground: this.inputValidationInfoBackground, + inputValidationInfoForeground: this.inputValidationInfoForeground, + inputValidationInfoBorder: this.inputValidationInfoBorder, + inputValidationWarningBackground: this.inputValidationWarningBackground, + inputValidationWarningForeground: this.inputValidationWarningForeground, + inputValidationWarningBorder: this.inputValidationWarningBorder, + inputValidationErrorBackground: this.inputValidationErrorBackground, + inputValidationErrorForeground: this.inputValidationErrorForeground, + inputValidationErrorBorder: this.inputValidationErrorBorder, + history, + flexibleHeight, + flexibleWidth, + flexibleMaxHeight + })); + + this.preserveCase = this._register(new PreserveCaseCheckbox({ + appendTitle: '', + isChecked: false, + inputActiveOptionBorder: this.inputActiveOptionBorder + })); + this._register(this.preserveCase.onChange(viaKeyboard => { + this._onDidOptionChange.fire(viaKeyboard); + if (!viaKeyboard && this.fixFocusOnOptionClickEnabled) { + this.inputBox.focus(); + } + this.validate(); + })); + this._register(this.preserveCase.onKeyDown(e => { + this._onPreserveCaseKeyDown.fire(e); + })); + + if (this._showOptionButtons) { + this.cachedOptionsWidth = this.preserveCase.width(); + // const paddingRight = () + 'px'; + // this.inputBox.inputElement.style.paddingRight = paddingRight; + // if (this.inputBox.mirrorElement) { + // this.inputBox.mirrorElement.style.paddingRight = paddingRight; + // } + } else { + this.cachedOptionsWidth = 0; + } + + // Arrow-Key support to navigate between options + let indexes = [this.preserveCase.domNode]; + this.onkeydown(this.domNode, (event: IKeyboardEvent) => { + if (event.equals(KeyCode.LeftArrow) || event.equals(KeyCode.RightArrow) || event.equals(KeyCode.Escape)) { + let index = indexes.indexOf(document.activeElement); + if (index >= 0) { + let newIndex: number = -1; + if (event.equals(KeyCode.RightArrow)) { + newIndex = (index + 1) % indexes.length; + } else if (event.equals(KeyCode.LeftArrow)) { + if (index === 0) { + newIndex = indexes.length - 1; + } else { + newIndex = index - 1; + } + } + + if (event.equals(KeyCode.Escape)) { + indexes[index].blur(); + } else if (newIndex >= 0) { + indexes[newIndex].focus(); + } + + dom.EventHelper.stop(event, true); + } + } + }); + + + let controls = document.createElement('div'); + controls.className = 'controls'; + controls.style.display = this._showOptionButtons ? 'block' : 'none'; + controls.appendChild(this.preserveCase.domNode); + + this.domNode.appendChild(controls); + } + + public validate(): void { + if (this.inputBox) { + this.inputBox.validate(); + } + } + + public showMessage(message: InputBoxMessage): void { + if (this.inputBox) { + this.inputBox.showMessage(message); + } + } + + public clearMessage(): void { + if (this.inputBox) { + this.inputBox.hideMessage(); + } + } + + private clearValidation(): void { + if (this.inputBox) { + this.inputBox.hideMessage(); + } + } + + public set width(newWidth: number) { + this.inputBox.paddingRight = this.cachedOptionsWidth; + this.inputBox.width = newWidth; + this.domNode.style.width = newWidth + 'px'; + } + + public dispose(): void { + super.dispose(); + } +} diff --git a/src/vs/base/browser/ui/inputbox/inputBox.ts b/src/vs/base/browser/ui/inputbox/inputBox.ts index 7af2a58f46d..3bd9a5ce12b 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.ts +++ b/src/vs/base/browser/ui/inputbox/inputBox.ts @@ -32,6 +32,7 @@ export interface IInputOptions extends IInputBoxStyles { readonly type?: string; readonly validationOptions?: IInputValidationOptions; readonly flexibleHeight?: boolean; + readonly flexibleWidth?: boolean; readonly flexibleMaxHeight?: number; readonly actions?: ReadonlyArray; } @@ -173,6 +174,12 @@ export class InputBox extends Widget { this.mirror.innerHTML = ' '; this.scrollableElement = new ScrollableElement(this.element, { vertical: ScrollbarVisibility.Auto }); + + if (this.options.flexibleWidth) { + this.input.setAttribute('wrap', 'off'); + this.mirror.style.whiteSpace = 'pre'; + } + dom.append(container, this.scrollableElement.getDomNode()); this._register(this.scrollableElement); @@ -321,12 +328,36 @@ export class InputBox extends Widget { } public set width(width: number) { - this.input.style.width = width + 'px'; + if (this.options.flexibleHeight && this.options.flexibleWidth) { + // textarea with horizontal scrolling + let horizontalPadding = 0; + if (this.mirror) { + const paddingLeft = parseFloat(this.mirror.style.paddingLeft || '') || 0; + const paddingRight = parseFloat(this.mirror.style.paddingRight || '') || 0; + horizontalPadding = paddingLeft + paddingRight; + } + this.input.style.width = (width - horizontalPadding) + 'px'; + } else { + this.input.style.width = width + 'px'; + } + if (this.mirror) { this.mirror.style.width = width + 'px'; } } + public set paddingRight(paddingRight: number) { + if (this.options.flexibleHeight && this.options.flexibleWidth) { + this.input.style.width = `calc(100% - ${paddingRight}px)`; + } else { + this.input.style.paddingRight = paddingRight + 'px'; + } + + if (this.mirror) { + this.mirror.style.paddingRight = paddingRight + 'px'; + } + } + private updateScrollDimensions(): void { if (typeof this.cachedContentHeight !== 'number' || typeof this.cachedHeight !== 'number') { return; diff --git a/src/vs/editor/contrib/find/findWidget.css b/src/vs/editor/contrib/find/findWidget.css index ac0a74d55b9..d9eb731d1e3 100644 --- a/src/vs/editor/contrib/find/findWidget.css +++ b/src/vs/editor/contrib/find/findWidget.css @@ -62,7 +62,7 @@ min-height: 0; } -.monaco-editor .find-widget .replace-input .input { +.monaco-editor .find-widget .monaco-findInput .input { font-size: 13px; } @@ -79,12 +79,8 @@ min-height: 25px; } -.monaco-editor .find-widget > .find-part .monaco-inputbox > .wrapper > .input { - width: 100% !important; - padding-right: 66px; -} -.monaco-editor .find-widget > .replace-part .monaco-inputbox > .wrapper > .input { +.monaco-editor .find-widget > .replace-part .monaco-inputbox > .wrapper > .mirror { padding-right: 22px; } @@ -120,8 +116,7 @@ width: 100%; } -.monaco-editor .find-widget .monaco-findInput .monaco-scrollable-element .scrollbar.vertical, -.monaco-editor .find-widget .replace-input .monaco-scrollable-element .scrollbar.vertical { +.monaco-editor .find-widget .monaco-findInput .monaco-scrollable-element .scrollbar.vertical { /* Hide vertical scrollbar */ opacity: 0; } @@ -257,15 +252,17 @@ display: none; } -.monaco-editor .find-widget > .replace-part > .replace-input { +.monaco-editor .find-widget > .replace-part > .monaco-findInput { position: relative; display: flex; display: -webkit-flex; vertical-align: middle; - width: auto !important; + flex: auto; + flex-grow: 0; + flex-shrink: 0; } -.monaco-editor .find-widget > .replace-part > .replace-input > .controls { +.monaco-editor .find-widget > .replace-part > .monaco-findInput > .controls { position: absolute; top: 3px; right: 2px; diff --git a/src/vs/editor/contrib/find/findWidget.ts b/src/vs/editor/contrib/find/findWidget.ts index 6b59dafaba9..865fb6c220d 100644 --- a/src/vs/editor/contrib/find/findWidget.ts +++ b/src/vs/editor/contrib/find/findWidget.ts @@ -10,10 +10,9 @@ import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { IMouseEvent } from 'vs/base/browser/mouseEvent'; import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview'; import { FindInput, IFindInputStyles } from 'vs/base/browser/ui/findinput/findInput'; -import { HistoryInputBox, IMessage as InputBoxMessage } from 'vs/base/browser/ui/inputbox/inputBox'; +import { IMessage as InputBoxMessage } from 'vs/base/browser/ui/inputbox/inputBox'; import { IHorizontalSashLayoutProvider, ISashEvent, Orientation, Sash } from 'vs/base/browser/ui/sash/sash'; import { Widget } from 'vs/base/browser/ui/widget'; -import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox'; import { Delayer } from 'vs/base/common/async'; import { Color } from 'vs/base/common/color'; import { onUnexpectedError } from 'vs/base/common/errors'; @@ -30,9 +29,10 @@ import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/c import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { contrastBorder, editorFindMatch, editorFindMatchBorder, editorFindMatchHighlight, editorFindMatchHighlightBorder, editorFindRangeHighlight, editorFindRangeHighlightBorder, editorWidgetBackground, editorWidgetBorder, editorWidgetResizeBorder, errorForeground, inputActiveOptionBorder, inputActiveOptionBackground, inputBackground, inputBorder, inputForeground, inputValidationErrorBackground, inputValidationErrorBorder, inputValidationErrorForeground, inputValidationInfoBackground, inputValidationInfoBorder, inputValidationInfoForeground, inputValidationWarningBackground, inputValidationWarningBorder, inputValidationWarningForeground, widgetShadow, editorWidgetForeground } from 'vs/platform/theme/common/colorRegistry'; import { ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; -import { ContextScopedFindInput, ContextScopedHistoryInputBox } from 'vs/platform/browser/contextScopedHistoryWidget'; +import { ContextScopedFindInput, ContextScopedReplaceInput } from 'vs/platform/browser/contextScopedHistoryWidget'; import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; import { alert as alertFn } from 'vs/base/browser/ui/aria/aria'; +import { ReplaceInput } from 'vs/base/browser/ui/findinput/replaceInput'; export interface IFindController { replace(): void; @@ -48,7 +48,6 @@ const NLS_TOGGLE_SELECTION_FIND_TITLE = nls.localize('label.toggleSelectionFind' const NLS_CLOSE_BTN_LABEL = nls.localize('label.closeButton', "Close"); const NLS_REPLACE_INPUT_LABEL = nls.localize('label.replace', "Replace"); const NLS_REPLACE_INPUT_PLACEHOLDER = nls.localize('placeholder.replace', "Replace"); -const NLS_PRESERVE_CASE_LABEL = nls.localize('label.preserveCaseCheckbox', "Preserve Case"); const NLS_REPLACE_BTN_LABEL = nls.localize('label.replaceButton', "Replace"); const NLS_REPLACE_ALL_BTN_LABEL = nls.localize('label.replaceAllButton', "Replace All"); const NLS_TOGGLE_REPLACE_MODE_BTN_LABEL = nls.localize('label.toggleReplaceButton', "Toggle Replace mode"); @@ -59,7 +58,6 @@ const NLS_NO_RESULTS = nls.localize('label.noResults', "No Results"); const FIND_WIDGET_INITIAL_WIDTH = 411; const PART_WIDTH = 275; const FIND_INPUT_AREA_WIDTH = PART_WIDTH - 54; -const REPLACE_INPUT_AREA_WIDTH = FIND_INPUT_AREA_WIDTH; let MAX_MATCHES_COUNT_WIDTH = 69; let FIND_ALL_CONTROLS_WIDTH = 17/** Find Input margin-left */ + (MAX_MATCHES_COUNT_WIDTH + 3 + 1) /** Match Results */ + 23 /** Button */ * 4 + 2/** sash */; @@ -110,7 +108,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas private _domNode!: HTMLElement; private _cachedHeight: number | null; private _findInput!: FindInput; - private _replaceInputBox!: HistoryInputBox; + private _replaceInput!: ReplaceInput; private _toggleReplaceBtn!: SimpleButton; private _matchesCount!: HTMLElement; @@ -118,7 +116,6 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas private _nextBtn!: SimpleButton; private _toggleSelectionFind!: SimpleCheckbox; private _closeBtn!: SimpleButton; - private _preserveCase!: Checkbox; private _replaceBtn!: SimpleButton; private _replaceAllBtn!: SimpleButton; @@ -218,7 +215,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas })); this._replaceInputFocused = CONTEXT_REPLACE_INPUT_FOCUSED.bindTo(contextKeyService); - this._replaceFocusTracker = this._register(dom.trackFocus(this._replaceInputBox.inputElement)); + this._replaceFocusTracker = this._register(dom.trackFocus(this._replaceInput.inputBox.inputElement)); this._register(this._replaceFocusTracker.onDidFocus(() => { this._replaceInputFocused.set(true); this._updateSearchScope(); @@ -288,7 +285,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas this._updateButtons(); } if (e.replaceString) { - this._replaceInputBox.value = this._state.replaceString; + this._replaceInput.inputBox.value = this._state.replaceString; } if (e.isRevealed) { if (this._state.isRevealed) { @@ -301,7 +298,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas if (this._state.isReplaceRevealed) { if (!this._codeEditor.getConfiguration().readOnly && !this._isReplaceVisible) { this._isReplaceVisible = true; - this._replaceInputBox.width = this._findInput.inputBox.width; + this._replaceInput.width = dom.getTotalWidth(this._findInput.domNode); this._updateButtons(); } } else { @@ -358,7 +355,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas this._findInput.inputBox.addToHistory(); } if (this._state.replaceString) { - this._replaceInputBox.addToHistory(); + this._replaceInput.inputBox.addToHistory(); } } @@ -423,7 +420,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas private _updateButtons(): void { this._findInput.setEnabled(this._isVisible); - this._replaceInputBox.setEnabled(this._isVisible && this._isReplaceVisible); + this._replaceInput.setEnabled(this._isVisible && this._isReplaceVisible); this._updateToggleSelectionFindButton(); this._closeBtn.setEnabled(this._isVisible); @@ -617,8 +614,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas inputValidationErrorBorder: theme.getColor(inputValidationErrorBorder), }; this._findInput.style(inputStyles); - this._replaceInputBox.style(inputStyles); - this._preserveCase.style(inputStyles); + this._replaceInput.style(inputStyles); } private _tryUpdateWidgetWidth() { @@ -648,7 +644,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas if (widgetWidth > FIND_WIDGET_INITIAL_WIDTH) { // as the widget is resized by users, we may need to change the max width of the widget as the editor width changes. this._domNode.style.maxWidth = `${editorWidth - 28 - minimapWidth - 15}px`; - this._replaceInputBox.width = dom.getTotalWidth(this._findInput.inputBox.inputElement); + this._replaceInput.width = dom.getTotalWidth(this._findInput.domNode); return; } } @@ -675,7 +671,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas this._findInput.inputBox.layout(); let findInputWidth = this._findInput.inputBox.width; if (findInputWidth > 0) { - this._replaceInputBox.width = findInputWidth; + this._replaceInput.width = findInputWidth; } } } @@ -693,7 +689,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas // replace input margin totalheight += 4; - totalheight += this._replaceInputBox.height + 2 /** input box border */; + totalheight += this._replaceInput.inputBox.height + 2 /** input box border */; } // margin bottom @@ -722,9 +718,9 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } public focusReplaceInput(): void { - this._replaceInputBox.select(); + this._replaceInput.select(); // Edge browser requires focus() in addition to select() - this._replaceInputBox.focus(); + this._replaceInput.focus(); } public highlightFindOptions(): void { @@ -790,7 +786,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas if (e.equals(KeyCode.Tab)) { if (this._isReplaceVisible) { - this._replaceInputBox.focus(); + this._replaceInput.focus(); } else { this._findInput.focusOnCaseSensitive(); } @@ -822,16 +818,16 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } if (e.equals(KeyMod.WinCtrl | KeyCode.Enter)) { - const inputElement = this._replaceInputBox.inputElement; + const inputElement = this._replaceInput.inputBox.inputElement; const start = inputElement.selectionStart; const end = inputElement.selectionEnd; const content = inputElement.value; if (start && end) { const value = content.substr(0, start) + '\n' + content.substr(end); - this._replaceInputBox.value = value; + this._replaceInput.inputBox.value = value; inputElement.setSelectionRange(start + 1, start + 1); - this._replaceInputBox.layout(); + this._replaceInput.inputBox.layout(); e.preventDefault(); return; } @@ -862,11 +858,11 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } if (e.equals(KeyCode.UpArrow)) { - return stopPropagationForMultiLineUpwards(e, this._replaceInputBox.value, this._replaceInputBox.element.querySelector('textarea')); + return stopPropagationForMultiLineUpwards(e, this._replaceInput.inputBox.value, this._replaceInput.inputBox.element.querySelector('textarea')); } if (e.equals(KeyCode.DownArrow)) { - return stopPropagationForMultiLineDownwards(e, this._replaceInputBox.value, this._replaceInputBox.element.querySelector('textarea')); + return stopPropagationForMultiLineDownwards(e, this._replaceInput.inputBox.value, this._replaceInput.inputBox.element.querySelector('textarea')); } } @@ -913,6 +909,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } }, flexibleHeight: true, + flexibleWidth: true, flexibleMaxHeight: 118 }, this._contextKeyService, true)); this._findInput.setRegex(!!this._state.isRegex); @@ -935,7 +932,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas this._register(this._findInput.onCaseSensitiveKeyDown((e) => { if (e.equals(KeyMod.Shift | KeyCode.Tab)) { if (this._isReplaceVisible) { - this._replaceInputBox.focus(); + this._replaceInput.focus(); e.preventDefault(); } } @@ -943,7 +940,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas this._register(this._findInput.onRegexKeyDown((e) => { if (e.equals(KeyCode.Tab)) { if (this._isReplaceVisible) { - this._preserveCase.focus(); + this._replaceInput.focusOnPreserve(); e.preventDefault(); } } @@ -1034,41 +1031,30 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas actionsContainer.appendChild(this._closeBtn.domNode); // Replace input - let replaceInput = document.createElement('div'); - replaceInput.className = 'replace-input'; - replaceInput.style.width = REPLACE_INPUT_AREA_WIDTH + 'px'; - this._replaceInputBox = this._register(new ContextScopedHistoryInputBox(replaceInput, undefined, { - ariaLabel: NLS_REPLACE_INPUT_LABEL, + this._replaceInput = this._register(new ContextScopedReplaceInput(null, undefined, { + label: NLS_REPLACE_INPUT_LABEL, placeholder: NLS_REPLACE_INPUT_PLACEHOLDER, history: [], flexibleHeight: true, + flexibleWidth: true, flexibleMaxHeight: 118 - }, this._contextKeyService)); - - - this._register(dom.addStandardDisposableListener(this._replaceInputBox.inputElement, 'keydown', (e) => this._onReplaceInputKeyDown(e))); - this._register(this._replaceInputBox.onDidChange(() => { - this._state.change({ replaceString: this._replaceInputBox.value }, false); + }, this._contextKeyService, true)); + this._replaceInput.setPreserveCase(!!this._state.preserveCase); + this._register(this._replaceInput.onKeyDown((e) => this._onReplaceInputKeyDown(e))); + this._register(this._replaceInput.inputBox.onDidChange(() => { + this._state.change({ replaceString: this._replaceInput.inputBox.value }, false); })); - this._register(this._replaceInputBox.onDidHeightChange((e) => { + this._register(this._replaceInput.inputBox.onDidHeightChange((e) => { if (this._isReplaceVisible && this._tryUpdateHeight()) { this._showViewZone(); } })); - - this._preserveCase = this._register(new Checkbox({ - actionClassName: 'monaco-preserve-case', - title: NLS_PRESERVE_CASE_LABEL, - isChecked: false, + this._register(this._replaceInput.onDidOptionChange(() => { + this._state.change({ + preserveCase: this._replaceInput.getPreserveCase() + }, true); })); - this._preserveCase.checked = !!this._state.preserveCase; - this._register(this._preserveCase.onChange(viaKeyboard => { - if (!viaKeyboard) { - this._state.change({ preserveCase: !this._state.preserveCase }, false); - this._replaceInputBox.focus(); - } - })); - this._register(this._preserveCase.onKeyDown((e) => { + this._register(this._replaceInput.onPreserveCaseKeyDown((e) => { if (e.equals(KeyCode.Tab)) { if (this._prevBtn.isEnabled()) { this._prevBtn.focus(); @@ -1082,8 +1068,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas e.preventDefault(); } - } - )); + })); // Replace one button this._replaceBtn = this._register(new SimpleButton({ @@ -1109,15 +1094,9 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } })); - let controls = document.createElement('div'); - controls.className = 'controls'; - controls.style.display = 'block'; - controls.appendChild(this._preserveCase.domNode); - replaceInput.appendChild(controls); - let replacePart = document.createElement('div'); replacePart.className = 'replace-part'; - replacePart.appendChild(replaceInput); + replacePart.appendChild(this._replaceInput.domNode); const replaceActionsContainer = document.createElement('div'); replaceActionsContainer.className = 'replace-actions'; @@ -1133,8 +1112,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas onTrigger: () => { this._state.change({ isReplaceRevealed: !this._isReplaceVisible }, false); if (this._isReplaceVisible) { - this._replaceInputBox.width = this._findInput.inputBox.width; - this._replaceInputBox.layout(); + this._replaceInput.width = dom.getTotalWidth(this._findInput.domNode); + this._replaceInput.inputBox.layout(); } this._showViewZone(); } @@ -1179,7 +1158,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas this._domNode.style.width = `${width}px`; this._findInput.inputBox.width = inputBoxWidth; if (this._isReplaceVisible) { - this._replaceInputBox.width = inputBoxWidth; + this._replaceInput.width = dom.getTotalWidth(this._findInput.domNode); } this._findInput.inputBox.layout(); diff --git a/src/vs/platform/browser/contextScopedHistoryWidget.ts b/src/vs/platform/browser/contextScopedHistoryWidget.ts index 5e5e8603683..8625db10ee8 100644 --- a/src/vs/platform/browser/contextScopedHistoryWidget.ts +++ b/src/vs/platform/browser/contextScopedHistoryWidget.ts @@ -10,6 +10,7 @@ import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview import { IHistoryNavigationWidget } from 'vs/base/browser/history'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; +import { ReplaceInput, IReplaceInputOptions } from 'vs/base/browser/ui/findinput/replaceInput'; export const HistoryNavigationWidgetContext = 'historyNavigationWidget'; export const HistoryNavigationEnablementContext = 'historyNavigationEnabled'; @@ -60,6 +61,16 @@ export class ContextScopedFindInput extends FindInput { super(container, contextViewProvider, showFindOptions, options); this._register(createAndBindHistoryNavigationWidgetScopedContextKeyService(contextKeyService, { target: this.inputBox.element, historyNavigator: this.inputBox }).scopedContextKeyService); } +} + +export class ContextScopedReplaceInput extends ReplaceInput { + + constructor(container: HTMLElement | null, contextViewProvider: IContextViewProvider | undefined, options: IReplaceInputOptions, + @IContextKeyService contextKeyService: IContextKeyService, showReplaceOptions: boolean = false + ) { + super(container, contextViewProvider, showReplaceOptions, options); + this._register(createAndBindHistoryNavigationWidgetScopedContextKeyService(contextKeyService, { target: this.inputBox.element, historyNavigator: this.inputBox }).scopedContextKeyService); + } } From 3d4e72b0bd3b5a88a301eb631f49775a3f92a0dd Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 20 Aug 2019 11:50:59 -0700 Subject: [PATCH 846/861] remove commented code --- src/vs/base/browser/ui/findinput/replaceInput.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/vs/base/browser/ui/findinput/replaceInput.ts b/src/vs/base/browser/ui/findinput/replaceInput.ts index db0c44edf2e..d597fb8bd49 100644 --- a/src/vs/base/browser/ui/findinput/replaceInput.ts +++ b/src/vs/base/browser/ui/findinput/replaceInput.ts @@ -296,11 +296,6 @@ export class ReplaceInput extends Widget { if (this._showOptionButtons) { this.cachedOptionsWidth = this.preserveCase.width(); - // const paddingRight = () + 'px'; - // this.inputBox.inputElement.style.paddingRight = paddingRight; - // if (this.inputBox.mirrorElement) { - // this.inputBox.mirrorElement.style.paddingRight = paddingRight; - // } } else { this.cachedOptionsWidth = 0; } From 3b3490c29c0f636c3fa1323f5c1a6869dcd301a0 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 20 Aug 2019 14:08:15 -0700 Subject: [PATCH 847/861] Sort imports --- src/vs/base/browser/ui/inputbox/inputBox.ts | 1 + src/vs/editor/contrib/find/findWidget.ts | 14 ++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/vs/base/browser/ui/inputbox/inputBox.ts b/src/vs/base/browser/ui/inputbox/inputBox.ts index 3bd9a5ce12b..430f250ce38 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.ts +++ b/src/vs/base/browser/ui/inputbox/inputBox.ts @@ -178,6 +178,7 @@ export class InputBox extends Widget { if (this.options.flexibleWidth) { this.input.setAttribute('wrap', 'off'); this.mirror.style.whiteSpace = 'pre'; + this.mirror.style.wordWrap = 'initial'; } dom.append(container, this.scrollableElement.getDomNode()); diff --git a/src/vs/editor/contrib/find/findWidget.ts b/src/vs/editor/contrib/find/findWidget.ts index 865fb6c220d..c98923dff42 100644 --- a/src/vs/editor/contrib/find/findWidget.ts +++ b/src/vs/editor/contrib/find/findWidget.ts @@ -9,8 +9,10 @@ import * as dom from 'vs/base/browser/dom'; import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { IMouseEvent } from 'vs/base/browser/mouseEvent'; import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview'; +import { alert as alertFn } from 'vs/base/browser/ui/aria/aria'; import { FindInput, IFindInputStyles } from 'vs/base/browser/ui/findinput/findInput'; import { IMessage as InputBoxMessage } from 'vs/base/browser/ui/inputbox/inputBox'; +import { ReplaceInput } from 'vs/base/browser/ui/findinput/replaceInput'; import { IHorizontalSashLayoutProvider, ISashEvent, Orientation, Sash } from 'vs/base/browser/ui/sash/sash'; import { Widget } from 'vs/base/browser/ui/widget'; import { Delayer } from 'vs/base/common/async'; @@ -31,8 +33,6 @@ import { contrastBorder, editorFindMatch, editorFindMatchBorder, editorFindMatch import { ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { ContextScopedFindInput, ContextScopedReplaceInput } from 'vs/platform/browser/contextScopedHistoryWidget'; import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; -import { alert as alertFn } from 'vs/base/browser/ui/aria/aria'; -import { ReplaceInput } from 'vs/base/browser/ui/findinput/replaceInput'; export interface IFindController { replace(): void; @@ -888,6 +888,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } private _buildDomNode(): void { + const flexibleHeight = platform.isNative; + const flexibleWidth = platform.isNative; // Find input this._findInput = this._register(new ContextScopedFindInput(null, this._contextViewProvider, { width: FIND_INPUT_AREA_WIDTH, @@ -908,8 +910,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas return { content: e.message }; } }, - flexibleHeight: true, - flexibleWidth: true, + flexibleHeight, + flexibleWidth, flexibleMaxHeight: 118 }, this._contextKeyService, true)); this._findInput.setRegex(!!this._state.isRegex); @@ -1035,8 +1037,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas label: NLS_REPLACE_INPUT_LABEL, placeholder: NLS_REPLACE_INPUT_PLACEHOLDER, history: [], - flexibleHeight: true, - flexibleWidth: true, + flexibleHeight, + flexibleWidth, flexibleMaxHeight: 118 }, this._contextKeyService, true)); this._replaceInput.setPreserveCase(!!this._state.preserveCase); From e37d0e7e43f26f387b92e9b54c60d1f199f21608 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 20 Aug 2019 14:18:13 -0700 Subject: [PATCH 848/861] Auto rewrite vscode-resource entries in csp in web iframe based webviews --- src/vs/workbench/contrib/webview/browser/pre/main.js | 5 +++++ src/vs/workbench/contrib/webview/browser/webviewElement.ts | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/webview/browser/pre/main.js b/src/vs/workbench/contrib/webview/browser/pre/main.js index 0b25585c611..c766b83c114 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/main.js +++ b/src/vs/workbench/contrib/webview/browser/pre/main.js @@ -289,6 +289,11 @@ const csp = newDocument.querySelector('meta[http-equiv="Content-Security-Policy"]'); if (!csp) { host.postMessage('no-csp-found'); + } else { + // Rewrite vscode-resource in csp + if (data.endpoint) { + csp.setAttribute('content', csp.getAttribute('content').replace(/vscode-resource:/g, data.endpoint)); + } } // set DOCTYPE for newDocument explicitly as DOMParser.parseFromString strips it off diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index 65b09a14dde..7a0015be053 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -202,7 +202,8 @@ export class IFrameWebview extends Disposable implements Webview { this._send('content', { contents: this.content.html, options: this.content.options, - state: this.content.state + state: this.content.state, + endpoint: this.endpoint, }); } From 5bfea5092d4e300e72cb597cb82ebef82c7258b8 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 20 Aug 2019 14:52:53 -0700 Subject: [PATCH 849/861] Move more inputbox keybindings to Commands --- src/vs/editor/contrib/find/findController.ts | 85 ++++++++++++++++++-- src/vs/editor/contrib/find/findWidget.ts | 52 ++++++------ 2 files changed, 103 insertions(+), 34 deletions(-) diff --git a/src/vs/editor/contrib/find/findController.ts b/src/vs/editor/contrib/find/findController.ts index ed3544d10ff..664bc8c8bf3 100644 --- a/src/vs/editor/contrib/find/findController.ts +++ b/src/vs/editor/contrib/find/findController.ts @@ -12,19 +12,20 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorAction, EditorCommand, ServicesAccessor, registerEditorAction, registerEditorCommand, registerEditorContribution } from 'vs/editor/browser/editorExtensions'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; -import { CONTEXT_FIND_INPUT_FOCUSED, CONTEXT_FIND_WIDGET_VISIBLE, FIND_IDS, FindModelBoundToEditorModel, ToggleCaseSensitiveKeybinding, ToggleRegexKeybinding, ToggleSearchScopeKeybinding, ToggleWholeWordKeybinding } from 'vs/editor/contrib/find/findModel'; +import { CONTEXT_FIND_INPUT_FOCUSED, CONTEXT_FIND_WIDGET_VISIBLE, FIND_IDS, FindModelBoundToEditorModel, ToggleCaseSensitiveKeybinding, ToggleRegexKeybinding, ToggleSearchScopeKeybinding, ToggleWholeWordKeybinding, CONTEXT_REPLACE_INPUT_FOCUSED } from 'vs/editor/contrib/find/findModel'; import { FindOptionsWidget } from 'vs/editor/contrib/find/findOptionsWidget'; import { FindReplaceState, FindReplaceStateChangedEvent, INewFindReplaceState } from 'vs/editor/contrib/find/findState'; import { FindWidget, IFindController } from 'vs/editor/contrib/find/findWidget'; import { MenuId } from 'vs/platform/actions/common/actions'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; -import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IContextKey, IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { optional } from 'vs/platform/instantiation/common/instantiation'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { INotificationService } from 'vs/platform/notification/common/notification'; const SEARCH_STRING_MAX_LENGTH = 524288; @@ -75,7 +76,7 @@ export class CommonFindController extends Disposable implements editorCommon.IEd protected _state: FindReplaceState; protected _updateHistoryDelayer: Delayer; private _model: FindModelBoundToEditorModel | null; - private readonly _storageService: IStorageService; + protected readonly _storageService: IStorageService; private readonly _clipboardService: IClipboardService; protected readonly _contextKeyService: IContextKeyService; @@ -383,10 +384,11 @@ export class FindController extends CommonFindController implements IFindControl @IContextKeyService _contextKeyService: IContextKeyService, @IKeybindingService private readonly _keybindingService: IKeybindingService, @IThemeService private readonly _themeService: IThemeService, - @IStorageService storageService: IStorageService, - @optional(IClipboardService) clipboardService: IClipboardService + @INotificationService private readonly _notificationService: INotificationService, + @IStorageService _storageService: IStorageService, + @optional(IClipboardService) clipboardService: IClipboardService, ) { - super(editor, _contextKeyService, storageService, clipboardService); + super(editor, _contextKeyService, _storageService, clipboardService); this._widget = null; this._findOptionsWidget = null; } @@ -422,7 +424,7 @@ export class FindController extends CommonFindController implements IFindControl } private _createFindWidget() { - this._widget = this._register(new FindWidget(this._editor, this, this._state, this._contextViewService, this._keybindingService, this._contextKeyService, this._themeService)); + this._widget = this._register(new FindWidget(this._editor, this, this._state, this._contextViewService, this._keybindingService, this._contextKeyService, this._themeService, this._storageService, this._notificationService)); this._findOptionsWidget = this._register(new FindOptionsWidget(this._editor, this._state, this._keybindingService, this._themeService)); } } @@ -540,6 +542,27 @@ export class NextMatchFindAction extends MatchFindAction { } } +export class NextMatchFindAction2 extends MatchFindAction { + + constructor() { + super({ + id: FIND_IDS.NextMatchFindAction, + label: nls.localize('findNextMatchAction', "Find Next"), + alias: 'Find Next', + precondition: undefined, + kbOpts: { + kbExpr: ContextKeyExpr.and(EditorContextKeys.focus, CONTEXT_FIND_INPUT_FOCUSED), + primary: KeyCode.Enter, + weight: KeybindingWeight.EditorContrib + } + }); + } + + protected _run(controller: CommonFindController): boolean { + return controller.moveToNextMatch(); + } +} + export class PreviousMatchFindAction extends MatchFindAction { constructor() { @@ -562,6 +585,27 @@ export class PreviousMatchFindAction extends MatchFindAction { } } +export class PreviousMatchFindAction2 extends MatchFindAction { + + constructor() { + super({ + id: FIND_IDS.PreviousMatchFindAction, + label: nls.localize('findPreviousMatchAction', "Find Previous"), + alias: 'Find Previous', + precondition: undefined, + kbOpts: { + kbExpr: ContextKeyExpr.and(EditorContextKeys.focus, CONTEXT_FIND_INPUT_FOCUSED), + primary: KeyMod.Shift | KeyCode.Enter, + weight: KeybindingWeight.EditorContrib + } + }); + } + + protected _run(controller: CommonFindController): boolean { + return controller.moveToPrevMatch(); + } +} + export abstract class SelectionMatchFindAction extends EditorAction { public run(accessor: ServicesAccessor | null, editor: ICodeEditor): void { let controller = CommonFindController.get(editor); @@ -695,7 +739,9 @@ registerEditorContribution(FindController); registerEditorAction(StartFindAction); registerEditorAction(StartFindWithSelectionAction); registerEditorAction(NextMatchFindAction); +registerEditorAction(NextMatchFindAction2); registerEditorAction(PreviousMatchFindAction); +registerEditorAction(PreviousMatchFindAction2); registerEditorAction(NextSelectionMatchFindAction); registerEditorAction(PreviousSelectionMatchFindAction); registerEditorAction(StartFindReplaceAction); @@ -781,6 +827,17 @@ registerEditorCommand(new FindCommand({ } })); +registerEditorCommand(new FindCommand({ + id: FIND_IDS.ReplaceOneAction, + precondition: CONTEXT_FIND_WIDGET_VISIBLE, + handler: x => x.replace(), + kbOpts: { + weight: KeybindingWeight.EditorContrib + 5, + kbExpr: ContextKeyExpr.and(EditorContextKeys.focus, CONTEXT_REPLACE_INPUT_FOCUSED), + primary: KeyCode.Enter + } +})); + registerEditorCommand(new FindCommand({ id: FIND_IDS.ReplaceAllAction, precondition: CONTEXT_FIND_WIDGET_VISIBLE, @@ -792,6 +849,20 @@ registerEditorCommand(new FindCommand({ } })); +registerEditorCommand(new FindCommand({ + id: FIND_IDS.ReplaceAllAction, + precondition: CONTEXT_FIND_WIDGET_VISIBLE, + handler: x => x.replaceAll(), + kbOpts: { + weight: KeybindingWeight.EditorContrib + 5, + kbExpr: ContextKeyExpr.and(EditorContextKeys.focus, CONTEXT_REPLACE_INPUT_FOCUSED), + primary: undefined, + mac: { + primary: KeyMod.CtrlCmd | KeyCode.Enter, + } + } +})); + registerEditorCommand(new FindCommand({ id: FIND_IDS.SelectAllMatchesAction, precondition: CONTEXT_FIND_WIDGET_VISIBLE, diff --git a/src/vs/editor/contrib/find/findWidget.ts b/src/vs/editor/contrib/find/findWidget.ts index c98923dff42..d56ad012398 100644 --- a/src/vs/editor/contrib/find/findWidget.ts +++ b/src/vs/editor/contrib/find/findWidget.ts @@ -33,6 +33,8 @@ import { contrastBorder, editorFindMatch, editorFindMatchBorder, editorFindMatch import { ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { ContextScopedFindInput, ContextScopedReplaceInput } from 'vs/platform/browser/contextScopedHistoryWidget'; import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; +import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; +import { INotificationService } from 'vs/platform/notification/common/notification'; export interface IFindController { replace(): void; @@ -63,6 +65,7 @@ let MAX_MATCHES_COUNT_WIDTH = 69; let FIND_ALL_CONTROLS_WIDTH = 17/** Find Input margin-left */ + (MAX_MATCHES_COUNT_WIDTH + 3 + 1) /** Match Results */ + 23 /** Button */ * 4 + 2/** sash */; const FIND_INPUT_AREA_HEIGHT = 33; // The height of Find Widget when Replace Input is not visible. +const ctrlEnterReplaceAllWarningPromptedKey = 'ctrlEnterReplaceAll.windows.donotask'; export class FindWidgetViewZone implements IViewZone { public readonly afterLineNumber: number; @@ -104,6 +107,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas private readonly _contextViewProvider: IContextViewProvider; private readonly _keybindingService: IKeybindingService; private readonly _contextKeyService: IContextKeyService; + private readonly _storageService: IStorageService; + private readonly _notificationService: INotificationService; private _domNode!: HTMLElement; private _cachedHeight: number | null; @@ -122,6 +127,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas private _isVisible: boolean; private _isReplaceVisible: boolean; private _ignoreChangeEvent: boolean; + private _ctrlEnterReplaceAllWarningPrompted: boolean; private readonly _findFocusTracker: dom.IFocusTracker; private readonly _findInputFocused: IContextKey; @@ -141,7 +147,9 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas contextViewProvider: IContextViewProvider, keybindingService: IKeybindingService, contextKeyService: IContextKeyService, - themeService: IThemeService + themeService: IThemeService, + storageService: IStorageService, + notificationService: INotificationService, ) { super(); this._codeEditor = codeEditor; @@ -150,6 +158,10 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas this._contextViewProvider = contextViewProvider; this._keybindingService = keybindingService; this._contextKeyService = contextKeyService; + this._storageService = storageService; + this._notificationService = notificationService; + + this._ctrlEnterReplaceAllWarningPrompted = !!storageService.getBoolean(ctrlEnterReplaceAllWarningPromptedKey, StorageScope.GLOBAL); this._isVisible = false; this._isReplaceVisible = false; @@ -755,19 +767,6 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } private _onFindInputKeyDown(e: IKeyboardEvent): void { - - if (e.equals(KeyCode.Enter)) { - this._codeEditor.getAction(FIND_IDS.NextMatchFindAction).run().then(undefined, onUnexpectedError); - e.preventDefault(); - return; - } - - if (e.equals(KeyMod.Shift | KeyCode.Enter)) { - this._codeEditor.getAction(FIND_IDS.PreviousMatchFindAction).run().then(undefined, onUnexpectedError); - e.preventDefault(); - return; - } - if (e.equals(KeyMod.WinCtrl | KeyCode.Enter)) { const inputElement = this._findInput.inputBox.inputElement; const start = inputElement.selectionStart; @@ -810,14 +809,19 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } private _onReplaceInputKeyDown(e: IKeyboardEvent): void { - - if (e.equals(KeyCode.Enter)) { - this._controller.replace(); - e.preventDefault(); - return; - } - if (e.equals(KeyMod.WinCtrl | KeyCode.Enter)) { + if (platform.isWindows && platform.isNative && !this._ctrlEnterReplaceAllWarningPrompted) { + // this is the first time when users press Ctrl + Enter to replace all + this._notificationService.info( + nls.localize('ctrlEnter.keybindingChanged', + 'Ctrl+Enter now inserts line break instead of replacing all. You can modify the keybinding for editor.action.replaceAll to override this behavior.') + ); + + this._ctrlEnterReplaceAllWarningPrompted = true; + this._storageService.store(ctrlEnterReplaceAllWarningPromptedKey, true, StorageScope.GLOBAL); + + } + const inputElement = this._replaceInput.inputBox.inputElement; const start = inputElement.selectionStart; const end = inputElement.selectionEnd; @@ -833,12 +837,6 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } } - if (e.equals(KeyMod.CtrlCmd | KeyCode.Enter)) { - this._controller.replaceAll(); - e.preventDefault(); - return; - } - if (e.equals(KeyCode.Tab)) { this._findInput.focusOnCaseSensitive(); e.preventDefault(); From 7cbc0d78f20a72d5bad1423eb5f904e56f1881be Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 20 Aug 2019 14:56:35 -0700 Subject: [PATCH 850/861] Add try/catch around .focus call Fixes #79171 --- .../contrib/webview/electron-browser/webviewElement.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts index 830fd2effc8..bdd1c7e3956 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts @@ -496,7 +496,11 @@ export class ElectronWebviewBasedWebview extends Disposable implements Webview { if (!this._webview) { return; } - this._webview.focus(); + try { + this._webview.focus(); + } catch { + // noop + } this._send('focus'); // Handle focus change programmatically (do not rely on event from ) From 646d4ddb759171479bd6a02a2b306610c30efc96 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 20 Aug 2019 15:07:25 -0700 Subject: [PATCH 851/861] Use _register --- .../src/features/preview.ts | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/extensions/markdown-language-features/src/features/preview.ts b/extensions/markdown-language-features/src/features/preview.ts index 775734d1140..3ee4d26f4f2 100644 --- a/extensions/markdown-language-features/src/features/preview.ts +++ b/extensions/markdown-language-features/src/features/preview.ts @@ -172,19 +172,19 @@ export class MarkdownPreview extends Disposable { this._locked = locked; this.editor = webview; - this.editor.onDidDispose(() => { + this._register(this.editor.onDidDispose(() => { this.dispose(); - }, null, this._disposables); + })); - this.editor.onDidChangeViewState(e => { + this._register(this.editor.onDidChangeViewState(e => { this._onDidChangeViewStateEmitter.fire(e); - }, null, this._disposables); + })); - _contributionProvider.onContributionsChanged(() => { + this._register(_contributionProvider.onContributionsChanged(() => { setImmediate(() => this.refresh()); - }, null, this._disposables); + })); - this.editor.webview.onDidReceiveMessage((e: CacheImageSizesMessage | RevealLineMessage | DidClickMessage | ClickLinkMessage | ShowPreviewSecuritySelectorMessage | PreviewStyleLoadErrorMessage) => { + this._register(this.editor.webview.onDidReceiveMessage((e: CacheImageSizesMessage | RevealLineMessage | DidClickMessage | ClickLinkMessage | ShowPreviewSecuritySelectorMessage | PreviewStyleLoadErrorMessage) => { if (e.source !== this._resource.toString()) { return; } @@ -214,21 +214,21 @@ export class MarkdownPreview extends Disposable { vscode.window.showWarningMessage(localize('onPreviewStyleLoadError', "Could not load 'markdown.styles': {0}", e.body.unloadedStyles.join(', '))); break; } - }, null, this._disposables); + })); - vscode.workspace.onDidChangeTextDocument(event => { + this._register(vscode.workspace.onDidChangeTextDocument(event => { if (this.isPreviewOf(event.document.uri)) { this.refresh(); } - }, null, this._disposables); + })); - topmostLineMonitor.onDidChangeTopmostLine(event => { + this._register(topmostLineMonitor.onDidChangeTopmostLine(event => { if (this.isPreviewOf(event.resource)) { this.updateForView(event.resource, event.line); } - }, null, this._disposables); + })); - vscode.window.onDidChangeTextEditorSelection(event => { + this._register(vscode.window.onDidChangeTextEditorSelection(event => { if (this.isPreviewOf(event.textEditor.document.uri)) { this.postMessage({ type: 'onDidChangeTextEditorSelection', @@ -236,19 +236,19 @@ export class MarkdownPreview extends Disposable { source: this.resource.toString() }); } - }, null, this._disposables); + })); - vscode.window.onDidChangeActiveTextEditor(editor => { + this._register(vscode.window.onDidChangeActiveTextEditor(editor => { if (editor && isMarkdownFile(editor.document) && !this._locked) { this.update(editor.document.uri); } - }, null, this._disposables); + })); } - private readonly _onDisposeEmitter = new vscode.EventEmitter(); + private readonly _onDisposeEmitter = this._register(new vscode.EventEmitter()); public readonly onDispose = this._onDisposeEmitter.event; - private readonly _onDidChangeViewStateEmitter = new vscode.EventEmitter(); + private readonly _onDidChangeViewStateEmitter = this._register(new vscode.EventEmitter()); public readonly onDidChangeViewState = this._onDidChangeViewStateEmitter.event; public get resource(): vscode.Uri { From 5e5721210771b3b12dfc35b233f96c8d542ff748 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 20 Aug 2019 15:52:56 -0700 Subject: [PATCH 852/861] Better handle cases where webview view state in api can get out sync with real view state Fixes #79492 Simplifies view state management logic in `mainThreadWebviews` to: * Not be stateful * Handle cases where a webview's view state changes through a more complex means (see #79492 for an example of this) --- .../api/browser/mainThreadWebview.ts | 85 ++++++------------- src/vs/workbench/api/common/extHostWebview.ts | 5 +- 2 files changed, 30 insertions(+), 60 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadWebview.ts b/src/vs/workbench/api/browser/mainThreadWebview.ts index d4beebbd5ff..a405a4b108c 100644 --- a/src/vs/workbench/api/browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/browser/mainThreadWebview.ts @@ -17,7 +17,7 @@ import { editorGroupToViewColumn, EditorViewColumn, viewColumnToEditorGroup } fr import { WebviewEditorInput } from 'vs/workbench/contrib/webview/browser/webviewEditorInput'; import { ICreateWebViewShowOptions, IWebviewEditorService, WebviewInputOptions } from 'vs/workbench/contrib/webview/browser/webviewEditorService'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; -import { ACTIVE_GROUP, IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { extHostNamedCustomer } from '../common/extHostCustomers'; import { IProductService } from 'vs/platform/product/common/product'; @@ -47,8 +47,6 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews private readonly _webviews = new Map(); private readonly _revivers = new Map(); - private _activeWebview: WebviewPanelHandle | undefined = undefined; - constructor( context: IExtHostContext, @IExtensionService extensionService: IExtensionService, @@ -62,8 +60,8 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews super(); this._proxy = context.getProxy(ExtHostContext.ExtHostWebviews); - this._register(_editorService.onDidActiveEditorChange(this.onActiveEditorChanged, this)); - this._register(_editorService.onDidVisibleEditorsChange(this.onVisibleEditorsChanged, this)); + this._register(_editorService.onDidActiveEditorChange(this.updateWebviewViewStates, this)); + this._register(_editorService.onDidVisibleEditorsChange(this.updateWebviewViewStates, this)); // This reviver's only job is to activate webview extensions // This should trigger the real reviver to be registered from the extension host side. @@ -246,70 +244,41 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews }); } - private onActiveEditorChanged() { + private updateWebviewViewStates() { const activeEditor = this._editorService.activeControl; - let newActiveWebview: { input: WebviewEditorInput, handle: WebviewPanelHandle } | undefined = undefined; - if (activeEditor && activeEditor.input instanceof WebviewEditorInput) { - for (const handle of map.keys(this._webviewEditorInputs)) { - const input = this._webviewEditorInputs.get(handle)!; - if (input.matches(activeEditor.input)) { - newActiveWebview = { input, handle }; - break; + + const webviews = new Map(); + for (const group of this._editorGroupService.groups) { + for (const input of group.editors) { + if (!(input instanceof WebviewEditorInput)) { + continue; } - } - } - - if (newActiveWebview && newActiveWebview.handle === this._activeWebview) { - // Webview itself unchanged but position may have changed - this._proxy.$onDidChangeWebviewPanelViewState(newActiveWebview.handle, { - active: true, - visible: true, - position: editorGroupToViewColumn(this._editorGroupService, newActiveWebview.input.group || 0) - }); - return; - } - - // Broadcast view state update for currently active - if (typeof this._activeWebview !== 'undefined') { - const oldActiveWebview = this._webviewEditorInputs.get(this._activeWebview); - if (oldActiveWebview) { - this._proxy.$onDidChangeWebviewPanelViewState(this._activeWebview, { - active: false, - visible: this._editorService.visibleControls.some(editor => !!editor.input && editor.input.matches(oldActiveWebview)), - position: editorGroupToViewColumn(this._editorGroupService, oldActiveWebview.group || 0), + webviews.set(input, { + group: group.id, + visible: input === group.activeEditor, + active: !!activeEditor && input === activeEditor.input }); } } - // Then for newly active - if (newActiveWebview) { - this._proxy.$onDidChangeWebviewPanelViewState(newActiveWebview.handle, { - active: true, - visible: true, - position: editorGroupToViewColumn(this._editorGroupService, activeEditor ? activeEditor.group : ACTIVE_GROUP), - }); - this._activeWebview = newActiveWebview.handle; - } else { - this._activeWebview = undefined; - } - } - - private onVisibleEditorsChanged(): void { - this._webviewEditorInputs.forEach((input, handle) => { - for (const workbenchEditor of this._editorService.visibleControls) { - if (workbenchEditor.input && workbenchEditor.input.matches(input)) { - const editorPosition = editorGroupToViewColumn(this._editorGroupService, workbenchEditor.group!); - - input.updateGroup(workbenchEditor.group!.id); + for (const webview of map.keys(webviews)) { + const state = webviews.get(webview)!; + for (const handle of map.keys(this._webviewEditorInputs)) { + const input = this._webviewEditorInputs.get(handle)!; + if (input === webview) { this._proxy.$onDidChangeWebviewPanelViewState(handle, { - active: handle === this._activeWebview, - visible: true, - position: editorPosition + active: state.active, + visible: state.visible, + position: editorGroupToViewColumn(this._editorGroupService, state.group || 0), }); break; } } - }); + } } private onDidClickLink(handle: WebviewPanelHandle, link: URI): void { diff --git a/src/vs/workbench/api/common/extHostWebview.ts b/src/vs/workbench/api/common/extHostWebview.ts index 44b99bcbd4c..adfe974bcf4 100644 --- a/src/vs/workbench/api/common/extHostWebview.ts +++ b/src/vs/workbench/api/common/extHostWebview.ts @@ -89,11 +89,12 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { private readonly _options: vscode.WebviewPanelOptions; private readonly _webview: ExtHostWebview; - private _isDisposed: boolean = false; private _viewColumn: vscode.ViewColumn | undefined; private _visible: boolean = true; private _active: boolean = true; + _isDisposed: boolean = false; + readonly _onDisposeEmitter = new Emitter(); public readonly onDidDispose: Event = this._onDisposeEmitter.event; @@ -302,7 +303,7 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { newState: WebviewPanelViewState ): void { const panel = this.getWebviewPanel(handle); - if (!panel) { + if (!panel || panel._isDisposed) { return; } From 1c05a14d3cacb19dacbe614056d67d3905d9e71d Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 20 Aug 2019 16:00:23 -0700 Subject: [PATCH 853/861] Don't track webviews separately from inputs The webviews should always be accessible through the inputs --- src/vs/workbench/api/browser/mainThreadWebview.ts | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadWebview.ts b/src/vs/workbench/api/browser/mainThreadWebview.ts index a405a4b108c..a87e8ba83be 100644 --- a/src/vs/workbench/api/browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/browser/mainThreadWebview.ts @@ -44,7 +44,6 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews private readonly _proxy: ExtHostWebviewsShape; private readonly _webviewEditorInputs = new Map(); - private readonly _webviews = new Map(); private readonly _revivers = new Map(); constructor( @@ -103,7 +102,6 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews this.hookupWebviewEventDelegate(handle, webview); this._webviewEditorInputs.set(handle, webview); - this._webviews.set(handle, webview.webview); /* __GDPR__ "webviews:createWebviewPanel" : { @@ -174,7 +172,6 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews const handle = `revival-${MainThreadWebviews.revivalPool++}`; this._webviewEditorInputs.set(handle, webviewEditorInput); - this._webviews.set(handle, webviewEditorInput.webview); this.hookupWebviewEventDelegate(handle, webviewEditorInput); let state = undefined; @@ -232,7 +229,6 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews input.onDispose(() => { this._proxy.$onDidDisposeWebviewPanel(handle).finally(() => { this._webviewEditorInputs.delete(handle); - this._webviews.delete(handle); }); }); input.webview.onDidUpdateState((newState: any) => { @@ -315,15 +311,7 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews } private getWebview(handle: WebviewPanelHandle): Webview { - const webview = this.tryGetWebview(handle); - if (!webview) { - throw new Error('Unknown webview handle:' + handle); - } - return webview; - } - - private tryGetWebview(handle: WebviewPanelHandle): Webview | undefined { - return this._webviews.get(handle); + return this.getWebviewEditorInput(handle).webview; } private static getDeserializationFailedContents(viewType: string) { From 4d9460470a66905a7d7950dcc35bb42ddf1fbfe5 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 20 Aug 2019 16:01:31 -0700 Subject: [PATCH 854/861] Simplify csp for getDeserializationFailedContents This page should never contain anything except text --- src/vs/workbench/api/browser/mainThreadWebview.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadWebview.ts b/src/vs/workbench/api/browser/mainThreadWebview.ts index a87e8ba83be..cd44af83844 100644 --- a/src/vs/workbench/api/browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/browser/mainThreadWebview.ts @@ -318,9 +318,8 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews return ` - - + ${localize('errorMessage', "An error occurred while restoring view:{0}", viewType)} `; From b1dd95c883668f6014973908f7c27cfe0a9d8cda Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 20 Aug 2019 16:20:42 -0700 Subject: [PATCH 855/861] Fire a single batched event internally to update all webview view states Previously we fired one event per webview. This change switches to fire on event per update --- .../api/browser/mainThreadWebview.ts | 46 +++++++++---------- .../workbench/api/common/extHost.protocol.ts | 12 +++-- src/vs/workbench/api/common/extHostWebview.ts | 38 +++++++-------- 3 files changed, 47 insertions(+), 49 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadWebview.ts b/src/vs/workbench/api/browser/mainThreadWebview.ts index cd44af83844..fdff6a4e387 100644 --- a/src/vs/workbench/api/browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/browser/mainThreadWebview.ts @@ -12,7 +12,7 @@ import { localize } from 'vs/nls'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { ExtHostContext, ExtHostWebviewsShape, IExtHostContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelShowOptions } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostContext, ExtHostWebviewsShape, IExtHostContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelShowOptions, WebviewPanelViewStateData } from 'vs/workbench/api/common/extHost.protocol'; import { editorGroupToViewColumn, EditorViewColumn, viewColumnToEditorGroup } from 'vs/workbench/api/common/shared/editor'; import { WebviewEditorInput } from 'vs/workbench/contrib/webview/browser/webviewEditorInput'; import { ICreateWebViewShowOptions, IWebviewEditorService, WebviewInputOptions } from 'vs/workbench/contrib/webview/browser/webviewEditorService'; @@ -23,6 +23,7 @@ import { extHostNamedCustomer } from '../common/extHostCustomers'; import { IProductService } from 'vs/platform/product/common/product'; import { startsWith } from 'vs/base/common/strings'; import { Webview } from 'vs/workbench/contrib/webview/browser/webview'; +import { find } from 'vs/base/common/arrays'; interface OldMainThreadWebviewState { readonly viewType: string; @@ -241,39 +242,34 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews } private updateWebviewViewStates() { - const activeEditor = this._editorService.activeControl; + if (!this._webviewEditorInputs.size) { + return; + } - const webviews = new Map(); + const activeInput = this._editorService.activeControl && this._editorService.activeControl.input; + const viewStates: WebviewPanelViewStateData = {}; for (const group of this._editorGroupService.groups) { for (const input of group.editors) { if (!(input instanceof WebviewEditorInput)) { continue; } - webviews.set(input, { - group: group.id, - visible: input === group.activeEditor, - active: !!activeEditor && input === activeEditor.input - }); + + const handle = find( + map.keys(this._webviewEditorInputs), + handle => input === this._webviewEditorInputs.get(handle)); + + if (handle) { + viewStates[handle] = { + visible: input === group.activeEditor, + active: input === activeInput, + position: editorGroupToViewColumn(this._editorGroupService, group.id || 0), + }; + } } } - for (const webview of map.keys(webviews)) { - const state = webviews.get(webview)!; - for (const handle of map.keys(this._webviewEditorInputs)) { - const input = this._webviewEditorInputs.get(handle)!; - if (input === webview) { - this._proxy.$onDidChangeWebviewPanelViewState(handle, { - active: state.active, - visible: state.visible, - position: editorGroupToViewColumn(this._editorGroupService, state.group || 0), - }); - break; - } - } + if (Object.keys(viewStates).length) { + this._proxy.$onDidChangeWebviewPanelViewStates(viewStates); } } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 055786be742..b10008dbe56 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -549,15 +549,17 @@ export interface MainThreadWebviewsShape extends IDisposable { $unregisterSerializer(viewType: string): void; } -export interface WebviewPanelViewState { - readonly active: boolean; - readonly visible: boolean; - readonly position: EditorViewColumn; +export interface WebviewPanelViewStateData { + [handle: string]: { + readonly active: boolean; + readonly visible: boolean; + readonly position: EditorViewColumn; + }; } export interface ExtHostWebviewsShape { $onMessage(handle: WebviewPanelHandle, message: any): void; - $onDidChangeWebviewPanelViewState(handle: WebviewPanelHandle, newState: WebviewPanelViewState): void; + $onDidChangeWebviewPanelViewStates(newState: WebviewPanelViewStateData): void; $onDidDisposeWebviewPanel(handle: WebviewPanelHandle): Promise; $deserializeWebviewPanel(newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, state: any, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions): Promise; } diff --git a/src/vs/workbench/api/common/extHostWebview.ts b/src/vs/workbench/api/common/extHostWebview.ts index adfe974bcf4..d0eea9511b9 100644 --- a/src/vs/workbench/api/common/extHostWebview.ts +++ b/src/vs/workbench/api/common/extHostWebview.ts @@ -5,15 +5,15 @@ import { Emitter, Event } from 'vs/base/common/event'; import { URI } from 'vs/base/common/uri'; +import { generateUuid } from 'vs/base/common/uuid'; +import * as modes from 'vs/editor/common/modes'; +import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters'; import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor'; +import { asWebviewUri, WebviewInitData } from 'vs/workbench/api/common/shared/webview'; import * as vscode from 'vscode'; -import { ExtHostWebviewsShape, IMainContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelViewState } from './extHost.protocol'; +import { ExtHostWebviewsShape, IMainContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelViewStateData } from './extHost.protocol'; import { Disposable } from './extHostTypes'; -import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; -import * as modes from 'vs/editor/common/modes'; -import { WebviewInitData, asWebviewUri } from 'vs/workbench/api/common/shared/webview'; -import { generateUuid } from 'vs/base/common/uuid'; type IconPath = URI | { light: URI, dark: URI }; @@ -298,21 +298,21 @@ export class ExtHostWebviews implements ExtHostWebviewsShape { } } - public $onDidChangeWebviewPanelViewState( - handle: WebviewPanelHandle, - newState: WebviewPanelViewState - ): void { - const panel = this.getWebviewPanel(handle); - if (!panel || panel._isDisposed) { - return; - } + public $onDidChangeWebviewPanelViewStates(newStates: WebviewPanelViewStateData): void { + for (const handle of Object.keys(newStates)) { + const panel = this.getWebviewPanel(handle); + if (!panel || panel._isDisposed) { + continue; + } - const viewColumn = typeConverters.ViewColumn.to(newState.position); - if (panel.active !== newState.active || panel.visible !== newState.visible || panel.viewColumn !== viewColumn) { - panel._setActive(newState.active); - panel._setVisible(newState.visible); - panel._setViewColumn(viewColumn); - panel._onDidChangeViewStateEmitter.fire({ webviewPanel: panel }); + const newState = newStates[handle]; + const viewColumn = typeConverters.ViewColumn.to(newState.position); + if (panel.active !== newState.active || panel.visible !== newState.visible || panel.viewColumn !== viewColumn) { + panel._setActive(newState.active); + panel._setVisible(newState.visible); + panel._setViewColumn(viewColumn); + panel._onDidChangeViewStateEmitter.fire({ webviewPanel: panel }); + } } } From d241987248081955f2f53863351117c2bbc7dc3b Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 20 Aug 2019 16:27:43 -0700 Subject: [PATCH 856/861] Use bi-direcitonal map for mapping webviews to handles --- .../api/browser/mainThreadWebview.ts | 54 ++++++++++++++----- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadWebview.ts b/src/vs/workbench/api/browser/mainThreadWebview.ts index fdff6a4e387..78a62fbba9b 100644 --- a/src/vs/workbench/api/browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/browser/mainThreadWebview.ts @@ -5,31 +5,62 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; -import * as map from 'vs/base/common/map'; +import { startsWith } from 'vs/base/common/strings'; import { URI, UriComponents } from 'vs/base/common/uri'; import * as modes from 'vs/editor/common/modes'; import { localize } from 'vs/nls'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { IProductService } from 'vs/platform/product/common/product'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ExtHostContext, ExtHostWebviewsShape, IExtHostContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelShowOptions, WebviewPanelViewStateData } from 'vs/workbench/api/common/extHost.protocol'; import { editorGroupToViewColumn, EditorViewColumn, viewColumnToEditorGroup } from 'vs/workbench/api/common/shared/editor'; +import { Webview } from 'vs/workbench/contrib/webview/browser/webview'; import { WebviewEditorInput } from 'vs/workbench/contrib/webview/browser/webviewEditorInput'; import { ICreateWebViewShowOptions, IWebviewEditorService, WebviewInputOptions } from 'vs/workbench/contrib/webview/browser/webviewEditorService'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { extHostNamedCustomer } from '../common/extHostCustomers'; -import { IProductService } from 'vs/platform/product/common/product'; -import { startsWith } from 'vs/base/common/strings'; -import { Webview } from 'vs/workbench/contrib/webview/browser/webview'; -import { find } from 'vs/base/common/arrays'; interface OldMainThreadWebviewState { readonly viewType: string; state: any; } +/** + * Bi-directional map between webview handles and inputs. + */ +class WebviewHandleStore { + private readonly _handlesToInputs = new Map(); + private readonly _inputsToHandles = new Map(); + + public add(handle: string, input: WebviewEditorInput): void { + this._handlesToInputs.set(handle, input); + this._inputsToHandles.set(input, handle); + } + + public getHandleForInput(input: WebviewEditorInput): string | undefined { + return this._inputsToHandles.get(input); + } + + public getInputForHandle(handle: string): WebviewEditorInput | undefined { + return this._handlesToInputs.get(handle); + } + + public delete(handle: string): void { + const input = this.getInputForHandle(handle); + this._handlesToInputs.delete(handle); + if (input) { + this._inputsToHandles.delete(input); + } + } + + public get size(): number { + return this._handlesToInputs.size; + } +} + @extHostNamedCustomer(MainContext.MainThreadWebviews) export class MainThreadWebviews extends Disposable implements MainThreadWebviewsShape { @@ -44,7 +75,7 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews private static revivalPool = 0; private readonly _proxy: ExtHostWebviewsShape; - private readonly _webviewEditorInputs = new Map(); + private readonly _webviewEditorInputs = new WebviewHandleStore(); private readonly _revivers = new Map(); constructor( @@ -102,7 +133,7 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews }); this.hookupWebviewEventDelegate(handle, webview); - this._webviewEditorInputs.set(handle, webview); + this._webviewEditorInputs.add(handle, webview); /* __GDPR__ "webviews:createWebviewPanel" : { @@ -172,7 +203,7 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews } const handle = `revival-${MainThreadWebviews.revivalPool++}`; - this._webviewEditorInputs.set(handle, webviewEditorInput); + this._webviewEditorInputs.add(handle, webviewEditorInput); this.hookupWebviewEventDelegate(handle, webviewEditorInput); let state = undefined; @@ -254,10 +285,7 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews continue; } - const handle = find( - map.keys(this._webviewEditorInputs), - handle => input === this._webviewEditorInputs.get(handle)); - + const handle = this._webviewEditorInputs.getHandleForInput(input); if (handle) { viewStates[handle] = { visible: input === group.activeEditor, @@ -303,7 +331,7 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews } private tryGetWebviewEditorInput(handle: WebviewPanelHandle): WebviewEditorInput | undefined { - return this._webviewEditorInputs.get(handle); + return this._webviewEditorInputs.getInputForHandle(handle); } private getWebview(handle: WebviewPanelHandle): Webview { From 6e530127a1bb8ffbd1bfb77dc680c321dc0d71f5 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 20 Aug 2019 16:32:23 -0700 Subject: [PATCH 857/861] Make sure we update the webview's internally tracked group for restoration --- src/vs/workbench/api/browser/mainThreadWebview.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/workbench/api/browser/mainThreadWebview.ts b/src/vs/workbench/api/browser/mainThreadWebview.ts index 78a62fbba9b..4c5b97e060d 100644 --- a/src/vs/workbench/api/browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/browser/mainThreadWebview.ts @@ -285,6 +285,8 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews continue; } + input.updateGroup(group.id); + const handle = this._webviewEditorInputs.getHandleForInput(input); if (handle) { viewStates[handle] = { From 6e6c3e7acba6f989b140e08bbdc62314349cc134 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Tue, 20 Aug 2019 19:33:37 -0700 Subject: [PATCH 858/861] unset VSCODE_LOGS to fix spdlog issue --- scripts/code.bat | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/code.bat b/scripts/code.bat index 8c058365dca..f4689608e4a 100644 --- a/scripts/code.bat +++ b/scripts/code.bat @@ -33,6 +33,7 @@ set VSCODE_CLI=1 set ELECTRON_DEFAULT_ERROR_MODE=1 set ELECTRON_ENABLE_LOGGING=1 set ELECTRON_ENABLE_STACK_DUMPING=1 +set VSCODE_LOGS= :: Launch Code From e563f98c1381b8d296543fd82c3ac225b7fe6c7e Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 20 Aug 2019 20:07:33 -0700 Subject: [PATCH 859/861] animation for single line and no luck for multiple line --- src/vs/editor/contrib/find/findWidget.css | 25 +++++++++++++++++++---- src/vs/editor/contrib/find/findWidget.ts | 8 ++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/find/findWidget.css b/src/vs/editor/contrib/find/findWidget.css index d9eb731d1e3..d8f2f70a798 100644 --- a/src/vs/editor/contrib/find/findWidget.css +++ b/src/vs/editor/contrib/find/findWidget.css @@ -32,11 +32,11 @@ .monaco-editor .find-widget { position: absolute; z-index: 10; - top: unset; - bottom: 10px; + top: -44px; + height: 33px; overflow: hidden; line-height: 19px; - transition: top bottom 200ms linear; + transition: top 200ms linear; padding: 0 4px; } @@ -45,6 +45,11 @@ } /* Find widget when replace is toggled on */ +.monaco-editor .find-widget.replaceToggled { + top: -74px; + /* find input height + replace input height + shadow (10px) */ +} + .monaco-editor .find-widget.replaceToggled > .replace-part { display: flex; display: -webkit-flex; @@ -52,7 +57,19 @@ .monaco-editor .find-widget.visible, .monaco-editor .find-widget.replaceToggled.visible { - top: 0; + top: 0px; +} + +/* Multiple line find widget */ + +.monaco-editor .find-widget.multipleline { + top: unset; + bottom: 10px; +} + +.monaco-editor .find-widget.multipleline.visible, +.monaco-editor .find-widget.multipleline.replaceToggled.visible { + top: 0px; bottom: unset; } diff --git a/src/vs/editor/contrib/find/findWidget.ts b/src/vs/editor/contrib/find/findWidget.ts index d56ad012398..2ea8ba03dd7 100644 --- a/src/vs/editor/contrib/find/findWidget.ts +++ b/src/vs/editor/contrib/find/findWidget.ts @@ -173,6 +173,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas this._buildDomNode(); this._updateButtons(); this._tryUpdateWidgetWidth(); + this._findInput.inputBox.layout(); this._register(this._codeEditor.onDidChangeConfiguration((e: IConfigurationChangedEvent) => { if (e.readOnly) { @@ -288,6 +289,12 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas private _onStateChanged(e: FindReplaceStateChangedEvent): void { if (e.searchString) { + if (this._state.searchString.indexOf('\n') >= 0) { + dom.addClass(this._domNode, 'multipleline'); + } else { + dom.removeClass(this._domNode, 'multipleline'); + } + try { this._ignoreChangeEvent = true; this._findInput.setValue(this._state.searchString); @@ -312,6 +319,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas this._isReplaceVisible = true; this._replaceInput.width = dom.getTotalWidth(this._findInput.domNode); this._updateButtons(); + this._replaceInput.inputBox.layout(); } } else { if (this._isReplaceVisible) { From 4de4433c711674fd33912aaa5a46a29a90a94377 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 20 Aug 2019 20:09:07 -0700 Subject: [PATCH 860/861] :lipstick: --- src/vs/editor/contrib/find/findWidget.css | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/find/findWidget.css b/src/vs/editor/contrib/find/findWidget.css index d8f2f70a798..d6c6f602e48 100644 --- a/src/vs/editor/contrib/find/findWidget.css +++ b/src/vs/editor/contrib/find/findWidget.css @@ -46,10 +46,8 @@ /* Find widget when replace is toggled on */ .monaco-editor .find-widget.replaceToggled { - top: -74px; - /* find input height + replace input height + shadow (10px) */ + top: -74px; /* find input height + replace input height + shadow (10px) */ } - .monaco-editor .find-widget.replaceToggled > .replace-part { display: flex; display: -webkit-flex; @@ -57,7 +55,7 @@ .monaco-editor .find-widget.visible, .monaco-editor .find-widget.replaceToggled.visible { - top: 0px; + top: 0; } /* Multiple line find widget */ From 7621355f7e0c560dc30ad0c04f62d30bc1659b61 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 20 Aug 2019 22:37:19 -0700 Subject: [PATCH 861/861] Avoid redundant keymap change --- .../workbench/services/keybinding/browser/keymapService.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/services/keybinding/browser/keymapService.ts b/src/vs/workbench/services/keybinding/browser/keymapService.ts index c90e58fc0a9..e3744643efd 100644 --- a/src/vs/workbench/services/keybinding/browser/keymapService.ts +++ b/src/vs/workbench/services/keybinding/browser/keymapService.ts @@ -176,6 +176,7 @@ export class BrowserKeyboardMapperFactoryBase { } setActiveKeyMapping(keymap: IKeyboardMapping | null) { + let keymapUpdated = false; let matchedKeyboardLayout = this.getMatchedKeymapInfo(keymap); if (matchedKeyboardLayout) { // let score = matchedKeyboardLayout.score; @@ -209,18 +210,21 @@ export class BrowserKeyboardMapperFactoryBase { if (!this._activeKeymapInfo) { this._activeKeymapInfo = matchedKeyboardLayout.result; + keymapUpdated = true; } else if (keymap) { if (matchedKeyboardLayout.result.getScore(keymap) > this._activeKeymapInfo.getScore(keymap)) { this._activeKeymapInfo = matchedKeyboardLayout.result; + keymapUpdated = true; } } } if (!this._activeKeymapInfo) { this._activeKeymapInfo = this.getUSStandardLayout(); + keymapUpdated = true; } - if (!this._activeKeymapInfo) { + if (!this._activeKeymapInfo || !keymapUpdated) { return; }