mirror of
https://github.com/microsoft/vscode.git
synced 2026-06-06 23:56:32 +01:00
Merge branch 'master' into ben/folder-id
This commit is contained in:
@@ -976,6 +976,7 @@
|
||||
"vscode-dts-interface-naming": "warn",
|
||||
"vscode-dts-cancellation": "warn",
|
||||
"vscode-dts-use-thenable": "warn",
|
||||
"vscode-dts-region-comments": "warn",
|
||||
"vscode-dts-provider-naming": [
|
||||
"warn",
|
||||
{
|
||||
|
||||
@@ -11,10 +11,13 @@
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.2.6",
|
||||
"@octokit/rest": "^18.0.12",
|
||||
"@slack/web-api": "^6.0.0"
|
||||
"@slack/web-api": "^6.0.0",
|
||||
"azure-storage": "^2.10.3",
|
||||
"stream-buffers": "^3.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.14.22",
|
||||
"@types/stream-buffers": "^3.0.3",
|
||||
"typescript": "^4.1.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,23 +6,25 @@
|
||||
import * as core from '@actions/core';
|
||||
import { Octokit, RestEndpointMethodTypes } from '@octokit/rest';
|
||||
import { WebClient } from '@slack/web-api';
|
||||
import * as storage from 'azure-storage';
|
||||
import { WritableStreamBuffer } from 'stream-buffers';
|
||||
|
||||
(async () => {
|
||||
const actionUrl = core.getInput('workflow_run_url');
|
||||
const url = actionUrl || 'https://api.github.com/repos/microsoft/vscode/actions/runs/500731641';
|
||||
console.log(url);
|
||||
const parts = url.split('/');
|
||||
const owner = parts[parts.length - 5];
|
||||
const repo = parts[parts.length - 4];
|
||||
const runId = parseInt(parts[parts.length - 1], 10);
|
||||
if (actionUrl) {
|
||||
await handleNotification(owner, repo, runId);
|
||||
} else {
|
||||
const results = await buildComplete(owner, repo, runId);
|
||||
for (const message of [...results.logMessages, ...results.messages]) {
|
||||
console.log(message);
|
||||
}
|
||||
}
|
||||
const actionUrl = core.getInput('workflow_run_url');
|
||||
const url = actionUrl || 'https://api.github.com/repos/microsoft/vscode/actions/runs/501214268';
|
||||
console.log(url);
|
||||
const parts = url.split('/');
|
||||
const owner = parts[parts.length - 5];
|
||||
const repo = parts[parts.length - 4];
|
||||
const runId = parseInt(parts[parts.length - 1], 10);
|
||||
if (actionUrl) {
|
||||
await handleNotification(owner, repo, runId);
|
||||
} else {
|
||||
const results = await buildComplete(owner, repo, runId);
|
||||
for (const message of [...results.logMessages, ...results.messages]) {
|
||||
console.log(message);
|
||||
}
|
||||
}
|
||||
})()
|
||||
.then(null, console.error);
|
||||
|
||||
@@ -116,8 +118,10 @@ async function buildComplete(owner: string, repo: string, runId: number) {
|
||||
const vscode = repo === 'vscode';
|
||||
const name = vscode ? `VS Code ${buildResult.name} Build` : buildResult.name;
|
||||
// TBD: `Requester: ${vstsToSlackUser(build.requester, build.degraded)}${pingBenForSmokeTests && releaseBuild && build.result === 'partiallySucceeded' ? ' | Ping: @bpasero' : ''}`
|
||||
const accounts = await readAccounts();
|
||||
const githubAccountMap = githubToAccounts(accounts);
|
||||
const messages = transitionedBuilds.map(build => `${name}
|
||||
Result: ${build.data.conclusion} | Branch: ${build.data.head_branch} | Authors: ${githubToSlackUsers(build.authors, build.degraded).sort().join(', ') || `None (rebuild)`}
|
||||
Result: ${build.data.conclusion} | Branch: ${build.data.head_branch} | Authors: ${githubToSlackUsers(githubAccountMap, build.authors, build.degraded).sort().join(', ') || `None (rebuild)`}
|
||||
Build: ${build.buildHtmlUrl}
|
||||
Changes: ${build.changesHtmlUrl}`);
|
||||
return { logMessages, messages };
|
||||
@@ -141,23 +145,51 @@ async function compareCommits(octokit: Octokit, owner: string, repo: string, bas
|
||||
return octokit.repos.compareCommits({ owner, repo, base, head });
|
||||
}
|
||||
|
||||
function githubToSlackUsers(githubUsers: string[], at?: boolean) {
|
||||
function githubToSlackUsers(githubToAccounts: Record<string, Accounts>, githubUsers: string[], at?: boolean) {
|
||||
return githubUsers.map(g => githubToAccounts[g] ? `${at ? '@' : ''}${githubToAccounts[g].slack}` : g);
|
||||
}
|
||||
|
||||
const accounts = [
|
||||
{
|
||||
github: 'tbd',
|
||||
slack: 'tbd'
|
||||
interface Accounts {
|
||||
github: string;
|
||||
slack: string;
|
||||
vsts: string;
|
||||
}
|
||||
|
||||
function githubToAccounts(accounts: Accounts[]) {
|
||||
return accounts.reduce((m, e) => {
|
||||
m[e.github] = e;
|
||||
return m;
|
||||
}, <Record<string, Accounts>>{});
|
||||
}
|
||||
|
||||
async function readAccounts() {
|
||||
const connectionString = process.env.BUILD_CHAT_STORAGE_CONNECTION_STRING;
|
||||
if (!connectionString) {
|
||||
console.error('Connection string missing.');
|
||||
return [];
|
||||
}
|
||||
];
|
||||
const buf = await readFile(connectionString, 'config', '/', 'accounts.json');
|
||||
return JSON.parse(buf.toString()) as Accounts[];
|
||||
}
|
||||
|
||||
type Accounts = (typeof accounts)[0];
|
||||
|
||||
const githubToAccounts = accounts.reduce((m, e) => {
|
||||
m[e.github] = e;
|
||||
return m;
|
||||
}, <Record<string, Accounts>>{});
|
||||
async function readFile(connectionString: string, share: string, directory: string, filename: string) {
|
||||
return new Promise<Buffer>((resolve, reject) => {
|
||||
const stream = new WritableStreamBuffer()
|
||||
const fileService = storage.createFileService(connectionString);
|
||||
fileService.getFileToStream(share, directory, filename, stream, err => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
const contents = stream.getContents();
|
||||
if (contents) {
|
||||
resolve(contents);
|
||||
} else {
|
||||
reject(new Error('No content'));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
interface AllChannels {
|
||||
channels: {
|
||||
|
||||
@@ -155,11 +155,50 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d"
|
||||
integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==
|
||||
|
||||
"@types/stream-buffers@^3.0.3":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/stream-buffers/-/stream-buffers-3.0.3.tgz#34e565bf64e3e4bdeee23fd4aa58d4636014a02b"
|
||||
integrity sha512-NeFeX7YfFZDYsCfbuaOmFQ0OjSmHreKBpp7MQ4alWQBHeh2USLsj7qyMyn9t82kjqIX516CR/5SRHnARduRtbQ==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
ajv@^6.12.3:
|
||||
version "6.12.6"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
|
||||
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.1"
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
json-schema-traverse "^0.4.1"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
asn1@~0.2.3:
|
||||
version "0.2.4"
|
||||
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
|
||||
integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
|
||||
dependencies:
|
||||
safer-buffer "~2.1.0"
|
||||
|
||||
assert-plus@1.0.0, assert-plus@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
|
||||
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
|
||||
|
||||
aws-sign2@~0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
|
||||
integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
|
||||
|
||||
aws4@^1.8.0:
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59"
|
||||
integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==
|
||||
|
||||
axios@^0.21.1:
|
||||
version "0.21.1"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
|
||||
@@ -167,18 +206,64 @@ axios@^0.21.1:
|
||||
dependencies:
|
||||
follow-redirects "^1.10.0"
|
||||
|
||||
azure-storage@^2.10.3:
|
||||
version "2.10.3"
|
||||
resolved "https://registry.yarnpkg.com/azure-storage/-/azure-storage-2.10.3.tgz#c5966bf929d87587d78f6847040ea9a4b1d4a50a"
|
||||
integrity sha512-IGLs5Xj6kO8Ii90KerQrrwuJKexLgSwYC4oLWmc11mzKe7Jt2E5IVg+ZQ8K53YWZACtVTMBNO3iGuA+4ipjJxQ==
|
||||
dependencies:
|
||||
browserify-mime "~1.2.9"
|
||||
extend "^3.0.2"
|
||||
json-edm-parser "0.1.2"
|
||||
md5.js "1.3.4"
|
||||
readable-stream "~2.0.0"
|
||||
request "^2.86.0"
|
||||
underscore "~1.8.3"
|
||||
uuid "^3.0.0"
|
||||
validator "~9.4.1"
|
||||
xml2js "0.2.8"
|
||||
xmlbuilder "^9.0.7"
|
||||
|
||||
bcrypt-pbkdf@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
|
||||
integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
|
||||
dependencies:
|
||||
tweetnacl "^0.14.3"
|
||||
|
||||
before-after-hook@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.1.0.tgz#b6c03487f44e24200dd30ca5e6a1979c5d2fb635"
|
||||
integrity sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A==
|
||||
|
||||
combined-stream@^1.0.6:
|
||||
browserify-mime@~1.2.9:
|
||||
version "1.2.9"
|
||||
resolved "https://registry.yarnpkg.com/browserify-mime/-/browserify-mime-1.2.9.tgz#aeb1af28de6c0d7a6a2ce40adb68ff18422af31f"
|
||||
integrity sha1-rrGvKN5sDXpqLOQK22j/GEIq8x8=
|
||||
|
||||
caseless@~0.12.0:
|
||||
version "0.12.0"
|
||||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
||||
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
||||
|
||||
combined-stream@^1.0.6, combined-stream@~1.0.6:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
||||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
core-util-is@1.0.2, core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
||||
|
||||
dashdash@^1.12.0:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
|
||||
integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
|
||||
delayed-stream@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
@@ -189,6 +274,14 @@ deprecation@^2.0.0, deprecation@^2.3.1:
|
||||
resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919"
|
||||
integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==
|
||||
|
||||
ecc-jsbn@~0.1.1:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
|
||||
integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
|
||||
dependencies:
|
||||
jsbn "~0.1.0"
|
||||
safer-buffer "^2.1.0"
|
||||
|
||||
eventemitter3@^3.1.0:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7"
|
||||
@@ -199,11 +292,41 @@ eventemitter3@^4.0.4:
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
|
||||
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
|
||||
|
||||
extend@^3.0.2, extend@~3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
||||
|
||||
extsprintf@1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
|
||||
integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
|
||||
|
||||
extsprintf@^1.2.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
|
||||
integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
|
||||
|
||||
fast-deep-equal@^3.1.1:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||
|
||||
fast-json-stable-stringify@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
|
||||
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
|
||||
|
||||
follow-redirects@^1.10.0:
|
||||
version "1.13.1"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.1.tgz#5f69b813376cee4fd0474a3aba835df04ab763b7"
|
||||
integrity sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==
|
||||
|
||||
forever-agent@~0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
||||
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
|
||||
|
||||
form-data@^2.5.0:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4"
|
||||
@@ -213,6 +336,58 @@ form-data@^2.5.0:
|
||||
combined-stream "^1.0.6"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
form-data@~2.3.2:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
|
||||
integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.6"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
getpass@^0.1.1:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
|
||||
integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
|
||||
har-schema@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
|
||||
integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
|
||||
|
||||
har-validator@~5.1.3:
|
||||
version "5.1.5"
|
||||
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd"
|
||||
integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==
|
||||
dependencies:
|
||||
ajv "^6.12.3"
|
||||
har-schema "^2.0.0"
|
||||
|
||||
hash-base@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33"
|
||||
integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==
|
||||
dependencies:
|
||||
inherits "^2.0.4"
|
||||
readable-stream "^3.6.0"
|
||||
safe-buffer "^5.2.0"
|
||||
|
||||
http-signature@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
|
||||
integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
jsprim "^1.2.2"
|
||||
sshpk "^1.7.0"
|
||||
|
||||
inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
is-plain-object@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344"
|
||||
@@ -223,12 +398,77 @@ is-stream@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
|
||||
|
||||
is-typedarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
|
||||
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
|
||||
|
||||
isarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
|
||||
|
||||
isstream@~0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
||||
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
|
||||
|
||||
jsbn@~0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
||||
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
|
||||
|
||||
json-edm-parser@0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/json-edm-parser/-/json-edm-parser-0.1.2.tgz#1e60b0fef1bc0af67bc0d146dfdde5486cd615b4"
|
||||
integrity sha1-HmCw/vG8CvZ7wNFG393lSGzWFbQ=
|
||||
dependencies:
|
||||
jsonparse "~1.2.0"
|
||||
|
||||
json-schema-traverse@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
||||
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
|
||||
|
||||
json-schema@0.2.3:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
||||
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
|
||||
|
||||
json-stringify-safe@~5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
|
||||
|
||||
jsonparse@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.2.0.tgz#5c0c5685107160e72fe7489bddea0b44c2bc67bd"
|
||||
integrity sha1-XAxWhRBxYOcv50ib3eoLRMK8Z70=
|
||||
|
||||
jsprim@^1.2.2:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
|
||||
integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
|
||||
dependencies:
|
||||
assert-plus "1.0.0"
|
||||
extsprintf "1.3.0"
|
||||
json-schema "0.2.3"
|
||||
verror "1.10.0"
|
||||
|
||||
md5.js@1.3.4:
|
||||
version "1.3.4"
|
||||
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d"
|
||||
integrity sha1-6b296UogpawYsENA/Fdk1bCdkB0=
|
||||
dependencies:
|
||||
hash-base "^3.0.0"
|
||||
inherits "^2.0.1"
|
||||
|
||||
mime-db@1.45.0:
|
||||
version "1.45.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.45.0.tgz#cceeda21ccd7c3a745eba2decd55d4b73e7879ea"
|
||||
integrity sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==
|
||||
|
||||
mime-types@^2.1.12:
|
||||
mime-types@^2.1.12, mime-types@~2.1.19:
|
||||
version "2.1.28"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.28.tgz#1160c4757eab2c5363888e005273ecf79d2a0ecd"
|
||||
integrity sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==
|
||||
@@ -240,6 +480,11 @@ node-fetch@^2.6.1:
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
||||
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
||||
|
||||
oauth-sign@~0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
|
||||
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
|
||||
|
||||
once@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
@@ -275,22 +520,209 @@ p-timeout@^3.2.0:
|
||||
dependencies:
|
||||
p-finally "^1.0.0"
|
||||
|
||||
performance-now@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
||||
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
|
||||
|
||||
process-nextick-args@~1.0.6:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
|
||||
integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=
|
||||
|
||||
psl@^1.1.28:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
|
||||
integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==
|
||||
|
||||
punycode@^2.1.0, punycode@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
||||
|
||||
qs@~6.5.2:
|
||||
version "6.5.2"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
|
||||
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
|
||||
|
||||
readable-stream@^3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
|
||||
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
|
||||
dependencies:
|
||||
inherits "^2.0.3"
|
||||
string_decoder "^1.1.1"
|
||||
util-deprecate "^1.0.1"
|
||||
|
||||
readable-stream@~2.0.0:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e"
|
||||
integrity sha1-j5A0HmilPMySh4jaz80Rs265t44=
|
||||
dependencies:
|
||||
core-util-is "~1.0.0"
|
||||
inherits "~2.0.1"
|
||||
isarray "~1.0.0"
|
||||
process-nextick-args "~1.0.6"
|
||||
string_decoder "~0.10.x"
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
request@^2.86.0:
|
||||
version "2.88.2"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
|
||||
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
|
||||
dependencies:
|
||||
aws-sign2 "~0.7.0"
|
||||
aws4 "^1.8.0"
|
||||
caseless "~0.12.0"
|
||||
combined-stream "~1.0.6"
|
||||
extend "~3.0.2"
|
||||
forever-agent "~0.6.1"
|
||||
form-data "~2.3.2"
|
||||
har-validator "~5.1.3"
|
||||
http-signature "~1.2.0"
|
||||
is-typedarray "~1.0.0"
|
||||
isstream "~0.1.2"
|
||||
json-stringify-safe "~5.0.1"
|
||||
mime-types "~2.1.19"
|
||||
oauth-sign "~0.9.0"
|
||||
performance-now "^2.1.0"
|
||||
qs "~6.5.2"
|
||||
safe-buffer "^5.1.2"
|
||||
tough-cookie "~2.5.0"
|
||||
tunnel-agent "^0.6.0"
|
||||
uuid "^3.3.2"
|
||||
|
||||
retry@^0.12.0:
|
||||
version "0.12.0"
|
||||
resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b"
|
||||
integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=
|
||||
|
||||
safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
||||
safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
|
||||
sax@0.5.x:
|
||||
version "0.5.8"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1"
|
||||
integrity sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=
|
||||
|
||||
sshpk@^1.7.0:
|
||||
version "1.16.1"
|
||||
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
|
||||
integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==
|
||||
dependencies:
|
||||
asn1 "~0.2.3"
|
||||
assert-plus "^1.0.0"
|
||||
bcrypt-pbkdf "^1.0.0"
|
||||
dashdash "^1.12.0"
|
||||
ecc-jsbn "~0.1.1"
|
||||
getpass "^0.1.1"
|
||||
jsbn "~0.1.0"
|
||||
safer-buffer "^2.0.2"
|
||||
tweetnacl "~0.14.0"
|
||||
|
||||
stream-buffers@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-3.0.2.tgz#5249005a8d5c2d00b3a32e6e0a6ea209dc4f3521"
|
||||
integrity sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ==
|
||||
|
||||
string_decoder@^1.1.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
|
||||
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
|
||||
dependencies:
|
||||
safe-buffer "~5.2.0"
|
||||
|
||||
string_decoder@~0.10.x:
|
||||
version "0.10.31"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
|
||||
integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
|
||||
|
||||
tough-cookie@~2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
|
||||
integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
|
||||
dependencies:
|
||||
psl "^1.1.28"
|
||||
punycode "^2.1.1"
|
||||
|
||||
tunnel-agent@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
|
||||
integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
|
||||
dependencies:
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
||||
version "0.14.5"
|
||||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
||||
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
|
||||
|
||||
typescript@^4.1.3:
|
||||
version "4.1.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7"
|
||||
integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==
|
||||
|
||||
underscore@~1.8.3:
|
||||
version "1.8.3"
|
||||
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022"
|
||||
integrity sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=
|
||||
|
||||
universal-user-agent@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee"
|
||||
integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==
|
||||
|
||||
uri-js@^4.2.2:
|
||||
version "4.4.1"
|
||||
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
|
||||
integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
|
||||
dependencies:
|
||||
punycode "^2.1.0"
|
||||
|
||||
util-deprecate@^1.0.1, util-deprecate@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
|
||||
|
||||
uuid@^3.0.0, uuid@^3.3.2:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
|
||||
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
|
||||
|
||||
validator@~9.4.1:
|
||||
version "9.4.1"
|
||||
resolved "https://registry.yarnpkg.com/validator/-/validator-9.4.1.tgz#abf466d398b561cd243050112c6ff1de6cc12663"
|
||||
integrity sha512-YV5KjzvRmSyJ1ee/Dm5UED0G+1L4GZnLN3w6/T+zZm8scVua4sOhYKWTUrKa0H/tMiJyO9QLHMPN+9mB/aMunA==
|
||||
|
||||
verror@1.10.0:
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
|
||||
integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
core-util-is "1.0.2"
|
||||
extsprintf "^1.2.0"
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||
|
||||
xml2js@0.2.8:
|
||||
version "0.2.8"
|
||||
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.2.8.tgz#9b81690931631ff09d1957549faf54f4f980b3c2"
|
||||
integrity sha1-m4FpCTFjH/CdGVdUn69U9PmAs8I=
|
||||
dependencies:
|
||||
sax "0.5.x"
|
||||
|
||||
xmlbuilder@^9.0.7:
|
||||
version "9.0.7"
|
||||
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
|
||||
integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=
|
||||
|
||||
@@ -33,3 +33,4 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }}
|
||||
BUILD_CHAT_STORAGE_CONNECTION_STRING: ${{ secrets.BUILD_CHAT_STORAGE_CONNECTION_STRING }}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
"use strict";
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const path = require("path");
|
||||
const retry_1 = require("./retry");
|
||||
const { installBrowsersWithProgressBar } = require('playwright/lib/install/installer');
|
||||
const playwrightPath = path.dirname(require.resolve('playwright'));
|
||||
async function install() {
|
||||
await retry_1.retry(() => installBrowsersWithProgressBar(playwrightPath));
|
||||
}
|
||||
install();
|
||||
@@ -0,0 +1,15 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as path from 'path';
|
||||
import { retry } from './retry';
|
||||
const { installBrowsersWithProgressBar } = require('playwright/lib/install/installer');
|
||||
const playwrightPath = path.dirname(require.resolve('playwright'));
|
||||
|
||||
async function install() {
|
||||
await retry(() => installBrowsersWithProgressBar(playwrightPath));
|
||||
}
|
||||
|
||||
install();
|
||||
@@ -0,0 +1,35 @@
|
||||
"use strict";
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
module.exports = new class ApiEventNaming {
|
||||
constructor() {
|
||||
this.meta = {
|
||||
messages: {
|
||||
comment: 'region comments should start with the GH issue link, e.g #region https://github.com/microsoft/vscode/issues/<number>',
|
||||
}
|
||||
};
|
||||
}
|
||||
create(context) {
|
||||
const sourceCode = context.getSourceCode();
|
||||
return {
|
||||
['Program']: (_node) => {
|
||||
for (let comment of sourceCode.getAllComments()) {
|
||||
if (comment.type !== 'Line') {
|
||||
continue;
|
||||
}
|
||||
if (!comment.value.match(/^\s*#region /)) {
|
||||
continue;
|
||||
}
|
||||
if (!comment.value.match(/https:\/\/github.com\/microsoft\/vscode\/issues\/\d+/i)) {
|
||||
context.report({
|
||||
node: comment,
|
||||
messageId: 'comment',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as eslint from 'eslint';
|
||||
|
||||
export = new class ApiEventNaming implements eslint.Rule.RuleModule {
|
||||
|
||||
readonly meta: eslint.Rule.RuleMetaData = {
|
||||
messages: {
|
||||
comment: 'region comments should start with the GH issue link, e.g #region https://github.com/microsoft/vscode/issues/<number>',
|
||||
}
|
||||
};
|
||||
|
||||
create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener {
|
||||
|
||||
const sourceCode = context.getSourceCode();
|
||||
|
||||
|
||||
return {
|
||||
['Program']: (_node: any) => {
|
||||
|
||||
for (let comment of sourceCode.getAllComments()) {
|
||||
if (comment.type !== 'Line') {
|
||||
continue;
|
||||
}
|
||||
if (!comment.value.match(/^\s*#region /)) {
|
||||
continue;
|
||||
}
|
||||
if (!comment.value.match(/https:\/\/github.com\/microsoft\/vscode\/issues\/\d+/i)) {
|
||||
context.report({
|
||||
node: <any>comment,
|
||||
messageId: 'comment',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -165,7 +165,8 @@ function minifyTask(src, sourceMapBaseUrl) {
|
||||
const esbuild = require('esbuild');
|
||||
const sourceMappingURL = sourceMapBaseUrl ? ((f) => `${sourceMapBaseUrl}/${f.relative}.map`) : undefined;
|
||||
return cb => {
|
||||
const minifyCSS = require('gulp-cssnano');
|
||||
const cssnano = require('cssnano');
|
||||
const postcss = require('gulp-postcss');
|
||||
const sourcemaps = require('gulp-sourcemaps');
|
||||
const jsFilter = filter('**/*.js', { restore: true });
|
||||
const cssFilter = filter('**/*.css', { restore: true });
|
||||
@@ -185,7 +186,7 @@ function minifyTask(src, sourceMapBaseUrl) {
|
||||
f.sourceMap = JSON.parse(sourceMapFile.text);
|
||||
cb(undefined, f);
|
||||
}, cb);
|
||||
}), jsFilter.restore, cssFilter, minifyCSS({ reduceIdents: false }), cssFilter.restore, sourcemaps.mapSources((sourcePath) => {
|
||||
}), jsFilter.restore, cssFilter, postcss([cssnano({ preset: 'default' })]), cssFilter.restore, sourcemaps.mapSources((sourcePath) => {
|
||||
if (sourcePath === 'bootstrap-fork.js') {
|
||||
return 'bootstrap-fork.orig.js';
|
||||
}
|
||||
|
||||
@@ -236,7 +236,8 @@ export function minifyTask(src: string, sourceMapBaseUrl?: string): (cb: any) =>
|
||||
const sourceMappingURL = sourceMapBaseUrl ? ((f: any) => `${sourceMapBaseUrl}/${f.relative}.map`) : undefined;
|
||||
|
||||
return cb => {
|
||||
const minifyCSS = require('gulp-cssnano') as typeof import('gulp-cssnano');
|
||||
const cssnano = require('cssnano') as typeof import('cssnano');
|
||||
const postcss = require('gulp-postcss') as typeof import('gulp-postcss');
|
||||
const sourcemaps = require('gulp-sourcemaps') as typeof import('gulp-sourcemaps');
|
||||
|
||||
const jsFilter = filter('**/*.js', { restore: true });
|
||||
@@ -267,7 +268,7 @@ export function minifyTask(src: string, sourceMapBaseUrl?: string): (cb: any) =>
|
||||
}),
|
||||
jsFilter.restore,
|
||||
cssFilter,
|
||||
minifyCSS({ reduceIdents: false }),
|
||||
postcss([cssnano({ preset: 'default' })]),
|
||||
cssFilter.restore,
|
||||
(<any>sourcemaps).mapSources((sourcePath: string) => {
|
||||
if (sourcePath === 'bootstrap-fork.js') {
|
||||
|
||||
Vendored
-12
@@ -1,12 +0,0 @@
|
||||
|
||||
declare module "gulp-cssnano" {
|
||||
function f(opts:{reduceIdents:boolean;}): NodeJS.ReadWriteStream;
|
||||
|
||||
/**
|
||||
* This is required as per:
|
||||
* https://github.com/microsoft/TypeScript/issues/5073
|
||||
*/
|
||||
namespace f {}
|
||||
|
||||
export = f;
|
||||
}
|
||||
+167
-202
@@ -354,13 +354,15 @@
|
||||
dependencies:
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
|
||||
ajv@^4.9.1:
|
||||
version "4.11.8"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
|
||||
integrity sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=
|
||||
ajv@^6.12.3:
|
||||
version "6.12.6"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
|
||||
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
|
||||
dependencies:
|
||||
co "^4.6.0"
|
||||
json-stable-stringify "^1.0.1"
|
||||
fast-deep-equal "^3.1.1"
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
json-schema-traverse "^0.4.1"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
applicationinsights@1.0.8:
|
||||
version "1.0.8"
|
||||
@@ -390,42 +392,37 @@ assert-plus@1.0.0, assert-plus@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
|
||||
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
|
||||
|
||||
assert-plus@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234"
|
||||
integrity sha1-104bh+ev/A24qttwIfP+SBAasjQ=
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
|
||||
|
||||
aws-sign2@~0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f"
|
||||
integrity sha1-FDQt0428yU0OW4fXY81jYSwOeU8=
|
||||
aws-sign2@~0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
|
||||
integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
|
||||
|
||||
aws4@^1.2.1:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
|
||||
integrity sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=
|
||||
aws4@^1.8.0:
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59"
|
||||
integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==
|
||||
|
||||
azure-storage@^2.1.0:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/azure-storage/-/azure-storage-2.6.0.tgz#84747ee54a4bd194bb960f89f3eff89d67acf1cf"
|
||||
integrity sha1-hHR+5UpL0ZS7lg+J8+/4nWes8c8=
|
||||
version "2.10.3"
|
||||
resolved "https://registry.yarnpkg.com/azure-storage/-/azure-storage-2.10.3.tgz#c5966bf929d87587d78f6847040ea9a4b1d4a50a"
|
||||
integrity sha512-IGLs5Xj6kO8Ii90KerQrrwuJKexLgSwYC4oLWmc11mzKe7Jt2E5IVg+ZQ8K53YWZACtVTMBNO3iGuA+4ipjJxQ==
|
||||
dependencies:
|
||||
browserify-mime "~1.2.9"
|
||||
extend "~1.2.1"
|
||||
extend "^3.0.2"
|
||||
json-edm-parser "0.1.2"
|
||||
md5.js "1.3.4"
|
||||
readable-stream "~2.0.0"
|
||||
request "~2.81.0"
|
||||
request "^2.86.0"
|
||||
underscore "~1.8.3"
|
||||
uuid "^3.0.0"
|
||||
validator "~3.35.0"
|
||||
xml2js "0.2.7"
|
||||
xmlbuilder "0.4.3"
|
||||
validator "~9.4.1"
|
||||
xml2js "0.2.8"
|
||||
xmlbuilder "^9.0.7"
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.0"
|
||||
@@ -454,13 +451,6 @@ boolbase@~1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
|
||||
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
|
||||
|
||||
boom@2.x.x:
|
||||
version "2.10.1"
|
||||
resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f"
|
||||
integrity sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=
|
||||
dependencies:
|
||||
hoek "2.x.x"
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
@@ -514,15 +504,10 @@ cheerio@^1.0.0-rc.1:
|
||||
lodash "^4.15.0"
|
||||
parse5 "^3.0.1"
|
||||
|
||||
co@^4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
|
||||
integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=
|
||||
|
||||
combined-stream@^1.0.5, combined-stream@~1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
|
||||
integrity sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=
|
||||
combined-stream@^1.0.6, combined-stream@~1.0.6:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
||||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
@@ -551,13 +536,6 @@ core-util-is@1.0.2, core-util-is@~1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
||||
|
||||
cryptiles@2.x.x:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
|
||||
integrity sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=
|
||||
dependencies:
|
||||
boom "2.x.x"
|
||||
|
||||
css-select@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
|
||||
@@ -724,21 +702,26 @@ estraverse@^4.1.0, estraverse@^4.1.1:
|
||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
|
||||
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
|
||||
|
||||
extend@~1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-1.2.1.tgz#a0f5fd6cfc83a5fe49ef698d60ec8a624dd4576c"
|
||||
integrity sha1-oPX9bPyDpf5J72mNYOyKYk3UV2w=
|
||||
extend@^3.0.2, extend@~3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
||||
|
||||
extend@~3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
|
||||
integrity sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=
|
||||
|
||||
extsprintf@1.3.0, extsprintf@^1.2.0:
|
||||
extsprintf@1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
|
||||
integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
|
||||
|
||||
extsprintf@^1.2.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
|
||||
integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
|
||||
|
||||
fast-deep-equal@^3.1.1:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||
|
||||
fast-json-stable-stringify@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
|
||||
@@ -756,13 +739,13 @@ forever-agent@~0.6.1:
|
||||
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
||||
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
|
||||
|
||||
form-data@~2.1.1:
|
||||
version "2.1.4"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1"
|
||||
integrity sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=
|
||||
form-data@~2.3.2:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
|
||||
integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.5"
|
||||
combined-stream "^1.0.6"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
@@ -801,41 +784,27 @@ glob@^7.1.6:
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
har-schema@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e"
|
||||
integrity sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=
|
||||
har-schema@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
|
||||
integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
|
||||
|
||||
har-validator@~4.2.1:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a"
|
||||
integrity sha1-M0gdDxu/9gDdID11gSpqX7oALio=
|
||||
har-validator@~5.1.3:
|
||||
version "5.1.5"
|
||||
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd"
|
||||
integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==
|
||||
dependencies:
|
||||
ajv "^4.9.1"
|
||||
har-schema "^1.0.5"
|
||||
ajv "^6.12.3"
|
||||
har-schema "^2.0.0"
|
||||
|
||||
hash-base@^3.0.0:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918"
|
||||
integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33"
|
||||
integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==
|
||||
dependencies:
|
||||
inherits "^2.0.1"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
hawk@~3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
|
||||
integrity sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=
|
||||
dependencies:
|
||||
boom "2.x.x"
|
||||
cryptiles "2.x.x"
|
||||
hoek "2.x.x"
|
||||
sntp "1.x.x"
|
||||
|
||||
hoek@2.x.x:
|
||||
version "2.16.3"
|
||||
resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
|
||||
integrity sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=
|
||||
inherits "^2.0.4"
|
||||
readable-stream "^3.6.0"
|
||||
safe-buffer "^5.2.0"
|
||||
|
||||
htmlparser2@^3.9.1:
|
||||
version "3.10.0"
|
||||
@@ -849,12 +818,12 @@ htmlparser2@^3.9.1:
|
||||
inherits "^2.0.1"
|
||||
readable-stream "^3.0.6"
|
||||
|
||||
http-signature@~1.1.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf"
|
||||
integrity sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=
|
||||
http-signature@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
|
||||
integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
|
||||
dependencies:
|
||||
assert-plus "^0.2.0"
|
||||
assert-plus "^1.0.0"
|
||||
jsprim "^1.2.2"
|
||||
sshpk "^1.7.0"
|
||||
|
||||
@@ -871,12 +840,12 @@ inflight@^1.0.4:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2:
|
||||
inherits@2, inherits@^2.0.1, inherits@^2.0.4, inherits@~2.0.1:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1:
|
||||
inherits@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||
@@ -932,18 +901,16 @@ json-edm-parser@0.1.2:
|
||||
dependencies:
|
||||
jsonparse "~1.2.0"
|
||||
|
||||
json-schema-traverse@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
||||
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
|
||||
|
||||
json-schema@0.2.3:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
||||
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
|
||||
|
||||
json-stable-stringify@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af"
|
||||
integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=
|
||||
dependencies:
|
||||
jsonify "~0.0.0"
|
||||
|
||||
json-stringify-safe@~5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||
@@ -954,11 +921,6 @@ jsonc-parser@^2.3.0:
|
||||
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.3.0.tgz#7c7fc988ee1486d35734faaaa866fadb00fa91ee"
|
||||
integrity sha512-b0EBt8SWFNnixVdvoR2ZtEGa9ZqLhbJnOjezn+WP+8kspFm+PFYDN8Z4Bc7pRlDjvuVcADSUkroIuTWWn/YiIA==
|
||||
|
||||
jsonify@~0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
|
||||
integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=
|
||||
|
||||
jsonparse@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.2.0.tgz#5c0c5685107160e72fe7489bddea0b44c2bc67bd"
|
||||
@@ -1027,17 +989,17 @@ mdurl@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
|
||||
integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=
|
||||
|
||||
mime-db@~1.30.0:
|
||||
version "1.30.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01"
|
||||
integrity sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=
|
||||
mime-db@1.45.0:
|
||||
version "1.45.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.45.0.tgz#cceeda21ccd7c3a745eba2decd55d4b73e7879ea"
|
||||
integrity sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==
|
||||
|
||||
mime-types@^2.1.12, mime-types@~2.1.7:
|
||||
version "2.1.17"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a"
|
||||
integrity sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=
|
||||
mime-types@^2.1.12, mime-types@~2.1.19:
|
||||
version "2.1.28"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.28.tgz#1160c4757eab2c5363888e005273ecf79d2a0ecd"
|
||||
integrity sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==
|
||||
dependencies:
|
||||
mime-db "~1.30.0"
|
||||
mime-db "1.45.0"
|
||||
|
||||
mime@^1.3.4:
|
||||
version "1.4.1"
|
||||
@@ -1098,10 +1060,10 @@ nth-check@~1.0.1:
|
||||
dependencies:
|
||||
boolbase "~1.0.0"
|
||||
|
||||
oauth-sign@~0.8.1:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
|
||||
integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=
|
||||
oauth-sign@~0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
|
||||
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
|
||||
|
||||
once@^1.3.0:
|
||||
version "1.4.0"
|
||||
@@ -1152,10 +1114,10 @@ pend@~1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
|
||||
integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA=
|
||||
|
||||
performance-now@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
|
||||
integrity sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=
|
||||
performance-now@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
||||
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
|
||||
|
||||
plist@^3.0.1:
|
||||
version "3.0.1"
|
||||
@@ -1176,20 +1138,25 @@ process-nextick-args@~1.0.6:
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
|
||||
integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=
|
||||
|
||||
punycode@^1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
|
||||
integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
|
||||
psl@^1.1.28:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
|
||||
integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==
|
||||
|
||||
punycode@^2.1.0, punycode@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
||||
|
||||
q@^1.0.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
|
||||
integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
|
||||
|
||||
qs@~6.4.0:
|
||||
version "6.4.0"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
|
||||
integrity sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=
|
||||
qs@~6.5.2:
|
||||
version "6.5.2"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
|
||||
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
|
||||
|
||||
read@^1.0.7:
|
||||
version "1.0.7"
|
||||
@@ -1207,6 +1174,15 @@ readable-stream@^3.0.6:
|
||||
string_decoder "^1.1.1"
|
||||
util-deprecate "^1.0.1"
|
||||
|
||||
readable-stream@^3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
|
||||
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
|
||||
dependencies:
|
||||
inherits "^2.0.3"
|
||||
string_decoder "^1.1.1"
|
||||
util-deprecate "^1.0.1"
|
||||
|
||||
readable-stream@~2.0.0:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e"
|
||||
@@ -1219,38 +1195,36 @@ readable-stream@~2.0.0:
|
||||
string_decoder "~0.10.x"
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
request@~2.81.0:
|
||||
version "2.81.0"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0"
|
||||
integrity sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=
|
||||
request@^2.86.0:
|
||||
version "2.88.2"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
|
||||
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
|
||||
dependencies:
|
||||
aws-sign2 "~0.6.0"
|
||||
aws4 "^1.2.1"
|
||||
aws-sign2 "~0.7.0"
|
||||
aws4 "^1.8.0"
|
||||
caseless "~0.12.0"
|
||||
combined-stream "~1.0.5"
|
||||
extend "~3.0.0"
|
||||
combined-stream "~1.0.6"
|
||||
extend "~3.0.2"
|
||||
forever-agent "~0.6.1"
|
||||
form-data "~2.1.1"
|
||||
har-validator "~4.2.1"
|
||||
hawk "~3.1.3"
|
||||
http-signature "~1.1.0"
|
||||
form-data "~2.3.2"
|
||||
har-validator "~5.1.3"
|
||||
http-signature "~1.2.0"
|
||||
is-typedarray "~1.0.0"
|
||||
isstream "~0.1.2"
|
||||
json-stringify-safe "~5.0.1"
|
||||
mime-types "~2.1.7"
|
||||
oauth-sign "~0.8.1"
|
||||
performance-now "^0.2.0"
|
||||
qs "~6.4.0"
|
||||
safe-buffer "^5.0.1"
|
||||
stringstream "~0.0.4"
|
||||
tough-cookie "~2.3.0"
|
||||
mime-types "~2.1.19"
|
||||
oauth-sign "~0.9.0"
|
||||
performance-now "^2.1.0"
|
||||
qs "~6.5.2"
|
||||
safe-buffer "^5.1.2"
|
||||
tough-cookie "~2.5.0"
|
||||
tunnel-agent "^0.6.0"
|
||||
uuid "^3.0.0"
|
||||
uuid "^3.3.2"
|
||||
|
||||
safe-buffer@^5.0.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
|
||||
integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==
|
||||
safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
||||
safe-buffer@~5.1.0:
|
||||
version "5.1.2"
|
||||
@@ -1262,10 +1236,10 @@ safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
|
||||
sax@0.5.2:
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.2.tgz#735ffaa39a1cff8ffb9598f0223abdb03a9fb2ea"
|
||||
integrity sha1-c1/6o5oc/4/7lZjwIjq9sDqfsuo=
|
||||
sax@0.5.x:
|
||||
version "0.5.8"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1"
|
||||
integrity sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=
|
||||
|
||||
semaphore@^1.0.5:
|
||||
version "1.1.0"
|
||||
@@ -1289,13 +1263,6 @@ semver@^7.3.2:
|
||||
dependencies:
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
sntp@1.x.x:
|
||||
version "1.0.9"
|
||||
resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198"
|
||||
integrity sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=
|
||||
dependencies:
|
||||
hoek "2.x.x"
|
||||
|
||||
source-map@0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
@@ -1333,11 +1300,6 @@ string_decoder@~0.10.x:
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
|
||||
integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
|
||||
|
||||
stringstream@~0.0.4:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.6.tgz#7880225b0d4ad10e30927d167a1d6f2fd3b33a72"
|
||||
integrity sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==
|
||||
|
||||
tmp@0.0.29:
|
||||
version "0.0.29"
|
||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.29.tgz#f25125ff0dd9da3ccb0c2dd371ee1288bb9128c0"
|
||||
@@ -1345,12 +1307,13 @@ tmp@0.0.29:
|
||||
dependencies:
|
||||
os-tmpdir "~1.0.1"
|
||||
|
||||
tough-cookie@~2.3.0:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561"
|
||||
integrity sha1-C2GKVWW23qkL80JdBNVe3EdadWE=
|
||||
tough-cookie@~2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
|
||||
integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
|
||||
dependencies:
|
||||
punycode "^1.4.1"
|
||||
psl "^1.1.28"
|
||||
punycode "^2.1.1"
|
||||
|
||||
tslib@^1.8.1:
|
||||
version "1.9.3"
|
||||
@@ -1419,6 +1382,13 @@ universal-user-agent@^6.0.0:
|
||||
resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee"
|
||||
integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==
|
||||
|
||||
uri-js@^4.2.2:
|
||||
version "4.4.1"
|
||||
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
|
||||
integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
|
||||
dependencies:
|
||||
punycode "^2.1.0"
|
||||
|
||||
url-join@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/url-join/-/url-join-1.1.0.tgz#741c6c2f4596c4830d6718460920d0c92202dc78"
|
||||
@@ -1429,20 +1399,20 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
|
||||
|
||||
uuid@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
|
||||
integrity sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==
|
||||
uuid@^3.0.0, uuid@^3.3.2:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
|
||||
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
|
||||
|
||||
uuid@^8.3.0:
|
||||
version "8.3.1"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.1.tgz#2ba2e6ca000da60fce5a196954ab241131e05a31"
|
||||
integrity sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==
|
||||
|
||||
validator@~3.35.0:
|
||||
version "3.35.0"
|
||||
resolved "https://registry.yarnpkg.com/validator/-/validator-3.35.0.tgz#3f07249402c1fc8fc093c32c6e43d72a79cca1dc"
|
||||
integrity sha1-PwcklALB/I/Ak8MsbkPXKnnModw=
|
||||
validator@~9.4.1:
|
||||
version "9.4.1"
|
||||
resolved "https://registry.yarnpkg.com/validator/-/validator-9.4.1.tgz#abf466d398b561cd243050112c6ff1de6cc12663"
|
||||
integrity sha512-YV5KjzvRmSyJ1ee/Dm5UED0G+1L4GZnLN3w6/T+zZm8scVua4sOhYKWTUrKa0H/tMiJyO9QLHMPN+9mB/aMunA==
|
||||
|
||||
verror@1.10.0:
|
||||
version "1.10.0"
|
||||
@@ -1491,17 +1461,12 @@ wrappy@1:
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||
|
||||
xml2js@0.2.7:
|
||||
version "0.2.7"
|
||||
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.2.7.tgz#1838518bb01741cae0878bab4915e494c32306af"
|
||||
integrity sha1-GDhRi7AXQcrgh4urSRXklMMjBq8=
|
||||
xml2js@0.2.8:
|
||||
version "0.2.8"
|
||||
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.2.8.tgz#9b81690931631ff09d1957549faf54f4f980b3c2"
|
||||
integrity sha1-m4FpCTFjH/CdGVdUn69U9PmAs8I=
|
||||
dependencies:
|
||||
sax "0.5.2"
|
||||
|
||||
xmlbuilder@0.4.3:
|
||||
version "0.4.3"
|
||||
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-0.4.3.tgz#c4614ba74e0ad196e609c9272cd9e1ddb28a8a58"
|
||||
integrity sha1-xGFLp04K0ZbmCcknLNnh3bKKilg=
|
||||
sax "0.5.x"
|
||||
|
||||
xmlbuilder@^9.0.7:
|
||||
version "9.0.7"
|
||||
|
||||
@@ -71,6 +71,11 @@
|
||||
"category": "Git",
|
||||
"icon": "$(compare-changes)"
|
||||
},
|
||||
{
|
||||
"command": "git.openAllChanges",
|
||||
"title": "%command.openAllChanges%",
|
||||
"category": "Git"
|
||||
},
|
||||
{
|
||||
"command": "git.openFile",
|
||||
"title": "%command.openFile%",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"command.close": "Close Repository",
|
||||
"command.refresh": "Refresh",
|
||||
"command.openChange": "Open Changes",
|
||||
"command.openAllChanges": "Open All Changes",
|
||||
"command.openFile": "Open File",
|
||||
"command.openHEADFile": "Open File (HEAD)",
|
||||
"command.stage": "Stage Changes",
|
||||
|
||||
@@ -372,6 +372,20 @@ export class CommandCenter {
|
||||
await resource.open();
|
||||
}
|
||||
|
||||
@command('git.openAllChanges', { repository: true })
|
||||
async openChanges(repository: Repository): Promise<void> {
|
||||
[
|
||||
...repository.workingTreeGroup.resourceStates,
|
||||
...repository.untrackedGroup.resourceStates,
|
||||
].forEach(resource => {
|
||||
commands.executeCommand(
|
||||
'vscode.open',
|
||||
resource.resourceUri,
|
||||
{ preview: false, }
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
async cloneRepository(url?: string, parentPath?: string, options: { recursive?: boolean } = {}): Promise<void> {
|
||||
if (!url || typeof url !== 'string') {
|
||||
url = await pickRemoteSource(this.model, {
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
# Simple Browser files
|
||||
|
||||
**Notice:** This extension is bundled with Visual Studio Code. It can be disabled but not uninstalled.
|
||||
|
||||
|
||||
a $a + b = c$ b
|
||||
|
||||
a $\pm\sqrt{a^2 + b^2}$ b
|
||||
|
||||
@@ -46,7 +46,7 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
manager.show(url.toString(), showOptions);
|
||||
}));
|
||||
|
||||
context.subscriptions.push(vscode.window.registerExternalUriOpener(openerId, ['http', 'https'], {
|
||||
context.subscriptions.push(vscode.window.registerExternalUriOpener(openerId, {
|
||||
canOpenExternalUri(uri: vscode.Uri) {
|
||||
const originalUri = new URL(uri.toString());
|
||||
if (enabledHosts.has(originalUri.hostname)) {
|
||||
@@ -63,6 +63,7 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
});
|
||||
}
|
||||
}, {
|
||||
schemes: ['http', 'https'],
|
||||
label: localize('openTitle', "Open in simple browser"),
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
"onCommand:vscode-testresolver.newWindow",
|
||||
"onCommand:vscode-testresolver.newWindowWithError",
|
||||
"onCommand:vscode-testresolver.showLog",
|
||||
"onCommand:vscode-testresolver.openTunnel"
|
||||
"onCommand:vscode-testresolver.openTunnel",
|
||||
"onCommand:vscode-testresolver.startRemoteServer"
|
||||
],
|
||||
"main": "./out/extension",
|
||||
"devDependencies": {
|
||||
@@ -55,12 +56,27 @@
|
||||
"command": "vscode-testresolver.killServerAndTriggerHandledError"
|
||||
},
|
||||
{
|
||||
"title": "Open Tunnel 100",
|
||||
"title": "Open Tunnel...",
|
||||
"category": "Remote-TestResolver",
|
||||
"command": "vscode-testresolver.openTunnel"
|
||||
},
|
||||
{
|
||||
"title": "Open Remote Server...",
|
||||
"category": "Remote-TestResolver",
|
||||
"command": "vscode-testresolver.startRemoteServer"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"commandPalette": [
|
||||
{
|
||||
"command": "vscode-testresolver.openTunnel",
|
||||
"when": "remoteName == test"
|
||||
},
|
||||
{
|
||||
"command": "vscode-testresolver.startRemoteServer",
|
||||
"when": "remoteName == test"
|
||||
}
|
||||
],
|
||||
"statusBar/windowIndicator": [
|
||||
{
|
||||
"command": "vscode-testresolver.newWindow",
|
||||
@@ -76,6 +92,16 @@
|
||||
"command": "vscode-testresolver.newWindow",
|
||||
"when": "remoteName == test",
|
||||
"group": "1_remote_testresolver_open@1"
|
||||
},
|
||||
{
|
||||
"command": "vscode-testresolver.openTunnel",
|
||||
"when": "remoteName == test",
|
||||
"group": "1_remote_testresolver_open@4"
|
||||
},
|
||||
{
|
||||
"command": "vscode-testresolver.startRemoteServer",
|
||||
"when": "remoteName == test",
|
||||
"group": "1_remote_testresolver_open@5"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -9,6 +9,7 @@ import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
import * as net from 'net';
|
||||
import * as http from 'http';
|
||||
import { downloadAndUnzipVSCodeServer } from './download';
|
||||
import { terminateProcess } from './util/processes';
|
||||
|
||||
@@ -216,7 +217,7 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
},
|
||||
tunnelFactory,
|
||||
tunnelFeatures: { elevation: true, public: false },
|
||||
showCandidatePort: async (_host, port) => port === 100
|
||||
showCandidatePort
|
||||
});
|
||||
context.subscriptions.push(authorityResolverDisposable);
|
||||
|
||||
@@ -245,14 +246,35 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
outputChannel.show();
|
||||
}
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('vscode-testresolver.openTunnel', () => {
|
||||
vscode.workspace.openTunnel({
|
||||
remoteAddress: {
|
||||
host: 'localhost',
|
||||
port: 100
|
||||
},
|
||||
localAddressPort: 100
|
||||
|
||||
context.subscriptions.push(vscode.commands.registerCommand('vscode-testresolver.openTunnel', async () => {
|
||||
const result = await vscode.window.showInputBox({
|
||||
prompt: 'Enter the remote port for the tunnel',
|
||||
value: '5000',
|
||||
validateInput: input => /^[\d]+$/.test(input) ? undefined : 'Not a valid number'
|
||||
});
|
||||
if (result) {
|
||||
const port = Number.parseInt(result);
|
||||
vscode.workspace.openTunnel({
|
||||
remoteAddress: {
|
||||
host: 'localhost',
|
||||
port: port
|
||||
},
|
||||
localAddressPort: port + 1
|
||||
});
|
||||
}
|
||||
|
||||
}));
|
||||
context.subscriptions.push(vscode.commands.registerCommand('vscode-testresolver.startRemoteServer', async () => {
|
||||
const result = await vscode.window.showInputBox({
|
||||
prompt: 'Enter the port for the remote server',
|
||||
value: '5000',
|
||||
validateInput: input => /^[\d]+$/.test(input) ? undefined : 'Not a valid number'
|
||||
});
|
||||
if (result) {
|
||||
runHTTPTestServer(Number.parseInt(result));
|
||||
}
|
||||
|
||||
}));
|
||||
vscode.commands.executeCommand('setContext', 'forwardedPortsViewEnabled', true);
|
||||
}
|
||||
@@ -316,13 +338,19 @@ function getConfiguration<T>(id: string): T | undefined {
|
||||
return vscode.workspace.getConfiguration('testresolver').get<T>(id);
|
||||
}
|
||||
|
||||
function tunnelFactory(tunnelOptions: vscode.TunnelOptions): Promise<vscode.Tunnel> | undefined {
|
||||
let remotePort = tunnelOptions.remoteAddress.port;
|
||||
if (remotePort === 100) {
|
||||
return createTunnelService();
|
||||
}
|
||||
return undefined;
|
||||
const remoteServers: number[] = [];
|
||||
|
||||
async function showCandidatePort(_host: string, port: number, _detail: string): Promise<boolean> {
|
||||
return remoteServers.includes(port) || port === 100;
|
||||
}
|
||||
|
||||
async function tunnelFactory(tunnelOptions: vscode.TunnelOptions, tunnelCreationOptions: vscode.TunnelCreationOptions): Promise<vscode.Tunnel> {
|
||||
outputChannel.appendLine(`Tunnel factory request: Remote ${tunnelOptions.remoteAddress.port} -> local ${tunnelOptions.localAddressPort}`);
|
||||
if (tunnelCreationOptions.elevationRequired) {
|
||||
await vscode.window.showInformationMessage('This is a fake elevation message. A real resolver would show a native elevation prompt.', { modal: true }, 'Ok');
|
||||
}
|
||||
|
||||
return createTunnelService();
|
||||
|
||||
function newTunnel(localAddress: { host: string, port: number }) {
|
||||
const onDidDispose: vscode.EventEmitter<void> = new vscode.EventEmitter();
|
||||
@@ -344,14 +372,32 @@ function tunnelFactory(tunnelOptions: vscode.TunnelOptions): Promise<vscode.Tunn
|
||||
function createTunnelService(): Promise<vscode.Tunnel> {
|
||||
return new Promise<vscode.Tunnel>((res, _rej) => {
|
||||
const proxyServer = net.createServer(proxySocket => {
|
||||
outputChannel.appendLine(`Connection accepted`);
|
||||
const remoteSocket = net.createConnection({ host: tunnelOptions.remoteAddress.host, port: tunnelOptions.remoteAddress.port });
|
||||
remoteSocket.pipe(proxySocket);
|
||||
proxySocket.pipe(remoteSocket);
|
||||
});
|
||||
proxyServer.listen(tunnelOptions.localAddressPort === undefined ? 0 : tunnelOptions.localAddressPort, () => {
|
||||
let localPort = 0;
|
||||
|
||||
if (tunnelOptions.localAddressPort) {
|
||||
// When the tunnelOptions include a localAddressPort, we should use that.
|
||||
// However, the test resolver all runs on one machine, so if the localAddressPort is the same as the remote port,
|
||||
// then we must use a different port number.
|
||||
localPort = tunnelOptions.localAddressPort;
|
||||
} else {
|
||||
localPort = tunnelOptions.remoteAddress.port;
|
||||
}
|
||||
|
||||
if (localPort === tunnelOptions.remoteAddress.port) {
|
||||
localPort += 1;
|
||||
}
|
||||
|
||||
// The test resolver can't actually handle privileged ports, it only pretends to.
|
||||
if (localPort < 1024 && process.platform !== 'win32') {
|
||||
localPort = 0;
|
||||
}
|
||||
proxyServer.listen(localPort, () => {
|
||||
const localPort = (<net.AddressInfo>proxyServer.address()).port;
|
||||
console.log(`New test resolver tunnel service: Remote ${tunnelOptions.remoteAddress.port} -> local ${localPort}`);
|
||||
outputChannel.appendLine(`New test resolver tunnel service: Remote ${tunnelOptions.remoteAddress.port} -> local ${localPort}`);
|
||||
const tunnel = newTunnel({ host: 'localhost', port: localPort });
|
||||
tunnel.onDidDispose(() => proxyServer.close());
|
||||
res(tunnel);
|
||||
@@ -359,3 +405,24 @@ function tunnelFactory(tunnelOptions: vscode.TunnelOptions): Promise<vscode.Tunn
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function runHTTPTestServer(port: number): vscode.Disposable {
|
||||
const server = http.createServer((_req, res) => {
|
||||
res.writeHead(200);
|
||||
res.end(`Hello, World from test server running on port ${port}!`);
|
||||
});
|
||||
remoteServers.push(port);
|
||||
server.listen(port);
|
||||
const message = `Opened HTTP server on http://localhost:${port}`;
|
||||
console.log(message);
|
||||
outputChannel.appendLine(message);
|
||||
return {
|
||||
dispose: () => {
|
||||
server.close();
|
||||
const index = remoteServers.indexOf(port);
|
||||
if (index !== -1) {
|
||||
remoteServers.splice(index, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
+14
-8
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "code-oss-dev",
|
||||
"version": "1.53.0",
|
||||
"distro": "9743d4c538f650da5636ce1b2994c719dfa8e953",
|
||||
"distro": "65cbf43543d86e78b90fb749d535c3d3ed9dd3a5",
|
||||
"author": {
|
||||
"name": "Microsoft Corporation"
|
||||
},
|
||||
@@ -47,7 +47,7 @@
|
||||
"watch-web": "node --max_old_space_size=4095 ./node_modules/gulp/bin/gulp.js watch-web",
|
||||
"eslint": "node build/eslint",
|
||||
"electron-rebuild": "electron-rebuild --arch=arm64 --force --version=11.2.0",
|
||||
"playwright-install": "node node_modules/playwright/install.js",
|
||||
"playwright-install": "node build/azure-pipelines/common/installPlaywright.js",
|
||||
"compile-build": "node --max_old_space_size=4095 ./node_modules/gulp/bin/gulp.js compile-build",
|
||||
"compile-extensions-build": "node --max_old_space_size=4095 ./node_modules/gulp/bin/gulp.js compile-extensions-build",
|
||||
"minify-vscode": "node --max_old_space_size=4095 ./node_modules/gulp/bin/gulp.js minify-vscode",
|
||||
@@ -98,8 +98,10 @@
|
||||
"@types/chokidar": "2.1.3",
|
||||
"@types/cookie": "^0.3.3",
|
||||
"@types/copy-webpack-plugin": "^6.0.3",
|
||||
"@types/cssnano": "^4.0.0",
|
||||
"@types/debug": "4.1.5",
|
||||
"@types/graceful-fs": "4.1.2",
|
||||
"@types/gulp-postcss": "^8.0.0",
|
||||
"@types/http-proxy-agent": "^2.0.1",
|
||||
"@types/keytar": "^4.4.0",
|
||||
"@types/minimist": "^1.2.1",
|
||||
@@ -123,6 +125,7 @@
|
||||
"copy-webpack-plugin": "^6.0.3",
|
||||
"cson-parser": "^1.3.3",
|
||||
"css-loader": "^3.2.0",
|
||||
"cssnano": "^4.1.10",
|
||||
"debounce": "^1.0.0",
|
||||
"deemon": "^1.4.0",
|
||||
"electron": "11.2.0",
|
||||
@@ -133,15 +136,13 @@
|
||||
"fancy-log": "^1.3.3",
|
||||
"fast-plist": "0.1.2",
|
||||
"file-loader": "^4.2.0",
|
||||
"github-releases": "^0.4.1",
|
||||
"glob": "^5.0.13",
|
||||
"gulp": "^4.0.0",
|
||||
"gulp-atom-electron": "^1.22.0",
|
||||
"gulp-azure-storage": "^0.11.1",
|
||||
"gulp-bom": "^1.0.0",
|
||||
"gulp-bom": "^3.0.0",
|
||||
"gulp-buffer": "0.0.2",
|
||||
"gulp-concat": "^2.6.1",
|
||||
"gulp-cssnano": "^2.1.3",
|
||||
"gulp-eslint": "^5.0.0",
|
||||
"gulp-filter": "^5.1.0",
|
||||
"gulp-flatmap": "^1.0.2",
|
||||
@@ -149,11 +150,12 @@
|
||||
"gulp-gzip": "^1.4.2",
|
||||
"gulp-json-editor": "^2.5.0",
|
||||
"gulp-plumber": "^1.2.0",
|
||||
"gulp-postcss": "^9.0.0",
|
||||
"gulp-remote-retry-src": "^0.6.0",
|
||||
"gulp-rename": "^1.2.0",
|
||||
"gulp-replace": "^0.5.4",
|
||||
"gulp-shell": "^0.6.5",
|
||||
"gulp-sourcemaps": "^1.11.0",
|
||||
"gulp-sourcemaps": "^3.0.0",
|
||||
"gulp-tsb": "4.0.5",
|
||||
"gulp-untar": "^0.0.7",
|
||||
"gulp-vinyl-zip": "^2.1.2",
|
||||
@@ -189,8 +191,8 @@
|
||||
"source-map": "0.6.1",
|
||||
"source-map-support": "^0.3.2",
|
||||
"style-loader": "^1.0.0",
|
||||
"tsec": "0.1.1",
|
||||
"ts-loader": "^6.2.1",
|
||||
"tsec": "0.1.1",
|
||||
"typescript": "4.2.0-dev.20201207",
|
||||
"typescript-formatter": "7.1.0",
|
||||
"underscore": "^1.8.2",
|
||||
@@ -218,5 +220,9 @@
|
||||
"windows-foreground-love": "0.2.0",
|
||||
"windows-mutex": "0.3.0",
|
||||
"windows-process-tree": "0.2.4"
|
||||
},
|
||||
"resolutions": {
|
||||
"elliptic": "^6.5.3",
|
||||
"nwmatcher": "^1.4.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ComposedTreeDelegate, IAbstractTreeOptions, IAbstractTreeOptionsUpdate } from 'vs/base/browser/ui/tree/abstractTree';
|
||||
import { ObjectTree, IObjectTreeOptions, CompressibleObjectTree, ICompressibleTreeRenderer, ICompressibleKeyboardNavigationLabelProvider, ICompressibleObjectTreeOptions } from 'vs/base/browser/ui/tree/objectTree';
|
||||
import { ObjectTree, IObjectTreeOptions, CompressibleObjectTree, ICompressibleTreeRenderer, ICompressibleKeyboardNavigationLabelProvider, ICompressibleObjectTreeOptions, IObjectTreeSetChildrenOptions } from 'vs/base/browser/ui/tree/objectTree';
|
||||
import { IListVirtualDelegate, IIdentityProvider, IListDragAndDrop, IListDragOverReaction } from 'vs/base/browser/ui/list/list';
|
||||
import { ITreeElement, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeSorter, ICollapseStateChangeEvent, IAsyncDataSource, ITreeDragAndDrop, TreeError, WeakMapper, ITreeFilter, TreeVisibility, TreeFilterResult } from 'vs/base/browser/ui/tree/tree';
|
||||
import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
@@ -20,7 +20,6 @@ import { ICompressedTreeNode, ICompressedTreeElement } from 'vs/base/browser/ui/
|
||||
import { IThemable } from 'vs/base/common/styler';
|
||||
import { isFilterResult, getVisibleState } from 'vs/base/browser/ui/tree/indexTreeModel';
|
||||
import { treeItemLoadingIcon } from 'vs/base/browser/ui/tree/treeIcons';
|
||||
import { IObjectTreeSetChildrenOptions } from 'vs/base/browser/ui/tree/objectTreeModel';
|
||||
|
||||
interface IAsyncDataTreeNode<TInput, T> {
|
||||
element: TInput | T;
|
||||
@@ -280,7 +279,7 @@ function asObjectTreeOptions<TInput, T, TFilterData>(options?: IAsyncDataTreeOpt
|
||||
}
|
||||
|
||||
export interface IAsyncDataTreeOptionsUpdate extends IAbstractTreeOptionsUpdate { }
|
||||
export interface IAsyncDataTreeUpdateChildrenOptions<T, TFilterData> extends IObjectTreeSetChildrenOptions<T, TFilterData> { }
|
||||
export interface IAsyncDataTreeUpdateChildrenOptions<T> extends IObjectTreeSetChildrenOptions<T> { }
|
||||
|
||||
export interface IAsyncDataTreeOptions<T, TFilterData = void> extends IAsyncDataTreeOptionsUpdate, Pick<IAbstractTreeOptions<T, TFilterData>, Exclude<keyof IAbstractTreeOptions<T, TFilterData>, 'collapseByDefault'>> {
|
||||
readonly collapseByDefault?: { (e: T): boolean; };
|
||||
@@ -501,11 +500,11 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
async updateChildren(element: TInput | T = this.root.element, recursive = true, rerender = false, options?: IAsyncDataTreeUpdateChildrenOptions<T | TInput, TFilterData>): Promise<void> {
|
||||
async updateChildren(element: TInput | T = this.root.element, recursive = true, rerender = false, options?: IAsyncDataTreeUpdateChildrenOptions<T>): Promise<void> {
|
||||
await this._updateChildren(element, recursive, rerender, undefined, options);
|
||||
}
|
||||
|
||||
private async _updateChildren(element: TInput | T = this.root.element, recursive = true, rerender = false, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>, options?: IAsyncDataTreeUpdateChildrenOptions<T | TInput, TFilterData>): Promise<void> {
|
||||
private async _updateChildren(element: TInput | T = this.root.element, recursive = true, rerender = false, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>, options?: IAsyncDataTreeUpdateChildrenOptions<T>): Promise<void> {
|
||||
if (typeof this.root.element === 'undefined') {
|
||||
throw new TreeError(this.user, 'Tree input not set');
|
||||
}
|
||||
@@ -706,7 +705,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
|
||||
return node;
|
||||
}
|
||||
|
||||
private async refreshAndRenderNode(node: IAsyncDataTreeNode<TInput, T>, recursive: boolean, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>, options?: IAsyncDataTreeUpdateChildrenOptions<T | TInput, TFilterData>): Promise<void> {
|
||||
private async refreshAndRenderNode(node: IAsyncDataTreeNode<TInput, T>, recursive: boolean, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>, options?: IAsyncDataTreeUpdateChildrenOptions<T>): Promise<void> {
|
||||
await this.refreshNode(node, recursive, viewStateContext);
|
||||
this.render(node, viewStateContext, options);
|
||||
}
|
||||
@@ -923,20 +922,18 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
|
||||
return childrenToRefresh;
|
||||
}
|
||||
|
||||
protected render(node: IAsyncDataTreeNode<TInput, T>, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>, options?: IAsyncDataTreeUpdateChildrenOptions<T, TFilterData>): void {
|
||||
protected render(node: IAsyncDataTreeNode<TInput, T>, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>, options?: IAsyncDataTreeUpdateChildrenOptions<T>): void {
|
||||
const children = node.children.map(node => this.asTreeElement(node, viewStateContext));
|
||||
|
||||
const diffIdentity = options?.diffIdentityProvider;
|
||||
const treeOptions = options ? {
|
||||
diffIdentityProvider: diffIdentity ? {
|
||||
const objectTreeOptions: IObjectTreeSetChildrenOptions<IAsyncDataTreeNode<TInput, T>> | undefined = options && {
|
||||
...options,
|
||||
diffIdentityProvider: options!.diffIdentityProvider && {
|
||||
getId(node: IAsyncDataTreeNode<TInput, T>): { toString(): string; } {
|
||||
return diffIdentity.getId(node.element as T);
|
||||
return options!.diffIdentityProvider!.getId(node.element as T);
|
||||
}
|
||||
} : undefined,
|
||||
diffDept: options.diffDepth
|
||||
} : undefined;
|
||||
}
|
||||
};
|
||||
|
||||
this.tree.setChildren(node === this.root ? null : node, children, treeOptions);
|
||||
this.tree.setChildren(node === this.root ? null : node, children, objectTreeOptions);
|
||||
|
||||
if (node !== this.root) {
|
||||
this.tree.setCollapsible(node, node.hasChildren);
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
import { Iterable } from 'vs/base/common/iterator';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { ITreeModel, ITreeNode, ITreeElement, ICollapseStateChangeEvent, ITreeModelSpliceEvent, TreeError, TreeFilterResult, TreeVisibility, WeakMapper } from 'vs/base/browser/ui/tree/tree';
|
||||
import { IObjectTreeModelOptions, ObjectTreeModel, IObjectTreeModel, IObjectTreeSetChildrenOptions } from 'vs/base/browser/ui/tree/objectTreeModel';
|
||||
import { IIndexedSpliceOptions, IList } from 'vs/base/browser/ui/tree/indexTreeModel';
|
||||
import { IObjectTreeModelOptions, ObjectTreeModel, IObjectTreeModel, IObjectTreeModelSetChildrenOptions } from 'vs/base/browser/ui/tree/objectTreeModel';
|
||||
import { IIndexTreeModelSpliceOptions, IList } from 'vs/base/browser/ui/tree/indexTreeModel';
|
||||
import { IIdentityProvider } from 'vs/base/browser/ui/list/list';
|
||||
|
||||
// Exported only for test reasons, do not use directly
|
||||
@@ -144,7 +144,7 @@ export class CompressedObjectTreeModel<T extends NonNullable<any>, TFilterData e
|
||||
setChildren(
|
||||
element: T | null,
|
||||
children: Iterable<ICompressedTreeElement<T>> = Iterable.empty(),
|
||||
options: IObjectTreeSetChildrenOptions<T, TFilterData>,
|
||||
options: IObjectTreeModelSetChildrenOptions<T, TFilterData>,
|
||||
): void {
|
||||
// Diffs must be deem, since the compression can affect nested elements.
|
||||
// @see https://github.com/microsoft/vscode/pull/114237#issuecomment-759425034
|
||||
@@ -206,7 +206,7 @@ export class CompressedObjectTreeModel<T extends NonNullable<any>, TFilterData e
|
||||
private _setChildren(
|
||||
node: ICompressedTreeNode<T> | null,
|
||||
children: Iterable<ITreeElement<ICompressedTreeNode<T>>>,
|
||||
options: IIndexedSpliceOptions<ICompressedTreeNode<T>, TFilterData>,
|
||||
options: IIndexTreeModelSpliceOptions<ICompressedTreeNode<T>, TFilterData>,
|
||||
): void {
|
||||
const insertedElements = new Set<T | null>();
|
||||
const onDidCreateNode = (node: ITreeNode<ICompressedTreeNode<T>, TFilterData>) => {
|
||||
@@ -451,7 +451,7 @@ export class CompressibleObjectTreeModel<T extends NonNullable<any>, TFilterData
|
||||
setChildren(
|
||||
element: T | null,
|
||||
children: Iterable<ICompressedTreeElement<T>> = Iterable.empty(),
|
||||
options: IObjectTreeSetChildrenOptions<T, TFilterData> = {},
|
||||
options: IObjectTreeModelSetChildrenOptions<T, TFilterData> = {},
|
||||
): void {
|
||||
this.model.setChildren(element, children, options);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ export interface IIndexTreeModelOptions<T, TFilterData> {
|
||||
readonly autoExpandSingleChildren?: boolean;
|
||||
}
|
||||
|
||||
export interface IIndexedSpliceOptions<T, TFilterData> {
|
||||
export interface IIndexTreeModelSpliceOptions<T, TFilterData> {
|
||||
/**
|
||||
* If set, child updates will recurse the given number of levels even if
|
||||
* items in the splice operation are unchanged. `Infinity` is a valid value.
|
||||
@@ -140,7 +140,7 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
|
||||
location: number[],
|
||||
deleteCount: number,
|
||||
toInsert: Iterable<ITreeElement<T>> = Iterable.empty(),
|
||||
options: IIndexedSpliceOptions<T, TFilterData> = {},
|
||||
options: IIndexTreeModelSpliceOptions<T, TFilterData> = {},
|
||||
): void {
|
||||
if (location.length === 0) {
|
||||
throw new TreeError(this.user, 'Invalid tree location');
|
||||
@@ -158,7 +158,7 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
|
||||
location: number[],
|
||||
deleteCount: number,
|
||||
toInsertIterable: Iterable<ITreeElement<T>> = Iterable.empty(),
|
||||
options: IIndexedSpliceOptions<T, TFilterData>,
|
||||
options: IIndexTreeModelSpliceOptions<T, TFilterData>,
|
||||
recurseLevels = options.diffDepth ?? 0,
|
||||
) {
|
||||
const { parentNode } = this.getParentNodeWithListIndex(location);
|
||||
@@ -221,7 +221,7 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
|
||||
location: number[],
|
||||
deleteCount: number,
|
||||
toInsert: Iterable<ITreeElement<T>> = Iterable.empty(),
|
||||
{ onDidCreateNode, onDidDeleteNode }: IIndexedSpliceOptions<T, TFilterData>,
|
||||
{ onDidCreateNode, onDidDeleteNode }: IIndexTreeModelSpliceOptions<T, TFilterData>,
|
||||
) {
|
||||
const { parentNode, listIndex, revealed, visible } = this.getParentNodeWithListIndex(location);
|
||||
const treeListElementsToInsert: ITreeNode<T, TFilterData>[] = [];
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
import { Iterable } from 'vs/base/common/iterator';
|
||||
import { AbstractTree, IAbstractTreeOptions, IAbstractTreeOptionsUpdate } from 'vs/base/browser/ui/tree/abstractTree';
|
||||
import { ITreeNode, ITreeModel, ITreeElement, ITreeRenderer, ITreeSorter, ICollapseStateChangeEvent } from 'vs/base/browser/ui/tree/tree';
|
||||
import { ObjectTreeModel, IObjectTreeModel, IObjectTreeSetChildrenOptions } from 'vs/base/browser/ui/tree/objectTreeModel';
|
||||
import { IListVirtualDelegate, IKeyboardNavigationLabelProvider } from 'vs/base/browser/ui/list/list';
|
||||
import { ObjectTreeModel, IObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel';
|
||||
import { IListVirtualDelegate, IKeyboardNavigationLabelProvider, IIdentityProvider } from 'vs/base/browser/ui/list/list';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { CompressibleObjectTreeModel, ElementMapper, ICompressedTreeNode, ICompressedTreeElement } from 'vs/base/browser/ui/tree/compressedObjectTreeModel';
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
@@ -17,6 +17,25 @@ export interface IObjectTreeOptions<T, TFilterData = void> extends IAbstractTree
|
||||
readonly sorter?: ITreeSorter<T>;
|
||||
}
|
||||
|
||||
export interface IObjectTreeSetChildrenOptions<T> {
|
||||
|
||||
/**
|
||||
* If set, child updates will recurse the given number of levels even if
|
||||
* items in the splice operation are unchanged. `Infinity` is a valid value.
|
||||
*/
|
||||
readonly diffDepth?: number;
|
||||
|
||||
/**
|
||||
* Identity provider used to optimize splice() calls in the IndexTree. If
|
||||
* this is not present, optimized splicing is not enabled.
|
||||
*
|
||||
* Warning: if this is present, calls to `setChildren()` will not replace
|
||||
* or update nodes if their identity is the same, even if the elements are
|
||||
* different. For this, you should call `rerender()`.
|
||||
*/
|
||||
readonly diffIdentityProvider?: IIdentityProvider<T>;
|
||||
}
|
||||
|
||||
export class ObjectTree<T extends NonNullable<any>, TFilterData = void> extends AbstractTree<T | null, TFilterData, T | null> {
|
||||
|
||||
protected model!: IObjectTreeModel<T, TFilterData>;
|
||||
@@ -33,7 +52,7 @@ export class ObjectTree<T extends NonNullable<any>, TFilterData = void> extends
|
||||
super(user, container, delegate, renderers, options as IObjectTreeOptions<T | null, TFilterData>);
|
||||
}
|
||||
|
||||
setChildren(element: T | null, children: Iterable<ITreeElement<T>> = Iterable.empty(), options?: IObjectTreeSetChildrenOptions<T, TFilterData>): void {
|
||||
setChildren(element: T | null, children: Iterable<ITreeElement<T>> = Iterable.empty(), options?: IObjectTreeSetChildrenOptions<T>): void {
|
||||
this.model.setChildren(element, children, options);
|
||||
}
|
||||
|
||||
@@ -189,7 +208,7 @@ export class CompressibleObjectTree<T extends NonNullable<any>, TFilterData = vo
|
||||
super(user, container, delegate, compressibleRenderers, asObjectTreeOptions<T, TFilterData>(compressedTreeNodeProvider, options));
|
||||
}
|
||||
|
||||
setChildren(element: T | null, children: Iterable<ICompressedTreeElement<T>> = Iterable.empty(), options: IObjectTreeSetChildrenOptions<T, TFilterData> = {}): void {
|
||||
setChildren(element: T | null, children: Iterable<ICompressedTreeElement<T>> = Iterable.empty(), options?: IObjectTreeSetChildrenOptions<T>): void {
|
||||
this.model.setChildren(element, children, options);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Iterable } from 'vs/base/common/iterator';
|
||||
import { IndexTreeModel, IIndexTreeModelOptions, IList, IIndexedSpliceOptions } from 'vs/base/browser/ui/tree/indexTreeModel';
|
||||
import { IndexTreeModel, IIndexTreeModelOptions, IList, IIndexTreeModelSpliceOptions } from 'vs/base/browser/ui/tree/indexTreeModel';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { ITreeModel, ITreeNode, ITreeElement, ITreeSorter, ICollapseStateChangeEvent, ITreeModelSpliceEvent, TreeError } from 'vs/base/browser/ui/tree/tree';
|
||||
import { IIdentityProvider } from 'vs/base/browser/ui/list/list';
|
||||
@@ -13,12 +13,12 @@ import { mergeSort } from 'vs/base/common/arrays';
|
||||
export type ITreeNodeCallback<T, TFilterData> = (node: ITreeNode<T, TFilterData>) => void;
|
||||
|
||||
export interface IObjectTreeModel<T extends NonNullable<any>, TFilterData extends NonNullable<any> = void> extends ITreeModel<T | null, TFilterData, T | null> {
|
||||
setChildren(element: T | null, children: Iterable<ITreeElement<T>> | undefined, options?: IObjectTreeSetChildrenOptions<T, TFilterData>): void;
|
||||
setChildren(element: T | null, children: Iterable<ITreeElement<T>> | undefined, options?: IObjectTreeModelSetChildrenOptions<T, TFilterData>): void;
|
||||
resort(element?: T | null, recursive?: boolean): void;
|
||||
updateElementHeight(element: T, height: number): void;
|
||||
}
|
||||
|
||||
export interface IObjectTreeSetChildrenOptions<T, TFilterData> extends IIndexedSpliceOptions<T, TFilterData> {
|
||||
export interface IObjectTreeModelSetChildrenOptions<T, TFilterData> extends IIndexTreeModelSpliceOptions<T, TFilterData> {
|
||||
}
|
||||
|
||||
export interface IObjectTreeModelOptions<T, TFilterData> extends IIndexTreeModelOptions<T, TFilterData> {
|
||||
@@ -66,7 +66,7 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends Non
|
||||
setChildren(
|
||||
element: T | null,
|
||||
children: Iterable<ITreeElement<T>> = Iterable.empty(),
|
||||
options: IObjectTreeSetChildrenOptions<T, TFilterData> = {},
|
||||
options: IObjectTreeModelSetChildrenOptions<T, TFilterData> = {},
|
||||
): void {
|
||||
const location = this.getElementLocation(element);
|
||||
this._setChildren(location, this.preserveCollapseState(children), options);
|
||||
@@ -75,7 +75,7 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends Non
|
||||
private _setChildren(
|
||||
location: number[],
|
||||
children: Iterable<ITreeElement<T>> = Iterable.empty(),
|
||||
options: IObjectTreeSetChildrenOptions<T, TFilterData>,
|
||||
options: IObjectTreeModelSetChildrenOptions<T, TFilterData>,
|
||||
): void {
|
||||
const insertedElements = new Set<T | null>();
|
||||
const insertedElementIds = new Set<string>();
|
||||
|
||||
@@ -38,7 +38,7 @@ export class Client extends MessagePortClient implements IDisposable {
|
||||
export async function connect(window: BrowserWindow): Promise<MessagePortMain> {
|
||||
|
||||
// Assert healthy window to talk to
|
||||
if (window.webContents.isDestroyed()) {
|
||||
if (window.isDestroyed() || window.webContents.isDestroyed()) {
|
||||
throw new Error('ipc.mp#connect: Cannot talk to window because it is closed or destroyed');
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import { compress, ICompressedTreeElement, ICompressedTreeNode, decompress, Comp
|
||||
import { Iterable } from 'vs/base/common/iterator';
|
||||
import { ITreeNode } from 'vs/base/browser/ui/tree/tree';
|
||||
import { IList } from 'vs/base/browser/ui/tree/indexTreeModel';
|
||||
import { IObjectTreeSetChildrenOptions } from 'vs/base/browser/ui/tree/objectTreeModel';
|
||||
import { IObjectTreeModelSetChildrenOptions } from 'vs/base/browser/ui/tree/objectTreeModel';
|
||||
|
||||
interface IResolvedCompressedTreeElement<T> extends ICompressedTreeElement<T> {
|
||||
readonly element: T;
|
||||
@@ -309,7 +309,7 @@ suite('CompressedObjectTree', function () {
|
||||
* Calls that test function twice, once with an empty options and
|
||||
* once with `diffIdentityProvider`.
|
||||
*/
|
||||
function withSmartSplice(fn: (options: IObjectTreeSetChildrenOptions<number, any>) => void) {
|
||||
function withSmartSplice(fn: (options: IObjectTreeModelSetChildrenOptions<number, any>) => void) {
|
||||
fn({});
|
||||
fn({ diffIdentityProvider: { getId: n => String(n) } });
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { ITreeNode, ITreeFilter, TreeVisibility, ITreeElement } from 'vs/base/browser/ui/tree/tree';
|
||||
import { IndexTreeModel, IIndexTreeNode, IList, IIndexedSpliceOptions } from 'vs/base/browser/ui/tree/indexTreeModel';
|
||||
import { IndexTreeModel, IIndexTreeNode, IList, IIndexTreeModelSpliceOptions } from 'vs/base/browser/ui/tree/indexTreeModel';
|
||||
|
||||
function toList<T>(arr: T[]): IList<T> {
|
||||
return {
|
||||
@@ -31,7 +31,7 @@ const diffIdentityProvider = { getId: (n: number) => String(n) };
|
||||
* Calls that test function twice, once with an empty options and
|
||||
* once with `diffIdentityProvider`.
|
||||
*/
|
||||
function withSmartSplice(fn: (options: IIndexedSpliceOptions<number, any>) => void) {
|
||||
function withSmartSplice(fn: (options: IIndexTreeModelSpliceOptions<number, any>) => void) {
|
||||
fn({});
|
||||
fn({ diffIdentityProvider });
|
||||
}
|
||||
|
||||
@@ -10,25 +10,25 @@ suite('Arrays', () => {
|
||||
const array = [1, 4, 5, 7, 55, 59, 60, 61, 64, 69];
|
||||
|
||||
let idx = arrays.findFirstInSorted(array, e => e >= 0);
|
||||
assert.equal(array[idx], 1);
|
||||
assert.strictEqual(array[idx], 1);
|
||||
|
||||
idx = arrays.findFirstInSorted(array, e => e > 1);
|
||||
assert.equal(array[idx], 4);
|
||||
assert.strictEqual(array[idx], 4);
|
||||
|
||||
idx = arrays.findFirstInSorted(array, e => e >= 8);
|
||||
assert.equal(array[idx], 55);
|
||||
assert.strictEqual(array[idx], 55);
|
||||
|
||||
idx = arrays.findFirstInSorted(array, e => e >= 61);
|
||||
assert.equal(array[idx], 61);
|
||||
assert.strictEqual(array[idx], 61);
|
||||
|
||||
idx = arrays.findFirstInSorted(array, e => e >= 69);
|
||||
assert.equal(array[idx], 69);
|
||||
assert.strictEqual(array[idx], 69);
|
||||
|
||||
idx = arrays.findFirstInSorted(array, e => e >= 70);
|
||||
assert.equal(idx, array.length);
|
||||
assert.strictEqual(idx, array.length);
|
||||
|
||||
idx = arrays.findFirstInSorted([], e => e >= 0);
|
||||
assert.equal(array[idx], 1);
|
||||
assert.strictEqual(array[idx], 1);
|
||||
});
|
||||
|
||||
test('quickSelect', () => {
|
||||
@@ -36,10 +36,10 @@ suite('Arrays', () => {
|
||||
function assertMedian(expexted: number, data: number[], nth: number = Math.floor(data.length / 2)) {
|
||||
const compare = (a: number, b: number) => a - b;
|
||||
let actual1 = arrays.quickSelect(nth, data, compare);
|
||||
assert.equal(actual1, expexted);
|
||||
assert.strictEqual(actual1, expexted);
|
||||
|
||||
let actual2 = data.slice().sort(compare)[nth];
|
||||
assert.equal(actual2, expexted);
|
||||
assert.strictEqual(actual2, expexted);
|
||||
}
|
||||
|
||||
assertMedian(5, [9, 1, 0, 2, 3, 4, 6, 8, 7, 10, 5]);
|
||||
@@ -72,18 +72,18 @@ suite('Arrays', () => {
|
||||
|
||||
test('mergeSort', () => {
|
||||
let data = arrays.mergeSort([6, 5, 3, 1, 8, 7, 2, 4], (a, b) => a - b);
|
||||
assert.deepEqual(data, [1, 2, 3, 4, 5, 6, 7, 8]);
|
||||
assert.deepStrictEqual(data, [1, 2, 3, 4, 5, 6, 7, 8]);
|
||||
});
|
||||
|
||||
test('mergeSort, sorted array', function () {
|
||||
let data = arrays.mergeSort([1, 2, 3, 4, 5, 6], (a, b) => a - b);
|
||||
assert.deepEqual(data, [1, 2, 3, 4, 5, 6]);
|
||||
assert.deepStrictEqual(data, [1, 2, 3, 4, 5, 6]);
|
||||
});
|
||||
|
||||
test('mergeSort, is stable', function () {
|
||||
|
||||
let numbers = arrays.mergeSort([33, 22, 11, 4, 99, 1], (a, b) => 0);
|
||||
assert.deepEqual(numbers, [33, 22, 11, 4, 99, 1]);
|
||||
assert.deepStrictEqual(numbers, [33, 22, 11, 4, 99, 1]);
|
||||
});
|
||||
|
||||
test('mergeSort, many random numbers', function () {
|
||||
@@ -129,40 +129,40 @@ suite('Arrays', () => {
|
||||
}
|
||||
|
||||
let d = arrays.sortedDiff([1, 2, 4], [], compare);
|
||||
assert.deepEqual(d, [
|
||||
assert.deepStrictEqual(d, [
|
||||
{ start: 0, deleteCount: 3, toInsert: [] }
|
||||
]);
|
||||
|
||||
d = arrays.sortedDiff([], [1, 2, 4], compare);
|
||||
assert.deepEqual(d, [
|
||||
assert.deepStrictEqual(d, [
|
||||
{ start: 0, deleteCount: 0, toInsert: [1, 2, 4] }
|
||||
]);
|
||||
|
||||
d = arrays.sortedDiff([1, 2, 4], [1, 2, 4], compare);
|
||||
assert.deepEqual(d, []);
|
||||
assert.deepStrictEqual(d, []);
|
||||
|
||||
d = arrays.sortedDiff([1, 2, 4], [2, 3, 4, 5], compare);
|
||||
assert.deepEqual(d, [
|
||||
assert.deepStrictEqual(d, [
|
||||
{ start: 0, deleteCount: 1, toInsert: [] },
|
||||
{ start: 2, deleteCount: 0, toInsert: [3] },
|
||||
{ start: 3, deleteCount: 0, toInsert: [5] },
|
||||
]);
|
||||
|
||||
d = arrays.sortedDiff([2, 3, 4, 5], [1, 2, 4], compare);
|
||||
assert.deepEqual(d, [
|
||||
assert.deepStrictEqual(d, [
|
||||
{ start: 0, deleteCount: 0, toInsert: [1] },
|
||||
{ start: 1, deleteCount: 1, toInsert: [] },
|
||||
{ start: 3, deleteCount: 1, toInsert: [] },
|
||||
]);
|
||||
|
||||
d = arrays.sortedDiff([1, 3, 5, 7], [5, 9, 11], compare);
|
||||
assert.deepEqual(d, [
|
||||
assert.deepStrictEqual(d, [
|
||||
{ start: 0, deleteCount: 2, toInsert: [] },
|
||||
{ start: 3, deleteCount: 1, toInsert: [9, 11] }
|
||||
]);
|
||||
|
||||
d = arrays.sortedDiff([1, 3, 7], [5, 9, 11], compare);
|
||||
assert.deepEqual(d, [
|
||||
assert.deepStrictEqual(d, [
|
||||
{ start: 0, deleteCount: 3, toInsert: [5, 9, 11] }
|
||||
]);
|
||||
});
|
||||
@@ -173,32 +173,32 @@ suite('Arrays', () => {
|
||||
}
|
||||
|
||||
let d = arrays.delta([1, 2, 4], [], compare);
|
||||
assert.deepEqual(d.removed, [1, 2, 4]);
|
||||
assert.deepEqual(d.added, []);
|
||||
assert.deepStrictEqual(d.removed, [1, 2, 4]);
|
||||
assert.deepStrictEqual(d.added, []);
|
||||
|
||||
d = arrays.delta([], [1, 2, 4], compare);
|
||||
assert.deepEqual(d.removed, []);
|
||||
assert.deepEqual(d.added, [1, 2, 4]);
|
||||
assert.deepStrictEqual(d.removed, []);
|
||||
assert.deepStrictEqual(d.added, [1, 2, 4]);
|
||||
|
||||
d = arrays.delta([1, 2, 4], [1, 2, 4], compare);
|
||||
assert.deepEqual(d.removed, []);
|
||||
assert.deepEqual(d.added, []);
|
||||
assert.deepStrictEqual(d.removed, []);
|
||||
assert.deepStrictEqual(d.added, []);
|
||||
|
||||
d = arrays.delta([1, 2, 4], [2, 3, 4, 5], compare);
|
||||
assert.deepEqual(d.removed, [1]);
|
||||
assert.deepEqual(d.added, [3, 5]);
|
||||
assert.deepStrictEqual(d.removed, [1]);
|
||||
assert.deepStrictEqual(d.added, [3, 5]);
|
||||
|
||||
d = arrays.delta([2, 3, 4, 5], [1, 2, 4], compare);
|
||||
assert.deepEqual(d.removed, [3, 5]);
|
||||
assert.deepEqual(d.added, [1]);
|
||||
assert.deepStrictEqual(d.removed, [3, 5]);
|
||||
assert.deepStrictEqual(d.added, [1]);
|
||||
|
||||
d = arrays.delta([1, 3, 5, 7], [5, 9, 11], compare);
|
||||
assert.deepEqual(d.removed, [1, 3, 7]);
|
||||
assert.deepEqual(d.added, [9, 11]);
|
||||
assert.deepStrictEqual(d.removed, [1, 3, 7]);
|
||||
assert.deepStrictEqual(d.added, [9, 11]);
|
||||
|
||||
d = arrays.delta([1, 3, 7], [5, 9, 11], compare);
|
||||
assert.deepEqual(d.removed, [1, 3, 7]);
|
||||
assert.deepEqual(d.added, [5, 9, 11]);
|
||||
assert.deepStrictEqual(d.removed, [1, 3, 7]);
|
||||
assert.deepStrictEqual(d.added, [5, 9, 11]);
|
||||
});
|
||||
|
||||
test('binarySearch', () => {
|
||||
@@ -207,13 +207,13 @@ suite('Arrays', () => {
|
||||
}
|
||||
const array = [1, 4, 5, 7, 55, 59, 60, 61, 64, 69];
|
||||
|
||||
assert.equal(arrays.binarySearch(array, 1, compare), 0);
|
||||
assert.equal(arrays.binarySearch(array, 5, compare), 2);
|
||||
assert.strictEqual(arrays.binarySearch(array, 1, compare), 0);
|
||||
assert.strictEqual(arrays.binarySearch(array, 5, compare), 2);
|
||||
|
||||
// insertion point
|
||||
assert.equal(arrays.binarySearch(array, 0, compare), ~0);
|
||||
assert.equal(arrays.binarySearch(array, 6, compare), ~3);
|
||||
assert.equal(arrays.binarySearch(array, 70, compare), ~10);
|
||||
assert.strictEqual(arrays.binarySearch(array, 0, compare), ~0);
|
||||
assert.strictEqual(arrays.binarySearch(array, 6, compare), ~3);
|
||||
assert.strictEqual(arrays.binarySearch(array, 70, compare), ~10);
|
||||
|
||||
});
|
||||
|
||||
@@ -222,11 +222,11 @@ suite('Arrays', () => {
|
||||
return a;
|
||||
}
|
||||
|
||||
assert.deepEqual(arrays.distinct(['32', '4', '5'], compare), ['32', '4', '5']);
|
||||
assert.deepEqual(arrays.distinct(['32', '4', '5', '4'], compare), ['32', '4', '5']);
|
||||
assert.deepEqual(arrays.distinct(['32', 'constructor', '5', '1'], compare), ['32', 'constructor', '5', '1']);
|
||||
assert.deepEqual(arrays.distinct(['32', 'constructor', 'proto', 'proto', 'constructor'], compare), ['32', 'constructor', 'proto']);
|
||||
assert.deepEqual(arrays.distinct(['32', '4', '5', '32', '4', '5', '32', '4', '5', '5'], compare), ['32', '4', '5']);
|
||||
assert.deepStrictEqual(arrays.distinct(['32', '4', '5'], compare), ['32', '4', '5']);
|
||||
assert.deepStrictEqual(arrays.distinct(['32', '4', '5', '4'], compare), ['32', '4', '5']);
|
||||
assert.deepStrictEqual(arrays.distinct(['32', 'constructor', '5', '1'], compare), ['32', 'constructor', '5', '1']);
|
||||
assert.deepStrictEqual(arrays.distinct(['32', 'constructor', 'proto', 'proto', 'constructor'], compare), ['32', 'constructor', 'proto']);
|
||||
assert.deepStrictEqual(arrays.distinct(['32', '4', '5', '32', '4', '5', '32', '4', '5', '5'], compare), ['32', '4', '5']);
|
||||
});
|
||||
|
||||
test('top', () => {
|
||||
@@ -236,13 +236,13 @@ suite('Arrays', () => {
|
||||
return a - b;
|
||||
};
|
||||
|
||||
assert.deepEqual(arrays.top([], cmp, 1), []);
|
||||
assert.deepEqual(arrays.top([1], cmp, 0), []);
|
||||
assert.deepEqual(arrays.top([1, 2], cmp, 1), [1]);
|
||||
assert.deepEqual(arrays.top([2, 1], cmp, 1), [1]);
|
||||
assert.deepEqual(arrays.top([1, 3, 2], cmp, 2), [1, 2]);
|
||||
assert.deepEqual(arrays.top([3, 2, 1], cmp, 3), [1, 2, 3]);
|
||||
assert.deepEqual(arrays.top([4, 6, 2, 7, 8, 3, 5, 1], cmp, 3), [1, 2, 3]);
|
||||
assert.deepStrictEqual(arrays.top([], cmp, 1), []);
|
||||
assert.deepStrictEqual(arrays.top([1], cmp, 0), []);
|
||||
assert.deepStrictEqual(arrays.top([1, 2], cmp, 1), [1]);
|
||||
assert.deepStrictEqual(arrays.top([2, 1], cmp, 1), [1]);
|
||||
assert.deepStrictEqual(arrays.top([1, 3, 2], cmp, 2), [1, 2]);
|
||||
assert.deepStrictEqual(arrays.top([3, 2, 1], cmp, 3), [1, 2, 3]);
|
||||
assert.deepStrictEqual(arrays.top([4, 6, 2, 7, 8, 3, 5, 1], cmp, 3), [1, 2, 3]);
|
||||
});
|
||||
|
||||
test('topAsync', async () => {
|
||||
@@ -259,56 +259,56 @@ suite('Arrays', () => {
|
||||
async function testTopAsync(cmp: any, m: number) {
|
||||
{
|
||||
const result = await arrays.topAsync([], cmp, 1, m);
|
||||
assert.deepEqual(result, []);
|
||||
assert.deepStrictEqual(result, []);
|
||||
}
|
||||
{
|
||||
const result = await arrays.topAsync([1], cmp, 0, m);
|
||||
assert.deepEqual(result, []);
|
||||
assert.deepStrictEqual(result, []);
|
||||
}
|
||||
{
|
||||
const result = await arrays.topAsync([1, 2], cmp, 1, m);
|
||||
assert.deepEqual(result, [1]);
|
||||
assert.deepStrictEqual(result, [1]);
|
||||
}
|
||||
{
|
||||
const result = await arrays.topAsync([2, 1], cmp, 1, m);
|
||||
assert.deepEqual(result, [1]);
|
||||
assert.deepStrictEqual(result, [1]);
|
||||
}
|
||||
{
|
||||
const result = await arrays.topAsync([1, 3, 2], cmp, 2, m);
|
||||
assert.deepEqual(result, [1, 2]);
|
||||
assert.deepStrictEqual(result, [1, 2]);
|
||||
}
|
||||
{
|
||||
const result = await arrays.topAsync([3, 2, 1], cmp, 3, m);
|
||||
assert.deepEqual(result, [1, 2, 3]);
|
||||
assert.deepStrictEqual(result, [1, 2, 3]);
|
||||
}
|
||||
{
|
||||
const result = await arrays.topAsync([4, 6, 2, 7, 8, 3, 5, 1], cmp, 3, m);
|
||||
assert.deepEqual(result, [1, 2, 3]);
|
||||
assert.deepStrictEqual(result, [1, 2, 3]);
|
||||
}
|
||||
}
|
||||
|
||||
test('coalesce', () => {
|
||||
let a: Array<number | null> = arrays.coalesce([null, 1, null, 2, 3]);
|
||||
assert.equal(a.length, 3);
|
||||
assert.equal(a[0], 1);
|
||||
assert.equal(a[1], 2);
|
||||
assert.equal(a[2], 3);
|
||||
assert.strictEqual(a.length, 3);
|
||||
assert.strictEqual(a[0], 1);
|
||||
assert.strictEqual(a[1], 2);
|
||||
assert.strictEqual(a[2], 3);
|
||||
|
||||
arrays.coalesce([null, 1, null, undefined, undefined, 2, 3]);
|
||||
assert.equal(a.length, 3);
|
||||
assert.equal(a[0], 1);
|
||||
assert.equal(a[1], 2);
|
||||
assert.equal(a[2], 3);
|
||||
assert.strictEqual(a.length, 3);
|
||||
assert.strictEqual(a[0], 1);
|
||||
assert.strictEqual(a[1], 2);
|
||||
assert.strictEqual(a[2], 3);
|
||||
|
||||
let b: number[] = [];
|
||||
b[10] = 1;
|
||||
b[20] = 2;
|
||||
b[30] = 3;
|
||||
b = arrays.coalesce(b);
|
||||
assert.equal(b.length, 3);
|
||||
assert.equal(b[0], 1);
|
||||
assert.equal(b[1], 2);
|
||||
assert.equal(b[2], 3);
|
||||
assert.strictEqual(b.length, 3);
|
||||
assert.strictEqual(b[0], 1);
|
||||
assert.strictEqual(b[1], 2);
|
||||
assert.strictEqual(b[2], 3);
|
||||
|
||||
let sparse: number[] = [];
|
||||
sparse[0] = 1;
|
||||
@@ -317,36 +317,36 @@ suite('Arrays', () => {
|
||||
sparse[1000] = 1;
|
||||
sparse[1001] = 1;
|
||||
|
||||
assert.equal(sparse.length, 1002);
|
||||
assert.strictEqual(sparse.length, 1002);
|
||||
|
||||
sparse = arrays.coalesce(sparse);
|
||||
assert.equal(sparse.length, 5);
|
||||
assert.strictEqual(sparse.length, 5);
|
||||
});
|
||||
|
||||
test('coalesce - inplace', function () {
|
||||
let a: Array<number | null> = [null, 1, null, 2, 3];
|
||||
arrays.coalesceInPlace(a);
|
||||
assert.equal(a.length, 3);
|
||||
assert.equal(a[0], 1);
|
||||
assert.equal(a[1], 2);
|
||||
assert.equal(a[2], 3);
|
||||
assert.strictEqual(a.length, 3);
|
||||
assert.strictEqual(a[0], 1);
|
||||
assert.strictEqual(a[1], 2);
|
||||
assert.strictEqual(a[2], 3);
|
||||
|
||||
a = [null, 1, null, undefined!, undefined!, 2, 3];
|
||||
arrays.coalesceInPlace(a);
|
||||
assert.equal(a.length, 3);
|
||||
assert.equal(a[0], 1);
|
||||
assert.equal(a[1], 2);
|
||||
assert.equal(a[2], 3);
|
||||
assert.strictEqual(a.length, 3);
|
||||
assert.strictEqual(a[0], 1);
|
||||
assert.strictEqual(a[1], 2);
|
||||
assert.strictEqual(a[2], 3);
|
||||
|
||||
let b: number[] = [];
|
||||
b[10] = 1;
|
||||
b[20] = 2;
|
||||
b[30] = 3;
|
||||
arrays.coalesceInPlace(b);
|
||||
assert.equal(b.length, 3);
|
||||
assert.equal(b[0], 1);
|
||||
assert.equal(b[1], 2);
|
||||
assert.equal(b[2], 3);
|
||||
assert.strictEqual(b.length, 3);
|
||||
assert.strictEqual(b[0], 1);
|
||||
assert.strictEqual(b[1], 2);
|
||||
assert.strictEqual(b[2], 3);
|
||||
|
||||
let sparse: number[] = [];
|
||||
sparse[0] = 1;
|
||||
@@ -355,18 +355,18 @@ suite('Arrays', () => {
|
||||
sparse[1000] = 1;
|
||||
sparse[1001] = 1;
|
||||
|
||||
assert.equal(sparse.length, 1002);
|
||||
assert.strictEqual(sparse.length, 1002);
|
||||
|
||||
arrays.coalesceInPlace(sparse);
|
||||
assert.equal(sparse.length, 5);
|
||||
assert.strictEqual(sparse.length, 5);
|
||||
});
|
||||
|
||||
test('insert, remove', function () {
|
||||
const array: string[] = [];
|
||||
const remove = arrays.insert(array, 'foo');
|
||||
assert.equal(array[0], 'foo');
|
||||
assert.strictEqual(array[0], 'foo');
|
||||
|
||||
remove();
|
||||
assert.equal(array.length, 0);
|
||||
assert.strictEqual(array.length, 0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -18,7 +18,7 @@ suite('Async', () => {
|
||||
return new Promise(resolve => { /*never*/ });
|
||||
});
|
||||
let result = promise.then(_ => assert.ok(false), err => {
|
||||
assert.equal(canceled, 1);
|
||||
assert.strictEqual(canceled, 1);
|
||||
assert.ok(isPromiseCanceledError(err));
|
||||
});
|
||||
promise.cancel();
|
||||
@@ -33,7 +33,7 @@ suite('Async', () => {
|
||||
return Promise.resolve(1234);
|
||||
});
|
||||
let result = promise.then(_ => assert.ok(false), err => {
|
||||
assert.equal(canceled, 1);
|
||||
assert.strictEqual(canceled, 1);
|
||||
assert.ok(isPromiseCanceledError(err));
|
||||
});
|
||||
promise.cancel();
|
||||
@@ -60,7 +60,7 @@ suite('Async', () => {
|
||||
cancellablePromise.cancel();
|
||||
order.push('afterCancel');
|
||||
|
||||
return promise.then(() => assert.deepEqual(order, ['in callback', 'afterCreate', 'cancelled', 'afterCancel', 'finally']));
|
||||
return promise.then(() => assert.deepStrictEqual(order, ['in callback', 'afterCreate', 'cancelled', 'afterCancel', 'finally']));
|
||||
});
|
||||
|
||||
// Cancelling an async cancelable promise is just the same as a sync cancellable promise.
|
||||
@@ -82,7 +82,7 @@ suite('Async', () => {
|
||||
cancellablePromise.cancel();
|
||||
order.push('afterCancel');
|
||||
|
||||
return promise.then(() => assert.deepEqual(order, ['in callback', 'afterCreate', 'cancelled', 'afterCancel', 'finally']));
|
||||
return promise.then(() => assert.deepStrictEqual(order, ['in callback', 'afterCreate', 'cancelled', 'afterCancel', 'finally']));
|
||||
});
|
||||
|
||||
test('cancelablePromise - get inner result', async function () {
|
||||
@@ -91,7 +91,7 @@ suite('Async', () => {
|
||||
});
|
||||
|
||||
let result = await promise;
|
||||
assert.equal(result, 1234);
|
||||
assert.strictEqual(result, 1234);
|
||||
});
|
||||
|
||||
test('Throttler - non async', function () {
|
||||
@@ -103,12 +103,12 @@ suite('Async', () => {
|
||||
let throttler = new async.Throttler();
|
||||
|
||||
return Promise.all([
|
||||
throttler.queue(factory).then((result) => { assert.equal(result, 1); }),
|
||||
throttler.queue(factory).then((result) => { assert.equal(result, 2); }),
|
||||
throttler.queue(factory).then((result) => { assert.equal(result, 2); }),
|
||||
throttler.queue(factory).then((result) => { assert.equal(result, 2); }),
|
||||
throttler.queue(factory).then((result) => { assert.equal(result, 2); })
|
||||
]).then(() => assert.equal(count, 2));
|
||||
throttler.queue(factory).then((result) => { assert.strictEqual(result, 1); }),
|
||||
throttler.queue(factory).then((result) => { assert.strictEqual(result, 2); }),
|
||||
throttler.queue(factory).then((result) => { assert.strictEqual(result, 2); }),
|
||||
throttler.queue(factory).then((result) => { assert.strictEqual(result, 2); }),
|
||||
throttler.queue(factory).then((result) => { assert.strictEqual(result, 2); })
|
||||
]).then(() => assert.strictEqual(count, 2));
|
||||
});
|
||||
|
||||
test('Throttler', () => {
|
||||
@@ -118,18 +118,18 @@ suite('Async', () => {
|
||||
let throttler = new async.Throttler();
|
||||
|
||||
return Promise.all([
|
||||
throttler.queue(factory).then((result) => { assert.equal(result, 1); }),
|
||||
throttler.queue(factory).then((result) => { assert.equal(result, 2); }),
|
||||
throttler.queue(factory).then((result) => { assert.equal(result, 2); }),
|
||||
throttler.queue(factory).then((result) => { assert.equal(result, 2); }),
|
||||
throttler.queue(factory).then((result) => { assert.equal(result, 2); })
|
||||
throttler.queue(factory).then((result) => { assert.strictEqual(result, 1); }),
|
||||
throttler.queue(factory).then((result) => { assert.strictEqual(result, 2); }),
|
||||
throttler.queue(factory).then((result) => { assert.strictEqual(result, 2); }),
|
||||
throttler.queue(factory).then((result) => { assert.strictEqual(result, 2); }),
|
||||
throttler.queue(factory).then((result) => { assert.strictEqual(result, 2); })
|
||||
]).then(() => {
|
||||
return Promise.all([
|
||||
throttler.queue(factory).then((result) => { assert.equal(result, 3); }),
|
||||
throttler.queue(factory).then((result) => { assert.equal(result, 4); }),
|
||||
throttler.queue(factory).then((result) => { assert.equal(result, 4); }),
|
||||
throttler.queue(factory).then((result) => { assert.equal(result, 4); }),
|
||||
throttler.queue(factory).then((result) => { assert.equal(result, 4); })
|
||||
throttler.queue(factory).then((result) => { assert.strictEqual(result, 3); }),
|
||||
throttler.queue(factory).then((result) => { assert.strictEqual(result, 4); }),
|
||||
throttler.queue(factory).then((result) => { assert.strictEqual(result, 4); }),
|
||||
throttler.queue(factory).then((result) => { assert.strictEqual(result, 4); }),
|
||||
throttler.queue(factory).then((result) => { assert.strictEqual(result, 4); })
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -143,9 +143,9 @@ suite('Async', () => {
|
||||
|
||||
let promises: Promise<any>[] = [];
|
||||
|
||||
promises.push(throttler.queue(factoryFactory(1)).then((n) => { assert.equal(n, 1); }));
|
||||
promises.push(throttler.queue(factoryFactory(2)).then((n) => { assert.equal(n, 3); }));
|
||||
promises.push(throttler.queue(factoryFactory(3)).then((n) => { assert.equal(n, 3); }));
|
||||
promises.push(throttler.queue(factoryFactory(1)).then((n) => { assert.strictEqual(n, 1); }));
|
||||
promises.push(throttler.queue(factoryFactory(2)).then((n) => { assert.strictEqual(n, 3); }));
|
||||
promises.push(throttler.queue(factoryFactory(3)).then((n) => { assert.strictEqual(n, 3); }));
|
||||
|
||||
return Promise.all(promises);
|
||||
});
|
||||
@@ -161,13 +161,13 @@ suite('Async', () => {
|
||||
|
||||
assert(!delayer.isTriggered());
|
||||
|
||||
promises.push(delayer.trigger(factory).then((result) => { assert.equal(result, 1); assert(!delayer.isTriggered()); }));
|
||||
promises.push(delayer.trigger(factory).then((result) => { assert.strictEqual(result, 1); assert(!delayer.isTriggered()); }));
|
||||
assert(delayer.isTriggered());
|
||||
|
||||
promises.push(delayer.trigger(factory).then((result) => { assert.equal(result, 1); assert(!delayer.isTriggered()); }));
|
||||
promises.push(delayer.trigger(factory).then((result) => { assert.strictEqual(result, 1); assert(!delayer.isTriggered()); }));
|
||||
assert(delayer.isTriggered());
|
||||
|
||||
promises.push(delayer.trigger(factory).then((result) => { assert.equal(result, 1); assert(!delayer.isTriggered()); }));
|
||||
promises.push(delayer.trigger(factory).then((result) => { assert.strictEqual(result, 1); assert(!delayer.isTriggered()); }));
|
||||
assert(delayer.isTriggered());
|
||||
|
||||
return Promise.all(promises).then(() => {
|
||||
@@ -237,7 +237,7 @@ suite('Async', () => {
|
||||
assert(!delayer.isTriggered());
|
||||
|
||||
const p = delayer.trigger(factory).then((result) => {
|
||||
assert.equal(result, 1);
|
||||
assert.strictEqual(result, 1);
|
||||
assert(!delayer.isTriggered());
|
||||
|
||||
promises.push(delayer.trigger(factory).then(undefined, () => { assert(true, 'yes, it was cancelled'); }));
|
||||
@@ -253,10 +253,10 @@ suite('Async', () => {
|
||||
|
||||
assert(!delayer.isTriggered());
|
||||
|
||||
promises.push(delayer.trigger(factory).then(() => { assert.equal(result, 1); assert(!delayer.isTriggered()); }));
|
||||
promises.push(delayer.trigger(factory).then(() => { assert.strictEqual(result, 1); assert(!delayer.isTriggered()); }));
|
||||
assert(delayer.isTriggered());
|
||||
|
||||
promises.push(delayer.trigger(factory).then(() => { assert.equal(result, 1); assert(!delayer.isTriggered()); }));
|
||||
promises.push(delayer.trigger(factory).then(() => { assert.strictEqual(result, 1); assert(!delayer.isTriggered()); }));
|
||||
assert(delayer.isTriggered());
|
||||
|
||||
const p = Promise.all(promises).then(() => {
|
||||
@@ -286,9 +286,9 @@ suite('Async', () => {
|
||||
|
||||
assert(!delayer.isTriggered());
|
||||
|
||||
promises.push(delayer.trigger(factoryFactory(1)).then((n) => { assert.equal(n, 3); }));
|
||||
promises.push(delayer.trigger(factoryFactory(2)).then((n) => { assert.equal(n, 3); }));
|
||||
promises.push(delayer.trigger(factoryFactory(3)).then((n) => { assert.equal(n, 3); }));
|
||||
promises.push(delayer.trigger(factoryFactory(1)).then((n) => { assert.strictEqual(n, 3); }));
|
||||
promises.push(delayer.trigger(factoryFactory(2)).then((n) => { assert.strictEqual(n, 3); }));
|
||||
promises.push(delayer.trigger(factoryFactory(3)).then((n) => { assert.strictEqual(n, 3); }));
|
||||
|
||||
const p = Promise.all(promises).then(() => {
|
||||
assert(!delayer.isTriggered());
|
||||
@@ -311,12 +311,12 @@ suite('Async', () => {
|
||||
factoryFactory(4),
|
||||
factoryFactory(5),
|
||||
]).then((result) => {
|
||||
assert.equal(5, result.length);
|
||||
assert.equal(1, result[0]);
|
||||
assert.equal(2, result[1]);
|
||||
assert.equal(3, result[2]);
|
||||
assert.equal(4, result[3]);
|
||||
assert.equal(5, result[4]);
|
||||
assert.strictEqual(5, result.length);
|
||||
assert.strictEqual(1, result[0]);
|
||||
assert.strictEqual(2, result[1]);
|
||||
assert.strictEqual(3, result[2]);
|
||||
assert.strictEqual(4, result[3]);
|
||||
assert.strictEqual(5, result[4]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -331,7 +331,7 @@ suite('Async', () => {
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(n => promises.push(limiter.queue(factoryFactory(n))));
|
||||
|
||||
return Promise.all(promises).then((res) => {
|
||||
assert.equal(10, res.length);
|
||||
assert.strictEqual(10, res.length);
|
||||
|
||||
limiter = new async.Limiter(100);
|
||||
|
||||
@@ -339,7 +339,7 @@ suite('Async', () => {
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(n => promises.push(limiter.queue(factoryFactory(n))));
|
||||
|
||||
return Promise.all(promises).then((res) => {
|
||||
assert.equal(10, res.length);
|
||||
assert.strictEqual(10, res.length);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -352,7 +352,7 @@ suite('Async', () => {
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(n => promises.push(limiter.queue(factoryFactory(n))));
|
||||
|
||||
return Promise.all(promises).then((res) => {
|
||||
assert.equal(10, res.length);
|
||||
assert.strictEqual(10, res.length);
|
||||
|
||||
limiter = new async.Limiter(100);
|
||||
|
||||
@@ -360,7 +360,7 @@ suite('Async', () => {
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(n => promises.push(limiter.queue(factoryFactory(n))));
|
||||
|
||||
return Promise.all(promises).then((res) => {
|
||||
assert.equal(10, res.length);
|
||||
assert.strictEqual(10, res.length);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -379,8 +379,8 @@ suite('Async', () => {
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(n => promises.push(limiter.queue(factoryFactory(n))));
|
||||
|
||||
return Promise.all(promises).then((res) => {
|
||||
assert.equal(10, res.length);
|
||||
assert.deepEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], res);
|
||||
assert.strictEqual(10, res.length);
|
||||
assert.deepStrictEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], res);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -393,15 +393,15 @@ suite('Async', () => {
|
||||
let asyncPromise = false;
|
||||
let f2 = () => async.timeout(10).then(() => asyncPromise = true);
|
||||
|
||||
assert.equal(queue.size, 0);
|
||||
assert.strictEqual(queue.size, 0);
|
||||
|
||||
queue.queue(f1);
|
||||
assert.equal(queue.size, 1);
|
||||
assert.strictEqual(queue.size, 1);
|
||||
|
||||
const p = queue.queue(f2);
|
||||
assert.equal(queue.size, 2);
|
||||
assert.strictEqual(queue.size, 2);
|
||||
return p.then(() => {
|
||||
assert.equal(queue.size, 0);
|
||||
assert.strictEqual(queue.size, 0);
|
||||
assert.ok(syncPromise);
|
||||
assert.ok(asyncPromise);
|
||||
});
|
||||
@@ -423,11 +423,11 @@ suite('Async', () => {
|
||||
queue.queue(f3);
|
||||
queue.queue(f4);
|
||||
return queue.queue(f5).then(() => {
|
||||
assert.equal(res[0], 1);
|
||||
assert.equal(res[1], 2);
|
||||
assert.equal(res[2], 3);
|
||||
assert.equal(res[3], 4);
|
||||
assert.equal(res[4], 5);
|
||||
assert.strictEqual(res[0], 1);
|
||||
assert.strictEqual(res[1], 2);
|
||||
assert.strictEqual(res[2], 3);
|
||||
assert.strictEqual(res[3], 4);
|
||||
assert.strictEqual(res[4], 5);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -448,11 +448,11 @@ suite('Async', () => {
|
||||
queue.queue(f3).then(undefined, () => error = true);
|
||||
queue.queue(f4);
|
||||
return queue.queue(f5).then(() => {
|
||||
assert.equal(res[0], 1);
|
||||
assert.equal(res[1], 2);
|
||||
assert.strictEqual(res[0], 1);
|
||||
assert.strictEqual(res[1], 2);
|
||||
assert.ok(error);
|
||||
assert.equal(res[2], 4);
|
||||
assert.equal(res[3], 5);
|
||||
assert.strictEqual(res[2], 4);
|
||||
assert.strictEqual(res[3], 5);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -472,11 +472,11 @@ suite('Async', () => {
|
||||
return queue.queue(f3).then(() => {
|
||||
return queue.queue(f4).then(() => {
|
||||
return queue.queue(f5).then(() => {
|
||||
assert.equal(res[0], 1);
|
||||
assert.equal(res[1], 2);
|
||||
assert.equal(res[2], 3);
|
||||
assert.equal(res[3], 4);
|
||||
assert.equal(res[4], 5);
|
||||
assert.strictEqual(res[0], 1);
|
||||
assert.strictEqual(res[1], 2);
|
||||
assert.strictEqual(res[2], 3);
|
||||
assert.strictEqual(res[3], 4);
|
||||
assert.strictEqual(res[4], 5);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -521,7 +521,7 @@ suite('Async', () => {
|
||||
|
||||
assert.ok(r1Queue);
|
||||
assert.ok(r2Queue);
|
||||
assert.equal(r1Queue, queue.queueFor(URI.file('/some/path'))); // same queue returned
|
||||
assert.strictEqual(r1Queue, queue.queueFor(URI.file('/some/path'))); // same queue returned
|
||||
|
||||
let syncPromiseFactory = () => Promise.resolve(undefined);
|
||||
|
||||
@@ -545,7 +545,7 @@ suite('Async', () => {
|
||||
return Promise.resolve(true);
|
||||
}, 10, 3);
|
||||
|
||||
assert.equal(res, true);
|
||||
assert.strictEqual(res, true);
|
||||
});
|
||||
|
||||
test('retry - error case', async () => {
|
||||
@@ -555,7 +555,7 @@ suite('Async', () => {
|
||||
return Promise.reject(expectedError);
|
||||
}, 10, 3);
|
||||
} catch (error) {
|
||||
assert.equal(error, error);
|
||||
assert.strictEqual(error, error);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -673,7 +673,7 @@ suite('Async', () => {
|
||||
await p1;
|
||||
|
||||
assert.ok(!triggered);
|
||||
assert.equal(timedout, true);
|
||||
assert.strictEqual(timedout, true);
|
||||
|
||||
// promise wins
|
||||
timedout = false;
|
||||
@@ -684,32 +684,32 @@ suite('Async', () => {
|
||||
await p2;
|
||||
|
||||
assert.ok(triggered);
|
||||
assert.equal(timedout, false);
|
||||
assert.strictEqual(timedout, false);
|
||||
});
|
||||
|
||||
test('SequencerByKey', async () => {
|
||||
const s = new async.SequencerByKey<string>();
|
||||
|
||||
const r1 = await s.queue('key1', () => Promise.resolve('hello'));
|
||||
assert.equal(r1, 'hello');
|
||||
assert.strictEqual(r1, 'hello');
|
||||
|
||||
await s.queue('key2', () => Promise.reject(new Error('failed'))).then(() => {
|
||||
throw new Error('should not be resolved');
|
||||
}, err => {
|
||||
// Expected error
|
||||
assert.equal(err.message, 'failed');
|
||||
assert.strictEqual(err.message, 'failed');
|
||||
});
|
||||
|
||||
// Still works after a queued promise is rejected
|
||||
const r3 = await s.queue('key2', () => Promise.resolve('hello'));
|
||||
assert.equal(r3, 'hello');
|
||||
assert.strictEqual(r3, 'hello');
|
||||
});
|
||||
|
||||
test('IntervalCounter', async () => {
|
||||
const counter = new async.IntervalCounter(10);
|
||||
assert.equal(counter.increment(), 1);
|
||||
assert.equal(counter.increment(), 2);
|
||||
assert.equal(counter.increment(), 3);
|
||||
assert.strictEqual(counter.increment(), 1);
|
||||
assert.strictEqual(counter.increment(), 2);
|
||||
assert.strictEqual(counter.increment(), 3);
|
||||
|
||||
const now = Date.now();
|
||||
await async.timeout(20);
|
||||
@@ -717,9 +717,9 @@ suite('Async', () => {
|
||||
return; // Firefox in Playwright seems to have a flaky timeout implementation (https://github.com/microsoft/vscode/issues/114028)
|
||||
}
|
||||
|
||||
assert.equal(counter.increment(), 1);
|
||||
assert.equal(counter.increment(), 2);
|
||||
assert.equal(counter.increment(), 3);
|
||||
assert.strictEqual(counter.increment(), 1);
|
||||
assert.strictEqual(counter.increment(), 2);
|
||||
assert.strictEqual(counter.increment(), 3);
|
||||
});
|
||||
|
||||
test('firstParallel - simple', async () => {
|
||||
@@ -728,19 +728,19 @@ suite('Async', () => {
|
||||
Promise.resolve(2),
|
||||
Promise.resolve(3),
|
||||
], v => v === 2);
|
||||
assert.equal(a, 2);
|
||||
assert.strictEqual(a, 2);
|
||||
});
|
||||
|
||||
test('firstParallel - uses null default', async () => {
|
||||
assert.equal(await async.firstParallel([Promise.resolve(1)], v => v === 2), null);
|
||||
assert.strictEqual(await async.firstParallel([Promise.resolve(1)], v => v === 2), null);
|
||||
});
|
||||
|
||||
test('firstParallel - uses value default', async () => {
|
||||
assert.equal(await async.firstParallel([Promise.resolve(1)], v => v === 2, 4), 4);
|
||||
assert.strictEqual(await async.firstParallel([Promise.resolve(1)], v => v === 2, 4), 4);
|
||||
});
|
||||
|
||||
test('firstParallel - empty', async () => {
|
||||
assert.equal(await async.firstParallel([], v => v === 2, 4), 4);
|
||||
assert.strictEqual(await async.firstParallel([], v => v === 2, 4), 4);
|
||||
});
|
||||
|
||||
test('firstParallel - cancels', async () => {
|
||||
@@ -757,9 +757,9 @@ suite('Async', () => {
|
||||
return 2;
|
||||
});
|
||||
|
||||
assert.equal(await async.firstParallel([p1, p2], v => v === 2, 4), 2);
|
||||
assert.equal(ct1!.isCancellationRequested, true, 'should cancel a');
|
||||
assert.equal(ct2!.isCancellationRequested, true, 'should cancel b');
|
||||
assert.strictEqual(await async.firstParallel([p1, p2], v => v === 2, 4), 2);
|
||||
assert.strictEqual(ct1!.isCancellationRequested, true, 'should cancel a');
|
||||
assert.strictEqual(ct2!.isCancellationRequested, true, 'should cancel b');
|
||||
});
|
||||
|
||||
test('firstParallel - rejection handling', async () => {
|
||||
@@ -776,9 +776,9 @@ suite('Async', () => {
|
||||
throw new Error('oh no');
|
||||
});
|
||||
|
||||
assert.equal(await async.firstParallel([p1, p2], v => v === 2, 4).catch(() => 'ok'), 'ok');
|
||||
assert.equal(ct1!.isCancellationRequested, true, 'should cancel a');
|
||||
assert.equal(ct2!.isCancellationRequested, true, 'should cancel b');
|
||||
assert.strictEqual(await async.firstParallel([p1, p2], v => v === 2, 4).catch(() => 'ok'), 'ok');
|
||||
assert.strictEqual(ct1!.isCancellationRequested, true, 'should cancel a');
|
||||
assert.strictEqual(ct2!.isCancellationRequested, true, 'should cancel b');
|
||||
});
|
||||
|
||||
suite('DeferredPromise', () => {
|
||||
|
||||
@@ -8,17 +8,17 @@ import { CancellationTokenSource, CancellationToken } from 'vs/base/common/cance
|
||||
suite('CancellationToken', function () {
|
||||
|
||||
test('None', () => {
|
||||
assert.equal(CancellationToken.None.isCancellationRequested, false);
|
||||
assert.equal(typeof CancellationToken.None.onCancellationRequested, 'function');
|
||||
assert.strictEqual(CancellationToken.None.isCancellationRequested, false);
|
||||
assert.strictEqual(typeof CancellationToken.None.onCancellationRequested, 'function');
|
||||
});
|
||||
|
||||
test('cancel before token', function (done) {
|
||||
|
||||
const source = new CancellationTokenSource();
|
||||
assert.equal(source.token.isCancellationRequested, false);
|
||||
assert.strictEqual(source.token.isCancellationRequested, false);
|
||||
source.cancel();
|
||||
|
||||
assert.equal(source.token.isCancellationRequested, true);
|
||||
assert.strictEqual(source.token.isCancellationRequested, true);
|
||||
|
||||
source.token.onCancellationRequested(function () {
|
||||
assert.ok(true);
|
||||
@@ -29,7 +29,7 @@ suite('CancellationToken', function () {
|
||||
test('cancel happens only once', function () {
|
||||
|
||||
let source = new CancellationTokenSource();
|
||||
assert.equal(source.token.isCancellationRequested, false);
|
||||
assert.strictEqual(source.token.isCancellationRequested, false);
|
||||
|
||||
let cancelCount = 0;
|
||||
function onCancel() {
|
||||
@@ -41,7 +41,7 @@ suite('CancellationToken', function () {
|
||||
source.cancel();
|
||||
source.cancel();
|
||||
|
||||
assert.equal(cancelCount, 1);
|
||||
assert.strictEqual(cancelCount, 1);
|
||||
});
|
||||
|
||||
test('cancel calls all listeners', function () {
|
||||
@@ -60,7 +60,7 @@ suite('CancellationToken', function () {
|
||||
});
|
||||
|
||||
source.cancel();
|
||||
assert.equal(count, 3);
|
||||
assert.strictEqual(count, 3);
|
||||
});
|
||||
|
||||
test('token stays the same', function () {
|
||||
@@ -92,7 +92,7 @@ suite('CancellationToken', function () {
|
||||
|
||||
source.dispose();
|
||||
source.cancel();
|
||||
assert.equal(count, 0);
|
||||
assert.strictEqual(count, 0);
|
||||
});
|
||||
|
||||
test('dispose calls no listeners (unless told to cancel)', function () {
|
||||
@@ -106,7 +106,7 @@ suite('CancellationToken', function () {
|
||||
|
||||
source.dispose(true);
|
||||
// source.cancel();
|
||||
assert.equal(count, 1);
|
||||
assert.strictEqual(count, 1);
|
||||
});
|
||||
|
||||
test('parent cancels child', function () {
|
||||
@@ -119,8 +119,8 @@ suite('CancellationToken', function () {
|
||||
|
||||
parent.cancel();
|
||||
|
||||
assert.equal(count, 1);
|
||||
assert.equal(child.token.isCancellationRequested, true);
|
||||
assert.equal(parent.token.isCancellationRequested, true);
|
||||
assert.strictEqual(count, 1);
|
||||
assert.strictEqual(child.token.isCancellationRequested, true);
|
||||
assert.strictEqual(parent.token.isCancellationRequested, true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -9,7 +9,7 @@ function filterOk(filter: IFilter, word: string, wordToMatchAgainst: string, hig
|
||||
let r = filter(word, wordToMatchAgainst);
|
||||
assert(r, `${word} didn't match ${wordToMatchAgainst}`);
|
||||
if (highlights) {
|
||||
assert.deepEqual(r, highlights);
|
||||
assert.deepStrictEqual(r, highlights);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ suite('Filters', () => {
|
||||
pos = match.end;
|
||||
}
|
||||
actualWord += word.substring(pos);
|
||||
assert.equal(actualWord, decoratedWord);
|
||||
assert.strictEqual(actualWord, decoratedWord);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,7 +442,7 @@ suite('Filters', () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
assert.equal(topIdx, expected, `${pattern} -> actual=${words[topIdx]} <> expected=${words[expected]}`);
|
||||
assert.strictEqual(topIdx, expected, `${pattern} -> actual=${words[topIdx]} <> expected=${words[expected]}`);
|
||||
}
|
||||
|
||||
test('topScore - fuzzyScore', function () {
|
||||
|
||||
@@ -11,19 +11,19 @@ suite('LinkedList', function () {
|
||||
function assertElements<E>(list: LinkedList<E>, ...elements: E[]) {
|
||||
|
||||
// check size
|
||||
assert.equal(list.size, elements.length);
|
||||
assert.strictEqual(list.size, elements.length);
|
||||
|
||||
// assert toArray
|
||||
assert.deepEqual(Array.from(list), elements);
|
||||
assert.deepStrictEqual(Array.from(list), elements);
|
||||
|
||||
// assert Symbol.iterator (1)
|
||||
assert.deepEqual([...list], elements);
|
||||
assert.deepStrictEqual([...list], elements);
|
||||
|
||||
// assert Symbol.iterator (2)
|
||||
for (const item of list) {
|
||||
assert.equal(item, elements.shift());
|
||||
assert.strictEqual(item, elements.shift());
|
||||
}
|
||||
assert.equal(elements.length, 0);
|
||||
assert.strictEqual(elements.length, 0);
|
||||
}
|
||||
|
||||
test('Push/Iter', () => {
|
||||
@@ -123,14 +123,14 @@ suite('LinkedList', function () {
|
||||
assertElements(list, 'a', 'b');
|
||||
|
||||
let a = list.shift();
|
||||
assert.equal(a, 'a');
|
||||
assert.strictEqual(a, 'a');
|
||||
assertElements(list, 'b');
|
||||
|
||||
list.unshift('a');
|
||||
assertElements(list, 'a', 'b');
|
||||
|
||||
let b = list.pop();
|
||||
assert.equal(b, 'b');
|
||||
assert.strictEqual(b, 'b');
|
||||
assertElements(list, 'a');
|
||||
|
||||
});
|
||||
|
||||
+244
-244
@@ -16,8 +16,8 @@ suite('Map', () => {
|
||||
map.set('bk', 'bv');
|
||||
assert.deepStrictEqual([...map.keys()], ['ak', 'bk']);
|
||||
assert.deepStrictEqual([...map.values()], ['av', 'bv']);
|
||||
assert.equal(map.first, 'av');
|
||||
assert.equal(map.last, 'bv');
|
||||
assert.strictEqual(map.first, 'av');
|
||||
assert.strictEqual(map.last, 'bv');
|
||||
});
|
||||
|
||||
test('LinkedMap - Touch Old one', () => {
|
||||
@@ -77,7 +77,7 @@ suite('Map', () => {
|
||||
test('LinkedMap - basics', function () {
|
||||
const map = new LinkedMap<string, any>();
|
||||
|
||||
assert.equal(map.size, 0);
|
||||
assert.strictEqual(map.size, 0);
|
||||
|
||||
map.set('1', 1);
|
||||
map.set('2', '2');
|
||||
@@ -89,23 +89,23 @@ suite('Map', () => {
|
||||
const date = Date.now();
|
||||
map.set('5', date);
|
||||
|
||||
assert.equal(map.size, 5);
|
||||
assert.equal(map.get('1'), 1);
|
||||
assert.equal(map.get('2'), '2');
|
||||
assert.equal(map.get('3'), true);
|
||||
assert.equal(map.get('4'), obj);
|
||||
assert.equal(map.get('5'), date);
|
||||
assert.strictEqual(map.size, 5);
|
||||
assert.strictEqual(map.get('1'), 1);
|
||||
assert.strictEqual(map.get('2'), '2');
|
||||
assert.strictEqual(map.get('3'), true);
|
||||
assert.strictEqual(map.get('4'), obj);
|
||||
assert.strictEqual(map.get('5'), date);
|
||||
assert.ok(!map.get('6'));
|
||||
|
||||
map.delete('6');
|
||||
assert.equal(map.size, 5);
|
||||
assert.equal(map.delete('1'), true);
|
||||
assert.equal(map.delete('2'), true);
|
||||
assert.equal(map.delete('3'), true);
|
||||
assert.equal(map.delete('4'), true);
|
||||
assert.equal(map.delete('5'), true);
|
||||
assert.strictEqual(map.size, 5);
|
||||
assert.strictEqual(map.delete('1'), true);
|
||||
assert.strictEqual(map.delete('2'), true);
|
||||
assert.strictEqual(map.delete('3'), true);
|
||||
assert.strictEqual(map.delete('4'), true);
|
||||
assert.strictEqual(map.delete('5'), true);
|
||||
|
||||
assert.equal(map.size, 0);
|
||||
assert.strictEqual(map.size, 0);
|
||||
assert.ok(!map.get('5'));
|
||||
assert.ok(!map.get('4'));
|
||||
assert.ok(!map.get('3'));
|
||||
@@ -117,13 +117,13 @@ suite('Map', () => {
|
||||
map.set('3', true);
|
||||
|
||||
assert.ok(map.has('1'));
|
||||
assert.equal(map.get('1'), 1);
|
||||
assert.equal(map.get('2'), '2');
|
||||
assert.equal(map.get('3'), true);
|
||||
assert.strictEqual(map.get('1'), 1);
|
||||
assert.strictEqual(map.get('2'), '2');
|
||||
assert.strictEqual(map.get('3'), true);
|
||||
|
||||
map.clear();
|
||||
|
||||
assert.equal(map.size, 0);
|
||||
assert.strictEqual(map.size, 0);
|
||||
assert.ok(!map.get('1'));
|
||||
assert.ok(!map.get('2'));
|
||||
assert.ok(!map.get('3'));
|
||||
@@ -231,7 +231,7 @@ suite('Map', () => {
|
||||
for (let i = 11; i <= 20; i++) {
|
||||
cache.set(i, i);
|
||||
}
|
||||
assert.deepEqual(cache.size, 15);
|
||||
assert.deepStrictEqual(cache.size, 15);
|
||||
let values: number[] = [];
|
||||
for (let i = 6; i <= 20; i++) {
|
||||
values.push(cache.get(i)!);
|
||||
@@ -269,14 +269,14 @@ suite('Map', () => {
|
||||
let i = 0;
|
||||
map.forEach((value, key) => {
|
||||
if (i === 0) {
|
||||
assert.equal(key, 'ak');
|
||||
assert.equal(value, 'av');
|
||||
assert.strictEqual(key, 'ak');
|
||||
assert.strictEqual(value, 'av');
|
||||
} else if (i === 1) {
|
||||
assert.equal(key, 'bk');
|
||||
assert.equal(value, 'bv');
|
||||
assert.strictEqual(key, 'bk');
|
||||
assert.strictEqual(value, 'bv');
|
||||
} else if (i === 2) {
|
||||
assert.equal(key, 'ck');
|
||||
assert.equal(value, 'cv');
|
||||
assert.strictEqual(key, 'ck');
|
||||
assert.strictEqual(value, 'cv');
|
||||
}
|
||||
i++;
|
||||
});
|
||||
@@ -285,44 +285,44 @@ suite('Map', () => {
|
||||
test('LinkedMap - delete Head and Tail', function () {
|
||||
const map = new LinkedMap<string, number>();
|
||||
|
||||
assert.equal(map.size, 0);
|
||||
assert.strictEqual(map.size, 0);
|
||||
|
||||
map.set('1', 1);
|
||||
assert.equal(map.size, 1);
|
||||
assert.strictEqual(map.size, 1);
|
||||
map.delete('1');
|
||||
assert.equal(map.get('1'), undefined);
|
||||
assert.equal(map.size, 0);
|
||||
assert.equal([...map.keys()].length, 0);
|
||||
assert.strictEqual(map.get('1'), undefined);
|
||||
assert.strictEqual(map.size, 0);
|
||||
assert.strictEqual([...map.keys()].length, 0);
|
||||
});
|
||||
|
||||
test('LinkedMap - delete Head', function () {
|
||||
const map = new LinkedMap<string, number>();
|
||||
|
||||
assert.equal(map.size, 0);
|
||||
assert.strictEqual(map.size, 0);
|
||||
|
||||
map.set('1', 1);
|
||||
map.set('2', 2);
|
||||
assert.equal(map.size, 2);
|
||||
assert.strictEqual(map.size, 2);
|
||||
map.delete('1');
|
||||
assert.equal(map.get('2'), 2);
|
||||
assert.equal(map.size, 1);
|
||||
assert.equal([...map.keys()].length, 1);
|
||||
assert.equal([...map.keys()][0], 2);
|
||||
assert.strictEqual(map.get('2'), 2);
|
||||
assert.strictEqual(map.size, 1);
|
||||
assert.strictEqual([...map.keys()].length, 1);
|
||||
assert.strictEqual([...map.keys()][0], '2');
|
||||
});
|
||||
|
||||
test('LinkedMap - delete Tail', function () {
|
||||
const map = new LinkedMap<string, number>();
|
||||
|
||||
assert.equal(map.size, 0);
|
||||
assert.strictEqual(map.size, 0);
|
||||
|
||||
map.set('1', 1);
|
||||
map.set('2', 2);
|
||||
assert.equal(map.size, 2);
|
||||
assert.strictEqual(map.size, 2);
|
||||
map.delete('2');
|
||||
assert.equal(map.get('1'), 1);
|
||||
assert.equal(map.size, 1);
|
||||
assert.equal([...map.keys()].length, 1);
|
||||
assert.equal([...map.keys()][0], 1);
|
||||
assert.strictEqual(map.get('1'), 1);
|
||||
assert.strictEqual(map.size, 1);
|
||||
assert.strictEqual([...map.keys()].length, 1);
|
||||
assert.strictEqual([...map.keys()][0], '1');
|
||||
});
|
||||
|
||||
|
||||
@@ -330,100 +330,100 @@ suite('Map', () => {
|
||||
const iter = new PathIterator();
|
||||
iter.reset('file:///usr/bin/file.txt');
|
||||
|
||||
assert.equal(iter.value(), 'file:');
|
||||
assert.equal(iter.hasNext(), true);
|
||||
assert.equal(iter.cmp('file:'), 0);
|
||||
assert.strictEqual(iter.value(), 'file:');
|
||||
assert.strictEqual(iter.hasNext(), true);
|
||||
assert.strictEqual(iter.cmp('file:'), 0);
|
||||
assert.ok(iter.cmp('a') < 0);
|
||||
assert.ok(iter.cmp('aile:') < 0);
|
||||
assert.ok(iter.cmp('z') > 0);
|
||||
assert.ok(iter.cmp('zile:') > 0);
|
||||
|
||||
iter.next();
|
||||
assert.equal(iter.value(), 'usr');
|
||||
assert.equal(iter.hasNext(), true);
|
||||
assert.strictEqual(iter.value(), 'usr');
|
||||
assert.strictEqual(iter.hasNext(), true);
|
||||
|
||||
iter.next();
|
||||
assert.equal(iter.value(), 'bin');
|
||||
assert.equal(iter.hasNext(), true);
|
||||
assert.strictEqual(iter.value(), 'bin');
|
||||
assert.strictEqual(iter.hasNext(), true);
|
||||
|
||||
iter.next();
|
||||
assert.equal(iter.value(), 'file.txt');
|
||||
assert.equal(iter.hasNext(), false);
|
||||
assert.strictEqual(iter.value(), 'file.txt');
|
||||
assert.strictEqual(iter.hasNext(), false);
|
||||
|
||||
iter.next();
|
||||
assert.equal(iter.value(), '');
|
||||
assert.equal(iter.hasNext(), false);
|
||||
assert.strictEqual(iter.value(), '');
|
||||
assert.strictEqual(iter.hasNext(), false);
|
||||
iter.next();
|
||||
assert.equal(iter.value(), '');
|
||||
assert.equal(iter.hasNext(), false);
|
||||
assert.strictEqual(iter.value(), '');
|
||||
assert.strictEqual(iter.hasNext(), false);
|
||||
|
||||
//
|
||||
iter.reset('/foo/bar/');
|
||||
assert.equal(iter.value(), 'foo');
|
||||
assert.equal(iter.hasNext(), true);
|
||||
assert.strictEqual(iter.value(), 'foo');
|
||||
assert.strictEqual(iter.hasNext(), true);
|
||||
|
||||
iter.next();
|
||||
assert.equal(iter.value(), 'bar');
|
||||
assert.equal(iter.hasNext(), false);
|
||||
assert.strictEqual(iter.value(), 'bar');
|
||||
assert.strictEqual(iter.hasNext(), false);
|
||||
});
|
||||
|
||||
test('URIIterator', function () {
|
||||
const iter = new UriIterator(() => false);
|
||||
iter.reset(URI.parse('file:///usr/bin/file.txt'));
|
||||
|
||||
assert.equal(iter.value(), 'file');
|
||||
// assert.equal(iter.cmp('FILE'), 0);
|
||||
assert.equal(iter.cmp('file'), 0);
|
||||
assert.equal(iter.hasNext(), true);
|
||||
assert.strictEqual(iter.value(), 'file');
|
||||
// assert.strictEqual(iter.cmp('FILE'), 0);
|
||||
assert.strictEqual(iter.cmp('file'), 0);
|
||||
assert.strictEqual(iter.hasNext(), true);
|
||||
iter.next();
|
||||
|
||||
assert.equal(iter.value(), 'usr');
|
||||
assert.equal(iter.hasNext(), true);
|
||||
assert.strictEqual(iter.value(), 'usr');
|
||||
assert.strictEqual(iter.hasNext(), true);
|
||||
iter.next();
|
||||
|
||||
assert.equal(iter.value(), 'bin');
|
||||
assert.equal(iter.hasNext(), true);
|
||||
assert.strictEqual(iter.value(), 'bin');
|
||||
assert.strictEqual(iter.hasNext(), true);
|
||||
iter.next();
|
||||
|
||||
assert.equal(iter.value(), 'file.txt');
|
||||
assert.equal(iter.hasNext(), false);
|
||||
assert.strictEqual(iter.value(), 'file.txt');
|
||||
assert.strictEqual(iter.hasNext(), false);
|
||||
|
||||
|
||||
iter.reset(URI.parse('file://share/usr/bin/file.txt?foo'));
|
||||
|
||||
// scheme
|
||||
assert.equal(iter.value(), 'file');
|
||||
// assert.equal(iter.cmp('FILE'), 0);
|
||||
assert.equal(iter.cmp('file'), 0);
|
||||
assert.equal(iter.hasNext(), true);
|
||||
assert.strictEqual(iter.value(), 'file');
|
||||
// assert.strictEqual(iter.cmp('FILE'), 0);
|
||||
assert.strictEqual(iter.cmp('file'), 0);
|
||||
assert.strictEqual(iter.hasNext(), true);
|
||||
iter.next();
|
||||
|
||||
// authority
|
||||
assert.equal(iter.value(), 'share');
|
||||
assert.equal(iter.cmp('SHARe'), 0);
|
||||
assert.equal(iter.hasNext(), true);
|
||||
assert.strictEqual(iter.value(), 'share');
|
||||
assert.strictEqual(iter.cmp('SHARe'), 0);
|
||||
assert.strictEqual(iter.hasNext(), true);
|
||||
iter.next();
|
||||
|
||||
// path
|
||||
assert.equal(iter.value(), 'usr');
|
||||
assert.equal(iter.hasNext(), true);
|
||||
assert.strictEqual(iter.value(), 'usr');
|
||||
assert.strictEqual(iter.hasNext(), true);
|
||||
iter.next();
|
||||
|
||||
// path
|
||||
assert.equal(iter.value(), 'bin');
|
||||
assert.equal(iter.hasNext(), true);
|
||||
assert.strictEqual(iter.value(), 'bin');
|
||||
assert.strictEqual(iter.hasNext(), true);
|
||||
iter.next();
|
||||
|
||||
// path
|
||||
assert.equal(iter.value(), 'file.txt');
|
||||
assert.equal(iter.hasNext(), true);
|
||||
assert.strictEqual(iter.value(), 'file.txt');
|
||||
assert.strictEqual(iter.hasNext(), true);
|
||||
iter.next();
|
||||
|
||||
// query
|
||||
assert.equal(iter.value(), 'foo');
|
||||
assert.equal(iter.cmp('z') > 0, true);
|
||||
assert.equal(iter.cmp('a') < 0, true);
|
||||
assert.equal(iter.hasNext(), false);
|
||||
assert.strictEqual(iter.value(), 'foo');
|
||||
assert.strictEqual(iter.cmp('z') > 0, true);
|
||||
assert.strictEqual(iter.cmp('a') < 0, true);
|
||||
assert.strictEqual(iter.hasNext(), false);
|
||||
});
|
||||
|
||||
function assertTernarySearchTree<E>(trie: TernarySearchTree<string, E>, ...elements: [string, E][]) {
|
||||
@@ -432,24 +432,24 @@ suite('Map', () => {
|
||||
map.set(key, value);
|
||||
}
|
||||
map.forEach((value, key) => {
|
||||
assert.equal(trie.get(key), value);
|
||||
assert.strictEqual(trie.get(key), value);
|
||||
});
|
||||
|
||||
// forEach
|
||||
let forEachCount = 0;
|
||||
trie.forEach((element, key) => {
|
||||
assert.equal(element, map.get(key));
|
||||
assert.strictEqual(element, map.get(key));
|
||||
forEachCount++;
|
||||
});
|
||||
assert.equal(map.size, forEachCount);
|
||||
assert.strictEqual(map.size, forEachCount);
|
||||
|
||||
// iterator
|
||||
let iterCount = 0;
|
||||
for (let [key, value] of trie) {
|
||||
assert.equal(value, map.get(key));
|
||||
assert.strictEqual(value, map.get(key));
|
||||
iterCount++;
|
||||
}
|
||||
assert.equal(map.size, iterCount);
|
||||
assert.strictEqual(map.size, iterCount);
|
||||
}
|
||||
|
||||
test('TernarySearchTree - set', function () {
|
||||
@@ -493,13 +493,13 @@ suite('Map', () => {
|
||||
trie.set('foobar', 2);
|
||||
trie.set('foobaz', 3);
|
||||
|
||||
assert.equal(trie.findSubstr('f'), undefined);
|
||||
assert.equal(trie.findSubstr('z'), undefined);
|
||||
assert.equal(trie.findSubstr('foo'), 1);
|
||||
assert.equal(trie.findSubstr('fooö'), 1);
|
||||
assert.equal(trie.findSubstr('fooba'), 1);
|
||||
assert.equal(trie.findSubstr('foobarr'), 2);
|
||||
assert.equal(trie.findSubstr('foobazrr'), 3);
|
||||
assert.strictEqual(trie.findSubstr('f'), undefined);
|
||||
assert.strictEqual(trie.findSubstr('z'), undefined);
|
||||
assert.strictEqual(trie.findSubstr('foo'), 1);
|
||||
assert.strictEqual(trie.findSubstr('fooö'), 1);
|
||||
assert.strictEqual(trie.findSubstr('fooba'), 1);
|
||||
assert.strictEqual(trie.findSubstr('foobarr'), 2);
|
||||
assert.strictEqual(trie.findSubstr('foobazrr'), 3);
|
||||
});
|
||||
|
||||
test('TernarySearchTree - basics', function () {
|
||||
@@ -509,27 +509,27 @@ suite('Map', () => {
|
||||
trie.set('bar', 2);
|
||||
trie.set('foobar', 3);
|
||||
|
||||
assert.equal(trie.get('foo'), 1);
|
||||
assert.equal(trie.get('bar'), 2);
|
||||
assert.equal(trie.get('foobar'), 3);
|
||||
assert.equal(trie.get('foobaz'), undefined);
|
||||
assert.equal(trie.get('foobarr'), undefined);
|
||||
assert.strictEqual(trie.get('foo'), 1);
|
||||
assert.strictEqual(trie.get('bar'), 2);
|
||||
assert.strictEqual(trie.get('foobar'), 3);
|
||||
assert.strictEqual(trie.get('foobaz'), undefined);
|
||||
assert.strictEqual(trie.get('foobarr'), undefined);
|
||||
|
||||
assert.equal(trie.findSubstr('fo'), undefined);
|
||||
assert.equal(trie.findSubstr('foo'), 1);
|
||||
assert.equal(trie.findSubstr('foooo'), 1);
|
||||
assert.strictEqual(trie.findSubstr('fo'), undefined);
|
||||
assert.strictEqual(trie.findSubstr('foo'), 1);
|
||||
assert.strictEqual(trie.findSubstr('foooo'), 1);
|
||||
|
||||
|
||||
trie.delete('foobar');
|
||||
trie.delete('bar');
|
||||
assert.equal(trie.get('foobar'), undefined);
|
||||
assert.equal(trie.get('bar'), undefined);
|
||||
assert.strictEqual(trie.get('foobar'), undefined);
|
||||
assert.strictEqual(trie.get('bar'), undefined);
|
||||
|
||||
trie.set('foobar', 17);
|
||||
trie.set('barr', 18);
|
||||
assert.equal(trie.get('foobar'), 17);
|
||||
assert.equal(trie.get('barr'), 18);
|
||||
assert.equal(trie.get('bar'), undefined);
|
||||
assert.strictEqual(trie.get('foobar'), 17);
|
||||
assert.strictEqual(trie.get('barr'), 18);
|
||||
assert.strictEqual(trie.get('bar'), undefined);
|
||||
});
|
||||
|
||||
test('TernarySearchTree - delete & cleanup', function () {
|
||||
@@ -576,20 +576,20 @@ suite('Map', () => {
|
||||
trie.set('/user/foo', 2);
|
||||
trie.set('/user/foo/flip/flop', 3);
|
||||
|
||||
assert.equal(trie.get('/user/foo/bar'), 1);
|
||||
assert.equal(trie.get('/user/foo'), 2);
|
||||
assert.equal(trie.get('/user//foo'), 2);
|
||||
assert.equal(trie.get('/user\\foo'), 2);
|
||||
assert.equal(trie.get('/user/foo/flip/flop'), 3);
|
||||
assert.strictEqual(trie.get('/user/foo/bar'), 1);
|
||||
assert.strictEqual(trie.get('/user/foo'), 2);
|
||||
assert.strictEqual(trie.get('/user//foo'), 2);
|
||||
assert.strictEqual(trie.get('/user\\foo'), 2);
|
||||
assert.strictEqual(trie.get('/user/foo/flip/flop'), 3);
|
||||
|
||||
assert.equal(trie.findSubstr('/user/bar'), undefined);
|
||||
assert.equal(trie.findSubstr('/user/foo'), 2);
|
||||
assert.equal(trie.findSubstr('\\user\\foo'), 2);
|
||||
assert.equal(trie.findSubstr('/user//foo'), 2);
|
||||
assert.equal(trie.findSubstr('/user/foo/ba'), 2);
|
||||
assert.equal(trie.findSubstr('/user/foo/far/boo'), 2);
|
||||
assert.equal(trie.findSubstr('/user/foo/bar'), 1);
|
||||
assert.equal(trie.findSubstr('/user/foo/bar/far/boo'), 1);
|
||||
assert.strictEqual(trie.findSubstr('/user/bar'), undefined);
|
||||
assert.strictEqual(trie.findSubstr('/user/foo'), 2);
|
||||
assert.strictEqual(trie.findSubstr('\\user\\foo'), 2);
|
||||
assert.strictEqual(trie.findSubstr('/user//foo'), 2);
|
||||
assert.strictEqual(trie.findSubstr('/user/foo/ba'), 2);
|
||||
assert.strictEqual(trie.findSubstr('/user/foo/far/boo'), 2);
|
||||
assert.strictEqual(trie.findSubstr('/user/foo/bar'), 1);
|
||||
assert.strictEqual(trie.findSubstr('/user/foo/bar/far/boo'), 1);
|
||||
});
|
||||
|
||||
test('TernarySearchTree (PathSegments) - lookup', function () {
|
||||
@@ -599,11 +599,11 @@ suite('Map', () => {
|
||||
map.set('/user/foo', 2);
|
||||
map.set('/user/foo/flip/flop', 3);
|
||||
|
||||
assert.equal(map.get('/foo'), undefined);
|
||||
assert.equal(map.get('/user'), undefined);
|
||||
assert.equal(map.get('/user/foo'), 2);
|
||||
assert.equal(map.get('/user/foo/bar'), 1);
|
||||
assert.equal(map.get('/user/foo/bar/boo'), undefined);
|
||||
assert.strictEqual(map.get('/foo'), undefined);
|
||||
assert.strictEqual(map.get('/user'), undefined);
|
||||
assert.strictEqual(map.get('/user/foo'), 2);
|
||||
assert.strictEqual(map.get('/user/foo/bar'), 1);
|
||||
assert.strictEqual(map.get('/user/foo/bar/boo'), undefined);
|
||||
});
|
||||
|
||||
test('TernarySearchTree (PathSegments) - superstr', function () {
|
||||
@@ -618,31 +618,31 @@ suite('Map', () => {
|
||||
let iter = map.findSuperstr('/user');
|
||||
|
||||
item = iter!.next();
|
||||
assert.equal(item.value[1], 2);
|
||||
assert.equal(item.done, false);
|
||||
assert.strictEqual(item.value[1], 2);
|
||||
assert.strictEqual(item.done, false);
|
||||
item = iter!.next();
|
||||
assert.equal(item.value[1], 1);
|
||||
assert.equal(item.done, false);
|
||||
assert.strictEqual(item.value[1], 1);
|
||||
assert.strictEqual(item.done, false);
|
||||
item = iter!.next();
|
||||
assert.equal(item.value[1], 3);
|
||||
assert.equal(item.done, false);
|
||||
assert.strictEqual(item.value[1], 3);
|
||||
assert.strictEqual(item.done, false);
|
||||
item = iter!.next();
|
||||
assert.equal(item.value, undefined);
|
||||
assert.equal(item.done, true);
|
||||
assert.strictEqual(item.value, undefined);
|
||||
assert.strictEqual(item.done, true);
|
||||
|
||||
iter = map.findSuperstr('/usr');
|
||||
item = iter!.next();
|
||||
assert.equal(item.value[1], 4);
|
||||
assert.equal(item.done, false);
|
||||
assert.strictEqual(item.value[1], 4);
|
||||
assert.strictEqual(item.done, false);
|
||||
|
||||
item = iter!.next();
|
||||
assert.equal(item.value, undefined);
|
||||
assert.equal(item.done, true);
|
||||
assert.strictEqual(item.value, undefined);
|
||||
assert.strictEqual(item.done, true);
|
||||
|
||||
assert.equal(map.findSuperstr('/not'), undefined);
|
||||
assert.equal(map.findSuperstr('/us'), undefined);
|
||||
assert.equal(map.findSuperstr('/usrr'), undefined);
|
||||
assert.equal(map.findSuperstr('/userr'), undefined);
|
||||
assert.strictEqual(map.findSuperstr('/not'), undefined);
|
||||
assert.strictEqual(map.findSuperstr('/us'), undefined);
|
||||
assert.strictEqual(map.findSuperstr('/usrr'), undefined);
|
||||
assert.strictEqual(map.findSuperstr('/userr'), undefined);
|
||||
});
|
||||
|
||||
|
||||
@@ -688,16 +688,16 @@ suite('Map', () => {
|
||||
trie.set(URI.file('/user/foo'), 2);
|
||||
trie.set(URI.file('/user/foo/flip/flop'), 3);
|
||||
|
||||
assert.equal(trie.get(URI.file('/user/foo/bar')), 1);
|
||||
assert.equal(trie.get(URI.file('/user/foo')), 2);
|
||||
assert.equal(trie.get(URI.file('/user/foo/flip/flop')), 3);
|
||||
assert.strictEqual(trie.get(URI.file('/user/foo/bar')), 1);
|
||||
assert.strictEqual(trie.get(URI.file('/user/foo')), 2);
|
||||
assert.strictEqual(trie.get(URI.file('/user/foo/flip/flop')), 3);
|
||||
|
||||
assert.equal(trie.findSubstr(URI.file('/user/bar')), undefined);
|
||||
assert.equal(trie.findSubstr(URI.file('/user/foo')), 2);
|
||||
assert.equal(trie.findSubstr(URI.file('/user/foo/ba')), 2);
|
||||
assert.equal(trie.findSubstr(URI.file('/user/foo/far/boo')), 2);
|
||||
assert.equal(trie.findSubstr(URI.file('/user/foo/bar')), 1);
|
||||
assert.equal(trie.findSubstr(URI.file('/user/foo/bar/far/boo')), 1);
|
||||
assert.strictEqual(trie.findSubstr(URI.file('/user/bar')), undefined);
|
||||
assert.strictEqual(trie.findSubstr(URI.file('/user/foo')), 2);
|
||||
assert.strictEqual(trie.findSubstr(URI.file('/user/foo/ba')), 2);
|
||||
assert.strictEqual(trie.findSubstr(URI.file('/user/foo/far/boo')), 2);
|
||||
assert.strictEqual(trie.findSubstr(URI.file('/user/foo/bar')), 1);
|
||||
assert.strictEqual(trie.findSubstr(URI.file('/user/foo/bar/far/boo')), 1);
|
||||
});
|
||||
|
||||
test('TernarySearchTree (URI) - lookup', function () {
|
||||
@@ -708,23 +708,23 @@ suite('Map', () => {
|
||||
map.set(URI.parse('http://foo.bar/user/foo?QUERY'), 3);
|
||||
map.set(URI.parse('http://foo.bar/user/foo/flip/flop'), 3);
|
||||
|
||||
assert.equal(map.get(URI.parse('http://foo.bar/foo')), undefined);
|
||||
assert.equal(map.get(URI.parse('http://foo.bar/user')), undefined);
|
||||
assert.equal(map.get(URI.parse('http://foo.bar/user/foo/bar')), 1);
|
||||
assert.equal(map.get(URI.parse('http://foo.bar/user/foo?query')), 2);
|
||||
assert.equal(map.get(URI.parse('http://foo.bar/user/foo?Query')), undefined);
|
||||
assert.equal(map.get(URI.parse('http://foo.bar/user/foo?QUERY')), 3);
|
||||
assert.equal(map.get(URI.parse('http://foo.bar/user/foo/bar/boo')), undefined);
|
||||
assert.strictEqual(map.get(URI.parse('http://foo.bar/foo')), undefined);
|
||||
assert.strictEqual(map.get(URI.parse('http://foo.bar/user')), undefined);
|
||||
assert.strictEqual(map.get(URI.parse('http://foo.bar/user/foo/bar')), 1);
|
||||
assert.strictEqual(map.get(URI.parse('http://foo.bar/user/foo?query')), 2);
|
||||
assert.strictEqual(map.get(URI.parse('http://foo.bar/user/foo?Query')), undefined);
|
||||
assert.strictEqual(map.get(URI.parse('http://foo.bar/user/foo?QUERY')), 3);
|
||||
assert.strictEqual(map.get(URI.parse('http://foo.bar/user/foo/bar/boo')), undefined);
|
||||
});
|
||||
|
||||
test('TernarySearchTree (URI) - lookup, casing', function () {
|
||||
|
||||
const map = new TernarySearchTree<URI, number>(new UriIterator(uri => /^https?$/.test(uri.scheme)));
|
||||
map.set(URI.parse('http://foo.bar/user/foo/bar'), 1);
|
||||
assert.equal(map.get(URI.parse('http://foo.bar/USER/foo/bar')), 1);
|
||||
assert.strictEqual(map.get(URI.parse('http://foo.bar/USER/foo/bar')), 1);
|
||||
|
||||
map.set(URI.parse('foo://foo.bar/user/foo/bar'), 1);
|
||||
assert.equal(map.get(URI.parse('foo://foo.bar/USER/foo/bar')), undefined);
|
||||
assert.strictEqual(map.get(URI.parse('foo://foo.bar/USER/foo/bar')), undefined);
|
||||
});
|
||||
|
||||
test('TernarySearchTree (URI) - superstr', function () {
|
||||
@@ -739,48 +739,48 @@ suite('Map', () => {
|
||||
let iter = map.findSuperstr(URI.file('/user'))!;
|
||||
|
||||
item = iter.next();
|
||||
assert.equal(item.value[1], 2);
|
||||
assert.equal(item.done, false);
|
||||
assert.strictEqual(item.value[1], 2);
|
||||
assert.strictEqual(item.done, false);
|
||||
item = iter.next();
|
||||
assert.equal(item.value[1], 1);
|
||||
assert.equal(item.done, false);
|
||||
assert.strictEqual(item.value[1], 1);
|
||||
assert.strictEqual(item.done, false);
|
||||
item = iter.next();
|
||||
assert.equal(item.value[1], 3);
|
||||
assert.equal(item.done, false);
|
||||
assert.strictEqual(item.value[1], 3);
|
||||
assert.strictEqual(item.done, false);
|
||||
item = iter.next();
|
||||
assert.equal(item.value, undefined);
|
||||
assert.equal(item.done, true);
|
||||
assert.strictEqual(item.value, undefined);
|
||||
assert.strictEqual(item.done, true);
|
||||
|
||||
iter = map.findSuperstr(URI.file('/usr'))!;
|
||||
item = iter.next();
|
||||
assert.equal(item.value[1], 4);
|
||||
assert.equal(item.done, false);
|
||||
assert.strictEqual(item.value[1], 4);
|
||||
assert.strictEqual(item.done, false);
|
||||
|
||||
item = iter.next();
|
||||
assert.equal(item.value, undefined);
|
||||
assert.equal(item.done, true);
|
||||
assert.strictEqual(item.value, undefined);
|
||||
assert.strictEqual(item.done, true);
|
||||
|
||||
iter = map.findSuperstr(URI.file('/'))!;
|
||||
item = iter.next();
|
||||
assert.equal(item.value[1], 2);
|
||||
assert.equal(item.done, false);
|
||||
assert.strictEqual(item.value[1], 2);
|
||||
assert.strictEqual(item.done, false);
|
||||
item = iter.next();
|
||||
assert.equal(item.value[1], 1);
|
||||
assert.equal(item.done, false);
|
||||
assert.strictEqual(item.value[1], 1);
|
||||
assert.strictEqual(item.done, false);
|
||||
item = iter.next();
|
||||
assert.equal(item.value[1], 3);
|
||||
assert.equal(item.done, false);
|
||||
assert.strictEqual(item.value[1], 3);
|
||||
assert.strictEqual(item.done, false);
|
||||
item = iter.next();
|
||||
assert.equal(item.value[1], 4);
|
||||
assert.equal(item.done, false);
|
||||
assert.strictEqual(item.value[1], 4);
|
||||
assert.strictEqual(item.done, false);
|
||||
item = iter.next();
|
||||
assert.equal(item.value, undefined);
|
||||
assert.equal(item.done, true);
|
||||
assert.strictEqual(item.value, undefined);
|
||||
assert.strictEqual(item.done, true);
|
||||
|
||||
assert.equal(map.findSuperstr(URI.file('/not')), undefined);
|
||||
assert.equal(map.findSuperstr(URI.file('/us')), undefined);
|
||||
assert.equal(map.findSuperstr(URI.file('/usrr')), undefined);
|
||||
assert.equal(map.findSuperstr(URI.file('/userr')), undefined);
|
||||
assert.strictEqual(map.findSuperstr(URI.file('/not')), undefined);
|
||||
assert.strictEqual(map.findSuperstr(URI.file('/us')), undefined);
|
||||
assert.strictEqual(map.findSuperstr(URI.file('/usrr')), undefined);
|
||||
assert.strictEqual(map.findSuperstr(URI.file('/userr')), undefined);
|
||||
});
|
||||
|
||||
test('TernarySearchTree (ConfigKeySegments) - basics', function () {
|
||||
@@ -790,16 +790,16 @@ suite('Map', () => {
|
||||
trie.set('config.foo', 2);
|
||||
trie.set('config.foo.flip.flop', 3);
|
||||
|
||||
assert.equal(trie.get('config.foo.bar'), 1);
|
||||
assert.equal(trie.get('config.foo'), 2);
|
||||
assert.equal(trie.get('config.foo.flip.flop'), 3);
|
||||
assert.strictEqual(trie.get('config.foo.bar'), 1);
|
||||
assert.strictEqual(trie.get('config.foo'), 2);
|
||||
assert.strictEqual(trie.get('config.foo.flip.flop'), 3);
|
||||
|
||||
assert.equal(trie.findSubstr('config.bar'), undefined);
|
||||
assert.equal(trie.findSubstr('config.foo'), 2);
|
||||
assert.equal(trie.findSubstr('config.foo.ba'), 2);
|
||||
assert.equal(trie.findSubstr('config.foo.far.boo'), 2);
|
||||
assert.equal(trie.findSubstr('config.foo.bar'), 1);
|
||||
assert.equal(trie.findSubstr('config.foo.bar.far.boo'), 1);
|
||||
assert.strictEqual(trie.findSubstr('config.bar'), undefined);
|
||||
assert.strictEqual(trie.findSubstr('config.foo'), 2);
|
||||
assert.strictEqual(trie.findSubstr('config.foo.ba'), 2);
|
||||
assert.strictEqual(trie.findSubstr('config.foo.far.boo'), 2);
|
||||
assert.strictEqual(trie.findSubstr('config.foo.bar'), 1);
|
||||
assert.strictEqual(trie.findSubstr('config.foo.bar.far.boo'), 1);
|
||||
});
|
||||
|
||||
test('TernarySearchTree (ConfigKeySegments) - lookup', function () {
|
||||
@@ -809,11 +809,11 @@ suite('Map', () => {
|
||||
map.set('config.foo', 2);
|
||||
map.set('config.foo.flip.flop', 3);
|
||||
|
||||
assert.equal(map.get('foo'), undefined);
|
||||
assert.equal(map.get('config'), undefined);
|
||||
assert.equal(map.get('config.foo'), 2);
|
||||
assert.equal(map.get('config.foo.bar'), 1);
|
||||
assert.equal(map.get('config.foo.bar.boo'), undefined);
|
||||
assert.strictEqual(map.get('foo'), undefined);
|
||||
assert.strictEqual(map.get('config'), undefined);
|
||||
assert.strictEqual(map.get('config.foo'), 2);
|
||||
assert.strictEqual(map.get('config.foo.bar'), 1);
|
||||
assert.strictEqual(map.get('config.foo.bar.boo'), undefined);
|
||||
});
|
||||
|
||||
test('TernarySearchTree (ConfigKeySegments) - superstr', function () {
|
||||
@@ -828,21 +828,21 @@ suite('Map', () => {
|
||||
let iter = map.findSuperstr('config');
|
||||
|
||||
item = iter!.next();
|
||||
assert.equal(item.value[1], 2);
|
||||
assert.equal(item.done, false);
|
||||
assert.strictEqual(item.value[1], 2);
|
||||
assert.strictEqual(item.done, false);
|
||||
item = iter!.next();
|
||||
assert.equal(item.value[1], 1);
|
||||
assert.equal(item.done, false);
|
||||
assert.strictEqual(item.value[1], 1);
|
||||
assert.strictEqual(item.done, false);
|
||||
item = iter!.next();
|
||||
assert.equal(item.value[1], 3);
|
||||
assert.equal(item.done, false);
|
||||
assert.strictEqual(item.value[1], 3);
|
||||
assert.strictEqual(item.done, false);
|
||||
item = iter!.next();
|
||||
assert.equal(item.value, undefined);
|
||||
assert.equal(item.done, true);
|
||||
assert.strictEqual(item.value, undefined);
|
||||
assert.strictEqual(item.done, true);
|
||||
|
||||
assert.equal(map.findSuperstr('foo'), undefined);
|
||||
assert.equal(map.findSuperstr('config.foo.no'), undefined);
|
||||
assert.equal(map.findSuperstr('config.foop'), undefined);
|
||||
assert.strictEqual(map.findSuperstr('foo'), undefined);
|
||||
assert.strictEqual(map.findSuperstr('config.foo.no'), undefined);
|
||||
assert.strictEqual(map.findSuperstr('config.foop'), undefined);
|
||||
});
|
||||
|
||||
|
||||
@@ -891,7 +891,7 @@ suite('Map', () => {
|
||||
const resource5 = URI.parse('some://5');
|
||||
const resource6 = URI.parse('some://6');
|
||||
|
||||
assert.equal(map.size, 0);
|
||||
assert.strictEqual(map.size, 0);
|
||||
|
||||
let res = map.set(resource1, 1);
|
||||
assert.ok(res === map);
|
||||
@@ -899,13 +899,13 @@ suite('Map', () => {
|
||||
map.set(resource3, true);
|
||||
|
||||
const values = [...map.values()];
|
||||
assert.equal(values[0], 1);
|
||||
assert.equal(values[1], '2');
|
||||
assert.equal(values[2], true);
|
||||
assert.strictEqual(values[0], 1);
|
||||
assert.strictEqual(values[1], '2');
|
||||
assert.strictEqual(values[2], true);
|
||||
|
||||
let counter = 0;
|
||||
map.forEach((value, key, mapObj) => {
|
||||
assert.equal(value, values[counter++]);
|
||||
assert.strictEqual(value, values[counter++]);
|
||||
assert.ok(URI.isUri(key));
|
||||
assert.ok(map === mapObj);
|
||||
});
|
||||
@@ -916,23 +916,23 @@ suite('Map', () => {
|
||||
const date = Date.now();
|
||||
map.set(resource5, date);
|
||||
|
||||
assert.equal(map.size, 5);
|
||||
assert.equal(map.get(resource1), 1);
|
||||
assert.equal(map.get(resource2), '2');
|
||||
assert.equal(map.get(resource3), true);
|
||||
assert.equal(map.get(resource4), obj);
|
||||
assert.equal(map.get(resource5), date);
|
||||
assert.strictEqual(map.size, 5);
|
||||
assert.strictEqual(map.get(resource1), 1);
|
||||
assert.strictEqual(map.get(resource2), '2');
|
||||
assert.strictEqual(map.get(resource3), true);
|
||||
assert.strictEqual(map.get(resource4), obj);
|
||||
assert.strictEqual(map.get(resource5), date);
|
||||
assert.ok(!map.get(resource6));
|
||||
|
||||
map.delete(resource6);
|
||||
assert.equal(map.size, 5);
|
||||
assert.strictEqual(map.size, 5);
|
||||
assert.ok(map.delete(resource1));
|
||||
assert.ok(map.delete(resource2));
|
||||
assert.ok(map.delete(resource3));
|
||||
assert.ok(map.delete(resource4));
|
||||
assert.ok(map.delete(resource5));
|
||||
|
||||
assert.equal(map.size, 0);
|
||||
assert.strictEqual(map.size, 0);
|
||||
assert.ok(!map.get(resource5));
|
||||
assert.ok(!map.get(resource4));
|
||||
assert.ok(!map.get(resource3));
|
||||
@@ -944,13 +944,13 @@ suite('Map', () => {
|
||||
map.set(resource3, true);
|
||||
|
||||
assert.ok(map.has(resource1));
|
||||
assert.equal(map.get(resource1), 1);
|
||||
assert.equal(map.get(resource2), '2');
|
||||
assert.equal(map.get(resource3), true);
|
||||
assert.strictEqual(map.get(resource1), 1);
|
||||
assert.strictEqual(map.get(resource2), '2');
|
||||
assert.strictEqual(map.get(resource3), true);
|
||||
|
||||
map.clear();
|
||||
|
||||
assert.equal(map.size, 0);
|
||||
assert.strictEqual(map.size, 0);
|
||||
assert.ok(!map.get(resource1));
|
||||
assert.ok(!map.get(resource2));
|
||||
assert.ok(!map.get(resource3));
|
||||
@@ -971,16 +971,16 @@ suite('Map', () => {
|
||||
const fileAUpper = URI.parse('file://SOME/FILEA');
|
||||
|
||||
map.set(fileA, 'true');
|
||||
assert.equal(map.get(fileA), 'true');
|
||||
assert.strictEqual(map.get(fileA), 'true');
|
||||
|
||||
assert.ok(!map.get(fileAUpper));
|
||||
|
||||
assert.ok(!map.get(fileB));
|
||||
|
||||
map.set(fileAUpper, 'false');
|
||||
assert.equal(map.get(fileAUpper), 'false');
|
||||
assert.strictEqual(map.get(fileAUpper), 'false');
|
||||
|
||||
assert.equal(map.get(fileA), 'true');
|
||||
assert.strictEqual(map.get(fileA), 'true');
|
||||
|
||||
const windowsFile = URI.file('c:\\test with %25\\c#code');
|
||||
const uncFile = URI.file('\\\\shäres\\path\\c#\\plugin.json');
|
||||
@@ -988,8 +988,8 @@ suite('Map', () => {
|
||||
map.set(windowsFile, 'true');
|
||||
map.set(uncFile, 'true');
|
||||
|
||||
assert.equal(map.get(windowsFile), 'true');
|
||||
assert.equal(map.get(uncFile), 'true');
|
||||
assert.strictEqual(map.get(windowsFile), 'true');
|
||||
assert.strictEqual(map.get(uncFile), 'true');
|
||||
});
|
||||
|
||||
test('ResourceMap - files (ignorecase)', function () {
|
||||
@@ -1000,16 +1000,16 @@ suite('Map', () => {
|
||||
const fileAUpper = URI.parse('file://SOME/FILEA');
|
||||
|
||||
map.set(fileA, 'true');
|
||||
assert.equal(map.get(fileA), 'true');
|
||||
assert.strictEqual(map.get(fileA), 'true');
|
||||
|
||||
assert.equal(map.get(fileAUpper), 'true');
|
||||
assert.strictEqual(map.get(fileAUpper), 'true');
|
||||
|
||||
assert.ok(!map.get(fileB));
|
||||
|
||||
map.set(fileAUpper, 'false');
|
||||
assert.equal(map.get(fileAUpper), 'false');
|
||||
assert.strictEqual(map.get(fileAUpper), 'false');
|
||||
|
||||
assert.equal(map.get(fileA), 'false');
|
||||
assert.strictEqual(map.get(fileA), 'false');
|
||||
|
||||
const windowsFile = URI.file('c:\\test with %25\\c#code');
|
||||
const uncFile = URI.file('\\\\shäres\\path\\c#\\plugin.json');
|
||||
@@ -1017,7 +1017,7 @@ suite('Map', () => {
|
||||
map.set(windowsFile, 'true');
|
||||
map.set(uncFile, 'true');
|
||||
|
||||
assert.equal(map.get(windowsFile), 'true');
|
||||
assert.equal(map.get(uncFile), 'true');
|
||||
assert.strictEqual(map.get(windowsFile), 'true');
|
||||
assert.strictEqual(map.get(uncFile), 'true');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -73,7 +73,7 @@ export class SharedProcess extends Disposable implements ISharedProcess {
|
||||
}
|
||||
|
||||
// Signal exit to shared process when shutting down
|
||||
if (!window.webContents.isDestroyed()) {
|
||||
if (!window.isDestroyed() && !window.webContents.isDestroyed()) {
|
||||
window.webContents.send('vscode:electron-main->shared-process=exit');
|
||||
}
|
||||
|
||||
|
||||
@@ -422,7 +422,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
this.dispose();
|
||||
});
|
||||
|
||||
const svgFileSchemes = new Set([Schemas.file, Schemas.vscodeFileResource, 'devtools']);
|
||||
const svgFileSchemes = new Set([Schemas.file, Schemas.vscodeFileResource, Schemas.vscodeRemoteResource, 'devtools']);
|
||||
this._win.webContents.session.webRequest.onBeforeRequest((details, callback) => {
|
||||
// Prevent loading of remote svgs
|
||||
if (details.url.endsWith('.svg')) {
|
||||
@@ -1265,7 +1265,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
|
||||
send(channel: string, ...args: any[]): void {
|
||||
if (this._win) {
|
||||
if (this._win.webContents.isDestroyed()) {
|
||||
if (this._win.isDestroyed() || this._win.webContents.isDestroyed()) {
|
||||
this.logService.warn(`Sending IPC message to channel ${channel} for window that is destroyed`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ import { ILocalizationsService } from 'vs/platform/localizations/common/localiza
|
||||
import { setUnexpectedErrorHandler } from 'vs/base/common/errors';
|
||||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
|
||||
export class CliMain extends Disposable {
|
||||
class CliMain extends Disposable {
|
||||
|
||||
constructor(
|
||||
private argv: NativeParsedArgs
|
||||
|
||||
@@ -255,7 +255,7 @@ export class ViewLayout extends Disposable implements IViewLayout {
|
||||
|
||||
let result = this._linesLayout.getLinesTotalHeight();
|
||||
if (options.get(EditorOption.scrollBeyondLastLine)) {
|
||||
result += height - options.get(EditorOption.lineHeight);
|
||||
result += Math.max(0, height - options.get(EditorOption.lineHeight) - options.get(EditorOption.padding).bottom);
|
||||
} else {
|
||||
result += this._getHorizontalScrollbarHeight(width, contentWidth);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,8 @@ const supportsCopy = (platform.isNative || document.queryCommandSupported('copy'
|
||||
const supportsCopyWithSyntaxHighlighting = (supportsCopy && !browser.isEdge);
|
||||
// Firefox only supports navigator.clipboard.readText() in browser extensions.
|
||||
// See https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/readText#Browser_compatibility
|
||||
const supportsPaste = (browser.isFirefox ? document.queryCommandSupported('paste') : true);
|
||||
// When loading over http, navigator.clipboard can be undefined. See https://github.com/microsoft/monaco-editor/issues/2313
|
||||
const supportsPaste = (typeof navigator.clipboard === 'undefined' || browser.isFirefox) ? document.queryCommandSupported('paste') : true;
|
||||
|
||||
function registerCommand<T extends Command>(command: T): T {
|
||||
command.register();
|
||||
|
||||
@@ -25,7 +25,7 @@ import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storag
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IIgnoredExtensionsManagementService } from 'vs/platform/userDataSync/common/ignoredExtensions';
|
||||
import { getErrorMessage } from 'vs/base/common/errors';
|
||||
import { forEach, IStringDictionary } from 'vs/base/common/collections';
|
||||
import { IStringDictionary } from 'vs/base/common/collections';
|
||||
import { IExtensionsStorageSyncService } from 'vs/platform/userDataSync/common/extensionsStorageSync';
|
||||
|
||||
interface IExtensionResourceMergeResult extends IAcceptResult {
|
||||
@@ -451,9 +451,9 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse
|
||||
const extensionState = getExtensionStorageState(publisher, name, this.storageService);
|
||||
const keys = version ? this.extensionsStorageSyncService.getKeysForSync({ id: getGalleryExtensionId(publisher, name), version }) : undefined;
|
||||
if (keys) {
|
||||
keys.forEach(key => extensionState[key] = state[key]);
|
||||
keys.forEach(key => { extensionState[key] = state[key]; });
|
||||
} else {
|
||||
forEach(state, ({ key, value }) => extensionState[key] = value);
|
||||
Object.keys(state).forEach(key => extensionState[key] = state[key]);
|
||||
}
|
||||
storeExtensionStorageState(publisher, name, extensionState, this.storageService);
|
||||
}
|
||||
@@ -556,7 +556,7 @@ export class ExtensionsInitializer extends AbstractInitializer {
|
||||
for (const { syncExtension, installedExtension } of installedExtensionsToSync) {
|
||||
if (syncExtension.state) {
|
||||
const extensionState = getExtensionStorageState(installedExtension.manifest.publisher, installedExtension.manifest.name, this.storageService);
|
||||
forEach(syncExtension.state, ({ key, value }) => extensionState[key] = value);
|
||||
Object.keys(syncExtension.state).forEach(key => extensionState[key] = syncExtension.state![key]);
|
||||
storeExtensionStorageState(installedExtension.manifest.publisher, installedExtension.manifest.name, extensionState, this.storageService);
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
-2
@@ -11944,8 +11944,6 @@ declare module 'vscode' {
|
||||
export const onDidChange: Event<void>;
|
||||
}
|
||||
|
||||
//#region Comments
|
||||
|
||||
/**
|
||||
* Collapsible state of a [comment thread](#CommentThread)
|
||||
*/
|
||||
|
||||
Vendored
+16
-6
@@ -131,6 +131,7 @@ declare module 'vscode' {
|
||||
|
||||
//#endregion
|
||||
|
||||
// eslint-disable-next-line vscode-dts-region-comments
|
||||
//#region @alexdima - resolvers
|
||||
|
||||
export interface MessageOptions {
|
||||
@@ -728,6 +729,7 @@ declare module 'vscode' {
|
||||
|
||||
//#endregion
|
||||
|
||||
// eslint-disable-next-line vscode-dts-region-comments
|
||||
//#region debug
|
||||
|
||||
/**
|
||||
@@ -748,6 +750,7 @@ declare module 'vscode' {
|
||||
|
||||
//#endregion
|
||||
|
||||
// eslint-disable-next-line vscode-dts-region-comments
|
||||
//#region @joaomoreno: SCM validation
|
||||
|
||||
/**
|
||||
@@ -798,6 +801,7 @@ declare module 'vscode' {
|
||||
|
||||
//#endregion
|
||||
|
||||
// eslint-disable-next-line vscode-dts-region-comments
|
||||
//#region @joaomoreno: SCM selected provider
|
||||
|
||||
export interface SourceControl {
|
||||
@@ -873,6 +877,7 @@ declare module 'vscode' {
|
||||
|
||||
//#endregion
|
||||
|
||||
// eslint-disable-next-line vscode-dts-region-comments
|
||||
//#region @jrieken -> exclusive document filters
|
||||
|
||||
export interface DocumentFilter {
|
||||
@@ -984,7 +989,7 @@ declare module 'vscode' {
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region @rebornix: Notebook
|
||||
//#region notebook https://github.com/microsoft/vscode/issues/106744
|
||||
|
||||
export enum CellKind {
|
||||
Markdown = 1,
|
||||
@@ -2445,7 +2450,7 @@ declare module 'vscode' {
|
||||
/**
|
||||
* The uri that triggered the open.
|
||||
*
|
||||
* Due to port forwarding, this may not match the `resolvedUri` passed to `openExternalUri`
|
||||
* Due to port forwarding, this may not match the `resolvedUri` passed to `openExternalUri`.
|
||||
*/
|
||||
readonly sourceUri: Uri;
|
||||
}
|
||||
@@ -2455,6 +2460,13 @@ declare module 'vscode' {
|
||||
*/
|
||||
interface ExternalUriOpenerMetadata {
|
||||
|
||||
/**
|
||||
* List of uri schemes the opener is triggered for.
|
||||
*
|
||||
* Currently only `http` and `https` are supported.
|
||||
*/
|
||||
readonly schemes: readonly string[]
|
||||
|
||||
/**
|
||||
* Text displayed to the user that explains what the opener does.
|
||||
*
|
||||
@@ -2471,14 +2483,12 @@ declare module 'vscode' {
|
||||
*
|
||||
* @param id Unique id of the opener, such as `myExtension.browserPreview`. This is used in settings
|
||||
* and commands to identify the opener.
|
||||
* @param schemes List of uri schemes the opener is triggered for. Currently only `http`
|
||||
* and `https` are supported.
|
||||
* @param opener Opener to register.
|
||||
* @param metadata Additional information about the opener.
|
||||
*
|
||||
* @returns Disposable that unregisters the opener.
|
||||
*/
|
||||
export function registerExternalUriOpener(id: string, schemes: readonly string[], opener: ExternalUriOpener, metadata: ExternalUriOpenerMetadata): Disposable;
|
||||
*/
|
||||
export function registerExternalUriOpener(id: string, opener: ExternalUriOpener, metadata: ExternalUriOpenerMetadata): Disposable;
|
||||
}
|
||||
|
||||
interface OpenExternalOptions {
|
||||
|
||||
@@ -681,9 +681,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostNotebook.showNotebookDocument(document, options);
|
||||
},
|
||||
registerExternalUriOpener(id: string, schemes: readonly string[], opener: vscode.ExternalUriOpener, metadata: vscode.ExternalUriOpenerMetadata) {
|
||||
registerExternalUriOpener(id: string, opener: vscode.ExternalUriOpener, metadata: vscode.ExternalUriOpenerMetadata) {
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostUriOpeners.registerUriOpener(extension.identifier, id, schemes, opener, metadata);
|
||||
return extHostUriOpeners.registerUriOpener(extension.identifier, id, opener, metadata);
|
||||
},
|
||||
get openEditors() {
|
||||
checkProposedApiEnabled(extension);
|
||||
|
||||
@@ -1798,7 +1798,7 @@ export interface ExtHostNotebookShape {
|
||||
$saveNotebookAs(viewType: string, uri: UriComponents, target: UriComponents, token: CancellationToken): Promise<boolean>;
|
||||
$backup(viewType: string, uri: UriComponents, cancellation: CancellationToken): Promise<string | undefined>;
|
||||
$acceptDisplayOrder(displayOrder: INotebookDisplayOrder): void;
|
||||
$acceptNotebookActiveKernelChange(event: { uri: UriComponents, providerHandle: number | undefined, kernelId: string | undefined }): void;
|
||||
$acceptNotebookActiveKernelChange(event: { uri: UriComponents, providerHandle: number | undefined, kernelFriendlyId: string | undefined }): void;
|
||||
$onDidReceiveMessage(editorId: string, rendererId: string | undefined, message: unknown): void;
|
||||
$acceptModelChanged(uriComponents: UriComponents, event: NotebookCellsChangedEventDto, isDirty: boolean): void;
|
||||
$acceptModelSaved(uriComponents: UriComponents): void;
|
||||
|
||||
@@ -78,8 +78,8 @@ export interface ExtHostNotebookOutputRenderingHandler {
|
||||
}
|
||||
|
||||
export class ExtHostNotebookKernelProviderAdapter extends Disposable {
|
||||
private _kernelToId = new Map<vscode.NotebookKernel, string>();
|
||||
private _idToKernel = new Map<string, vscode.NotebookKernel>();
|
||||
private _kernelToFriendlyId = new Map<vscode.NotebookKernel, string>();
|
||||
private _friendlyIdToKernel = new Map<string, vscode.NotebookKernel>();
|
||||
constructor(
|
||||
private readonly _proxy: MainThreadNotebookShape,
|
||||
private readonly _handle: number,
|
||||
@@ -101,24 +101,25 @@ export class ExtHostNotebookKernelProviderAdapter extends Disposable {
|
||||
|
||||
const newMap = new Map<vscode.NotebookKernel, string>();
|
||||
let kernel_unique_pool = 0;
|
||||
const kernelIdCache = new Set<string>();
|
||||
const kernelFriendlyIdCache = new Set<string>();
|
||||
|
||||
const transformedData: INotebookKernelInfoDto2[] = data.map(kernel => {
|
||||
let id = this._kernelToId.get(kernel);
|
||||
if (id === undefined) {
|
||||
if (kernel.id && kernelIdCache.has(kernel.id)) {
|
||||
id = `${this._extension.identifier.value}_${kernel.id}_${kernel_unique_pool++}`;
|
||||
let friendlyId = this._kernelToFriendlyId.get(kernel);
|
||||
if (friendlyId === undefined) {
|
||||
if (kernel.id && kernelFriendlyIdCache.has(kernel.id)) {
|
||||
friendlyId = `${this._extension.identifier.value}_${kernel.id}_${kernel_unique_pool++}`;
|
||||
} else {
|
||||
id = `${this._extension.identifier.value}_${kernel.id || UUID.generateUuid()}`;
|
||||
friendlyId = `${this._extension.identifier.value}_${kernel.id || UUID.generateUuid()}`;
|
||||
}
|
||||
|
||||
this._kernelToId.set(kernel, id);
|
||||
this._kernelToFriendlyId.set(kernel, friendlyId);
|
||||
}
|
||||
|
||||
newMap.set(kernel, id);
|
||||
newMap.set(kernel, friendlyId);
|
||||
|
||||
return {
|
||||
id,
|
||||
id: kernel.id,
|
||||
friendlyId: friendlyId,
|
||||
label: kernel.label,
|
||||
extension: this._extension.identifier,
|
||||
extensionLocation: this._extension.extensionLocation,
|
||||
@@ -129,22 +130,22 @@ export class ExtHostNotebookKernelProviderAdapter extends Disposable {
|
||||
};
|
||||
});
|
||||
|
||||
this._kernelToId = newMap;
|
||||
this._kernelToFriendlyId = newMap;
|
||||
|
||||
this._idToKernel.clear();
|
||||
this._kernelToId.forEach((value, key) => {
|
||||
this._idToKernel.set(value, key);
|
||||
this._friendlyIdToKernel.clear();
|
||||
this._kernelToFriendlyId.forEach((value, key) => {
|
||||
this._friendlyIdToKernel.set(value, key);
|
||||
});
|
||||
|
||||
return transformedData;
|
||||
}
|
||||
|
||||
getKernel(kernelId: string) {
|
||||
return this._idToKernel.get(kernelId);
|
||||
getKernelByFriendlyId(kernelId: string) {
|
||||
return this._friendlyIdToKernel.get(kernelId);
|
||||
}
|
||||
|
||||
async resolveNotebook(kernelId: string, document: ExtHostNotebookDocument, webview: vscode.NotebookCommunication, token: CancellationToken) {
|
||||
const kernel = this._idToKernel.get(kernelId);
|
||||
const kernel = this._friendlyIdToKernel.get(kernelId);
|
||||
|
||||
if (kernel && this._provider.resolveKernel) {
|
||||
return this._provider.resolveKernel(kernel, document.notebookDocument, webview, token);
|
||||
@@ -152,7 +153,7 @@ export class ExtHostNotebookKernelProviderAdapter extends Disposable {
|
||||
}
|
||||
|
||||
async executeNotebook(kernelId: string, document: ExtHostNotebookDocument, cell: ExtHostCell | undefined) {
|
||||
const kernel = this._idToKernel.get(kernelId);
|
||||
const kernel = this._friendlyIdToKernel.get(kernelId);
|
||||
|
||||
if (!kernel) {
|
||||
return;
|
||||
@@ -166,7 +167,7 @@ export class ExtHostNotebookKernelProviderAdapter extends Disposable {
|
||||
}
|
||||
|
||||
async cancelNotebook(kernelId: string, document: ExtHostNotebookDocument, cell: ExtHostCell | undefined) {
|
||||
const kernel = this._idToKernel.get(kernelId);
|
||||
const kernel = this._friendlyIdToKernel.get(kernelId);
|
||||
|
||||
if (!kernel) {
|
||||
return;
|
||||
@@ -580,10 +581,10 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
this._outputDisplayOrder = displayOrder;
|
||||
}
|
||||
|
||||
$acceptNotebookActiveKernelChange(event: { uri: UriComponents, providerHandle: number | undefined, kernelId: string | undefined; }) {
|
||||
$acceptNotebookActiveKernelChange(event: { uri: UriComponents, providerHandle: number | undefined, kernelFriendlyId: string | undefined; }) {
|
||||
if (event.providerHandle !== undefined) {
|
||||
this._withAdapter(event.providerHandle, event.uri, async (adapter, document) => {
|
||||
const kernel = event.kernelId ? adapter.getKernel(event.kernelId) : undefined;
|
||||
const kernel = event.kernelFriendlyId ? adapter.getKernelByFriendlyId(event.kernelFriendlyId) : undefined;
|
||||
this._editors.forEach(editor => {
|
||||
if (editor.editor.notebookData === document) {
|
||||
editor.editor._acceptKernel(kernel);
|
||||
|
||||
@@ -12,7 +12,7 @@ import { Emitter, Event } from 'vs/base/common/event';
|
||||
export class ExtensionSecrets implements vscode.SecretStorage {
|
||||
|
||||
protected readonly _id: string;
|
||||
protected readonly _secretState: ExtHostSecretState;
|
||||
readonly #secretState: ExtHostSecretState;
|
||||
|
||||
private _onDidChange = new Emitter<vscode.SecretStorageChangeEvent>();
|
||||
readonly onDidChange: Event<vscode.SecretStorageChangeEvent> = this._onDidChange.event;
|
||||
@@ -20,9 +20,9 @@ export class ExtensionSecrets implements vscode.SecretStorage {
|
||||
|
||||
constructor(extensionDescription: IExtensionDescription, secretState: ExtHostSecretState) {
|
||||
this._id = ExtensionIdentifier.toKey(extensionDescription.identifier);
|
||||
this._secretState = secretState;
|
||||
this.#secretState = secretState;
|
||||
|
||||
this._secretState.onDidChangePassword(e => {
|
||||
this.#secretState.onDidChangePassword(e => {
|
||||
if (e.extensionId === this._id) {
|
||||
this._onDidChange.fire({ key: e.key });
|
||||
}
|
||||
@@ -30,14 +30,14 @@ export class ExtensionSecrets implements vscode.SecretStorage {
|
||||
}
|
||||
|
||||
get(key: string): Promise<string | undefined> {
|
||||
return this._secretState.get(this._id, key);
|
||||
return this.#secretState.get(this._id, key);
|
||||
}
|
||||
|
||||
store(key: string, value: string): Promise<void> {
|
||||
return this._secretState.store(this._id, key, value);
|
||||
return this.#secretState.store(this._id, key, value);
|
||||
}
|
||||
|
||||
delete(key: string): Promise<void> {
|
||||
return this._secretState.delete(this._id, key);
|
||||
return this.#secretState.delete(this._id, key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +112,10 @@ export class ExtHostTesting implements ExtHostTestingShape {
|
||||
if (resource === ExtHostTestingResource.TextDocument) {
|
||||
const document = this.documents.getDocument(uri);
|
||||
if (document) {
|
||||
method = p => p.createDocumentTestHierarchy?.(document.document);
|
||||
const folder = await this.workspace.getWorkspaceFolder2(uri, false);
|
||||
method = p => p.createDocumentTestHierarchy
|
||||
? p.createDocumentTestHierarchy(document.document)
|
||||
: this.createDefaultDocumentTestHierarchy(p, document.document, folder);
|
||||
}
|
||||
} else {
|
||||
const folder = await this.workspace.getWorkspaceFolder2(uri, false);
|
||||
@@ -190,7 +193,10 @@ export class ExtHostTesting implements ExtHostTestingShape {
|
||||
return EMPTY_TEST_RESULT;
|
||||
}
|
||||
|
||||
const tests = req.ids.map(id => this.ownedTests.getTestById(id)?.actual).filter(isDefined);
|
||||
const tests = req.ids.map(id => this.ownedTests.getTestById(id)?.actual)
|
||||
.filter(isDefined)
|
||||
// Only send the actual TestItem's to the user to run.
|
||||
.map(t => t instanceof TestItemFilteredWrapper ? t.actual : t);
|
||||
if (!tests.length) {
|
||||
return EMPTY_TEST_RESULT;
|
||||
}
|
||||
@@ -217,6 +223,158 @@ export class ExtHostTesting implements ExtHostTestingShape {
|
||||
const { actual, previousChildren, previousEquals, ...item } = owned;
|
||||
return Promise.resolve(item);
|
||||
}
|
||||
|
||||
private createDefaultDocumentTestHierarchy(provider: vscode.TestProvider, document: vscode.TextDocument, folder: vscode.WorkspaceFolder | undefined): vscode.TestHierarchy<vscode.TestItem> | undefined {
|
||||
if (!folder) {
|
||||
return;
|
||||
}
|
||||
|
||||
const workspaceHierarchy = provider.createWorkspaceTestHierarchy?.(folder);
|
||||
if (!workspaceHierarchy) {
|
||||
return;
|
||||
}
|
||||
|
||||
const onDidChangeTest = new Emitter<vscode.TestItem>();
|
||||
workspaceHierarchy.onDidChangeTest(node => {
|
||||
const wrapper = TestItemFilteredWrapper.getWrapperForTestItem(node, document);
|
||||
const previouslySeen = wrapper.hasNodeMatchingFilter;
|
||||
|
||||
if (previouslySeen) {
|
||||
// reset cache and get whether you can currently see the TestItem.
|
||||
wrapper.reset();
|
||||
const currentlySeen = wrapper.hasNodeMatchingFilter;
|
||||
|
||||
if (currentlySeen) {
|
||||
onDidChangeTest.fire(wrapper);
|
||||
return;
|
||||
}
|
||||
|
||||
// Fire the event to say that the current visible parent has changed.
|
||||
onDidChangeTest.fire(wrapper.visibleParent);
|
||||
return;
|
||||
}
|
||||
|
||||
const previousParent = wrapper.visibleParent;
|
||||
wrapper.reset();
|
||||
const currentlySeen = wrapper.hasNodeMatchingFilter;
|
||||
|
||||
// It wasn't previously seen and isn't currently seen so
|
||||
// nothing has actually changed.
|
||||
if (!currentlySeen) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The test is now visible so we need to refresh the cache
|
||||
// of the previous visible parent and fire that it has changed.
|
||||
previousParent.reset();
|
||||
onDidChangeTest.fire(previousParent);
|
||||
});
|
||||
|
||||
return {
|
||||
root: TestItemFilteredWrapper.getWrapperForTestItem(workspaceHierarchy.root, document),
|
||||
dispose: () => {
|
||||
onDidChangeTest.dispose();
|
||||
TestItemFilteredWrapper.removeFilter(document);
|
||||
},
|
||||
onDidChangeTest: onDidChangeTest.event
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A class which wraps a vscode.TestItem that provides the ability to filter a TestItem's children
|
||||
* to only the children that are located in a certain vscode.Uri.
|
||||
*/
|
||||
export class TestItemFilteredWrapper implements vscode.TestItem {
|
||||
private static wrapperMap = new WeakMap<vscode.TextDocument, WeakMap<vscode.TestItem, TestItemFilteredWrapper>>();
|
||||
public static removeFilter(document: vscode.TextDocument): void {
|
||||
this.wrapperMap.delete(document);
|
||||
}
|
||||
|
||||
// Wraps the TestItem specified in a TestItemFilteredWrapper and pulls from a cache if it already exists.
|
||||
public static getWrapperForTestItem(item: vscode.TestItem, filterDocument: vscode.TextDocument, parent?: TestItemFilteredWrapper): TestItemFilteredWrapper {
|
||||
let innerMap = this.wrapperMap.get(filterDocument);
|
||||
if (innerMap?.has(item)) {
|
||||
return innerMap.get(item)!;
|
||||
}
|
||||
|
||||
if (!innerMap) {
|
||||
innerMap = new WeakMap<vscode.TestItem, TestItemFilteredWrapper>();
|
||||
this.wrapperMap.set(filterDocument, innerMap);
|
||||
|
||||
}
|
||||
|
||||
const w = new TestItemFilteredWrapper(item, filterDocument, parent);
|
||||
innerMap.set(item, w);
|
||||
return w;
|
||||
}
|
||||
|
||||
public get label() {
|
||||
return this.actual.label;
|
||||
}
|
||||
|
||||
public get debuggable() {
|
||||
return this.actual.debuggable;
|
||||
}
|
||||
|
||||
public get description() {
|
||||
return this.actual.description;
|
||||
}
|
||||
|
||||
public get location() {
|
||||
return this.actual.location;
|
||||
}
|
||||
|
||||
public get runnable() {
|
||||
return this.actual.runnable;
|
||||
}
|
||||
|
||||
public get state() {
|
||||
return this.actual.state;
|
||||
}
|
||||
|
||||
public get children() {
|
||||
// We only want children that match the filter.
|
||||
return this.getWrappedChildren().filter(child => child.hasNodeMatchingFilter);
|
||||
}
|
||||
|
||||
public get visibleParent(): TestItemFilteredWrapper {
|
||||
return this.hasNodeMatchingFilter ? this : this.parent!.visibleParent;
|
||||
}
|
||||
|
||||
private matchesFilter: boolean | undefined;
|
||||
|
||||
// Determines if the TestItem matches the filter. This would be true if:
|
||||
// 1. We don't have a parent (because the root is the workspace root node)
|
||||
// 2. The URI of the current node matches the filter URI
|
||||
// 3. Some child of the current node matches the filter URI
|
||||
public get hasNodeMatchingFilter(): boolean {
|
||||
if (this.matchesFilter === undefined) {
|
||||
this.matchesFilter = !this.parent
|
||||
|| this.actual.location?.uri.toString() === this.filterDocument.uri.toString()
|
||||
|| this.getWrappedChildren().some(child => child.hasNodeMatchingFilter);
|
||||
}
|
||||
|
||||
return this.matchesFilter;
|
||||
}
|
||||
|
||||
// Reset the cache of whether or not you can see a node from a particular node
|
||||
// up to it's visible parent.
|
||||
public reset(): void {
|
||||
if (this !== this.visibleParent) {
|
||||
this.parent?.reset();
|
||||
}
|
||||
this.matchesFilter = undefined;
|
||||
}
|
||||
|
||||
|
||||
private constructor(public readonly actual: vscode.TestItem, private filterDocument: vscode.TextDocument, private readonly parent?: TestItemFilteredWrapper) {
|
||||
this.getWrappedChildren();
|
||||
}
|
||||
|
||||
private getWrappedChildren() {
|
||||
return this.actual.children?.map(t => TestItemFilteredWrapper.getWrapperForTestItem(t, this.filterDocument, this)) || [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,18 +11,12 @@ import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import type * as vscode from 'vscode';
|
||||
import { ExtHostUriOpenersShape, IMainContext, MainContext, MainThreadUriOpenersShape } from './extHost.protocol';
|
||||
|
||||
interface OpenerEntry {
|
||||
readonly extension: ExtensionIdentifier;
|
||||
readonly schemes: ReadonlySet<string>;
|
||||
readonly opener: vscode.ExternalUriOpener;
|
||||
readonly metadata: vscode.ExternalUriOpenerMetadata;
|
||||
}
|
||||
|
||||
export class ExtHostUriOpeners implements ExtHostUriOpenersShape {
|
||||
|
||||
private readonly _proxy: MainThreadUriOpenersShape;
|
||||
|
||||
private readonly _openers = new Map<string, OpenerEntry>();
|
||||
private readonly _openers = new Map<string, vscode.ExternalUriOpener>();
|
||||
|
||||
constructor(
|
||||
mainContext: IMainContext,
|
||||
@@ -33,7 +27,6 @@ export class ExtHostUriOpeners implements ExtHostUriOpenersShape {
|
||||
registerUriOpener(
|
||||
extensionId: ExtensionIdentifier,
|
||||
id: string,
|
||||
schemes: readonly string[],
|
||||
opener: vscode.ExternalUriOpener,
|
||||
metadata: vscode.ExternalUriOpenerMetadata,
|
||||
): vscode.Disposable {
|
||||
@@ -41,13 +34,8 @@ export class ExtHostUriOpeners implements ExtHostUriOpenersShape {
|
||||
throw new Error(`Opener with id already registered: '${id}'`);
|
||||
}
|
||||
|
||||
this._openers.set(id, {
|
||||
opener,
|
||||
extension: extensionId,
|
||||
schemes: new Set(schemes),
|
||||
metadata
|
||||
});
|
||||
this._proxy.$registerUriOpener(id, schemes, extensionId, metadata.label);
|
||||
this._openers.set(id, opener);
|
||||
this._proxy.$registerUriOpener(id, metadata.schemes, extensionId, metadata.label);
|
||||
|
||||
return toDisposable(() => {
|
||||
this._openers.delete(id);
|
||||
@@ -56,21 +44,22 @@ export class ExtHostUriOpeners implements ExtHostUriOpenersShape {
|
||||
}
|
||||
|
||||
async $canOpenUri(id: string, uriComponents: UriComponents, token: CancellationToken): Promise<modes.ExternalUriOpenerPriority> {
|
||||
const entry = this._openers.get(id);
|
||||
if (!entry) {
|
||||
const opener = this._openers.get(id);
|
||||
if (!opener) {
|
||||
throw new Error(`Unknown opener with id: ${id}`);
|
||||
}
|
||||
|
||||
const uri = URI.revive(uriComponents);
|
||||
return entry.opener.canOpenExternalUri(uri, token);
|
||||
return opener.canOpenExternalUri(uri, token);
|
||||
}
|
||||
|
||||
async $openUri(id: string, context: { resolvedUri: UriComponents, sourceUri: UriComponents }, token: CancellationToken): Promise<void> {
|
||||
const entry = this._openers.get(id);
|
||||
if (!entry) {
|
||||
const opener = this._openers.get(id);
|
||||
if (!opener) {
|
||||
throw new Error(`Unknown opener id: '${id}'`);
|
||||
}
|
||||
return entry.opener.openExternalUri(URI.revive(context.resolvedUri), {
|
||||
|
||||
return opener.openExternalUri(URI.revive(context.resolvedUri), {
|
||||
sourceUri: URI.revive(context.sourceUri)
|
||||
}, token);
|
||||
}
|
||||
|
||||
@@ -259,7 +259,8 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe
|
||||
}
|
||||
|
||||
async $applyCandidateFilter(candidates: CandidatePort[]): Promise<CandidatePort[]> {
|
||||
return Promise.all(candidates.filter(candidate => this._showCandidatePort(candidate.host, candidate.port, candidate.detail)));
|
||||
const filter = await Promise.all(candidates.map(candidate => this._showCandidatePort(candidate.host, candidate.port, candidate.detail)));
|
||||
return candidates.filter((candidate, index) => filter[index]);
|
||||
}
|
||||
|
||||
async findCandidatePorts(): Promise<CandidatePort[]> {
|
||||
|
||||
@@ -51,12 +51,12 @@ import { isStandalone } from 'vs/base/browser/browser';
|
||||
'workbench.editor.decorations.badges': {
|
||||
'type': 'boolean',
|
||||
'markdownDescription': nls.localize('decorations.badges', "Controls whether editor file decorations should use badges."),
|
||||
'default': true
|
||||
'default': false
|
||||
},
|
||||
'workbench.editor.decorations.colors': {
|
||||
'type': 'boolean',
|
||||
'markdownDescription': nls.localize('decorations.colors', "Controls whether editor file decorations should use colors."),
|
||||
'default': true
|
||||
'default': false
|
||||
},
|
||||
'workbench.editor.labelFormat': {
|
||||
'type': 'string',
|
||||
|
||||
@@ -19,6 +19,8 @@ import { BulkCellEdits, ResourceNotebookCellEdit } from 'vs/workbench/contrib/bu
|
||||
import { UndoRedoGroup, UndoRedoSource } from 'vs/platform/undoRedo/common/undoRedo';
|
||||
import { LinkedList } from 'vs/base/common/linkedList';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
|
||||
class BulkEdit {
|
||||
|
||||
@@ -119,6 +121,8 @@ export class BulkEditService implements IBulkEditService {
|
||||
@IInstantiationService private readonly _instaService: IInstantiationService,
|
||||
@ILogService private readonly _logService: ILogService,
|
||||
@IEditorService private readonly _editorService: IEditorService,
|
||||
@ILifecycleService private readonly _lifecycleService: ILifecycleService,
|
||||
@IDialogService private readonly _dialogService: IDialogService
|
||||
) { }
|
||||
|
||||
setPreviewHandler(handler: IBulkEditPreviewHandler): IDisposable {
|
||||
@@ -176,9 +180,10 @@ export class BulkEditService implements IBulkEditService {
|
||||
undoRedoGroupRemove = this._activeUndoRedoGroups.push(undoRedoGroup);
|
||||
}
|
||||
|
||||
const label = options?.quotableLabel || options?.label;
|
||||
const bulkEdit = this._instaService.createInstance(
|
||||
BulkEdit,
|
||||
options?.quotableLabel || options?.label,
|
||||
label,
|
||||
codeEditor,
|
||||
options?.progress ?? Progress.None,
|
||||
options?.token ?? CancellationToken.None,
|
||||
@@ -189,7 +194,9 @@ export class BulkEditService implements IBulkEditService {
|
||||
);
|
||||
|
||||
try {
|
||||
const listener = this._lifecycleService.onBeforeShutdown(e => e.veto(this.shouldVeto(label), 'veto.blukEditService'));
|
||||
await bulkEdit.perform();
|
||||
listener.dispose();
|
||||
return { ariaSummary: bulkEdit.ariaMessage() };
|
||||
} catch (err) {
|
||||
// console.log('apply FAILED');
|
||||
@@ -200,6 +207,16 @@ export class BulkEditService implements IBulkEditService {
|
||||
undoRedoGroupRemove();
|
||||
}
|
||||
}
|
||||
|
||||
private async shouldVeto(label: string | undefined): Promise<boolean> {
|
||||
label = label || localize('fileOperation', "File operation");
|
||||
const result = await this._dialogService.confirm({
|
||||
message: localize('areYouSureQuiteBulkEdit', "Are you sure you want to quit? '{0}' is in progress.", label),
|
||||
primaryButton: localize('quit', "Quit")
|
||||
});
|
||||
|
||||
return !result.confirmed;
|
||||
}
|
||||
}
|
||||
|
||||
registerSingleton(IBulkEditService, BulkEditService, true);
|
||||
|
||||
@@ -2104,7 +2104,7 @@ CommandsRegistry.registerCommand('_resolveNotebookKernels', async (accessor, arg
|
||||
source.dispose();
|
||||
|
||||
return kernels.map(provider => ({
|
||||
id: provider.id,
|
||||
id: provider.friendlyId,
|
||||
label: provider.label,
|
||||
description: provider.description,
|
||||
detail: provider.detail,
|
||||
|
||||
@@ -33,11 +33,33 @@ registerAction2(class extends Action2 {
|
||||
title: { value: nls.localize('notebookActions.selectKernel', "Select Notebook Kernel"), original: 'Select Notebook Kernel' },
|
||||
precondition: NOTEBOOK_IS_ACTIVE_EDITOR,
|
||||
icon: selectKernelIcon,
|
||||
f1: true
|
||||
f1: true,
|
||||
description: {
|
||||
description: nls.localize('notebookActions.selectKernel.args', "Notebook Kernel Args"),
|
||||
args: [
|
||||
{
|
||||
name: 'kernelInfo',
|
||||
description: 'The kernel info',
|
||||
schema: {
|
||||
'type': 'object',
|
||||
'required': ['id', 'extension'],
|
||||
'properties': {
|
||||
'id': {
|
||||
'type': 'string'
|
||||
},
|
||||
'extension': {
|
||||
'type': 'string'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
async run(accessor: ServicesAccessor, context?: { id: string }): Promise<void> {
|
||||
async run(accessor: ServicesAccessor, context?: { id: string, extension: string }): Promise<void> {
|
||||
const editorService = accessor.get<IEditorService>(IEditorService);
|
||||
const quickInputService = accessor.get<IQuickInputService>(IQuickInputService);
|
||||
const configurationService = accessor.get<IConfigurationService>(IConfigurationService);
|
||||
@@ -64,9 +86,11 @@ registerAction2(class extends Action2 {
|
||||
const tokenSource = new CancellationTokenSource();
|
||||
const availableKernels = await editor.beginComputeContributedKernels();
|
||||
|
||||
if (availableKernels.length && availableKernels.find(kernel => kernel.id === context?.id)) {
|
||||
const selectedKernel = availableKernels.find(kernel => kernel.id === context?.id);
|
||||
const selectedKernel = availableKernels.length ? availableKernels.find(
|
||||
kernel => kernel.id && context?.id && kernel.id === context?.id && kernel.extension.value === context?.extension
|
||||
) : undefined;
|
||||
|
||||
if (selectedKernel) {
|
||||
editor.activeKernel = selectedKernel!;
|
||||
return selectedKernel!.resolve(editor.uri!, editor.getId(), tokenSource.token);
|
||||
} else {
|
||||
@@ -75,13 +99,13 @@ registerAction2(class extends Action2 {
|
||||
|
||||
const picks: QuickPickInput<IQuickPickItem & { run(): void; kernelProviderId?: string; }>[] = [...availableKernels].map((a) => {
|
||||
return {
|
||||
id: a.id,
|
||||
id: a.friendlyId,
|
||||
label: a.label,
|
||||
picked: a.id === activeKernel?.id,
|
||||
picked: a.friendlyId === activeKernel?.friendlyId,
|
||||
description:
|
||||
a.description
|
||||
? a.description
|
||||
: a.extension.value + (a.id === activeKernel?.id
|
||||
: a.extension.value + (a.friendlyId === activeKernel?.friendlyId
|
||||
? nls.localize('currentActiveKernel', " (Currently Active)")
|
||||
: ''),
|
||||
detail: a.detail,
|
||||
|
||||
@@ -175,9 +175,12 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
||||
this._activeKernelResolvePromise = undefined;
|
||||
|
||||
const memento = this._activeKernelMemento.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE);
|
||||
memento[this.viewModel.viewType] = this._activeKernel?.id;
|
||||
memento[this.viewModel.viewType] = this._activeKernel?.friendlyId;
|
||||
this._activeKernelMemento.saveMemento();
|
||||
this._onDidChangeKernel.fire();
|
||||
if (this._activeKernel) {
|
||||
this._loadKernelPreloads(this._activeKernel.extensionLocation, this._activeKernel);
|
||||
}
|
||||
}
|
||||
|
||||
private _activeKernelResolvePromise: Promise<void> | undefined = undefined;
|
||||
@@ -771,7 +774,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
||||
this.multipleKernelsAvailable = false;
|
||||
}
|
||||
|
||||
const activeKernelStillExist = [...availableKernels].find(kernel => kernel.id === this.activeKernel?.id && this.activeKernel?.id !== undefined);
|
||||
const activeKernelStillExist = [...availableKernels].find(kernel => kernel.friendlyId === this.activeKernel?.friendlyId && this.activeKernel?.friendlyId !== undefined);
|
||||
|
||||
if (activeKernelStillExist) {
|
||||
// the kernel still exist, we don't want to modify the selection otherwise user's temporary preference is lost
|
||||
@@ -797,7 +800,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
||||
const cachedKernelId = memento[provider.id];
|
||||
this.activeKernel =
|
||||
filteredKernels.find(kernel => kernel.isPreferred)
|
||||
|| filteredKernels.find(kernel => kernel.id === cachedKernelId)
|
||||
|| filteredKernels.find(kernel => kernel.friendlyId === cachedKernelId)
|
||||
|| filteredKernels[0];
|
||||
} else {
|
||||
this.activeKernel = undefined;
|
||||
@@ -818,7 +821,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
||||
}
|
||||
}
|
||||
|
||||
memento[provider.id] = this._activeKernel?.id;
|
||||
memento[provider.id] = this._activeKernel?.friendlyId;
|
||||
this._activeKernelMemento.saveMemento();
|
||||
|
||||
tokenSource.dispose();
|
||||
@@ -831,7 +834,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
||||
const cachedKernelId = memento[provider.id];
|
||||
|
||||
const preferedKernel = kernelsFromSameExtension.find(kernel => kernel.isPreferred)
|
||||
|| kernelsFromSameExtension.find(kernel => kernel.id === cachedKernelId)
|
||||
|| kernelsFromSameExtension.find(kernel => kernel.friendlyId === cachedKernelId)
|
||||
|| kernelsFromSameExtension[0];
|
||||
this.activeKernel = preferedKernel;
|
||||
if (this.activeKernel) {
|
||||
@@ -848,7 +851,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
||||
return;
|
||||
}
|
||||
|
||||
memento[provider.id] = this._activeKernel?.id;
|
||||
memento[provider.id] = this._activeKernel?.friendlyId;
|
||||
this._activeKernelMemento.saveMemento();
|
||||
tokenSource.dispose();
|
||||
return;
|
||||
@@ -1673,7 +1676,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
||||
const availableKernels = await this.beginComputeContributedKernels();
|
||||
const picks: QuickPickInput<IQuickPickItem & { run(): void; kernelProviderId?: string; }>[] = availableKernels.map((a) => {
|
||||
return {
|
||||
id: a.id,
|
||||
id: a.friendlyId,
|
||||
label: a.label,
|
||||
picked: false,
|
||||
description:
|
||||
|
||||
@@ -270,8 +270,8 @@ export class NotebookService extends Disposable implements INotebookService, ICu
|
||||
|
||||
private readonly _onDidChangeKernels = new Emitter<URI | undefined>();
|
||||
onDidChangeKernels: Event<URI | undefined> = this._onDidChangeKernels.event;
|
||||
private readonly _onDidChangeNotebookActiveKernel = new Emitter<{ uri: URI, providerHandle: number | undefined, kernelId: string | undefined; }>();
|
||||
onDidChangeNotebookActiveKernel: Event<{ uri: URI, providerHandle: number | undefined, kernelId: string | undefined; }> = this._onDidChangeNotebookActiveKernel.event;
|
||||
private readonly _onDidChangeNotebookActiveKernel = new Emitter<{ uri: URI, providerHandle: number | undefined, kernelFriendlyId: string | undefined; }>();
|
||||
onDidChangeNotebookActiveKernel: Event<{ uri: URI, providerHandle: number | undefined, kernelFriendlyId: string | undefined; }> = this._onDidChangeNotebookActiveKernel.event;
|
||||
private cutItems: NotebookCellTextModel[] | undefined;
|
||||
private _lastClipboardIsCopy: boolean = true;
|
||||
|
||||
@@ -696,9 +696,10 @@ export class NotebookService extends Disposable implements INotebookService, ICu
|
||||
const data = await provider.provideKernels(resource, token);
|
||||
result[index] = data.map(dto => {
|
||||
return {
|
||||
id: dto.id,
|
||||
extension: dto.extension,
|
||||
extensionLocation: URI.revive(dto.extensionLocation),
|
||||
id: dto.id,
|
||||
friendlyId: dto.friendlyId,
|
||||
label: dto.label,
|
||||
description: dto.description,
|
||||
detail: dto.detail,
|
||||
@@ -706,13 +707,13 @@ export class NotebookService extends Disposable implements INotebookService, ICu
|
||||
preloads: dto.preloads,
|
||||
providerHandle: dto.providerHandle,
|
||||
resolve: async (uri: URI, editorId: string, token: CancellationToken) => {
|
||||
return provider.resolveKernel(editorId, uri, dto.id, token);
|
||||
return provider.resolveKernel(editorId, uri, dto.friendlyId, token);
|
||||
},
|
||||
executeNotebookCell: async (uri: URI, handle: number | undefined) => {
|
||||
return provider.executeNotebook(uri, dto.id, handle);
|
||||
return provider.executeNotebook(uri, dto.friendlyId, handle);
|
||||
},
|
||||
cancelNotebookCell: (uri: URI, handle: number | undefined): Promise<void> => {
|
||||
return provider.cancelNotebook(uri, dto.id, handle);
|
||||
return provider.cancelNotebook(uri, dto.friendlyId, handle);
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -922,7 +923,7 @@ export class NotebookService extends Disposable implements INotebookService, ICu
|
||||
this._onDidChangeNotebookActiveKernel.fire({
|
||||
uri: editor.uri!,
|
||||
providerHandle: editor.activeKernel?.providerHandle,
|
||||
kernelId: editor.activeKernel?.id
|
||||
kernelFriendlyId: editor.activeKernel?.friendlyId
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -143,8 +143,11 @@ export class StatefulMarkdownCell extends Disposable {
|
||||
// active cell and no run status
|
||||
if (this._activeCellRunPlaceholder === null) {
|
||||
// const keybinding = this._keybindingService.lookupKeybinding(EXECUTE_CELL_COMMAND_ID);
|
||||
this._activeCellRunPlaceholder = this.notebookCellStatusBarService.addEntry(getExecuteCellPlaceholder(this.viewCell));
|
||||
this._register(this._activeCellRunPlaceholder);
|
||||
const placeholder = getExecuteCellPlaceholder(this.viewCell);
|
||||
if (!this.notebookCellStatusBarService.getEntries(this.viewCell.uri).find(entry => entry.text === placeholder.text && entry.command === placeholder.command)) {
|
||||
this._activeCellRunPlaceholder = this.notebookCellStatusBarService.addEntry(placeholder);
|
||||
this._register(this._activeCellRunPlaceholder);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -334,8 +337,9 @@ export class StatefulMarkdownCell extends Disposable {
|
||||
}
|
||||
);
|
||||
|
||||
this.viewCell.editorHeight = realContentHeight;
|
||||
this.relayoutCell();
|
||||
// LET the content size observer to handle it
|
||||
// this.viewCell.editorHeight = realContentHeight;
|
||||
// this.relayoutCell();
|
||||
}
|
||||
|
||||
private relayoutCell(): void {
|
||||
|
||||
@@ -787,7 +787,8 @@ export function notebookDocumentFilterMatch(filter: INotebookDocumentFilter, vie
|
||||
}
|
||||
|
||||
export interface INotebookKernelInfoDto2 {
|
||||
id: string;
|
||||
id?: string;
|
||||
friendlyId: string;
|
||||
label: string;
|
||||
extension: ExtensionIdentifier;
|
||||
extensionLocation: URI;
|
||||
|
||||
@@ -46,7 +46,7 @@ export interface INotebookService {
|
||||
onDidAddNotebookDocument: Event<NotebookTextModel>;
|
||||
onNotebookDocumentSaved: Event<URI>;
|
||||
onDidChangeKernels: Event<URI | undefined>;
|
||||
onDidChangeNotebookActiveKernel: Event<{ uri: URI, providerHandle: number | undefined, kernelId: string | undefined; }>;
|
||||
onDidChangeNotebookActiveKernel: Event<{ uri: URI, providerHandle: number | undefined, kernelFriendlyId: string | undefined; }>;
|
||||
registerNotebookController(viewType: string, extensionData: NotebookExtensionDescription, controller: IMainNotebookController): IDisposable;
|
||||
|
||||
getMimeTypeInfo(textModel: NotebookTextModel, output: ITransformedDisplayOutputDto): readonly IOrderedMimeType[];
|
||||
|
||||
@@ -18,7 +18,8 @@ import { ContextScopedHistoryInputBox } from 'vs/platform/browser/contextScopedH
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import type { IThemable } from 'vs/base/common/styler';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ISearchConfiguration } from 'vs/workbench/services/search/common/search';
|
||||
export interface IOptions {
|
||||
placeholder?: string;
|
||||
width?: number;
|
||||
@@ -50,7 +51,8 @@ export class PatternInputWidget extends Widget implements IThemable {
|
||||
|
||||
constructor(parent: HTMLElement, private contextViewProvider: IContextViewProvider, options: IOptions = Object.create(null),
|
||||
@IThemeService protected themeService: IThemeService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IConfigurationService protected readonly configurationService: IConfigurationService
|
||||
) {
|
||||
super();
|
||||
this.width = options.width || 100;
|
||||
@@ -178,6 +180,62 @@ export class PatternInputWidget extends Widget implements IThemable {
|
||||
}
|
||||
}
|
||||
|
||||
export class IncludePatternInputWidget extends PatternInputWidget {
|
||||
|
||||
private _onChangeSearchInEditorsBoxEmitter = this._register(new Emitter<void>());
|
||||
onChangeSearchInEditorsBox = this._onChangeSearchInEditorsBoxEmitter.event;
|
||||
|
||||
constructor(parent: HTMLElement, contextViewProvider: IContextViewProvider, options: IOptions = Object.create(null),
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
) {
|
||||
super(parent, contextViewProvider, options, themeService, contextKeyService, configurationService);
|
||||
}
|
||||
|
||||
private useSearchInEditorsBox!: Checkbox;
|
||||
|
||||
dispose(): void {
|
||||
super.dispose();
|
||||
this.useSearchInEditorsBox.dispose();
|
||||
}
|
||||
|
||||
onlySearchInOpenEditors(): boolean {
|
||||
return this.useSearchInEditorsBox.checked;
|
||||
}
|
||||
|
||||
setOnlySearchInOpenEditors(value: boolean) {
|
||||
this.useSearchInEditorsBox.checked = value;
|
||||
}
|
||||
|
||||
protected getSubcontrolsWidth(): number {
|
||||
if (this.configurationService.getValue<ISearchConfiguration>().search?.experimental?.searchInOpenEditors) {
|
||||
return super.getSubcontrolsWidth() + this.useSearchInEditorsBox.width();
|
||||
}
|
||||
return super.getSubcontrolsWidth();
|
||||
}
|
||||
|
||||
protected renderSubcontrols(controlsDiv: HTMLDivElement): void {
|
||||
this.useSearchInEditorsBox = this._register(new Checkbox({
|
||||
icon: Codicon.book,
|
||||
title: nls.localize('onlySearchInOpenEditors', "Search only in Open Editors"),
|
||||
isChecked: false,
|
||||
}));
|
||||
if (!this.configurationService.getValue<ISearchConfiguration>().search?.experimental?.searchInOpenEditors) {
|
||||
return;
|
||||
}
|
||||
this._register(this.useSearchInEditorsBox.onChange(viaKeyboard => {
|
||||
this._onChangeSearchInEditorsBoxEmitter.fire();
|
||||
if (!viaKeyboard) {
|
||||
this.inputBox.focus();
|
||||
}
|
||||
}));
|
||||
this._register(attachCheckboxStyler(this.useSearchInEditorsBox, this.themeService));
|
||||
controlsDiv.appendChild(this.useSearchInEditorsBox.domNode);
|
||||
super.renderSubcontrols(controlsDiv);
|
||||
}
|
||||
}
|
||||
|
||||
export class ExcludePatternInputWidget extends PatternInputWidget {
|
||||
|
||||
private _onChangeIgnoreBoxEmitter = this._register(new Emitter<void>());
|
||||
@@ -185,9 +243,10 @@ export class ExcludePatternInputWidget extends PatternInputWidget {
|
||||
|
||||
constructor(parent: HTMLElement, contextViewProvider: IContextViewProvider, options: IOptions = Object.create(null),
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
) {
|
||||
super(parent, contextViewProvider, options, themeService, contextKeyService);
|
||||
super(parent, contextViewProvider, options, themeService, contextKeyService, configurationService);
|
||||
}
|
||||
|
||||
private useExcludesAndIgnoreFilesBox!: Checkbox;
|
||||
|
||||
@@ -24,6 +24,7 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { IListService, WorkbenchListFocusContextKey, WorkbenchObjectTree } from 'vs/platform/list/browser/listService';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import { Extensions as QuickAccessExtensions, IQuickAccessRegistry } from 'vs/platform/quickinput/common/quickAccess';
|
||||
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
@@ -998,6 +999,11 @@ configurationRegistry.registerConfiguration({
|
||||
],
|
||||
'description': nls.localize('search.sortOrder', "Controls sorting order of search results.")
|
||||
},
|
||||
'search.experimental.searchInOpenEditors': {
|
||||
type: 'boolean',
|
||||
default: product.quality !== 'stable',
|
||||
markdownDescription: nls.localize('search.experimental.searchInOpenEditors', "Experimental. When enabled, an option is provided to make workspace search only search files that have been opened. **Requires restart to take effect.**")
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ import { IViewPaneOptions, ViewPane } from 'vs/workbench/browser/parts/views/vie
|
||||
import { IEditorPane } from 'vs/workbench/common/editor';
|
||||
import { Memento, MementoObject } from 'vs/workbench/common/memento';
|
||||
import { IViewDescriptorService } from 'vs/workbench/common/views';
|
||||
import { ExcludePatternInputWidget, PatternInputWidget } from 'vs/workbench/contrib/search/browser/patternInputWidget';
|
||||
import { ExcludePatternInputWidget, IncludePatternInputWidget } from 'vs/workbench/contrib/search/browser/patternInputWidget';
|
||||
import { appendKeyBindingLabel, IFindInFilesArgs } from 'vs/workbench/contrib/search/browser/searchActions';
|
||||
import { searchDetailsIcon } from 'vs/workbench/contrib/search/browser/searchIcons';
|
||||
import { FileMatchRenderer, FolderMatchRenderer, MatchRenderer, SearchAccessibilityProvider, SearchDelegate, SearchDND } from 'vs/workbench/contrib/search/browser/searchResultsView';
|
||||
@@ -125,7 +125,7 @@ export class SearchView extends ViewPane {
|
||||
private queryDetails!: HTMLElement;
|
||||
private toggleQueryDetailsButton!: HTMLElement;
|
||||
private inputPatternExcludes!: ExcludePatternInputWidget;
|
||||
private inputPatternIncludes!: PatternInputWidget;
|
||||
private inputPatternIncludes!: IncludePatternInputWidget;
|
||||
private resultsElement!: HTMLElement;
|
||||
|
||||
private currentSelectedFileMatch: FileMatch | undefined;
|
||||
@@ -309,14 +309,17 @@ export class SearchView extends ViewPane {
|
||||
const filesToIncludeTitle = nls.localize('searchScope.includes', "files to include");
|
||||
dom.append(folderIncludesList, $('h4', undefined, filesToIncludeTitle));
|
||||
|
||||
this.inputPatternIncludes = this._register(this.instantiationService.createInstance(PatternInputWidget, folderIncludesList, this.contextViewService, {
|
||||
this.inputPatternIncludes = this._register(this.instantiationService.createInstance(IncludePatternInputWidget, folderIncludesList, this.contextViewService, {
|
||||
ariaLabel: nls.localize('label.includes', 'Search Include Patterns'),
|
||||
history: patternIncludesHistory,
|
||||
}));
|
||||
|
||||
this.inputPatternIncludes.setValue(patternIncludes);
|
||||
|
||||
this._register(this.inputPatternIncludes.onSubmit(triggeredOnType => this.triggerQueryChange({ triggeredOnType, delay: this.searchConfig.searchOnTypeDebouncePeriod })));
|
||||
this._register(this.inputPatternIncludes.onCancel(() => this.cancelSearch(false)));
|
||||
this._register(this.inputPatternIncludes.onChangeSearchInEditorsBox(() => this.triggerQueryChange()));
|
||||
|
||||
this.trackInputBox(this.inputPatternIncludes.inputFocusTracker, this.inputPatternIncludesFocused);
|
||||
|
||||
// excludes list
|
||||
@@ -385,7 +388,7 @@ export class SearchView extends ViewPane {
|
||||
return this.searchWidget;
|
||||
}
|
||||
|
||||
get searchIncludePattern(): PatternInputWidget {
|
||||
get searchIncludePattern(): IncludePatternInputWidget {
|
||||
return this.inputPatternIncludes;
|
||||
}
|
||||
|
||||
@@ -1293,6 +1296,7 @@ export class SearchView extends ViewPane {
|
||||
const excludePatternText = this.inputPatternExcludes.getValue().trim();
|
||||
const includePatternText = this.inputPatternIncludes.getValue().trim();
|
||||
const useExcludesAndIgnoreFiles = this.inputPatternExcludes.useExcludesAndIgnoreFiles();
|
||||
const onlySearchInOpenEditors = this.inputPatternIncludes.onlySearchInOpenEditors();
|
||||
|
||||
if (contentPattern.length === 0) {
|
||||
this.clearSearchResults(false);
|
||||
@@ -1321,6 +1325,7 @@ export class SearchView extends ViewPane {
|
||||
maxResults: SearchView.MAX_TEXT_RESULTS,
|
||||
disregardIgnoreFiles: !useExcludesAndIgnoreFiles || undefined,
|
||||
disregardExcludeSettings: !useExcludesAndIgnoreFiles || undefined,
|
||||
onlyOpenEditors: onlySearchInOpenEditors,
|
||||
excludePattern,
|
||||
includePattern,
|
||||
previewOptions: {
|
||||
@@ -1443,14 +1448,26 @@ export class SearchView extends ViewPane {
|
||||
|
||||
if (!completed) {
|
||||
message = SEARCH_CANCELLED_MESSAGE;
|
||||
} else if (hasIncludes && hasExcludes) {
|
||||
message = nls.localize('noResultsIncludesExcludes', "No results found in '{0}' excluding '{1}' - ", includePatternText, excludePatternText);
|
||||
} else if (hasIncludes) {
|
||||
message = nls.localize('noResultsIncludes', "No results found in '{0}' - ", includePatternText);
|
||||
} else if (hasExcludes) {
|
||||
message = nls.localize('noResultsExcludes', "No results found excluding '{0}' - ", excludePatternText);
|
||||
} else if (this.inputPatternIncludes.onlySearchInOpenEditors()) {
|
||||
if (hasIncludes && hasExcludes) {
|
||||
message = nls.localize('noOpenEditorResultsIncludesExcludes', "No results found in open editors matching '{0}' excluding '{1}' - ", includePatternText, excludePatternText);
|
||||
} else if (hasIncludes) {
|
||||
message = nls.localize('noOpenEditorResultsIncludes', "No results found in open editors matching '{0}' - ", includePatternText);
|
||||
} else if (hasExcludes) {
|
||||
message = nls.localize('noOpenEditorResultsExcludes', "No results found in open editors excluding '{0}' - ", excludePatternText);
|
||||
} else {
|
||||
message = nls.localize('noOpenEditorResultsFound', "No results found in open editors. Review your settings for configured exclusions and check your gitignore files - ");
|
||||
}
|
||||
} else {
|
||||
message = nls.localize('noResultsFound', "No results found. Review your settings for configured exclusions and check your gitignore files - ");
|
||||
if (hasIncludes && hasExcludes) {
|
||||
message = nls.localize('noResultsIncludesExcludes', "No results found in '{0}' excluding '{1}' - ", includePatternText, excludePatternText);
|
||||
} else if (hasIncludes) {
|
||||
message = nls.localize('noResultsIncludes', "No results found in '{0}' - ", includePatternText);
|
||||
} else if (hasExcludes) {
|
||||
message = nls.localize('noResultsExcludes', "No results found excluding '{0}' - ", excludePatternText);
|
||||
} else {
|
||||
message = nls.localize('noResultsFound', "No results found. Review your settings for configured exclusions and check your gitignore files - ");
|
||||
}
|
||||
}
|
||||
|
||||
// Indicate as status to ARIA
|
||||
@@ -1472,6 +1489,7 @@ export class SearchView extends ViewPane {
|
||||
|
||||
this.inputPatternExcludes.setValue('');
|
||||
this.inputPatternIncludes.setValue('');
|
||||
this.inputPatternIncludes.setOnlySearchInOpenEditors(false);
|
||||
|
||||
this.triggerQueryChange({ preserveFocus: false });
|
||||
}));
|
||||
@@ -1599,7 +1617,7 @@ export class SearchView extends ViewPane {
|
||||
|
||||
this.messageDisposables.push(dom.addDisposableListener(openInEditorLink, dom.EventType.CLICK, (e: MouseEvent) => {
|
||||
dom.EventHelper.stop(e, false);
|
||||
this.instantiationService.invokeFunction(createEditorFromSearchResult, this.searchResult, this.searchIncludePattern.getValue(), this.searchExcludePattern.getValue());
|
||||
this.instantiationService.invokeFunction(createEditorFromSearchResult, this.searchResult, this.searchIncludePattern.getValue(), this.searchExcludePattern.getValue(), this.searchIncludePattern.onlySearchInOpenEditors());
|
||||
}));
|
||||
|
||||
this.reLayout();
|
||||
|
||||
@@ -16,6 +16,7 @@ import { isMultilineRegexSource } from 'vs/editor/common/model/textModelSearch';
|
||||
import * as nls from 'vs/nls';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IWorkspaceContextService, IWorkspaceFolderData, toWorkspaceFolder, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IPathService } from 'vs/workbench/services/path/common/pathService';
|
||||
import { getExcludes, ICommonQueryProps, IFileQuery, IFolderQuery, IPatternInfo, ISearchConfiguration, ITextQuery, ITextSearchPreviewOptions, pathIncludedInQuery, QueryType } from 'vs/workbench/services/search/common/search';
|
||||
|
||||
@@ -59,6 +60,7 @@ export interface ICommonQueryBuilderOptions {
|
||||
disregardExcludeSettings?: boolean;
|
||||
disregardSearchExcludeSettings?: boolean;
|
||||
ignoreSymlinks?: boolean;
|
||||
onlyOpenEditors?: boolean;
|
||||
}
|
||||
|
||||
export interface IFileQueryBuilderOptions extends ICommonQueryBuilderOptions {
|
||||
@@ -81,6 +83,7 @@ export class QueryBuilder {
|
||||
constructor(
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService,
|
||||
@IEditorGroupsService private readonly editorGroupsService: IEditorGroupsService,
|
||||
@IPathService private readonly pathService: IPathService
|
||||
) {
|
||||
}
|
||||
@@ -148,20 +151,21 @@ export class QueryBuilder {
|
||||
};
|
||||
}
|
||||
|
||||
private handleIncludeExclude(pattern: string | string[] | undefined, expandPatterns: boolean | undefined): ISearchPathsInfo {
|
||||
private handleIncludeExclude(pattern: string | string[] | undefined, expandPatterns: 'strict' | 'loose' | 'none'): ISearchPathsInfo {
|
||||
if (!pattern) {
|
||||
return {};
|
||||
}
|
||||
|
||||
pattern = Array.isArray(pattern) ? pattern.map(normalizeSlashes) : normalizeSlashes(pattern);
|
||||
return expandPatterns ?
|
||||
this.parseSearchPaths(pattern) :
|
||||
{ pattern: patternListToIExpression(...(Array.isArray(pattern) ? pattern : [pattern])) };
|
||||
return expandPatterns === 'none' ?
|
||||
{ pattern: patternListToIExpression(...(Array.isArray(pattern) ? pattern : [pattern])) } :
|
||||
this.parseSearchPaths(pattern, expandPatterns === 'strict');
|
||||
}
|
||||
|
||||
private commonQuery(folderResources: (IWorkspaceFolderData | URI)[] = [], options: ICommonQueryBuilderOptions = {}): ICommonQueryProps<uri> {
|
||||
const includeSearchPathsInfo: ISearchPathsInfo = this.handleIncludeExclude(options.includePattern, options.expandPatterns);
|
||||
const excludeSearchPathsInfo: ISearchPathsInfo = this.handleIncludeExclude(options.excludePattern, options.expandPatterns);
|
||||
private commonQuery(folderResources: (IWorkspaceFolderData | URI)[] = [], options: ICommonQueryBuilderOptions = {}, strictPatterns?: boolean): ICommonQueryProps<uri> {
|
||||
const patternExpansionMode = strictPatterns ? 'strict' : options.expandPatterns ? 'loose' : 'none';
|
||||
const includeSearchPathsInfo: ISearchPathsInfo = this.handleIncludeExclude(options.includePattern, patternExpansionMode);
|
||||
const excludeSearchPathsInfo: ISearchPathsInfo = this.handleIncludeExclude(options.excludePattern, patternExpansionMode);
|
||||
|
||||
// Build folderQueries from searchPaths, if given, otherwise folderResources
|
||||
const includeFolderName = folderResources.length > 1;
|
||||
@@ -178,9 +182,35 @@ export class QueryBuilder {
|
||||
|
||||
excludePattern: excludeSearchPathsInfo.pattern,
|
||||
includePattern: includeSearchPathsInfo.pattern,
|
||||
onlyOpenEditors: options.onlyOpenEditors,
|
||||
maxResults: options.maxResults
|
||||
};
|
||||
|
||||
// When "onlyOpenEditors" is enabled, filter all opened editors by the existing include/exclude patterns,
|
||||
// then rerun the query build setting the includes to those remaining editors
|
||||
if (options.onlyOpenEditors) {
|
||||
const openEditors = arrays.coalesce(arrays.flatten(this.editorGroupsService.groups.map(group => group.editors.map(editor => editor.resource))));
|
||||
const openEditorsInQuery = openEditors.filter(editor => pathIncludedInQuery(queryProps, editor.fsPath));
|
||||
const openEditorIncludes = openEditorsInQuery.map(editor => {
|
||||
const workspace = this.workspaceContextService.getWorkspaceFolder(editor);
|
||||
if (workspace) {
|
||||
const relPath = path.relative(workspace?.uri.fsPath, editor.fsPath);
|
||||
return includeFolderName ? `./${workspace.name}/${relPath}` : `${relPath}`;
|
||||
}
|
||||
else {
|
||||
return editor.fsPath.replace(/^\//, '');
|
||||
}
|
||||
});
|
||||
return this.commonQuery(folderResources, {
|
||||
...options,
|
||||
onlyOpenEditors: false,
|
||||
includePattern: openEditorIncludes,
|
||||
excludePattern: openEditorIncludes.length
|
||||
? options.excludePattern
|
||||
: '**/*' // when there are no included editors, explicitly exclude all other files
|
||||
}, true);
|
||||
}
|
||||
|
||||
// Filter extraFileResources against global include/exclude patterns - they are already expected to not belong to a workspace
|
||||
const extraFileResources = options.extraFileResources && options.extraFileResources.filter(extraFile => pathIncludedInQuery(queryProps, extraFile.fsPath));
|
||||
queryProps.extraFileResources = extraFileResources && extraFileResources.length ? extraFileResources : undefined;
|
||||
@@ -224,11 +254,11 @@ export class QueryBuilder {
|
||||
|
||||
/**
|
||||
* Take the includePattern as seen in the search viewlet, and split into components that look like searchPaths, and
|
||||
* glob patterns. Glob patterns are expanded from 'foo/bar' to '{foo/bar/**, **\/foo/bar}.
|
||||
* glob patterns. When `strictPatterns` is false, patterns are expanded from 'foo/bar' to '{foo/bar/**, **\/foo/bar}.
|
||||
*
|
||||
* Public for test.
|
||||
*/
|
||||
parseSearchPaths(pattern: string | string[]): ISearchPathsInfo {
|
||||
parseSearchPaths(pattern: string | string[], strictPatterns = false): ISearchPathsInfo {
|
||||
const isSearchPath = (segment: string) => {
|
||||
// A segment is a search path if it is an absolute path or starts with ./, ../, .\, or ..\
|
||||
return path.isAbsolute(segment) || /^\.\.?([\/\\]|$)/.test(segment);
|
||||
@@ -251,15 +281,15 @@ export class QueryBuilder {
|
||||
.map(s => strings.rtrim(s, '/'))
|
||||
.map(s => strings.rtrim(s, '\\'))
|
||||
.map(p => {
|
||||
if (p[0] === '.') {
|
||||
if (!strictPatterns && p[0] === '.') {
|
||||
p = '*' + p; // convert ".js" to "*.js"
|
||||
}
|
||||
|
||||
return expandGlobalGlob(p);
|
||||
return strictPatterns ? [p] : expandGlobalGlob(p);
|
||||
});
|
||||
|
||||
const result: ISearchPathsInfo = {};
|
||||
const searchPaths = this.expandSearchPathPatterns(groups.searchPaths || []);
|
||||
const searchPaths = this.expandSearchPathPatterns(groups.searchPaths || [], strictPatterns);
|
||||
if (searchPaths && searchPaths.length) {
|
||||
result.searchPaths = searchPaths;
|
||||
}
|
||||
@@ -282,7 +312,7 @@ export class QueryBuilder {
|
||||
/**
|
||||
* Split search paths (./ or ../ or absolute paths in the includePatterns) into absolute paths and globs applied to those paths
|
||||
*/
|
||||
private expandSearchPathPatterns(searchPaths: string[]): ISearchPathPattern[] {
|
||||
private expandSearchPathPatterns(searchPaths: string[], strictPatterns: boolean): ISearchPathPattern[] {
|
||||
if (!searchPaths || !searchPaths.length) {
|
||||
// No workspace => ignore search paths
|
||||
return [];
|
||||
@@ -302,7 +332,7 @@ export class QueryBuilder {
|
||||
|
||||
// Expanded search paths to multiple resolved patterns (with ** and without)
|
||||
return arrays.flatten(
|
||||
oneExpanded.map(oneExpandedResult => this.resolveOneSearchPathPattern(oneExpandedResult, globPortion)));
|
||||
oneExpanded.map(oneExpandedResult => this.resolveOneSearchPathPattern(oneExpandedResult, globPortion, strictPatterns)));
|
||||
}));
|
||||
|
||||
const searchPathPatternMap = new Map<string, ISearchPathPattern>();
|
||||
@@ -388,7 +418,7 @@ export class QueryBuilder {
|
||||
return [];
|
||||
}
|
||||
|
||||
private resolveOneSearchPathPattern(oneExpandedResult: IOneSearchPathPattern, globPortion?: string): IOneSearchPathPattern[] {
|
||||
private resolveOneSearchPathPattern(oneExpandedResult: IOneSearchPathPattern, globPortion: string | undefined, strictPatterns: boolean): IOneSearchPathPattern[] {
|
||||
const pattern = oneExpandedResult.pattern && globPortion ?
|
||||
`${oneExpandedResult.pattern}/${globPortion}` :
|
||||
oneExpandedResult.pattern || globPortion;
|
||||
@@ -399,7 +429,7 @@ export class QueryBuilder {
|
||||
pattern
|
||||
}];
|
||||
|
||||
if (pattern && !pattern.endsWith('**')) {
|
||||
if (!strictPatterns && pattern && !pattern.endsWith('**')) {
|
||||
results.push({
|
||||
searchPath: oneExpandedResult.searchPath,
|
||||
pattern: pattern + '/**'
|
||||
|
||||
@@ -571,15 +571,42 @@ suite('QueryBuilder', () => {
|
||||
].forEach(([includePattern, expectedPatterns]) => testSimpleIncludes(<string>includePattern, <string[]>expectedPatterns));
|
||||
});
|
||||
|
||||
function testIncludes(includePattern: string, expectedResult: ISearchPathsInfo): void {
|
||||
test('strict includes', () => {
|
||||
function testSimpleIncludes(includePattern: string, expectedPatterns: string[]): void {
|
||||
assert.deepEqual(
|
||||
queryBuilder.parseSearchPaths(includePattern, true),
|
||||
{
|
||||
pattern: patternsToIExpression(...expectedPatterns)
|
||||
},
|
||||
includePattern);
|
||||
}
|
||||
|
||||
[
|
||||
['a', ['a']],
|
||||
['a/b', ['a/b']],
|
||||
['a/b, c', ['a/b', 'c']],
|
||||
['a,.txt', ['a', '.txt']],
|
||||
['a,,,b', ['a', 'b']],
|
||||
['**/a,b/**', ['**/a', 'b/**']]
|
||||
].forEach(([includePattern, expectedPatterns]) => testSimpleIncludes(<string>includePattern, <string[]>expectedPatterns));
|
||||
});
|
||||
|
||||
function testIncludes(includePattern: string, expectedResultLoose: ISearchPathsInfo, expectedResultStrict?: ISearchPathsInfo): void {
|
||||
assertEqualSearchPathResults(
|
||||
queryBuilder.parseSearchPaths(includePattern),
|
||||
expectedResult,
|
||||
expectedResultLoose,
|
||||
includePattern);
|
||||
|
||||
if (expectedResultStrict) {
|
||||
assertEqualSearchPathResults(
|
||||
queryBuilder.parseSearchPaths(includePattern, true),
|
||||
expectedResultStrict,
|
||||
includePattern);
|
||||
}
|
||||
}
|
||||
|
||||
function testIncludesDataItem([includePattern, expectedResult]: [string, ISearchPathsInfo]): void {
|
||||
testIncludes(includePattern, expectedResult);
|
||||
function testIncludesDataItem([includePattern, expectedResultLoose, expectedResultStrict]: [string, ISearchPathsInfo, ISearchPathsInfo] | [string, ISearchPathsInfo]): void {
|
||||
testIncludes(includePattern, expectedResultLoose, expectedResultStrict);
|
||||
}
|
||||
|
||||
test('absolute includes', () => {
|
||||
@@ -652,7 +679,7 @@ suite('QueryBuilder', () => {
|
||||
});
|
||||
|
||||
test('relative includes w/single root folder', () => {
|
||||
const cases: [string, ISearchPathsInfo][] = [
|
||||
const cases: ([string, ISearchPathsInfo] | [string, ISearchPathsInfo, ISearchPathsInfo])[] = [
|
||||
[
|
||||
'./a',
|
||||
{
|
||||
@@ -660,6 +687,12 @@ suite('QueryBuilder', () => {
|
||||
searchPath: ROOT_1_URI,
|
||||
pattern: patternsToIExpression('a', 'a/**')
|
||||
}]
|
||||
},
|
||||
{
|
||||
searchPaths: [{
|
||||
searchPath: ROOT_1_URI,
|
||||
pattern: patternsToIExpression('a')
|
||||
}]
|
||||
}
|
||||
],
|
||||
[
|
||||
@@ -669,6 +702,12 @@ suite('QueryBuilder', () => {
|
||||
searchPath: ROOT_1_URI,
|
||||
pattern: patternsToIExpression('a', 'a/**')
|
||||
}]
|
||||
},
|
||||
{
|
||||
searchPaths: [{
|
||||
searchPath: ROOT_1_URI,
|
||||
pattern: patternsToIExpression('a')
|
||||
}]
|
||||
}
|
||||
],
|
||||
[
|
||||
@@ -700,6 +739,12 @@ suite('QueryBuilder', () => {
|
||||
searchPath: ROOT_1_URI,
|
||||
pattern: patternsToIExpression('a/b', 'a/b/**', 'c/d', 'c/d/**')
|
||||
}]
|
||||
},
|
||||
{
|
||||
searchPaths: [{
|
||||
searchPath: ROOT_1_URI,
|
||||
pattern: patternsToIExpression('a/b', 'c/d',)
|
||||
}]
|
||||
}
|
||||
],
|
||||
[
|
||||
@@ -735,9 +780,14 @@ suite('QueryBuilder', () => {
|
||||
mockWorkspace.folders = toWorkspaceFolders([{ path: ROOT_1_URI.fsPath }, { path: getUri(ROOT_2).fsPath }], WS_CONFIG_PATH, extUriBiasedIgnorePathCase);
|
||||
mockWorkspace.configuration = uri.file(fixPath('config'));
|
||||
|
||||
const cases: [string, ISearchPathsInfo][] = [
|
||||
const cases: ([string, ISearchPathsInfo] | [string, ISearchPathsInfo, ISearchPathsInfo])[] = [
|
||||
[
|
||||
'./root1',
|
||||
{
|
||||
searchPaths: [{
|
||||
searchPath: getUri(ROOT_1)
|
||||
}]
|
||||
},
|
||||
{
|
||||
searchPaths: [{
|
||||
searchPath: getUri(ROOT_1)
|
||||
@@ -750,6 +800,36 @@ suite('QueryBuilder', () => {
|
||||
searchPaths: [{
|
||||
searchPath: getUri(ROOT_2),
|
||||
}]
|
||||
},
|
||||
{
|
||||
searchPaths: [{
|
||||
searchPath: getUri(ROOT_2),
|
||||
}]
|
||||
}
|
||||
],
|
||||
[
|
||||
'./root1/a/b, ./root2/a.txt',
|
||||
{
|
||||
searchPaths: [
|
||||
{
|
||||
searchPath: ROOT_1_URI,
|
||||
pattern: patternsToIExpression('a/b', 'a/b/**')
|
||||
},
|
||||
{
|
||||
searchPath: getUri(ROOT_2),
|
||||
pattern: patternsToIExpression('a.txt', 'a.txt/**')
|
||||
}]
|
||||
},
|
||||
{
|
||||
searchPaths: [
|
||||
{
|
||||
searchPath: ROOT_1_URI,
|
||||
pattern: patternsToIExpression('a/b')
|
||||
},
|
||||
{
|
||||
searchPath: getUri(ROOT_2),
|
||||
pattern: patternsToIExpression('a.txt')
|
||||
}]
|
||||
}
|
||||
],
|
||||
[
|
||||
@@ -776,7 +856,7 @@ suite('QueryBuilder', () => {
|
||||
mockWorkspace.folders = toWorkspaceFolders([{ path: ROOT_1_URI.fsPath, name: ROOT_1_FOLDERNAME }, { path: getUri(ROOT_2).fsPath }], WS_CONFIG_PATH, extUriBiasedIgnorePathCase);
|
||||
mockWorkspace.configuration = uri.file(fixPath('config'));
|
||||
|
||||
const cases: [string, ISearchPathsInfo][] = [
|
||||
const cases: ([string, ISearchPathsInfo] | [string, ISearchPathsInfo, ISearchPathsInfo])[] = [
|
||||
[
|
||||
'./foldername',
|
||||
{
|
||||
@@ -792,6 +872,12 @@ suite('QueryBuilder', () => {
|
||||
searchPath: ROOT_1_URI,
|
||||
pattern: patternsToIExpression('foo', 'foo/**')
|
||||
}]
|
||||
},
|
||||
{
|
||||
searchPaths: [{
|
||||
searchPath: ROOT_1_URI,
|
||||
pattern: patternsToIExpression('foo', 'foo')
|
||||
}]
|
||||
}
|
||||
]
|
||||
];
|
||||
@@ -804,7 +890,7 @@ suite('QueryBuilder', () => {
|
||||
mockWorkspace.folders = toWorkspaceFolders([{ path: ROOT_1_URI.fsPath }, { path: getUri(ROOT_2).fsPath }, { path: getUri(ROOT_3).fsPath }], WS_CONFIG_PATH, extUriBiasedIgnorePathCase);
|
||||
mockWorkspace.configuration = uri.file(fixPath('/config'));
|
||||
|
||||
const cases: [string, ISearchPathsInfo][] = [
|
||||
const cases: ([string, ISearchPathsInfo] | [string, ISearchPathsInfo, ISearchPathsInfo])[] = [
|
||||
[
|
||||
'',
|
||||
{
|
||||
@@ -819,6 +905,11 @@ suite('QueryBuilder', () => {
|
||||
],
|
||||
[
|
||||
'./root1',
|
||||
{
|
||||
searchPaths: [{
|
||||
searchPath: getUri(ROOT_1)
|
||||
}]
|
||||
},
|
||||
{
|
||||
searchPaths: [{
|
||||
searchPath: getUri(ROOT_1)
|
||||
|
||||
@@ -318,7 +318,7 @@ registerAction2(class extends Action2 {
|
||||
const instantiationService = accessor.get(IInstantiationService);
|
||||
const searchView = getSearchView(viewsService);
|
||||
if (searchView) {
|
||||
await instantiationService.invokeFunction(createEditorFromSearchResult, searchView.searchResult, searchView.searchIncludePattern.getValue(), searchView.searchExcludePattern.getValue());
|
||||
await instantiationService.invokeFunction(createEditorFromSearchResult, searchView.searchResult, searchView.searchIncludePattern.getValue(), searchView.searchExcludePattern.getValue(), searchView.searchIncludePattern.onlySearchInOpenEditors());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -38,7 +38,7 @@ import { IThemeService, registerThemingParticipant, ThemeIcon } from 'vs/platfor
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { BaseTextEditor } from 'vs/workbench/browser/parts/editor/textEditor';
|
||||
import { EditorOptions, IEditorOpenContext } from 'vs/workbench/common/editor';
|
||||
import { ExcludePatternInputWidget, PatternInputWidget } from 'vs/workbench/contrib/search/browser/patternInputWidget';
|
||||
import { ExcludePatternInputWidget, IncludePatternInputWidget } from 'vs/workbench/contrib/search/browser/patternInputWidget';
|
||||
import { SearchWidget } from 'vs/workbench/contrib/search/browser/searchWidget';
|
||||
import { InputBoxFocusedKey } from 'vs/workbench/contrib/search/common/constants';
|
||||
import { ITextQueryBuilderOptions, QueryBuilder } from 'vs/workbench/contrib/search/common/queryBuilder';
|
||||
@@ -67,7 +67,7 @@ export class SearchEditor extends BaseTextEditor {
|
||||
private searchResultEditor!: CodeEditorWidget;
|
||||
private queryEditorContainer!: HTMLElement;
|
||||
private dimension?: DOM.Dimension;
|
||||
private inputPatternIncludes!: PatternInputWidget;
|
||||
private inputPatternIncludes!: IncludePatternInputWidget;
|
||||
private inputPatternExcludes!: ExcludePatternInputWidget;
|
||||
private includesExcludesContainer!: HTMLElement;
|
||||
private toggleQueryDetailsButton!: HTMLElement;
|
||||
@@ -168,10 +168,11 @@ export class SearchEditor extends BaseTextEditor {
|
||||
const folderIncludesList = DOM.append(this.includesExcludesContainer, DOM.$('.file-types.includes'));
|
||||
const filesToIncludeTitle = localize('searchScope.includes', "files to include");
|
||||
DOM.append(folderIncludesList, DOM.$('h4', undefined, filesToIncludeTitle));
|
||||
this.inputPatternIncludes = this._register(this.instantiationService.createInstance(PatternInputWidget, folderIncludesList, this.contextViewService, {
|
||||
this.inputPatternIncludes = this._register(this.instantiationService.createInstance(IncludePatternInputWidget, folderIncludesList, this.contextViewService, {
|
||||
ariaLabel: localize('label.includes', 'Search Include Patterns'),
|
||||
}));
|
||||
this.inputPatternIncludes.onSubmit(triggeredOnType => this.triggerSearch({ resetCursor: false, delay: triggeredOnType ? this.searchConfig.searchOnTypeDebouncePeriod : 0 }));
|
||||
this._register(this.inputPatternIncludes.onChangeSearchInEditorsBox(() => this.triggerSearch()));
|
||||
|
||||
// // Excludes
|
||||
const excludesList = DOM.append(this.includesExcludesContainer, DOM.$('.file-types.excludes'));
|
||||
@@ -181,7 +182,7 @@ export class SearchEditor extends BaseTextEditor {
|
||||
ariaLabel: localize('label.excludes', 'Search Exclude Patterns'),
|
||||
}));
|
||||
this.inputPatternExcludes.onSubmit(triggeredOnType => this.triggerSearch({ resetCursor: false, delay: triggeredOnType ? this.searchConfig.searchOnTypeDebouncePeriod : 0 }));
|
||||
this.inputPatternExcludes.onChangeIgnoreBox(() => this.triggerSearch());
|
||||
this._register(this.inputPatternExcludes.onChangeIgnoreBox(() => this.triggerSearch()));
|
||||
|
||||
[this.queryEditorWidget.searchInput, this.inputPatternIncludes, this.inputPatternExcludes].map(input =>
|
||||
this._register(attachInputBoxStyler(input, this.themeService, { inputBorder: searchEditorTextInputBorder })));
|
||||
@@ -449,6 +450,7 @@ export class SearchEditor extends BaseTextEditor {
|
||||
isRegexp: this.queryEditorWidget.searchInput.getRegex(),
|
||||
matchWholeWord: this.queryEditorWidget.searchInput.getWholeWords(),
|
||||
useExcludeSettingsAndIgnoreFiles: this.inputPatternExcludes.useExcludesAndIgnoreFiles(),
|
||||
onlyOpenEditors: this.inputPatternIncludes.onlySearchInOpenEditors(),
|
||||
showIncludesExcludes: this.showingIncludesExcludes
|
||||
};
|
||||
}
|
||||
@@ -483,6 +485,7 @@ export class SearchEditor extends BaseTextEditor {
|
||||
disregardExcludeSettings: !config.useExcludeSettingsAndIgnoreFiles || undefined,
|
||||
excludePattern: config.filesToExclude,
|
||||
includePattern: config.filesToInclude,
|
||||
onlyOpenEditors: config.onlyOpenEditors,
|
||||
previewOptions: {
|
||||
matchLines: 1,
|
||||
charsPerLine: 1000
|
||||
@@ -575,6 +578,7 @@ export class SearchEditor extends BaseTextEditor {
|
||||
if (config.contextLines !== undefined) { this.queryEditorWidget.setContextLines(config.contextLines); }
|
||||
if (config.filesToExclude !== undefined) { this.inputPatternExcludes.setValue(config.filesToExclude); }
|
||||
if (config.filesToInclude !== undefined) { this.inputPatternIncludes.setValue(config.filesToInclude); }
|
||||
if (config.onlyOpenEditors !== undefined) { this.inputPatternIncludes.setOnlySearchInOpenEditors(config.onlyOpenEditors); }
|
||||
if (config.useExcludeSettingsAndIgnoreFiles !== undefined) { this.inputPatternExcludes.setUseExcludesAndIgnoreFiles(config.useExcludeSettingsAndIgnoreFiles); }
|
||||
if (config.showIncludesExcludes !== undefined) { this.toggleIncludesExcludes(config.showIncludesExcludes); }
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ export async function openSearchEditor(accessor: ServicesAccessor): Promise<void
|
||||
if (searchView) {
|
||||
await instantiationService.invokeFunction(openNewSearchEditor, {
|
||||
filesToInclude: searchView.searchIncludePattern.getValue(),
|
||||
onlyOpenEditors: searchView.searchIncludePattern.onlySearchInOpenEditors(),
|
||||
filesToExclude: searchView.searchExcludePattern.getValue(),
|
||||
isRegexp: searchView.searchAndReplaceWidget.searchInput.getRegex(),
|
||||
isCaseSensitive: searchView.searchAndReplaceWidget.searchInput.getCaseSensitive(),
|
||||
@@ -161,7 +162,7 @@ export const openNewSearchEditor =
|
||||
};
|
||||
|
||||
export const createEditorFromSearchResult =
|
||||
async (accessor: ServicesAccessor, searchResult: SearchResult, rawIncludePattern: string, rawExcludePattern: string) => {
|
||||
async (accessor: ServicesAccessor, searchResult: SearchResult, rawIncludePattern: string, rawExcludePattern: string, onlySearchInOpenEditors: boolean) => {
|
||||
if (!searchResult.query) {
|
||||
console.error('Expected searchResult.query to be defined. Got', searchResult);
|
||||
return;
|
||||
@@ -180,6 +181,7 @@ export const createEditorFromSearchResult =
|
||||
const labelFormatter = (uri: URI): string => labelService.getUriLabel(uri, { relative: true });
|
||||
|
||||
const { text, matchRanges, config } = serializeSearchResultForEditor(searchResult, rawIncludePattern, rawExcludePattern, 0, labelFormatter, sortOrder);
|
||||
config.onlyOpenEditors = onlySearchInOpenEditors;
|
||||
const contextLines = configurationService.getValue<ISearchConfigurationProperties>('search').searchEditor.defaultNumberOfContextLines;
|
||||
|
||||
if (searchResult.isDirty || contextLines === 0 || contextLines === null) {
|
||||
|
||||
@@ -40,6 +40,7 @@ export type SearchConfiguration = {
|
||||
isRegexp: boolean,
|
||||
useExcludeSettingsAndIgnoreFiles: boolean,
|
||||
showIncludesExcludes: boolean,
|
||||
onlyOpenEditors: boolean,
|
||||
};
|
||||
|
||||
export const SEARCH_EDITOR_EXT = '.code-search';
|
||||
|
||||
@@ -115,6 +115,7 @@ const contentPatternToSearchConfiguration = (pattern: ITextQuery, includes: stri
|
||||
showIncludesExcludes: !!(includes || excludes || pattern?.userDisabledExcludesAndIgnoreFiles),
|
||||
useExcludeSettingsAndIgnoreFiles: (pattern?.userDisabledExcludesAndIgnoreFiles === undefined ? true : !pattern.userDisabledExcludesAndIgnoreFiles),
|
||||
contextLines,
|
||||
onlyOpenEditors: !!pattern.onlyOpenEditors,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -131,6 +132,7 @@ export const serializeSearchConfiguration = (config: Partial<SearchConfiguration
|
||||
config.isCaseSensitive && 'CaseSensitive',
|
||||
config.matchWholeWord && 'WordMatch',
|
||||
config.isRegexp && 'RegExp',
|
||||
config.onlyOpenEditors && 'OpenEditors',
|
||||
(config.useExcludeSettingsAndIgnoreFiles === false) && 'IgnoreExcludeSettings'
|
||||
]).join(' ')}`,
|
||||
config.filesToInclude ? `# Including: ${config.filesToInclude}` : undefined,
|
||||
@@ -153,6 +155,7 @@ export const defaultSearchConfig = (): SearchConfiguration => ({
|
||||
matchWholeWord: false,
|
||||
contextLines: 0,
|
||||
showIncludesExcludes: false,
|
||||
onlyOpenEditors: false,
|
||||
});
|
||||
|
||||
export const extractSearchQueryFromLines = (lines: string[]): SearchConfiguration => {
|
||||
@@ -197,6 +200,7 @@ export const extractSearchQueryFromLines = (lines: string[]): SearchConfiguratio
|
||||
query.isCaseSensitive = value.indexOf('CaseSensitive') !== -1;
|
||||
query.useExcludeSettingsAndIgnoreFiles = value.indexOf('IgnoreExcludeSettings') === -1;
|
||||
query.matchWholeWord = value.indexOf('WordMatch') !== -1;
|
||||
query.onlyOpenEditors = value.indexOf('OpenEditors') !== -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { Action, IAction } from 'vs/base/common/actions';
|
||||
import { EndOfLinePreference } from 'vs/editor/common/model';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { TERMINAL_VIEW_ID, ITerminalConfigHelper, TitleEventSource, TERMINAL_COMMAND_ID, KEYBINDING_CONTEXT_TERMINAL_FIND_FOCUSED, TERMINAL_ACTION_CATEGORY, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_FIND_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, KEYBINDING_CONTEXT_TERMINAL_FIND_NOT_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED, IRemoteTerminalAttachTarget } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { TERMINAL_VIEW_ID, ITerminalConfigHelper, TitleEventSource, TERMINAL_COMMAND_ID, KEYBINDING_CONTEXT_TERMINAL_FIND_FOCUSED, TERMINAL_ACTION_CATEGORY, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_FIND_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, KEYBINDING_CONTEXT_TERMINAL_FIND_NOT_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED, IRemoteTerminalAttachTarget, KEYBINDING_CONTEXT_TERMINAL_ALT_BUFFER_ACTIVE } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { attachSelectBoxStyler, attachStylerCallback } from 'vs/platform/theme/common/styler';
|
||||
import { IThemeService, ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
@@ -750,7 +750,7 @@ export function registerTerminalActions() {
|
||||
keybinding: {
|
||||
primary: KeyMod.Shift | KeyCode.PageDown,
|
||||
mac: { primary: KeyCode.PageDown },
|
||||
when: KEYBINDING_CONTEXT_TERMINAL_FOCUS,
|
||||
when: ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_ALT_BUFFER_ACTIVE.negate()),
|
||||
weight: KeybindingWeight.WorkbenchContrib
|
||||
},
|
||||
precondition: KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED
|
||||
@@ -810,7 +810,7 @@ export function registerTerminalActions() {
|
||||
keybinding: {
|
||||
primary: KeyMod.Shift | KeyCode.PageUp,
|
||||
mac: { primary: KeyCode.PageUp },
|
||||
when: KEYBINDING_CONTEXT_TERMINAL_FOCUS,
|
||||
when: ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_ALT_BUFFER_ACTIVE.negate()),
|
||||
weight: KeybindingWeight.WorkbenchContrib
|
||||
},
|
||||
precondition: KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED
|
||||
@@ -1416,7 +1416,7 @@ export function registerTerminalActions() {
|
||||
{
|
||||
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_F,
|
||||
when: ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED),
|
||||
weight: KeybindingWeight.WorkbenchContrib
|
||||
weight: KeybindingWeight.WorkbenchContrib + 50
|
||||
}
|
||||
],
|
||||
precondition: KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED
|
||||
|
||||
@@ -25,7 +25,7 @@ import { activeContrastBorder, scrollbarSliderActiveBackground, scrollbarSliderB
|
||||
import { ICssStyleCollector, IColorTheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { PANEL_BACKGROUND, SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager';
|
||||
import { IShellLaunchConfig, ITerminalProcessManager, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, NEVER_MEASURE_RENDER_TIME_STORAGE_KEY, ProcessState, TERMINAL_VIEW_ID, IWindowsShellHelper, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, INavigationMode, TitleEventSource, DEFAULT_COMMANDS_TO_SKIP_SHELL, ITerminalLaunchError, IProcessDataEvent, ITerminalDimensionsOverride, TERMINAL_CREATION_COMMANDS } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { IShellLaunchConfig, ITerminalProcessManager, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, NEVER_MEASURE_RENDER_TIME_STORAGE_KEY, ProcessState, TERMINAL_VIEW_ID, IWindowsShellHelper, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, INavigationMode, TitleEventSource, DEFAULT_COMMANDS_TO_SKIP_SHELL, ITerminalLaunchError, IProcessDataEvent, ITerminalDimensionsOverride, TERMINAL_CREATION_COMMANDS, KEYBINDING_CONTEXT_TERMINAL_ALT_BUFFER_ACTIVE } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { ansiColorIdentifiers, TERMINAL_BACKGROUND_COLOR, TERMINAL_CURSOR_BACKGROUND_COLOR, TERMINAL_CURSOR_FOREGROUND_COLOR, TERMINAL_FOREGROUND_COLOR, TERMINAL_SELECTION_BACKGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry';
|
||||
import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper';
|
||||
import { TerminalLinkManager } from 'vs/workbench/contrib/terminal/browser/links/terminalLinkManager';
|
||||
@@ -184,6 +184,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
||||
public constructor(
|
||||
private readonly _terminalFocusContextKey: IContextKey<boolean>,
|
||||
private readonly _terminalShellTypeContextKey: IContextKey<string>,
|
||||
private readonly _terminalAltBufferActiveContextKey: IContextKey<boolean>,
|
||||
private readonly _configHelper: TerminalConfigHelper,
|
||||
private _container: HTMLElement | undefined,
|
||||
private _shellLaunchConfig: IShellLaunchConfig,
|
||||
@@ -219,6 +220,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
||||
|
||||
this._terminalHasTextContextKey = KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED.bindTo(this._contextKeyService);
|
||||
this._terminalA11yTreeFocusContextKey = KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS.bindTo(this._contextKeyService);
|
||||
this._terminalAltBufferActiveContextKey = KEYBINDING_CONTEXT_TERMINAL_ALT_BUFFER_ACTIVE.bindTo(this._contextKeyService);
|
||||
this.disableLayout = false;
|
||||
|
||||
this._logService.trace(`terminalInstance#ctor (id: ${this.id})`, this._shellLaunchConfig);
|
||||
@@ -396,7 +398,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
||||
const editorOptions = this._configurationService.getValue<IEditorOptions>('editor');
|
||||
|
||||
const xterm = new Terminal({
|
||||
altClickMovesCursor: config.altClickMovesCursor,
|
||||
altClickMovesCursor: config.altClickMovesCursor && editorOptions.multiCursorModifier === 'alt',
|
||||
scrollback: config.scrollback,
|
||||
theme: this._getXtermTheme(),
|
||||
drawBoldTextInBrightColors: config.drawBoldTextInBrightColors,
|
||||
@@ -431,6 +433,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
||||
this._xterm.onLineFeed(() => this._onLineFeed());
|
||||
this._xterm.onKey(e => this._onKey(e.key, e.domEvent));
|
||||
this._xterm.onSelectionChange(async () => this._onSelectionChange());
|
||||
this._xterm.buffer.onBufferChange(() => this._refreshAltBufferContextKey());
|
||||
|
||||
this._processManager.onProcessData(e => this._onProcessData(e));
|
||||
this._xterm.onData(data => this._processManager.write(data));
|
||||
@@ -774,6 +777,10 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
||||
this.notifyFindWidgetFocusChanged(false);
|
||||
}
|
||||
|
||||
private _refreshAltBufferContextKey() {
|
||||
this._terminalAltBufferActiveContextKey.set(!!(this._xterm && this._xterm.buffer.active === this._xterm.buffer.alternate));
|
||||
}
|
||||
|
||||
public dispose(immediate?: boolean): void {
|
||||
this._logService.trace(`terminalInstance#dispose (id: ${this.id})`);
|
||||
|
||||
@@ -828,6 +835,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
||||
}
|
||||
|
||||
public focus(force?: boolean): void {
|
||||
this._refreshAltBufferContextKey();
|
||||
if (!this._xterm) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -157,11 +157,12 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
|
||||
const userHomeUri = await this._pathService.userHome();
|
||||
this.userHome = userHomeUri.path;
|
||||
if (hasRemoteAuthority) {
|
||||
const remoteEnv = await this._remoteAgentService.getEnvironment();
|
||||
if (remoteEnv) {
|
||||
this.userHome = remoteEnv.userHome.path;
|
||||
this.os = remoteEnv.os;
|
||||
}
|
||||
this._remoteAgentService.getEnvironment().then(remoteEnv => {
|
||||
if (remoteEnv) {
|
||||
this.userHome = remoteEnv.userHome.path;
|
||||
this.os = remoteEnv.os;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot();
|
||||
|
||||
@@ -24,7 +24,7 @@ import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/term
|
||||
import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance';
|
||||
import { TerminalTab } from 'vs/workbench/contrib/terminal/browser/terminalTab';
|
||||
import { TerminalViewPane } from 'vs/workbench/contrib/terminal/browser/terminalView';
|
||||
import { IAvailableShellsRequest, IRemoteTerminalAttachTarget, IShellDefinition, IShellLaunchConfig, ISpawnExtHostProcessRequest, IStartExtensionTerminalRequest, ITerminalConfigHelper, ITerminalLaunchError, ITerminalNativeWindowsDelegate, ITerminalProcessExtHostProxy, ITerminalsLayoutInfoById, KEYBINDING_CONTEXT_TERMINAL_FIND_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_IS_OPEN, KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED, KEYBINDING_CONTEXT_TERMINAL_SHELL_TYPE, LinuxDistro, TERMINAL_VIEW_ID } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { IAvailableShellsRequest, IRemoteTerminalAttachTarget, IShellDefinition, IShellLaunchConfig, ISpawnExtHostProcessRequest, IStartExtensionTerminalRequest, ITerminalConfigHelper, ITerminalLaunchError, ITerminalNativeWindowsDelegate, ITerminalProcessExtHostProxy, ITerminalsLayoutInfoById, KEYBINDING_CONTEXT_TERMINAL_ALT_BUFFER_ACTIVE, KEYBINDING_CONTEXT_TERMINAL_FIND_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_IS_OPEN, KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED, KEYBINDING_CONTEXT_TERMINAL_SHELL_TYPE, LinuxDistro, TERMINAL_VIEW_ID } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { escapeNonWindowsPath } from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
@@ -43,6 +43,7 @@ export class TerminalService implements ITerminalService {
|
||||
private _isShuttingDown: boolean;
|
||||
private _terminalFocusContextKey: IContextKey<boolean>;
|
||||
private _terminalShellTypeContextKey: IContextKey<string>;
|
||||
private _terminalAltBufferActiveContextKey: IContextKey<boolean>;
|
||||
private _findWidgetVisible: IContextKey<boolean>;
|
||||
private _terminalTabs: ITerminalTab[] = [];
|
||||
private _backgroundedTerminalInstances: ITerminalInstance[] = [];
|
||||
@@ -126,6 +127,7 @@ export class TerminalService implements ITerminalService {
|
||||
lifecycleService.onShutdown(() => this._onShutdown());
|
||||
this._terminalFocusContextKey = KEYBINDING_CONTEXT_TERMINAL_FOCUS.bindTo(this._contextKeyService);
|
||||
this._terminalShellTypeContextKey = KEYBINDING_CONTEXT_TERMINAL_SHELL_TYPE.bindTo(this._contextKeyService);
|
||||
this._terminalAltBufferActiveContextKey = KEYBINDING_CONTEXT_TERMINAL_ALT_BUFFER_ACTIVE.bindTo(this._contextKeyService);
|
||||
this._findWidgetVisible = KEYBINDING_CONTEXT_TERMINAL_FIND_VISIBLE.bindTo(this._contextKeyService);
|
||||
this._configHelper = this._instantiationService.createInstance(TerminalConfigHelper);
|
||||
this.onTabDisposed(tab => this._removeTab(tab));
|
||||
@@ -718,7 +720,14 @@ export class TerminalService implements ITerminalService {
|
||||
|
||||
|
||||
public createInstance(container: HTMLElement | undefined, shellLaunchConfig: IShellLaunchConfig): ITerminalInstance {
|
||||
const instance = this._instantiationService.createInstance(TerminalInstance, this._terminalFocusContextKey, this._terminalShellTypeContextKey, this._configHelper, container, shellLaunchConfig);
|
||||
const instance = this._instantiationService.createInstance(TerminalInstance,
|
||||
this._terminalFocusContextKey,
|
||||
this._terminalShellTypeContextKey,
|
||||
this._terminalAltBufferActiveContextKey,
|
||||
this._configHelper,
|
||||
container,
|
||||
shellLaunchConfig
|
||||
);
|
||||
this._onInstanceCreated.fire(instance);
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ export const KEYBINDING_CONTEXT_TERMINAL_SHELL_TYPE_KEY = 'terminalShellType';
|
||||
/** A context key that is set to the detected shell for the most recently active terminal, this is set to the last known value when no terminals exist. */
|
||||
export const KEYBINDING_CONTEXT_TERMINAL_SHELL_TYPE = new RawContextKey<string>(KEYBINDING_CONTEXT_TERMINAL_SHELL_TYPE_KEY, undefined);
|
||||
|
||||
export const KEYBINDING_CONTEXT_TERMINAL_ALT_BUFFER_ACTIVE = new RawContextKey<boolean>('terminalAltBufferActive', false);
|
||||
|
||||
/** A context key that is set when the integrated terminal does not have focus. */
|
||||
export const KEYBINDING_CONTEXT_TERMINAL_NOT_FOCUSED = KEYBINDING_CONTEXT_TERMINAL_FOCUS.toNegated();
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ export const terminalConfiguration: IConfigurationNode = {
|
||||
default: false
|
||||
},
|
||||
'terminal.integrated.altClickMovesCursor': {
|
||||
description: localize('terminal.integrated.altClickMovesCursor', "If enabled, alt/option + click will move the prompt cursor to position underneath the mouse. This may not work reliably depending on your shell."),
|
||||
description: localize('terminal.integrated.altClickMovesCursor', "If enabled, alt/option + click will reposition the prompt cursor to underneath the mouse when `#editor.multiCursorModifier#` is set to `'alt'` (the default value). This may not work reliably depending on your shell."),
|
||||
type: 'boolean',
|
||||
default: true
|
||||
},
|
||||
|
||||
@@ -111,54 +111,59 @@ export async function openEditorWith(
|
||||
return picked.item.handler.open(input, openOptions, targetGroup, OpenEditorContext.NEW_EDITOR)?.override;
|
||||
}
|
||||
|
||||
const picked = await new Promise<PickedResult | undefined>(resolve => {
|
||||
picker.onDidAccept(e => {
|
||||
if (picker.selectedItems.length === 1) {
|
||||
const result: PickedResult = {
|
||||
item: picker.selectedItems[0],
|
||||
keyMods: picker.keyMods,
|
||||
openInBackground: e.inBackground
|
||||
};
|
||||
let picked: PickedResult | undefined;
|
||||
try {
|
||||
picked = await new Promise<PickedResult | undefined>(resolve => {
|
||||
picker.onDidAccept(e => {
|
||||
if (picker.selectedItems.length === 1) {
|
||||
const result: PickedResult = {
|
||||
item: picker.selectedItems[0],
|
||||
keyMods: picker.keyMods,
|
||||
openInBackground: e.inBackground
|
||||
};
|
||||
|
||||
if (e.inBackground) {
|
||||
openEditor(result);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
} else {
|
||||
resolve(undefined);
|
||||
}
|
||||
});
|
||||
|
||||
picker.onDidTriggerItemButton(e => {
|
||||
const pick = e.item;
|
||||
const id = pick.id;
|
||||
resolve({ item: pick, openInBackground: false }); // open the view
|
||||
picker.dispose();
|
||||
|
||||
// And persist the setting
|
||||
if (pick && id) {
|
||||
const newAssociation: CustomEditorAssociation = { viewType: id, filenamePattern: '*' + resourceExt };
|
||||
const currentAssociations = [...configurationService.getValue<CustomEditorsAssociations>(customEditorsAssociationsSettingId)];
|
||||
|
||||
// First try updating existing association
|
||||
for (let i = 0; i < currentAssociations.length; ++i) {
|
||||
const existing = currentAssociations[i];
|
||||
if (existing.filenamePattern === newAssociation.filenamePattern) {
|
||||
currentAssociations.splice(i, 1, newAssociation);
|
||||
configurationService.updateValue(customEditorsAssociationsSettingId, currentAssociations);
|
||||
return;
|
||||
if (e.inBackground) {
|
||||
openEditor(result);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
} else {
|
||||
resolve(undefined);
|
||||
}
|
||||
});
|
||||
|
||||
// Otherwise, create a new one
|
||||
currentAssociations.unshift(newAssociation);
|
||||
configurationService.updateValue(customEditorsAssociationsSettingId, currentAssociations);
|
||||
}
|
||||
picker.onDidTriggerItemButton(e => {
|
||||
const pick = e.item;
|
||||
const id = pick.id;
|
||||
resolve({ item: pick, openInBackground: false }); // open the view
|
||||
picker.dispose();
|
||||
|
||||
// And persist the setting
|
||||
if (pick && id) {
|
||||
const newAssociation: CustomEditorAssociation = { viewType: id, filenamePattern: '*' + resourceExt };
|
||||
const currentAssociations = [...configurationService.getValue<CustomEditorsAssociations>(customEditorsAssociationsSettingId)];
|
||||
|
||||
// First try updating existing association
|
||||
for (let i = 0; i < currentAssociations.length; ++i) {
|
||||
const existing = currentAssociations[i];
|
||||
if (existing.filenamePattern === newAssociation.filenamePattern) {
|
||||
currentAssociations.splice(i, 1, newAssociation);
|
||||
configurationService.updateValue(customEditorsAssociationsSettingId, currentAssociations);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, create a new one
|
||||
currentAssociations.unshift(newAssociation);
|
||||
configurationService.updateValue(customEditorsAssociationsSettingId, currentAssociations);
|
||||
}
|
||||
});
|
||||
|
||||
picker.show();
|
||||
});
|
||||
|
||||
picker.show();
|
||||
});
|
||||
} finally {
|
||||
picker.dispose();
|
||||
}
|
||||
|
||||
if (!picked) {
|
||||
return undefined;
|
||||
|
||||
@@ -51,10 +51,10 @@ export const content: GettingStartedContent = [
|
||||
items: [
|
||||
{
|
||||
id: 'runProjectTask',
|
||||
title: localize('gettingStarted.runProject.title', "Build & run your project"),
|
||||
description: localize('gettingStarted.runProject.description', "Build, run & debug your application in your codespace instead of locally."),
|
||||
title: localize('gettingStarted.runProject.title', "Build & run your app"),
|
||||
description: localize('gettingStarted.runProject.description', "Build, run & debug your code right from the browser."),
|
||||
button: {
|
||||
title: localize('gettingStarted.runProject.button', "Run Project"),
|
||||
title: localize('gettingStarted.runProject.button', "Run Code"),
|
||||
command: 'workbench.action.debug.selectandstart'
|
||||
},
|
||||
doneOn: { commandExecuted: 'workbench.action.debug.selectandstart' },
|
||||
@@ -65,7 +65,7 @@ export const content: GettingStartedContent = [
|
||||
title: localize('gettingStarted.forwardPorts.title', "Access your running application"),
|
||||
description: localize('gettingStarted.forwardPorts.description', "Ports running within your codespace are automatically forwarded to the web, so you can open them in your browser."),
|
||||
button: {
|
||||
title: localize('gettingStarted.forwardPorts.button', "Show Ports panel"),
|
||||
title: localize('gettingStarted.forwardPorts.button', "Show Ports Panel"),
|
||||
command: '~remote.forwardedPorts.focus'
|
||||
},
|
||||
doneOn: { commandExecuted: '~remote.forwardedPorts.focus' },
|
||||
@@ -73,10 +73,10 @@ export const content: GettingStartedContent = [
|
||||
},
|
||||
{
|
||||
id: 'pullRequests',
|
||||
title: localize('gettingStarted.pullRequests.title', "Pull pequests at your fingertips"),
|
||||
description: localize('gettingStarted.pullRequests.description', "Codespaces brings your GitHub workflow closer to your code, where you can view pull requests, add comments, merge branches, and more."),
|
||||
title: localize('gettingStarted.pullRequests.title', "Pull requests at your fingertips"),
|
||||
description: localize('gettingStarted.pullRequests.description', "Bring your GitHub workflow closer to your code, so you can review pull requests, add comments, merge branches, and more."),
|
||||
button: {
|
||||
title: localize('gettingStarted.pullRequests.button', "Open GitHub view"),
|
||||
title: localize('gettingStarted.pullRequests.button', "Open GitHub View"),
|
||||
command: 'workbench.view.extension.github-pull-requests'
|
||||
},
|
||||
doneOn: { commandExecuted: 'workbench.view.extension.github-pull-requests' },
|
||||
@@ -85,7 +85,7 @@ export const content: GettingStartedContent = [
|
||||
{
|
||||
id: 'remoteTerminal',
|
||||
title: localize('gettingStarted.remoteTerminal.title', "Run tasks in the integrated terminal"),
|
||||
description: localize('gettingStarted.remoteTerminal.description', "Access your full development environment in the cloud and perform quick command-line tasks."),
|
||||
description: localize('gettingStarted.remoteTerminal.description', "Perform quick command-line tasks using the built-in terminal."),
|
||||
button: {
|
||||
title: localize('gettingStarted.remoteTerminal.button', "Focus Terminal"),
|
||||
command: 'terminal.focus'
|
||||
@@ -96,7 +96,7 @@ export const content: GettingStartedContent = [
|
||||
{
|
||||
id: 'openVSC',
|
||||
title: localize('gettingStarted.openVSC.title', "Develop remotely in VS Code"),
|
||||
description: localize('gettingStarted.openVSC.description', "Access the power of your cloud development environment from your local VS Code. Set up your local VS Code by installing the GitHub Codespaces extension and connecting your GitHub account."),
|
||||
description: localize('gettingStarted.openVSC.description', "Access the power of your cloud development environment from your local VS Code. Set it up by installing the GitHub Codespaces extension and connecting your GitHub account."),
|
||||
button: {
|
||||
title: localize('gettingStarted.openVSC.button', "Open in VS Code"),
|
||||
command: 'github.codespaces.openInStable'
|
||||
@@ -120,15 +120,15 @@ export const content: GettingStartedContent = [
|
||||
{
|
||||
id: 'pickColorTheme',
|
||||
title: localize('gettingStarted.pickColor.title', "Customize the look with themes"),
|
||||
description: localize('gettingStarted.pickColor.description', "Pick a theme to match your taste and mood. Browse even more from the vibrant themes community."),
|
||||
button: { title: localize('gettingStarted.pickColor.button', "Pick your Theme"), command: 'workbench.action.selectTheme' },
|
||||
description: localize('gettingStarted.pickColor.description', "Pick a color theme to match your taste and mood while coding."),
|
||||
button: { title: localize('gettingStarted.pickColor.button', "Pick a Theme"), command: 'workbench.action.selectTheme' },
|
||||
doneOn: { eventFired: 'themeSelected' },
|
||||
media: { type: 'image', altText: 'Color theme preview for dark and light theme.', path: 'colorTheme.jpg', }
|
||||
},
|
||||
{
|
||||
id: 'findLanguageExtensions',
|
||||
title: localize('gettingStarted.findLanguageExts.title', "Add more language & tools support"),
|
||||
description: localize('gettingStarted.findLanguageExts.description', "VS Code supports almost every major programming language. While many are built-in, others can be installed as extensions with one click."),
|
||||
title: localize('gettingStarted.findLanguageExts.title', "Code in any language, without switching editors"),
|
||||
description: localize('gettingStarted.findLanguageExts.description', "VS Code supports over 50+ programming languages. While many are built-in, others can be easily installed as extensions in one click."),
|
||||
button: {
|
||||
title: localize('gettingStarted.findLanguageExts.button', "Browse Language Extensions"),
|
||||
command: 'workbench.extensions.action.showLanguageExtensions',
|
||||
@@ -139,7 +139,7 @@ export const content: GettingStartedContent = [
|
||||
{
|
||||
id: 'settingsSync',
|
||||
title: localize('gettingStarted.settingsSync.title', "Sync your favorite setup"),
|
||||
description: localize('gettingStarted.settingsSync.description', "Never lose the perfect VS Code setup! Settings Sync will back up and share settings, keybindings and installed extensions across several VS Code installations."),
|
||||
description: localize('gettingStarted.settingsSync.description', "Never lose the perfect VS Code setup! Settings Sync will back up and share settings, keybindings & extensions across several VS Code instances."),
|
||||
when: 'syncStatus != uninitialized',
|
||||
button: {
|
||||
title: localize('gettingStarted.settingsSync.button', "Enable Settings Sync"),
|
||||
@@ -163,7 +163,7 @@ export const content: GettingStartedContent = [
|
||||
{
|
||||
id: 'pickAFolderTask-Other',
|
||||
title: localize('gettingStarted.setup.OpenFolder.title', "Open your project"),
|
||||
description: localize('gettingStarted.setup.OpenFolder.description', "Open a project folder to get started!"),
|
||||
description: localize('gettingStarted.setup.OpenFolder.description2', "Open a folder to get started!"),
|
||||
when: '!isMac',
|
||||
button: {
|
||||
title: localize('gettingStarted.setup.OpenFolder.button', "Pick a Folder"),
|
||||
@@ -186,8 +186,8 @@ export const content: GettingStartedContent = [
|
||||
items: [
|
||||
{
|
||||
id: 'commandPaletteTask',
|
||||
title: localize('gettingStarted.commandPalette.title', "Find and run commands"),
|
||||
description: localize('gettingStarted.commandPalette.description', "The easiest way to find everything VS Code can do. If you\'re ever looking for a feature or a shortcut, check here first!"),
|
||||
title: localize('gettingStarted.commandPalette.title', "Find & run commands"),
|
||||
description: localize('gettingStarted.commandPalette.description', "The easiest way to find everything VS Code can do. If you're ever looking for a feature or a shortcut, check here first!"),
|
||||
button: {
|
||||
title: localize('gettingStarted.commandPalette.button', "Open Command Palette"),
|
||||
command: 'workbench.action.showCommands'
|
||||
@@ -200,7 +200,7 @@ export const content: GettingStartedContent = [
|
||||
title: localize('gettingStarted.terminal.title', "Run tasks in the integrated terminal"),
|
||||
description: localize('gettingStarted.terminal.description', "Quickly run shell commands and monitor build output, right next to your code."),
|
||||
button: {
|
||||
title: localize('gettingStarted.terminal.button', "Open the Terminal"),
|
||||
title: localize('gettingStarted.terminal.button', "Open Terminal"),
|
||||
command: 'workbench.action.terminal.toggleTerminal'
|
||||
},
|
||||
doneOn: { commandExecuted: 'workbench.action.terminal.toggleTerminal' },
|
||||
@@ -209,7 +209,7 @@ export const content: GettingStartedContent = [
|
||||
{
|
||||
id: 'extensions',
|
||||
title: localize('gettingStarted.extensions.title', "Limitless extensibility"),
|
||||
description: localize('gettingStarted.extensions.description', "Extensions are VS Code's power ups. They range from handy productivity hacks, expanding out-of-the-box features, to adding completely new capabilities."),
|
||||
description: localize('gettingStarted.extensions.description', "Extensions are VS Code's power-ups. They range from handy productivity hacks, expanding out-of-the-box features, to adding completely new capabilities."),
|
||||
button: {
|
||||
title: localize('gettingStarted.extensions.button', "Browse Recommended Extensions"),
|
||||
command: 'workbench.extensions.action.showRecommendedExtensions'
|
||||
@@ -220,9 +220,9 @@ export const content: GettingStartedContent = [
|
||||
{
|
||||
id: 'settings',
|
||||
title: localize('gettingStarted.settings.title', "Everything is a setting"),
|
||||
description: localize('gettingStarted.settings.description', "Optimize every part of VS Code's look & feel to your liking. Enable Settings Sync lets you share your personal tweaks across machines."),
|
||||
description: localize('gettingStarted.settings.description', "Optimize every part of VS Code's look & feel to your liking. Enabling Settings Sync lets you share your personal tweaks across machines."),
|
||||
button: {
|
||||
title: localize('gettingStarted.settings.button', "Tweak Some Settings"),
|
||||
title: localize('gettingStarted.settings.button', "Tweak my Settings"),
|
||||
command: 'workbench.action.openSettings'
|
||||
},
|
||||
doneOn: { commandExecuted: 'workbench.action.openSettings' },
|
||||
|
||||
@@ -77,6 +77,8 @@ export interface ICommonQueryProps<U extends UriComponents> {
|
||||
excludePattern?: glob.IExpression;
|
||||
extraFileResources?: U[];
|
||||
|
||||
onlyOpenEditors?: boolean;
|
||||
|
||||
maxResults?: number;
|
||||
usingSearchPaths?: boolean;
|
||||
}
|
||||
@@ -372,6 +374,9 @@ export interface ISearchConfigurationProperties {
|
||||
defaultNumberOfContextLines: number | null,
|
||||
experimental: {}
|
||||
};
|
||||
experimental: {
|
||||
searchInOpenEditors: boolean
|
||||
}
|
||||
sortOrder: SearchSortOrder;
|
||||
}
|
||||
|
||||
@@ -407,21 +412,25 @@ export function pathIncludedInQuery(queryProps: ICommonQueryProps<URI>, fsPath:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (queryProps.includePattern && !glob.match(queryProps.includePattern, fsPath)) {
|
||||
return false;
|
||||
}
|
||||
if (queryProps.includePattern || queryProps.usingSearchPaths) {
|
||||
if (queryProps.includePattern && glob.match(queryProps.includePattern, fsPath)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If searchPaths are being used, the extra file must be in a subfolder and match the pattern, if present
|
||||
if (queryProps.usingSearchPaths) {
|
||||
return !!queryProps.folderQueries && queryProps.folderQueries.every(fq => {
|
||||
const searchPath = fq.folder.fsPath;
|
||||
if (extpath.isEqualOrParent(fsPath, searchPath)) {
|
||||
const relPath = relative(searchPath, fsPath);
|
||||
return !fq.includePattern || !!glob.match(fq.includePattern, relPath);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
// If searchPaths are being used, the extra file must be in a subfolder and match the pattern, if present
|
||||
if (queryProps.usingSearchPaths) {
|
||||
return !!queryProps.folderQueries && queryProps.folderQueries.some(fq => {
|
||||
const searchPath = fq.folder.fsPath;
|
||||
if (extpath.isEqualOrParent(fsPath, searchPath)) {
|
||||
const relPath = relative(searchPath, fsPath);
|
||||
return !fq.includePattern || !!glob.match(fq.includePattern, relPath);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -385,13 +385,7 @@ function getRgArgs(query: TextSearchQuery, options: TextSearchOptions): string[]
|
||||
|
||||
if (otherIncludes && otherIncludes.length) {
|
||||
const uniqueOthers = new Set<string>();
|
||||
otherIncludes.forEach(other => {
|
||||
if (!other.endsWith('/**')) {
|
||||
other += '/**';
|
||||
}
|
||||
|
||||
uniqueOthers.add(other);
|
||||
});
|
||||
otherIncludes.forEach(other => { uniqueOthers.add(other); });
|
||||
|
||||
args.push('-g', '!*');
|
||||
uniqueOthers
|
||||
@@ -508,10 +502,6 @@ function getRgArgs(query: TextSearchQuery, options: TextSearchOptions): string[]
|
||||
*/
|
||||
export function spreadGlobComponents(globArg: string): string[] {
|
||||
const components = splitGlobAware(globArg, '/');
|
||||
if (components[components.length - 1] !== '**') {
|
||||
components.push('**');
|
||||
}
|
||||
|
||||
return components.map((_, i) => components.slice(0, i + 1).join('/'));
|
||||
}
|
||||
|
||||
|
||||
@@ -4,12 +4,15 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { MirroredTestCollection } from 'vs/workbench/api/common/extHostTesting';
|
||||
import { MirroredTestCollection, TestItemFilteredWrapper } from 'vs/workbench/api/common/extHostTesting';
|
||||
import * as convert from 'vs/workbench/api/common/extHostTypeConverters';
|
||||
import { TestDiffOpType } from 'vs/workbench/contrib/testing/common/testCollection';
|
||||
import { stubTest, testStubs } from 'vs/workbench/contrib/testing/common/testStubs';
|
||||
import { TestOwnedTestCollection, TestSingleUseCollection } from 'vs/workbench/contrib/testing/test/common/ownedTestCollection';
|
||||
import { TestChangeEvent, TestItem } from 'vscode';
|
||||
import { TestChangeEvent, TestItem, TextDocument } from 'vscode';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Location } from 'vs/editor/common/modes';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
|
||||
const simplify = (item: TestItem) => {
|
||||
if ('toJSON' in item) {
|
||||
@@ -262,5 +265,141 @@ suite('ExtHost Testing', () => {
|
||||
assert.strictEqual(m.changeEvent.commonChangeAncestor?.label, 'root');
|
||||
});
|
||||
});
|
||||
|
||||
suite('TestItemFilteredWrapper', () => {
|
||||
const stubTestWithLocation = (label: string, location: Location): TestItem => {
|
||||
const t = stubTest(label);
|
||||
t.location = location as any;
|
||||
return t;
|
||||
};
|
||||
|
||||
const location1: Location = {
|
||||
range: new Range(0, 0, 0, 0),
|
||||
uri: URI.parse('file:///foo.ts')
|
||||
};
|
||||
|
||||
const location2: Location = {
|
||||
range: new Range(0, 0, 0, 0),
|
||||
uri: URI.parse('file:///bar.ts')
|
||||
};
|
||||
|
||||
const location3: Location = {
|
||||
range: new Range(0, 0, 0, 0),
|
||||
uri: URI.parse('file:///baz.ts')
|
||||
};
|
||||
|
||||
const textDocumentFilter = {
|
||||
uri: location1.uri
|
||||
} as TextDocument;
|
||||
|
||||
let testsWithLocation: TestItem;
|
||||
setup(() => {
|
||||
testsWithLocation = {
|
||||
...stubTest('root'),
|
||||
children: [
|
||||
{
|
||||
...stubTestWithLocation('a', location1),
|
||||
children: [stubTestWithLocation('aa', location1), stubTestWithLocation('ab', location1)]
|
||||
},
|
||||
{
|
||||
...stubTestWithLocation('b', location2),
|
||||
children: [stubTestWithLocation('ba', location2), stubTestWithLocation('bb', location2)]
|
||||
},
|
||||
{
|
||||
...stubTestWithLocation('b', location3),
|
||||
}
|
||||
],
|
||||
};
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
TestItemFilteredWrapper.removeFilter(textDocumentFilter);
|
||||
});
|
||||
|
||||
test('gets all actual properties', () => {
|
||||
const testItem: TestItem = stubTest('test1');
|
||||
const wrapper: TestItemFilteredWrapper = TestItemFilteredWrapper.getWrapperForTestItem(testItem, textDocumentFilter);
|
||||
|
||||
assert.strictEqual(testItem.debuggable, wrapper.debuggable);
|
||||
assert.strictEqual(testItem.description, wrapper.description);
|
||||
assert.strictEqual(testItem.label, wrapper.label);
|
||||
assert.strictEqual(testItem.location, wrapper.location);
|
||||
assert.strictEqual(testItem.runnable, wrapper.runnable);
|
||||
assert.strictEqual(testItem.state, wrapper.state);
|
||||
});
|
||||
|
||||
test('gets no children if nothing matches Uri filter', () => {
|
||||
let tests: TestItem = testStubs.nested();
|
||||
const wrapper = TestItemFilteredWrapper.getWrapperForTestItem(tests, textDocumentFilter);
|
||||
assert.strictEqual(wrapper.children.length, 0);
|
||||
});
|
||||
|
||||
test('filter is applied to children', () => {
|
||||
const wrapper = TestItemFilteredWrapper.getWrapperForTestItem(testsWithLocation, textDocumentFilter);
|
||||
assert.strictEqual(wrapper.label, 'root');
|
||||
assert.strictEqual(wrapper.children.length, 1);
|
||||
assert.strictEqual(wrapper.children[0] instanceof TestItemFilteredWrapper, true);
|
||||
assert.strictEqual(wrapper.children[0].label, 'a');
|
||||
});
|
||||
|
||||
test('can get if node has matching filter', () => {
|
||||
const rootWrapper = TestItemFilteredWrapper.getWrapperForTestItem(testsWithLocation, textDocumentFilter);
|
||||
|
||||
const invisible = testsWithLocation.children![1];
|
||||
const invisibleWrapper = TestItemFilteredWrapper.getWrapperForTestItem(invisible, textDocumentFilter);
|
||||
const visible = testsWithLocation.children![0];
|
||||
const visibleWrapper = TestItemFilteredWrapper.getWrapperForTestItem(visible, textDocumentFilter);
|
||||
|
||||
// The root is always visible
|
||||
assert.strictEqual(rootWrapper.hasNodeMatchingFilter, true);
|
||||
assert.strictEqual(invisibleWrapper.hasNodeMatchingFilter, false);
|
||||
assert.strictEqual(visibleWrapper.hasNodeMatchingFilter, true);
|
||||
});
|
||||
|
||||
test('can get visible parent', () => {
|
||||
const rootWrapper = TestItemFilteredWrapper.getWrapperForTestItem(testsWithLocation, textDocumentFilter);
|
||||
|
||||
const invisible = testsWithLocation.children![1];
|
||||
const invisibleWrapper = TestItemFilteredWrapper.getWrapperForTestItem(invisible, textDocumentFilter);
|
||||
const visible = testsWithLocation.children![0];
|
||||
const visibleWrapper = TestItemFilteredWrapper.getWrapperForTestItem(visible, textDocumentFilter);
|
||||
|
||||
// The root is always visible
|
||||
assert.strictEqual(rootWrapper.visibleParent, rootWrapper);
|
||||
assert.strictEqual(invisibleWrapper.visibleParent, rootWrapper);
|
||||
assert.strictEqual(visibleWrapper.visibleParent, visibleWrapper);
|
||||
});
|
||||
|
||||
test('can reset cached value of hasNodeMatchingFilter', () => {
|
||||
TestItemFilteredWrapper.getWrapperForTestItem(testsWithLocation, textDocumentFilter);
|
||||
|
||||
const invisible = testsWithLocation.children![1];
|
||||
const invisibleWrapper = TestItemFilteredWrapper.getWrapperForTestItem(invisible, textDocumentFilter);
|
||||
|
||||
assert.strictEqual(invisibleWrapper.hasNodeMatchingFilter, false);
|
||||
invisible.location = location1 as any;
|
||||
assert.strictEqual(invisibleWrapper.hasNodeMatchingFilter, false);
|
||||
invisibleWrapper.reset();
|
||||
assert.strictEqual(invisibleWrapper.hasNodeMatchingFilter, true);
|
||||
});
|
||||
|
||||
test('can reset cached value of hasNodeMatchingFilter of parents up to visible parent', () => {
|
||||
const rootWrapper = TestItemFilteredWrapper.getWrapperForTestItem(testsWithLocation, textDocumentFilter);
|
||||
|
||||
const invisibleParent = testsWithLocation.children![1];
|
||||
const invisibleParentWrapper = TestItemFilteredWrapper.getWrapperForTestItem(invisibleParent, textDocumentFilter);
|
||||
const invisible = invisibleParent.children![1];
|
||||
const invisibleWrapper = TestItemFilteredWrapper.getWrapperForTestItem(invisible, textDocumentFilter);
|
||||
|
||||
assert.strictEqual(invisibleParentWrapper.hasNodeMatchingFilter, false);
|
||||
invisible.location = location1 as any;
|
||||
assert.strictEqual(invisibleParentWrapper.hasNodeMatchingFilter, false);
|
||||
invisibleWrapper.reset();
|
||||
assert.strictEqual(invisibleParentWrapper.hasNodeMatchingFilter, true);
|
||||
|
||||
// the root should be undefined due to the reset.
|
||||
assert.strictEqual((rootWrapper as any).matchesFilter, undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@ import { Range } from 'vs/editor/common/core/range';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { EditOperation } from 'vs/editor/common/core/editOperation';
|
||||
import { TestFileService, TestEditorService, TestEditorGroupsService, TestEnvironmentService } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { TestFileService, TestEditorService, TestEditorGroupsService, TestEnvironmentService, TestLifecycleService } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { BulkEditService } from 'vs/workbench/contrib/bulkEdit/browser/bulkEditService';
|
||||
import { NullLogService, ILogService } from 'vs/platform/log/common/log';
|
||||
import { ITextModelService, IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService';
|
||||
@@ -52,6 +52,7 @@ import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/ur
|
||||
import { extUri } from 'vs/base/common/resources';
|
||||
import { ITextSnapshot } from 'vs/editor/common/model';
|
||||
import { VSBuffer, VSBufferReadable } from 'vs/base/common/buffer';
|
||||
import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle';
|
||||
|
||||
suite('MainThreadEditors', () => {
|
||||
|
||||
@@ -94,6 +95,7 @@ suite('MainThreadEditors', () => {
|
||||
services.set(ICodeEditorService, new TestCodeEditorService());
|
||||
services.set(IFileService, new TestFileService());
|
||||
services.set(IEditorService, new TestEditorService());
|
||||
services.set(ILifecycleService, new TestLifecycleService());
|
||||
services.set(IEditorGroupsService, new TestEditorGroupsService());
|
||||
services.set(ITextFileService, new class extends mock<ITextFileService>() {
|
||||
isDirty() { return false; }
|
||||
|
||||
@@ -15,6 +15,8 @@ export function setup() {
|
||||
return;
|
||||
}
|
||||
|
||||
await app.workbench.settingsEditor.addUserSetting('webview.experimental.useIframes', 'true');
|
||||
|
||||
await app.workbench.extensions.openExtensionsViewlet();
|
||||
|
||||
await app.workbench.extensions.installExtension('michelkaporin.vscode-smoketest-check', true);
|
||||
@@ -27,5 +29,11 @@ export function setup() {
|
||||
await app.workbench.quickaccess.runCommand('Smoke Test Check');
|
||||
await app.workbench.statusbar.waitForStatusbarText('smoke test', 'VS Code Smoke Test Check');
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
const app = this.app as Application;
|
||||
await app.workbench.settingsEditor.clearUserSettings();
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user