Merge remote-tracking branch 'origin/master' into tyriar/puppeteer

This commit is contained in:
Daniel Imms 2019-08-13 08:58:21 -07:00
commit e3cc50361d
179 changed files with 6027 additions and 4535 deletions

10
.github/commands.yml vendored
View file

@ -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!"

View file

@ -1,3 +1,3 @@
disturl "https://atom.io/download/electron"
target "4.2.7"
target "4.2.9"
runtime "electron"

View file

@ -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",

View file

@ -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'
]);
@ -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 }));

View file

@ -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();

View file

@ -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 {

View file

@ -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);
}
}
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');
});

View file

@ -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;

View file

@ -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": {

View file

@ -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"

View file

@ -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": {

View file

@ -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');

View file

@ -6,11 +6,11 @@
"git": {
"name": "jeff-hykin/cpp-textmate-grammar",
"repositoryUrl": "https://github.com/jeff-hykin/cpp-textmate-grammar",
"commitHash": "cbd71f90cd9be0f99ddc9b0f65cec62fc3ada6d1"
"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."
},
{

View file

@ -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"

File diff suppressed because it is too large Load diff

View file

@ -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,7 +23,7 @@
},
{
"c": " ",
"t": "source.cpp meta.preprocessor.cpp",
"t": "source.cpp meta.preprocessor.conditional.cpp",
"r": {
"dark_plus": "meta.preprocessor: #569CD6",
"light_plus": "meta.preprocessor: #0000FF",
@ -34,7 +34,7 @@
},
{
"c": "_UCRT",
"t": "source.cpp meta.preprocessor.cpp entity.name.function.preprocessor.cpp",
"t": "source.cpp meta.preprocessor.conditional.cpp entity.name.function.preprocessor.cpp",
"r": {
"dark_plus": "entity.name.function: #DCDCAA",
"light_plus": "entity.name.function: #795E26",
@ -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",

View file

@ -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,7 +23,7 @@
},
{
"c": " ",
"t": "source.cpp meta.preprocessor.cpp",
"t": "source.cpp meta.preprocessor.conditional.cpp",
"r": {
"dark_plus": "meta.preprocessor: #569CD6",
"light_plus": "meta.preprocessor: #0000FF",
@ -34,7 +34,7 @@
},
{
"c": "_UCRT",
"t": "source.cpp meta.preprocessor.cpp entity.name.function.preprocessor.cpp",
"t": "source.cpp meta.preprocessor.conditional.cpp entity.name.function.preprocessor.cpp",
"r": {
"dark_plus": "entity.name.function: #DCDCAA",
"light_plus": "entity.name.function: #795E26",
@ -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",

View file

@ -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,7 +23,7 @@
},
{
"c": " ",
"t": "source.cpp meta.preprocessor.cpp",
"t": "source.cpp meta.preprocessor.conditional.cpp",
"r": {
"dark_plus": "meta.preprocessor: #569CD6",
"light_plus": "meta.preprocessor: #0000FF",
@ -34,7 +34,7 @@
},
{
"c": "B4G_DEBUG_CHECK",
"t": "source.cpp meta.preprocessor.cpp entity.name.function.preprocessor.cpp",
"t": "source.cpp meta.preprocessor.conditional.cpp entity.name.function.preprocessor.cpp",
"r": {
"dark_plus": "entity.name.function: #DCDCAA",
"light_plus": "entity.name.function: #795E26",
@ -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",

View file

@ -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",

View file

@ -1354,6 +1354,15 @@
"scope": "resource",
"default": false,
"description": "%config.supportCancellation%"
},
"git.branchSortOrder": {
"type": "string",
"enum": [
"committerdate",
"alphabetically"
],
"default": "committerdate",
"description": "%config.branchSortOrder%"
}
}
},

View file

@ -127,6 +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.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.",

View file

@ -238,5 +238,6 @@ export const enum GitErrorCodes {
CantLockRef = 'CantLockRef',
CantRebaseMultipleBranches = 'CantRebaseMultipleBranches',
PatchDoesNotApply = 'PatchDoesNotApply',
NoPathFound = 'NoPathFound'
NoPathFound = 'NoPathFound',
UnknownPath = 'UnknownPath',
}

View file

@ -353,9 +353,11 @@ export class CommandCenter {
switch (resource.type) {
case Status.INDEX_MODIFIED:
case Status.INDEX_RENAMED:
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:
@ -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 '';

View file

@ -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];
@ -1128,15 +1128,21 @@ export class Repository {
}
let mode: string;
let add: string = '';
try {
const details = await this.getObjectDetails('HEAD', path);
mode = details.mode;
} catch (err) {
if (err.gitErrorCode !== GitErrorCodes.UnknownPath) {
throw 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<void> {
@ -1618,8 +1624,14 @@ export class Repository {
.map(([ref]) => ({ name: ref, type: RefType.Head } as Branch));
}
async getRefs(): Promise<Ref[]> {
const result = await this.run(['for-each-ref', '--format', '%(refname) %(objectname)', '--sort', '-committerdate']);
async getRefs(opts?: { sort?: 'alphabetically' | 'committerdate' }): Promise<Ref[]> {
const args = ['for-each-ref', '--format', '%(refname) %(objectname)'];
if (opts && opts.sort && opts.sort !== 'alphabetically') {
args.push('--sort', opts.sort);
}
const result = await this.run(args);
const fn = (line: string): Ref | null => {
let match: RegExpExecArray | null;

View file

@ -701,6 +701,9 @@ export class Repository implements Disposable {
onConfigListener(updateIndexGroupVisibility, this, this.disposables);
updateIndexGroupVisibility();
const onConfigListenerForBranchSortOrder = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.branchSortOrder', root));
onConfigListenerForBranchSortOrder(this.updateModelState, this, this.disposables);
this.mergeGroup.hideWhenEmpty = true;
this.disposables.push(this.mergeGroup);
@ -1405,7 +1408,6 @@ export class Repository implements Disposable {
const config = workspace.getConfiguration('git');
const shouldIgnore = config.get<boolean>('ignoreLimitWarning') === true;
const useIcons = !config.get<boolean>('decorations.enabled', true);
this.isRepositoryHuge = didHitLimit;
if (didHitLimit && !shouldIgnore && !this.didWarnAboutLimit) {
@ -1455,7 +1457,8 @@ 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 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;

View file

@ -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"

View file

@ -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<void> {
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<void> {
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);
}
}
});

View file

@ -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));
}

View file

@ -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==

View file

@ -1,7 +1,7 @@
{
"name": "code-oss-dev",
"version": "1.38.0",
"distro": "b9b380a45ae5d292a9203b1a0ca458796d78abcb",
"distro": "c70929f01c8688bf05a58fc514f649309e9d45a5",
"author": {
"name": "Microsoft Corporation"
},
@ -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",
@ -52,7 +53,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-beta99",
"xterm-addon-search": "0.2.0-beta3",
"xterm-addon-web-links": "0.1.0-beta10",
"yauzl": "^2.9.2",

View file

@ -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",
@ -18,9 +19,9 @@
"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-beta94",
"xterm": "3.15.0-beta99",
"xterm-addon-search": "0.2.0-beta3",
"xterm-addon-web-links": "0.1.0-beta10",
"yauzl": "^2.9.2",

View file

@ -1,3 +0,0 @@
disturl "http://nodejs.org/dist"
target "10.11.0"
runtime "node"

View file

@ -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",

View file

@ -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"

View file

@ -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"
@ -1123,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"
@ -1159,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-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-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"

View file

@ -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'],
@ -19,11 +23,15 @@ exports.serviceWorker = [{
dest: 'vs/workbench/contrib/resources/browser/resourceServiceWorkerMain.js'
}];
exports.workbench = require('./vs/workbench/buildfile').collectModules(['vs/workbench/workbench.main']);
exports.workbenchWeb = require('./vs/workbench/buildfile').collectModules(['vs/workbench/workbench.web.api']);
exports.workbench = require('./vs/workbench/buildfile').collectModules(['vs/workbench/workbench.desktop.main']);
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;

View file

@ -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;
}
}

View file

@ -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 <https://github.com/electron/electron>
// Definitions: https://github.com/electron/electron-typescript-definitions

View file

@ -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<T extends IView = IView> extends Disposable {

View file

@ -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,20 @@ 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');
}
// branch nodes should flip the normal/orthogonal directions
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 +226,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');
@ -347,7 +356,12 @@ 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);
}
getChildCachedVisibleSize(index: number): number | undefined {
@ -439,9 +453,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; }
@ -541,34 +552,26 @@ 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 {
if (visible) {
this._cachedVisibleSize = undefined;
} else {
this._cachedVisibleSize = this._size;
}
if (this.view.setVisible) {
this.view.setVisible(visible);
}
}
orthogonalLayout(size: number): void {
this._orthogonalSize = size;
if (this.layoutController.isLayoutEnabled) {
this.view.layout(this.width, this.height, orthogonal(this.orientation));
}
}
dispose(): void { }
}
@ -576,7 +579,7 @@ type Node = BranchNode | LeafNode;
function flipNode<T extends Node>(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;
@ -597,7 +600,7 @@ function flipNode<T extends Node>(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;
}
}
@ -642,8 +645,7 @@ 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);
}
get width(): number { return this.root.width; }
@ -657,14 +659,25 @@ export class GridView implements IDisposable {
private _onDidChange = new Relay<IViewSize | undefined>();
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 {
@ -673,9 +686,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 {
@ -702,9 +716,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);
@ -835,9 +848,6 @@ export class GridView implements IDisposable {
fromParent.addChild(toNode, fromSize, fromIndex);
toParent.addChild(fromNode, toSize, toIndex);
fromParent.layout(fromParent.orthogonalSize);
toParent.layout(toParent.orthogonalSize);
}
}
@ -877,13 +887,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 +953,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 +967,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;
}

View file

@ -618,7 +618,7 @@ export class MouseController<T> implements IDisposable {
}
}
private onDoubleClick(e: IListMouseEvent<T>): void {
protected onDoubleClick(e: IListMouseEvent<T>): void {
if (isInputElement(e.browserEvent.target as HTMLElement)) {
return;
}

View file

@ -72,4 +72,4 @@
.monaco-split-view2.separator-border.vertical > .split-view-container > .split-view-view:not(:first-child)::before {
height: 1px;
width: 100%;
}
}

View file

@ -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<number | undefined>;
readonly priority?: LayoutPriority;
readonly snap?: boolean;
layout(size: number, orientation: Orientation): void;
layout(size: number, orthogonalSize: number | undefined): void;
setVisible?(visible: boolean): void;
}
@ -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,7 +88,7 @@ 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;
}
@ -125,10 +125,13 @@ abstract class ViewItem {
dom.addClass(container, 'visible');
}
abstract 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 {
@ -139,17 +142,19 @@ abstract class ViewItem {
class VerticalViewItem extends ViewItem {
layout(): void {
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 {
layout(orthogonalSize: number | undefined): void {
super.layout(orthogonalSize);
this.container.style.width = `${this.size}px`;
this.layoutView(Orientation.HORIZONTAL);
this.layoutView(orthogonalSize);
}
}
@ -161,6 +166,7 @@ interface ISashItem {
interface ISashDragSnapState {
readonly index: number;
readonly limitDelta: number;
readonly size: number;
}
interface ISashDragState {
@ -199,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[] = [];
@ -453,7 +460,7 @@ export class SplitView extends Disposable {
}
const viewItem = this.viewItems[index];
viewItem.visible = visible;
viewItem.setVisible(visible);
this.distributeEmptySpace(index);
this.layoutViews();
@ -469,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);
@ -552,7 +560,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 +571,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 +750,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) {
@ -812,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());

View file

@ -1064,6 +1064,16 @@ class TreeNodeListMouseController<T, TFilterData, TRef> extends MouseController<
super.onPointer(e);
}
protected onDoubleClick(e: IListMouseEvent<ITreeNode<T, TFilterData>>): void {
const onTwistie = hasClass(e.browserEvent.target as HTMLElement, 'monaco-tl-twistie');
if (onTwistie) {
return;
}
super.onDoubleClick(e);
}
}
interface ITreeNodeListOptions<T, TFilterData, TRef> extends IListOptions<ITreeNode<T, TFilterData>> {

View file

@ -16,7 +16,7 @@ export interface IWorker extends IDisposable {
}
export interface IWorkerCallback {
(message: string): void;
(message: any): void;
}
export interface IWorkerFactory {

View file

@ -138,20 +138,6 @@ export async function readdir(path: string): Promise<string[]> {
return handleDirectoryChildren(await promisify(fs.readdir)(path));
}
export async function readdirWithFileTypes(path: string): Promise<fs.Dirent[]> {
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));
}

View file

@ -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,

View file

@ -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<void>();
@ -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();
});
});
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();
});
});

View file

@ -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');

View file

@ -20,8 +20,8 @@
let loadCode = function (moduleId: string) {
require([moduleId], function (ws) {
setTimeout(function () {
let messageHandler = ws.create((msg: any) => {
(<any>self).postMessage(msg);
let messageHandler = ws.create((msg: any, transfer?: Transferable[]) => {
(<any>self).postMessage(msg, transfer);
}, null);
self.onmessage = (e) => messageHandler.onmessage(e.data);

View file

@ -24,9 +24,6 @@
<body aria-label="">
</body>
<!-- Application insights telemetry library -->
<script src="https://az416426.vo.msecnd.net/scripts/a/ai.0.js"></script>
<!-- Require our AMD loader -->
<script src="./out/vs/loader.js"></script>

View file

@ -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);
});
})();
})();

View file

@ -10,4 +10,4 @@
<!-- Startup via workbench.js -->
<script src="workbench.js"></script>
</html>
</html>

View file

@ -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');
@ -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,

View file

@ -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

View file

@ -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<number, number[]>();
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);
}
}

View file

@ -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++) {

View file

@ -117,8 +117,8 @@ function getCodeActionProviders(
}
registerLanguageCommand('_executeCodeActionProvider', async function (accessor, args): Promise<ReadonlyArray<CodeAction>> {
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);

View file

@ -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 {

View file

@ -299,10 +299,12 @@ class LinkDetector implements editorCommon.IEditorContribution {
return this.openerService.open(uri, { openToSide });
}, err => {
const messageOrError =
err instanceof Error ? (<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);

View file

@ -84,12 +84,12 @@ export abstract class PeekViewWidget extends ZoneWidget {
private _onDidClose = new Emitter<PeekViewWidget>();
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.$<HTMLDivElement>('.head');
this._bodyElement = dom.$<HTMLDivElement>('.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`;
}
}
}

View file

@ -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 = <Token>{ 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 {

View file

@ -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 = <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((<FormatString>variable.transform!.children[0]).ifValue, 'import { hello } from world');
assert.equal((<FormatString>variable.transform!.children[0]).elseValue, undefined);
});
});

View file

@ -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: <any>registerLinkProvider,
registerColorProvider: <any>registerColorProvider,
registerFoldingRangeProvider: <any>registerFoldingRangeProvider,
registerDeclarationProvider: <any>registerDeclarationProvider,
registerSelectionRangeProvider: <any>registerSelectionRangeProvider,
// enums
DocumentHighlightKind: standaloneEnums.DocumentHighlightKind,

View file

@ -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({

10
src/vs/monaco.d.ts vendored
View file

@ -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.

View file

@ -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<IDiagnosticsService>(ID);
@ -72,9 +76,9 @@ export interface IDiagnosticsService {
getPerformanceInfo(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise<PerformanceInfo>;
getSystemInfo(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise<SystemInfo>;
getDiagnostics(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise<string>;
reportWorkspaceStats(workspace: IWorkspace): Promise<void>;
reportWorkspaceStats(workspace: IWorkspaceInformation): Promise<void>;
}
export function isRemoteDiagnosticError(x: any): x is IRemoteDiagnosticError {
return !!x.hostName && !!x.errorMessage;
}
}

View file

@ -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<void> {
public async reportWorkspaceStats(workspace: IWorkspaceInformation): Promise<void> {
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<WorkspaceStatsEvent, WorkspaceStatsClassification>('workspace.stats', {
'workspace.id': workspace.telemetryId,
fileTypes: stats.fileTypes,
configTypes: stats.configFiles,
launchConfigs: stats.launchConfigFiles
@ -545,4 +547,4 @@ export class DiagnosticsService implements IDiagnosticsService {
}
});
}
}
}

View file

@ -19,7 +19,6 @@ class BrowserWindowDriver extends BaseWindowDriver {
}
export async function registerWindowDriver(): Promise<IDisposable> {
console.log('registerWindowDriver');
(<any>window).driver = new BrowserWindowDriver();
// const windowDriverChannel = new WindowDriverChannel(windowDriver);
// mainProcessService.registerChannel('windowDriver', windowDriverChannel);

View file

@ -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

View file

@ -8,6 +8,8 @@ import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiatio
export class ProductService implements IProductService {
_serviceBrand!: ServiceIdentifier<IProductService>;
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<IProductService>;
get version(): string { return '1.35.0'; }
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 ''; }
get nameLong(): string { return this.productConfiguration ? this.productConfiguration.nameLong : 'Unknown'; }
get urlProtocol(): string { return ''; }

View file

@ -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<IProductService>('productService');
export interface IProductService {
_serviceBrand: any;
_serviceBrand: ServiceIdentifier<any>;
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;
}
}

View file

@ -90,13 +90,13 @@ export interface IProgress<T> {
export class Progress<T> implements IProgress<T> {
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;
}

View file

@ -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;
}

13
src/vs/vscode.d.ts vendored
View file

@ -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.
@ -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.
@ -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;

View file

@ -1012,7 +1012,7 @@ declare module 'vscode' {
/**
* An optional human-readable message that will be rendered in the view.
*/
message?: string | MarkdownString;
message?: string;
}

View file

@ -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;
@ -125,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();

View file

@ -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 = <ExtHostLogService>accessor.get(ILogService);
const extHostLogService = accessor.get(ILogService);
// register addressable instances
rpcProtocol.set(ExtHostContext.ExtHostLogService, extHostLogService);
rpcProtocol.set(ExtHostContext.ExtHostLogService, <ExtHostLogServiceShape><any>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);

View file

@ -245,7 +245,7 @@ export interface MainThreadTreeViewsShape extends IDisposable {
$registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean }): void;
$refresh(treeViewId: string, itemsToRefresh?: { [treeItemHandle: string]: ITreeItem }): Promise<void>;
$reveal(treeViewId: string, treeItem: ITreeItem, parentChain: ITreeItem[], options: IRevealOptions): Promise<void>;
$setMessage(treeViewId: string, message: string | IMarkdownString): void;
$setMessage(treeViewId: string, message: string): void;
}
export interface MainThreadDownloadServiceShape extends IDisposable {

View file

@ -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<CustomCodeAction[]>('_executeCodeActionProvider', args)
@ -504,6 +506,7 @@ export class ExtHostApiCommands {
if (codeAction.command) {
ret.command = this._commands.converter.fromInternal(codeAction.command);
}
ret.isPreferred = codeAction.isPreferred;
return ret;
}
}));

View file

@ -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;
}

View file

@ -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)
});
}
}

View file

@ -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<any>([
this._loadCommonJSModule(extensionDescription.main, activationTimesBuilder),
this._loadExtensionContext(extensionDescription)
]).then(values => {
return AbstractExtHostExtensionService._callActivate(this._extHostLogService, extensionDescription.identifier, <IExtensionModule>values[0], <IExtensionContext>values[1], activationTimesBuilder);
return AbstractExtHostExtensionService._callActivate(this._logService, extensionDescription.identifier, <IExtensionModule>values[0], <IExtensionContext>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,
});
});
@ -385,7 +384,8 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio
try {
activationTimesBuilder.activateCallStart();
logService.trace(`ExtensionService#_callActivateOptional ${extensionId.value}`);
const activateResult: Promise<IExtensionAPI> = extensionModule.activate.apply(global, [context]);
const scope = typeof global === 'object' ? global : self; // `global` is nodejs while `self` is for workers
const activateResult: Promise<IExtensionAPI> = extensionModule.activate.apply(scope, [context]);
activationTimesBuilder.activateCallStop();
activationTimesBuilder.activateResolveStart();
@ -478,7 +478,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio
}
private async _activateIfGlobPatterns(folders: ReadonlyArray<vscode.WorkspaceFolder>, extensionId: ExtensionIdentifier, globPatterns: string[]): Promise<void> {
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);
@ -525,7 +525,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio
}
private async _doHandleExtensionTests(): Promise<void> {
const { extensionDevelopmentLocationURI: extensionDevelopmentLocationURI, extensionTestsLocationURI } = this._initData.environment;
const { extensionDevelopmentLocationURI, extensionTestsLocationURI } = this._initData.environment;
if (!(extensionDevelopmentLocationURI && extensionTestsLocationURI && extensionTestsLocationURI.scheme === Schemas.file)) {
return Promise.resolve(undefined);
}
@ -605,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`);
});
}

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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<void> => {
return treeView.reveal(element, options);
},
@ -250,12 +253,12 @@ class ExtHostTreeView<T> 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 });
}

View file

@ -442,7 +442,7 @@ export namespace TextEdit {
export function from(edit: vscode.TextEdit): modes.TextEdit {
return <modes.TextEdit>{
text: edit.newText,
eol: EndOfLine.from(edit.newEol),
eol: edit.newEol && EndOfLine.from(edit.newEol),
range: Range.from(edit.range)
};
}

View file

@ -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;
@ -1075,6 +1075,8 @@ export class CodeAction {
kind?: CodeActionKind;
isPreferred?: boolean;
constructor(title: string, kind?: CodeActionKind) {
this.title = title;
this.kind = kind;
@ -1253,8 +1255,8 @@ export class SignatureInformation {
export class SignatureHelp {
signatures: SignatureInformation[];
activeSignature: number;
activeParameter: number;
activeSignature: number = 0;
activeParameter: number = 0;
constructor() {
this.signatures = [];
@ -1310,19 +1312,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;

View file

@ -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);

View file

@ -41,14 +41,24 @@ 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);
// 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<T>(modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise<T> {
let r: T | null = null;
activationTimesBuilder.codeLoadingStart();
this._extHostLogService.info(`ExtensionService#loadCommonJSModule ${modulePath}`);
this._logService.info(`ExtensionService#loadCommonJSModule ${modulePath}`);
try {
r = require.__$__nodeRequire<T>(modulePath);
} catch (e) {

View file

@ -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);
}
}

View file

@ -0,0 +1,98 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* 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 { 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<string, typeof vscode>();
constructor(
private readonly _apiFactory: IExtensionApiFactory,
private readonly _extensionPaths: TernarySearchTree<IExtensionDescription>,
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<void> {
// 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);
}
protected _loadCommonJSModule<T>(modulePath: string, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise<T> {
// 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 = <any>self;
const module = { exports: {} };
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();
importScripts(modulePath);
} finally {
activationTimesBuilder.codeLoadingStop();
}
return Promise.resolve(module.exports as T);
}
async $setRemoteEnvironment(env: { [key: string]: string | null }): Promise<void> {
throw new Error('Not supported');
}
}

View file

@ -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;
}
}

View file

@ -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<IWorkbenchActionRegistry>(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<IConfigurationRegistry>(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
}
}
});

View file

@ -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<void> {
return this.windowsService.openAboutDialog();
}
}
const registry = Registry.as<IWorkbenchActionRegistry>(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
});
});
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()
});

View file

@ -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')
});

View file

@ -71,6 +71,7 @@ export abstract class BreadcrumbsConfig<T> {
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<boolean>('breadcrumbs.icons');
static FileExcludes = BreadcrumbsConfig._stub<glob.IExpression>('files.exclude');
@ -160,6 +161,11 @@ Registry.as<IConfigurationRegistry>(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
}
}
});

View file

@ -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;
@ -143,6 +145,7 @@ export class BreadcrumbsControl {
private readonly _ckBreadcrumbsActive: IContextKey<boolean>;
private readonly _cfUseQuickPick: BreadcrumbsConfig<boolean>;
private readonly _cfShowIcons: BreadcrumbsConfig<boolean>;
readonly domNode: HTMLDivElement;
private readonly _widget: BreadcrumbsWidget;
@ -185,6 +188,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 +200,7 @@ export class BreadcrumbsControl {
this._ckBreadcrumbsVisible.reset();
this._ckBreadcrumbsActive.reset();
this._cfUseQuickPick.dispose();
this._cfShowIcons.dispose();
this._widget.dispose();
this.domNode.remove();
}
@ -246,15 +251,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({

View file

@ -798,7 +798,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
//#region openEditor()
openEditor(editor: EditorInput, options?: EditorOptions): Promise<IEditor | null> {
async openEditor(editor: EditorInput, options?: EditorOptions): Promise<IEditor | null> {
// 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<IEditor | undefined> {

View file

@ -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 {
@ -165,19 +161,16 @@ export class CustomTreeView extends Disposable implements ITreeView {
private _showCollapseAllAction = false;
private focused: boolean = false;
private domNode: HTMLElement;
private treeContainer: HTMLElement;
private _messageValue: string | IMarkdownString | undefined;
private messageElement: HTMLDivElement;
private tree: WorkbenchAsyncDataTree<ITreeItem, ITreeItem, FuzzyScore>;
private treeLabels: ResourceLabels;
private domNode!: HTMLElement;
private treeContainer!: HTMLElement;
private _messageValue: string | undefined;
private messageElement!: HTMLDivElement;
private tree: WorkbenchAsyncDataTree<ITreeItem, ITreeItem, FuzzyScore> | undefined;
private treeLabels: ResourceLabels | undefined;
private root: ITreeItem;
private elementsToRefresh: ITreeItem[] = [];
private menus: TitleMenus;
private markdownRenderer: MarkdownRenderer;
private markdownResult: IMarkdownRenderResult | null;
private readonly _onDidExpandItem: Emitter<ITreeItem> = this._register(new Emitter<ITreeItem>());
readonly onDidExpandItem: Event<ITreeItem> = 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<IViewsRegistry>(Extensions.ViewsRegistry).onDidChangeContainer(({ views, from, to }) => {
if (from === this.viewContainer && views.some(v => v.id === this.id)) {
this.viewContainer = to;
@ -231,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<ITreeItem[]> {
@ -251,17 +238,17 @@ export class CustomTreeView extends Disposable implements ITreeView {
this.updateMessage();
this.refresh();
} else {
this._dataProvider = null;
this._dataProvider = undefined;
this.updateMessage();
}
}
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();
}
@ -412,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 || []));
}
@ -429,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;
@ -449,13 +436,13 @@ export class CustomTreeView extends Disposable implements ITreeView {
onHide: (wasCancelled?: boolean) => {
if (wasCancelled) {
this.tree.domFocus();
this.tree!.domFocus();
}
},
getActionsContext: () => (<TreeViewItemHandleArg>{ $treeViewId: this.id, $treeItemHandle: node.handle }),
actionRunner: new MultipleSelectionActionRunner(() => this.tree.getSelection())
actionRunner: new MultipleSelectionActionRunner(() => this.tree!.getSelection())
});
}
@ -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,15 +476,11 @@ export class CustomTreeView extends Disposable implements ITreeView {
}
private resetMessageElement(): void {
if (this.markdownResult) {
this.markdownResult.dispose();
this.markdownResult = null;
}
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;
@ -552,10 +532,11 @@ export class CustomTreeView extends Disposable implements ITreeView {
}
async expand(itemOrItems: ITreeItem | ITreeItem[]): Promise<void> {
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);
@ -595,18 +576,19 @@ export class CustomTreeView extends Disposable implements ITreeView {
private refreshing: boolean = false;
private async doRefresh(elements: ITreeItem[]): Promise<void> {
if (this.tree) {
const tree = this.tree;
if (tree) {
this.refreshing = true;
const parents: Set<ITreeItem> = new Set<ITreeItem>();
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) {
@ -792,7 +774,7 @@ class TreeRenderer extends Disposable implements ITreeRenderer<ITreeItem, FuzzyS
}
class Aligner extends Disposable {
private _tree: WorkbenchAsyncDataTree<ITreeItem, ITreeItem, FuzzyScore>;
private _tree: WorkbenchAsyncDataTree<ITreeItem, ITreeItem, FuzzyScore> | undefined;
constructor(private themeService: IWorkbenchThemeService) {
super();
@ -810,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 {
@ -893,38 +879,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()
};
}
}

Some files were not shown because too many files have changed in this diff Show more