mirror of
https://github.com/Microsoft/vscode
synced 2024-09-13 13:46:13 +00:00
Merge branch 'main' into tyriar/170991
This commit is contained in:
commit
727ed13d70
|
@ -9,10 +9,10 @@ export = new class NoTestOnly implements eslint.Rule.RuleModule {
|
||||||
|
|
||||||
create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener {
|
create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener {
|
||||||
return {
|
return {
|
||||||
['MemberExpression[object.name="test"][property.name="only"]']: (node: any) => {
|
['MemberExpression[object.name=/^(test|suite)$/][property.name="only"]']: (node: any) => {
|
||||||
return context.report({
|
return context.report({
|
||||||
node,
|
node,
|
||||||
message: 'test.only is a dev-time tool and CANNOT be pushed'
|
message: 'only is a dev-time tool and CANNOT be pushed'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -149,6 +149,7 @@ steps:
|
||||||
security unlock-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain
|
security unlock-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain
|
||||||
echo "$(macos-developer-certificate)" | base64 -D > $(agent.tempdirectory)/cert.p12
|
echo "$(macos-developer-certificate)" | base64 -D > $(agent.tempdirectory)/cert.p12
|
||||||
security import $(agent.tempdirectory)/cert.p12 -k $(agent.tempdirectory)/buildagent.keychain -P "$(macos-developer-certificate-key)" -T /usr/bin/codesign
|
security import $(agent.tempdirectory)/cert.p12 -k $(agent.tempdirectory)/buildagent.keychain -P "$(macos-developer-certificate-key)" -T /usr/bin/codesign
|
||||||
|
export CODESIGN_IDENTITY=$(security find-identity -v -p codesigning $(agent.tempdirectory)/buildagent.keychain | grep -oEi "([0-9A-F]{40})" | head -n 1)
|
||||||
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k pwd $(agent.tempdirectory)/buildagent.keychain
|
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k pwd $(agent.tempdirectory)/buildagent.keychain
|
||||||
VSCODE_ARCH=$(VSCODE_ARCH) DEBUG=electron-osx-sign* node build/darwin/sign.js
|
VSCODE_ARCH=$(VSCODE_ARCH) DEBUG=electron-osx-sign* node build/darwin/sign.js
|
||||||
displayName: Set Hardened Entitlements
|
displayName: Set Hardened Entitlements
|
||||||
|
|
|
@ -237,6 +237,7 @@ steps:
|
||||||
security unlock-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain
|
security unlock-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain
|
||||||
echo "$(macos-developer-certificate)" | base64 -D > $(agent.tempdirectory)/cert.p12
|
echo "$(macos-developer-certificate)" | base64 -D > $(agent.tempdirectory)/cert.p12
|
||||||
security import $(agent.tempdirectory)/cert.p12 -k $(agent.tempdirectory)/buildagent.keychain -P "$(macos-developer-certificate-key)" -T /usr/bin/codesign
|
security import $(agent.tempdirectory)/cert.p12 -k $(agent.tempdirectory)/buildagent.keychain -P "$(macos-developer-certificate-key)" -T /usr/bin/codesign
|
||||||
|
export CODESIGN_IDENTITY=$(security find-identity -v -p codesigning $(agent.tempdirectory)/buildagent.keychain | grep -oEi "([0-9A-F]{40})" | head -n 1)
|
||||||
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k pwd $(agent.tempdirectory)/buildagent.keychain
|
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k pwd $(agent.tempdirectory)/buildagent.keychain
|
||||||
VSCODE_ARCH=$(VSCODE_ARCH) DEBUG=electron-osx-sign* node build/darwin/sign.js
|
VSCODE_ARCH=$(VSCODE_ARCH) DEBUG=electron-osx-sign* node build/darwin/sign.js
|
||||||
displayName: Set Hardened Entitlements
|
displayName: Set Hardened Entitlements
|
||||||
|
|
|
@ -13,6 +13,7 @@ async function main() {
|
||||||
const buildDir = process.env['AGENT_BUILDDIRECTORY'];
|
const buildDir = process.env['AGENT_BUILDDIRECTORY'];
|
||||||
const tempDir = process.env['AGENT_TEMPDIRECTORY'];
|
const tempDir = process.env['AGENT_TEMPDIRECTORY'];
|
||||||
const arch = process.env['VSCODE_ARCH'];
|
const arch = process.env['VSCODE_ARCH'];
|
||||||
|
const identity = process.env['CODESIGN_IDENTITY'];
|
||||||
if (!buildDir) {
|
if (!buildDir) {
|
||||||
throw new Error('$AGENT_BUILDDIRECTORY not set');
|
throw new Error('$AGENT_BUILDDIRECTORY not set');
|
||||||
}
|
}
|
||||||
|
@ -38,7 +39,7 @@ async function main() {
|
||||||
'pre-embed-provisioning-profile': false,
|
'pre-embed-provisioning-profile': false,
|
||||||
keychain: path.join(tempDir, 'buildagent.keychain'),
|
keychain: path.join(tempDir, 'buildagent.keychain'),
|
||||||
version: util.getElectronVersion(),
|
version: util.getElectronVersion(),
|
||||||
identity: '99FM488X57',
|
identity,
|
||||||
'gatekeeper-assess': false
|
'gatekeeper-assess': false
|
||||||
};
|
};
|
||||||
const appOpts = {
|
const appOpts = {
|
||||||
|
@ -104,4 +105,4 @@ if (require.main === module) {
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInNpZ24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOztBQUVoRyw4Q0FBOEM7QUFDOUMsNkJBQTZCO0FBQzdCLG9DQUFvQztBQUNwQyw4Q0FBOEM7QUFDOUMscUVBQW9EO0FBRXBELEtBQUssVUFBVSxJQUFJO0lBQ2xCLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0JBQXNCLENBQUMsQ0FBQztJQUNyRCxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLHFCQUFxQixDQUFDLENBQUM7SUFDbkQsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUV4QyxJQUFJLENBQUMsUUFBUSxFQUFFO1FBQ2QsTUFBTSxJQUFJLEtBQUssQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO0tBQ2pEO0lBRUQsSUFBSSxDQUFDLE9BQU8sRUFBRTtRQUNiLE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLENBQUMsQ0FBQztLQUNoRDtJQUVELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDeEMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsaUJBQWlCLElBQUksRUFBRSxDQUFDLENBQUM7SUFDN0QsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUM7SUFDMUMsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQy9FLE1BQU0saUJBQWlCLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQztJQUM1QyxNQUFNLGdCQUFnQixHQUFHLGlCQUFpQixHQUFHLG1CQUFtQixDQUFDO0lBQ2pFLE1BQU0scUJBQXFCLEdBQUcsaUJBQWlCLEdBQUcsd0JBQXdCLENBQUM7SUFDM0UsTUFBTSxtQkFBbUIsR0FBRyxpQkFBaUIsR0FBRyxzQkFBc0IsQ0FBQztJQUN2RSxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBRS9FLE1BQU0sV0FBVyxHQUF5QjtRQUN6QyxHQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDO1FBQ2hDLFFBQVEsRUFBRSxRQUFRO1FBQ2xCLFlBQVksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxRQUFRLEVBQUUsd0JBQXdCLENBQUM7UUFDdkYsc0JBQXNCLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLHdCQUF3QixDQUFDO1FBQ2pHLGVBQWUsRUFBRSxJQUFJO1FBQ3JCLHVCQUF1QixFQUFFLEtBQUs7UUFDOUIsZ0NBQWdDLEVBQUUsS0FBSztRQUN2QyxRQUFRLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUscUJBQXFCLENBQUM7UUFDbkQsT0FBTyxFQUFFLElBQUksQ0FBQyxrQkFBa0IsRUFBRTtRQUNsQyxRQUFRLEVBQUUsWUFBWTtRQUN0QixtQkFBbUIsRUFBRSxLQUFLO0tBQzFCLENBQUM7SUFFRixNQUFNLE9BQU8sR0FBRztRQUNmLEdBQUcsV0FBVztRQUNkLG1FQUFtRTtRQUNuRSxNQUFNLEVBQUUsQ0FBQyxRQUFnQixFQUFFLEVBQUU7WUFDNUIsT0FBTyxRQUFRLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDO2dCQUN6QyxRQUFRLENBQUMsUUFBUSxDQUFDLHFCQUFxQixDQUFDO2dCQUN4QyxRQUFRLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDekMsQ0FBQztLQUNELENBQUM7SUFFRixNQUFNLGFBQWEsR0FBeUI7UUFDM0MsR0FBRyxXQUFXO1FBQ2QsR0FBRyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsZ0JBQWdCLENBQUM7UUFDbEQsWUFBWSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFFBQVEsRUFBRSwrQkFBK0IsQ0FBQztRQUM5RixzQkFBc0IsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxRQUFRLEVBQUUsK0JBQStCLENBQUM7S0FDeEcsQ0FBQztJQUVGLE1BQU0sa0JBQWtCLEdBQXlCO1FBQ2hELEdBQUcsV0FBVztRQUNkLEdBQUcsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLHFCQUFxQixDQUFDO1FBQ3ZELFlBQVksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxRQUFRLEVBQUUsb0NBQW9DLENBQUM7UUFDbkcsc0JBQXNCLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLG9DQUFvQyxDQUFDO0tBQzdHLENBQUM7SUFFRixNQUFNLGdCQUFnQixHQUF5QjtRQUM5QyxHQUFHLFdBQVc7UUFDZCxHQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxtQkFBbUIsQ0FBQztRQUNyRCxZQUFZLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLGtDQUFrQyxDQUFDO1FBQ2pHLHNCQUFzQixFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFFBQVEsRUFBRSxrQ0FBa0MsQ0FBQztLQUMzRyxDQUFDO0lBRUYseURBQXlEO0lBQ3pELGtEQUFrRDtJQUNsRCxJQUFJLElBQUksS0FBSyxXQUFXLEVBQUU7UUFDekIsTUFBTSxJQUFBLDJCQUFLLEVBQUMsUUFBUSxFQUFFO1lBQ3JCLFNBQVM7WUFDVCwrQkFBK0I7WUFDL0IsU0FBUztZQUNULGdFQUFnRTtZQUNoRSxHQUFHLGFBQWEsRUFBRTtTQUNsQixDQUFDLENBQUM7UUFDSCxNQUFNLElBQUEsMkJBQUssRUFBQyxRQUFRLEVBQUU7WUFDckIsVUFBVTtZQUNWLDhCQUE4QjtZQUM5QixTQUFTO1lBQ1QsbUVBQW1FO1lBQ25FLEdBQUcsYUFBYSxFQUFFO1NBQ2xCLENBQUMsQ0FBQztRQUNILE1BQU0sSUFBQSwyQkFBSyxFQUFDLFFBQVEsRUFBRTtZQUNyQixVQUFVO1lBQ1YsMEJBQTBCO1lBQzFCLFNBQVM7WUFDVCwrREFBK0Q7WUFDL0QsR0FBRyxhQUFhLEVBQUU7U0FDbEIsQ0FBQyxDQUFDO0tBQ0g7SUFFRCxNQUFNLFFBQVEsQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDeEMsTUFBTSxRQUFRLENBQUMsU0FBUyxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDN0MsTUFBTSxRQUFRLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDM0MsTUFBTSxRQUFRLENBQUMsU0FBUyxDQUFDLE9BQWMsQ0FBQyxDQUFDO0FBQzFDLENBQUM7QUFFRCxJQUFJLE9BQU8sQ0FBQyxJQUFJLEtBQUssTUFBTSxFQUFFO0lBQzVCLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRTtRQUNsQixPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ25CLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakIsQ0FBQyxDQUFDLENBQUM7Q0FDSCJ9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInNpZ24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOztBQUVoRyw4Q0FBOEM7QUFDOUMsNkJBQTZCO0FBQzdCLG9DQUFvQztBQUNwQyw4Q0FBOEM7QUFDOUMscUVBQW9EO0FBRXBELEtBQUssVUFBVSxJQUFJO0lBQ2xCLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0JBQXNCLENBQUMsQ0FBQztJQUNyRCxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLHFCQUFxQixDQUFDLENBQUM7SUFDbkQsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUN4QyxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFFbEQsSUFBSSxDQUFDLFFBQVEsRUFBRTtRQUNkLE1BQU0sSUFBSSxLQUFLLENBQUMsK0JBQStCLENBQUMsQ0FBQztLQUNqRDtJQUVELElBQUksQ0FBQyxPQUFPLEVBQUU7UUFDYixNQUFNLElBQUksS0FBSyxDQUFDLDhCQUE4QixDQUFDLENBQUM7S0FDaEQ7SUFFRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3hDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLGlCQUFpQixJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzdELE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDO0lBQzFDLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUMvRSxNQUFNLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUM7SUFDNUMsTUFBTSxnQkFBZ0IsR0FBRyxpQkFBaUIsR0FBRyxtQkFBbUIsQ0FBQztJQUNqRSxNQUFNLHFCQUFxQixHQUFHLGlCQUFpQixHQUFHLHdCQUF3QixDQUFDO0lBQzNFLE1BQU0sbUJBQW1CLEdBQUcsaUJBQWlCLEdBQUcsc0JBQXNCLENBQUM7SUFDdkUsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUUvRSxNQUFNLFdBQVcsR0FBeUI7UUFDekMsR0FBRyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQztRQUNoQyxRQUFRLEVBQUUsUUFBUTtRQUNsQixZQUFZLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLHdCQUF3QixDQUFDO1FBQ3ZGLHNCQUFzQixFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFFBQVEsRUFBRSx3QkFBd0IsQ0FBQztRQUNqRyxlQUFlLEVBQUUsSUFBSTtRQUNyQix1QkFBdUIsRUFBRSxLQUFLO1FBQzlCLGdDQUFnQyxFQUFFLEtBQUs7UUFDdkMsUUFBUSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLHFCQUFxQixDQUFDO1FBQ25ELE9BQU8sRUFBRSxJQUFJLENBQUMsa0JBQWtCLEVBQUU7UUFDbEMsUUFBUTtRQUNSLG1CQUFtQixFQUFFLEtBQUs7S0FDMUIsQ0FBQztJQUVGLE1BQU0sT0FBTyxHQUFHO1FBQ2YsR0FBRyxXQUFXO1FBQ2QsbUVBQW1FO1FBQ25FLE1BQU0sRUFBRSxDQUFDLFFBQWdCLEVBQUUsRUFBRTtZQUM1QixPQUFPLFFBQVEsQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUM7Z0JBQ3pDLFFBQVEsQ0FBQyxRQUFRLENBQUMscUJBQXFCLENBQUM7Z0JBQ3hDLFFBQVEsQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUN6QyxDQUFDO0tBQ0QsQ0FBQztJQUVGLE1BQU0sYUFBYSxHQUF5QjtRQUMzQyxHQUFHLFdBQVc7UUFDZCxHQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxnQkFBZ0IsQ0FBQztRQUNsRCxZQUFZLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLCtCQUErQixDQUFDO1FBQzlGLHNCQUFzQixFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFFBQVEsRUFBRSwrQkFBK0IsQ0FBQztLQUN4RyxDQUFDO0lBRUYsTUFBTSxrQkFBa0IsR0FBeUI7UUFDaEQsR0FBRyxXQUFXO1FBQ2QsR0FBRyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUscUJBQXFCLENBQUM7UUFDdkQsWUFBWSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFFBQVEsRUFBRSxvQ0FBb0MsQ0FBQztRQUNuRyxzQkFBc0IsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxRQUFRLEVBQUUsb0NBQW9DLENBQUM7S0FDN0csQ0FBQztJQUVGLE1BQU0sZ0JBQWdCLEdBQXlCO1FBQzlDLEdBQUcsV0FBVztRQUNkLEdBQUcsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLG1CQUFtQixDQUFDO1FBQ3JELFlBQVksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxRQUFRLEVBQUUsa0NBQWtDLENBQUM7UUFDakcsc0JBQXNCLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLGtDQUFrQyxDQUFDO0tBQzNHLENBQUM7SUFFRix5REFBeUQ7SUFDekQsa0RBQWtEO0lBQ2xELElBQUksSUFBSSxLQUFLLFdBQVcsRUFBRTtRQUN6QixNQUFNLElBQUEsMkJBQUssRUFBQyxRQUFRLEVBQUU7WUFDckIsU0FBUztZQUNULCtCQUErQjtZQUMvQixTQUFTO1lBQ1QsZ0VBQWdFO1lBQ2hFLEdBQUcsYUFBYSxFQUFFO1NBQ2xCLENBQUMsQ0FBQztRQUNILE1BQU0sSUFBQSwyQkFBSyxFQUFDLFFBQVEsRUFBRTtZQUNyQixVQUFVO1lBQ1YsOEJBQThCO1lBQzlCLFNBQVM7WUFDVCxtRUFBbUU7WUFDbkUsR0FBRyxhQUFhLEVBQUU7U0FDbEIsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxJQUFBLDJCQUFLLEVBQUMsUUFBUSxFQUFFO1lBQ3JCLFVBQVU7WUFDViwwQkFBMEI7WUFDMUIsU0FBUztZQUNULCtEQUErRDtZQUMvRCxHQUFHLGFBQWEsRUFBRTtTQUNsQixDQUFDLENBQUM7S0FDSDtJQUVELE1BQU0sUUFBUSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUN4QyxNQUFNLFFBQVEsQ0FBQyxTQUFTLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUM3QyxNQUFNLFFBQVEsQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUMzQyxNQUFNLFFBQVEsQ0FBQyxTQUFTLENBQUMsT0FBYyxDQUFDLENBQUM7QUFDMUMsQ0FBQztBQUVELElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUU7SUFDNUIsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1FBQ2xCLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbkIsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNqQixDQUFDLENBQUMsQ0FBQztDQUNIIn0=
|
|
@ -13,6 +13,7 @@ async function main(): Promise<void> {
|
||||||
const buildDir = process.env['AGENT_BUILDDIRECTORY'];
|
const buildDir = process.env['AGENT_BUILDDIRECTORY'];
|
||||||
const tempDir = process.env['AGENT_TEMPDIRECTORY'];
|
const tempDir = process.env['AGENT_TEMPDIRECTORY'];
|
||||||
const arch = process.env['VSCODE_ARCH'];
|
const arch = process.env['VSCODE_ARCH'];
|
||||||
|
const identity = process.env['CODESIGN_IDENTITY'];
|
||||||
|
|
||||||
if (!buildDir) {
|
if (!buildDir) {
|
||||||
throw new Error('$AGENT_BUILDDIRECTORY not set');
|
throw new Error('$AGENT_BUILDDIRECTORY not set');
|
||||||
|
@ -42,7 +43,7 @@ async function main(): Promise<void> {
|
||||||
'pre-embed-provisioning-profile': false,
|
'pre-embed-provisioning-profile': false,
|
||||||
keychain: path.join(tempDir, 'buildagent.keychain'),
|
keychain: path.join(tempDir, 'buildagent.keychain'),
|
||||||
version: util.getElectronVersion(),
|
version: util.getElectronVersion(),
|
||||||
identity: '99FM488X57',
|
identity,
|
||||||
'gatekeeper-assess': false
|
'gatekeeper-assess': false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
|
|
||||||
import { Model } from '../model';
|
import { Model } from '../model';
|
||||||
import { Repository as BaseRepository, Resource } from '../repository';
|
import { Repository as BaseRepository, Resource } from '../repository';
|
||||||
import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, ForcePushMode, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions, APIState, CommitOptions, RefType, CredentialsProvider, BranchQuery, PushErrorHandler, PublishEvent, FetchOptions, RemoteSourceProvider, RemoteSourcePublisher, PostCommitCommandsProvider } from './git';
|
import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, ForcePushMode, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions, APIState, CommitOptions, RefType, CredentialsProvider, BranchQuery, PushErrorHandler, PublishEvent, FetchOptions, RemoteSourceProvider, RemoteSourcePublisher, PostCommitCommandsProvider, RefQuery } from './git';
|
||||||
import { Event, SourceControlInputBox, Uri, SourceControl, Disposable, commands } from 'vscode';
|
import { Event, SourceControlInputBox, Uri, SourceControl, Disposable, commands, CancellationToken } from 'vscode';
|
||||||
import { combinedDisposable, mapEvent } from '../util';
|
import { combinedDisposable, mapEvent } from '../util';
|
||||||
import { toGitUri } from '../uri';
|
import { toGitUri } from '../uri';
|
||||||
import { GitExtensionImpl } from './extension';
|
import { GitExtensionImpl } from './extension';
|
||||||
|
@ -170,14 +170,18 @@ export class ApiRepository implements Repository {
|
||||||
return this.repository.getBranch(name);
|
return this.repository.getBranch(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
getBranches(query: BranchQuery): Promise<Ref[]> {
|
getBranches(query: BranchQuery, cancellationToken?: CancellationToken): Promise<Ref[]> {
|
||||||
return this.repository.getBranches(query);
|
return this.repository.getBranches(query, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
setBranchUpstream(name: string, upstream: string): Promise<void> {
|
setBranchUpstream(name: string, upstream: string): Promise<void> {
|
||||||
return this.repository.setBranchUpstream(name, upstream);
|
return this.repository.setBranchUpstream(name, upstream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getRefs(query: RefQuery, cancellationToken?: CancellationToken): Promise<Ref[]> {
|
||||||
|
return this.repository.getRefs(query, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
getMergeBase(ref1: string, ref2: string): Promise<string> {
|
getMergeBase(ref1: string, ref2: string): Promise<string> {
|
||||||
return this.repository.getMergeBase(ref1, ref2);
|
return this.repository.getMergeBase(ref1, ref2);
|
||||||
}
|
}
|
||||||
|
|
18
extensions/git/src/api/git.d.ts
vendored
18
extensions/git/src/api/git.d.ts
vendored
|
@ -3,7 +3,7 @@
|
||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { Uri, Event, Disposable, ProviderResult, Command } from 'vscode';
|
import { Uri, Event, Disposable, ProviderResult, Command, CancellationToken } from 'vscode';
|
||||||
export { ProviderResult } from 'vscode';
|
export { ProviderResult } from 'vscode';
|
||||||
|
|
||||||
export interface Git {
|
export interface Git {
|
||||||
|
@ -156,11 +156,15 @@ export interface FetchOptions {
|
||||||
depth?: number;
|
depth?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BranchQuery {
|
export interface RefQuery {
|
||||||
readonly remote?: boolean;
|
|
||||||
readonly pattern?: string;
|
|
||||||
readonly count?: number;
|
|
||||||
readonly contains?: string;
|
readonly contains?: string;
|
||||||
|
readonly count?: number;
|
||||||
|
readonly pattern?: string;
|
||||||
|
readonly sort?: 'alphabetically' | 'committerdate';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BranchQuery extends RefQuery {
|
||||||
|
readonly remote?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Repository {
|
export interface Repository {
|
||||||
|
@ -204,9 +208,11 @@ export interface Repository {
|
||||||
createBranch(name: string, checkout: boolean, ref?: string): Promise<void>;
|
createBranch(name: string, checkout: boolean, ref?: string): Promise<void>;
|
||||||
deleteBranch(name: string, force?: boolean): Promise<void>;
|
deleteBranch(name: string, force?: boolean): Promise<void>;
|
||||||
getBranch(name: string): Promise<Branch>;
|
getBranch(name: string): Promise<Branch>;
|
||||||
getBranches(query: BranchQuery): Promise<Ref[]>;
|
getBranches(query: BranchQuery, cancellationToken?: CancellationToken): Promise<Ref[]>;
|
||||||
setBranchUpstream(name: string, upstream: string): Promise<void>;
|
setBranchUpstream(name: string, upstream: string): Promise<void>;
|
||||||
|
|
||||||
|
getRefs(query: RefQuery, cancellationToken?: CancellationToken): Promise<Ref[]>;
|
||||||
|
|
||||||
getMergeBase(ref1: string, ref2: string): Promise<string>;
|
getMergeBase(ref1: string, ref2: string): Promise<string>;
|
||||||
|
|
||||||
tag(name: string, upstream: string): Promise<void>;
|
tag(name: string, upstream: string): Promise<void>;
|
||||||
|
|
|
@ -2189,12 +2189,6 @@ export class CommandCenter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _branch(repository: Repository, defaultName?: string, from = false): Promise<void> {
|
private async _branch(repository: Repository, defaultName?: string, from = false): Promise<void> {
|
||||||
const branchName = await this.promptForBranchName(repository, defaultName);
|
|
||||||
|
|
||||||
if (!branchName) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let target = 'HEAD';
|
let target = 'HEAD';
|
||||||
|
|
||||||
if (from) {
|
if (from) {
|
||||||
|
@ -2202,7 +2196,7 @@ export class CommandCenter {
|
||||||
return [new HEADItem(repository), ...await createCheckoutItems(repository)];
|
return [new HEADItem(repository), ...await createCheckoutItems(repository)];
|
||||||
};
|
};
|
||||||
|
|
||||||
const placeHolder = l10n.t('Select a ref to create the "{0}" branch from', branchName);
|
const placeHolder = l10n.t('Select a ref to create the branch from');
|
||||||
const choice = await window.showQuickPick(getRefPicks(), { placeHolder });
|
const choice = await window.showQuickPick(getRefPicks(), { placeHolder });
|
||||||
|
|
||||||
if (!choice) {
|
if (!choice) {
|
||||||
|
@ -2214,6 +2208,12 @@ export class CommandCenter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const branchName = await this.promptForBranchName(repository, defaultName);
|
||||||
|
|
||||||
|
if (!branchName) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await repository.branch(branchName, true, target);
|
await repository.branch(branchName, true, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ import * as filetype from 'file-type';
|
||||||
import { assign, groupBy, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent, splitInChunks, Limiter, Versions, isWindows } from './util';
|
import { assign, groupBy, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent, splitInChunks, Limiter, Versions, isWindows } from './util';
|
||||||
import { CancellationError, CancellationToken, ConfigurationChangeEvent, LogOutputChannel, Progress, Uri, workspace } from 'vscode';
|
import { CancellationError, CancellationToken, ConfigurationChangeEvent, LogOutputChannel, Progress, Uri, workspace } from 'vscode';
|
||||||
import { detectEncoding } from './encoding';
|
import { detectEncoding } from './encoding';
|
||||||
import { Ref, RefType, Branch, Remote, ForcePushMode, GitErrorCodes, LogOptions, Change, Status, CommitOptions, BranchQuery } from './api/git';
|
import { Ref, RefType, Branch, Remote, ForcePushMode, GitErrorCodes, LogOptions, Change, Status, CommitOptions, RefQuery } from './api/git';
|
||||||
import * as byline from 'byline';
|
import * as byline from 'byline';
|
||||||
import { StringDecoder } from 'string_decoder';
|
import { StringDecoder } from 'string_decoder';
|
||||||
|
|
||||||
|
@ -2164,32 +2164,32 @@ export class Repository {
|
||||||
.map(([ref]) => ({ name: ref, type: RefType.Head } as Branch));
|
.map(([ref]) => ({ name: ref, type: RefType.Head } as Branch));
|
||||||
}
|
}
|
||||||
|
|
||||||
async getRefs(opts?: { sort?: 'alphabetically' | 'committerdate'; contains?: string; pattern?: string; count?: number; cancellationToken?: CancellationToken }): Promise<Ref[]> {
|
async getRefs(query: RefQuery, cancellationToken?: CancellationToken): Promise<Ref[]> {
|
||||||
if (opts?.cancellationToken && opts?.cancellationToken.isCancellationRequested) {
|
if (cancellationToken && cancellationToken.isCancellationRequested) {
|
||||||
throw new CancellationError();
|
throw new CancellationError();
|
||||||
}
|
}
|
||||||
|
|
||||||
const args = ['for-each-ref'];
|
const args = ['for-each-ref'];
|
||||||
|
|
||||||
if (opts?.count) {
|
if (query.count) {
|
||||||
args.push(`--count=${opts.count}`);
|
args.push(`--count=${query.count}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts && opts.sort && opts.sort !== 'alphabetically') {
|
if (query.sort && query.sort !== 'alphabetically') {
|
||||||
args.push('--sort', `-${opts.sort}`);
|
args.push('--sort', `-${query.sort}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
args.push('--format', '%(refname) %(objectname) %(*objectname)');
|
args.push('--format', '%(refname) %(objectname) %(*objectname)');
|
||||||
|
|
||||||
if (opts?.pattern) {
|
if (query.pattern) {
|
||||||
args.push(opts.pattern);
|
args.push(query.pattern.startsWith('refs/') ? query.pattern : `refs/${query.pattern}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts?.contains) {
|
if (query.contains) {
|
||||||
args.push('--contains', opts.contains);
|
args.push('--contains', query.contains);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await this.exec(args, { cancellationToken: opts?.cancellationToken });
|
const result = await this.exec(args, { cancellationToken });
|
||||||
|
|
||||||
const fn = (line: string): Ref | null => {
|
const fn = (line: string): Ref | null => {
|
||||||
let match: RegExpExecArray | null;
|
let match: RegExpExecArray | null;
|
||||||
|
@ -2404,11 +2404,6 @@ export class Repository {
|
||||||
return Promise.reject<Branch>(new Error('No such branch'));
|
return Promise.reject<Branch>(new Error('No such branch'));
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBranches(query: BranchQuery): Promise<Ref[]> {
|
|
||||||
const refs = await this.getRefs({ contains: query.contains, pattern: query.pattern ? `refs/${query.pattern}` : undefined, count: query.count });
|
|
||||||
return refs.filter(value => (value.type !== RefType.Tag) && (query.remote || !value.remote));
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Support core.commentChar
|
// TODO: Support core.commentChar
|
||||||
stripCommitMessageComments(message: string): string {
|
stripCommitMessageComments(message: string): string {
|
||||||
return message.replace(/^\s*#.*$\n?/gm, '').trim();
|
return message.replace(/^\s*#.*$\n?/gm, '').trim();
|
||||||
|
|
|
@ -8,7 +8,7 @@ import * as path from 'path';
|
||||||
import * as picomatch from 'picomatch';
|
import * as picomatch from 'picomatch';
|
||||||
import { CancellationToken, Command, Disposable, Event, EventEmitter, Memento, ProgressLocation, ProgressOptions, scm, SourceControl, SourceControlInputBox, SourceControlInputBoxValidation, SourceControlInputBoxValidationType, SourceControlResourceDecorations, SourceControlResourceGroup, SourceControlResourceState, ThemeColor, Uri, window, workspace, WorkspaceEdit, FileDecoration, commands, Tab, TabInputTextDiff, TabInputNotebookDiff, RelativePattern, CancellationTokenSource, LogOutputChannel, LogLevel, CancellationError, l10n } from 'vscode';
|
import { CancellationToken, Command, Disposable, Event, EventEmitter, Memento, ProgressLocation, ProgressOptions, scm, SourceControl, SourceControlInputBox, SourceControlInputBoxValidation, SourceControlInputBoxValidationType, SourceControlResourceDecorations, SourceControlResourceGroup, SourceControlResourceState, ThemeColor, Uri, window, workspace, WorkspaceEdit, FileDecoration, commands, Tab, TabInputTextDiff, TabInputNotebookDiff, RelativePattern, CancellationTokenSource, LogOutputChannel, LogLevel, CancellationError, l10n } from 'vscode';
|
||||||
import TelemetryReporter from '@vscode/extension-telemetry';
|
import TelemetryReporter from '@vscode/extension-telemetry';
|
||||||
import { Branch, Change, ForcePushMode, GitErrorCodes, LogOptions, Ref, Remote, Status, CommitOptions, BranchQuery, FetchOptions } from './api/git';
|
import { Branch, Change, ForcePushMode, GitErrorCodes, LogOptions, Ref, Remote, Status, CommitOptions, BranchQuery, FetchOptions, RefQuery, RefType } from './api/git';
|
||||||
import { AutoFetcher } from './autofetch';
|
import { AutoFetcher } from './autofetch';
|
||||||
import { debounce, memoize, throttle } from './decorators';
|
import { debounce, memoize, throttle } from './decorators';
|
||||||
import { Commit, GitError, Repository as BaseRepository, Stash, Submodule, LogFileOptions, PullOptions } from './git';
|
import { Commit, GitError, Repository as BaseRepository, Stash, Submodule, LogFileOptions, PullOptions } from './git';
|
||||||
|
@ -1374,12 +1374,22 @@ export class Repository implements Disposable {
|
||||||
return await this.run(Operation.GetBranch, () => this.repository.getBranch(name));
|
return await this.run(Operation.GetBranch, () => this.repository.getBranch(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBranches(query: BranchQuery): Promise<Ref[]> {
|
async getBranches(query: BranchQuery = {}, cancellationToken?: CancellationToken): Promise<Ref[]> {
|
||||||
return await this.run(Operation.GetBranches, () => this.repository.getBranches(query));
|
return await this.run(Operation.GetBranches, async () => {
|
||||||
|
const refs = await this.getRefs(query, cancellationToken);
|
||||||
|
return refs.filter(value => (value.type === RefType.Head || value.type === RefType.RemoteHead) && (query.remote || !value.remote));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async getRefs(opts?: { sort?: 'alphabetically' | 'committerdate'; contains?: string; pattern?: string; count?: number; cancellationToken?: CancellationToken }): Promise<Ref[]> {
|
async getRefs(query: RefQuery = {}, cancellationToken?: CancellationToken): Promise<Ref[]> {
|
||||||
return await this.run(Operation.GetRefs, () => this.repository.getRefs(opts));
|
const config = workspace.getConfiguration('git');
|
||||||
|
let defaultSort = config.get<'alphabetically' | 'committerdate'>('branchSortOrder');
|
||||||
|
if (defaultSort !== 'alphabetically' && defaultSort !== 'committerdate') {
|
||||||
|
defaultSort = 'alphabetically';
|
||||||
|
}
|
||||||
|
|
||||||
|
query = { ...query, sort: query?.sort ?? defaultSort };
|
||||||
|
return await this.run(Operation.GetRefs, () => this.repository.getRefs(query, cancellationToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
async getRemoteRefs(remote: string, opts?: { heads?: boolean; tags?: boolean }): Promise<Ref[]> {
|
async getRemoteRefs(remote: string, opts?: { heads?: boolean; tags?: boolean }): Promise<Ref[]> {
|
||||||
|
@ -1992,16 +2002,10 @@ export class Repository implements Disposable {
|
||||||
this._sourceControl.commitTemplate = commitTemplate;
|
this._sourceControl.commitTemplate = commitTemplate;
|
||||||
|
|
||||||
// Execute cancellable long-running operations
|
// Execute cancellable long-running operations
|
||||||
const config = workspace.getConfiguration('git');
|
|
||||||
let sort = config.get<'alphabetically' | 'committerdate'>('branchSortOrder') || 'alphabetically';
|
|
||||||
if (sort !== 'alphabetically' && sort !== 'committerdate') {
|
|
||||||
sort = 'alphabetically';
|
|
||||||
}
|
|
||||||
|
|
||||||
const [resourceGroups, refs] =
|
const [resourceGroups, refs] =
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.getStatus(cancellationToken),
|
this.getStatus(cancellationToken),
|
||||||
this.repository.getRefs({ sort, cancellationToken })]);
|
this.getRefs({}, cancellationToken)]);
|
||||||
|
|
||||||
this._refs = refs!;
|
this._refs = refs!;
|
||||||
this._updateResourceGroupsState(resourceGroups);
|
this._updateResourceGroupsState(resourceGroups);
|
||||||
|
|
|
@ -48,6 +48,14 @@ function renderImage(outputInfo: OutputItem, element: HTMLElement): IDisposable
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (element.firstChild) {
|
||||||
|
const display = element.firstChild as HTMLElement;
|
||||||
|
if (display.firstChild && display.firstChild.nodeName === 'IMG' && display.firstChild instanceof HTMLImageElement) {
|
||||||
|
display.firstChild.src = src;
|
||||||
|
return disposable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const image = document.createElement('img');
|
const image = document.createElement('img');
|
||||||
image.src = src;
|
image.src = src;
|
||||||
const display = document.createElement('div');
|
const display = document.createElement('div');
|
||||||
|
@ -301,6 +309,7 @@ export const activate: ActivationFunction<void> = (ctx) => {
|
||||||
case 'image/jpeg':
|
case 'image/jpeg':
|
||||||
case 'image/git':
|
case 'image/git':
|
||||||
{
|
{
|
||||||
|
disposables.get(outputInfo.id)?.dispose();
|
||||||
const disposable = renderImage(outputInfo, element);
|
const disposable = renderImage(outputInfo, element);
|
||||||
disposables.set(outputInfo.id, disposable);
|
disposables.set(outputInfo.id, disposable);
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,7 @@
|
||||||
"@vscode/l10n-dev": "0.0.21",
|
"@vscode/l10n-dev": "0.0.21",
|
||||||
"@vscode/telemetry-extractor": "^1.9.8",
|
"@vscode/telemetry-extractor": "^1.9.8",
|
||||||
"@vscode/test-web": "^0.0.32",
|
"@vscode/test-web": "^0.0.32",
|
||||||
"@vscode/vscode-perf": "^0.0.1",
|
"@vscode/vscode-perf": "^0.0.2",
|
||||||
"ansi-colors": "^3.2.3",
|
"ansi-colors": "^3.2.3",
|
||||||
"asar": "^3.0.3",
|
"asar": "^3.0.3",
|
||||||
"chromium-pickle-js": "^0.2.0",
|
"chromium-pickle-js": "^0.2.0",
|
||||||
|
|
|
@ -685,10 +685,6 @@ export class MouseController<T> implements IDisposable {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.browserEvent.defaultPrevented) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const focus = e.index;
|
const focus = e.index;
|
||||||
|
|
||||||
if (typeof focus === 'undefined') {
|
if (typeof focus === 'undefined') {
|
||||||
|
@ -713,7 +709,6 @@ export class MouseController<T> implements IDisposable {
|
||||||
this.list.setSelection([focus], e.browserEvent);
|
this.list.setSelection([focus], e.browserEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
e.browserEvent.preventDefault();
|
|
||||||
this._onPointer.fire(e);
|
this._onPointer.fire(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -726,13 +721,8 @@ export class MouseController<T> implements IDisposable {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.browserEvent.defaultPrevented) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const focus = this.list.getFocus();
|
const focus = this.list.getFocus();
|
||||||
this.list.setSelection(focus, e.browserEvent);
|
this.list.setSelection(focus, e.browserEvent);
|
||||||
e.browserEvent.preventDefault();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private changeSelection(e: IListMouseEvent<T> | IListTouchEvent<T>): void {
|
private changeSelection(e: IListMouseEvent<T> | IListTouchEvent<T>): void {
|
||||||
|
|
|
@ -1358,10 +1358,6 @@ class TreeNodeListMouseController<T, TFilterData, TRef> extends MouseController<
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.browserEvent.defaultPrevented) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const node = e.element;
|
const node = e.element;
|
||||||
|
|
||||||
if (!node) {
|
if (!node) {
|
||||||
|
@ -1413,10 +1409,6 @@ class TreeNodeListMouseController<T, TFilterData, TRef> extends MouseController<
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.browserEvent.defaultPrevented) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
super.onDoubleClick(e);
|
super.onDoubleClick(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -821,24 +821,32 @@ export class CodeApplication extends Disposable {
|
||||||
const windowsMainService = this.windowsMainService = accessor.get(IWindowsMainService);
|
const windowsMainService = this.windowsMainService = accessor.get(IWindowsMainService);
|
||||||
const urlService = accessor.get(IURLService);
|
const urlService = accessor.get(IURLService);
|
||||||
const nativeHostMainService = accessor.get(INativeHostMainService);
|
const nativeHostMainService = accessor.get(INativeHostMainService);
|
||||||
|
const logService = this.logService;
|
||||||
|
|
||||||
// Signal phase: ready (services set)
|
// Signal phase: ready (services set)
|
||||||
this.lifecycleMainService.phase = LifecycleMainPhase.Ready;
|
this.lifecycleMainService.phase = LifecycleMainPhase.Ready;
|
||||||
|
|
||||||
// Check for initial URLs to handle from protocol link invocations
|
// Check for initial URLs to handle from protocol link invocations
|
||||||
|
const protocolLinksFromCommandLine = this.environmentMainService.args['open-url'] ? this.environmentMainService.args._urls || [] : []; // Windows/Linux: protocol handler invokes CLI with --open-url
|
||||||
|
if (protocolLinksFromCommandLine.length) {
|
||||||
|
logService.trace('app#openFirstWindow() protocol links from command line:', protocolLinksFromCommandLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
const protocolLinksFromEvent = ((<any>global).getOpenUrls() || []) as string[]; // macOS: open-url events
|
||||||
|
if (protocolLinksFromEvent.length) {
|
||||||
|
logService.trace(`app#openFirstWindow() protocol links from macOS 'open-url' event:`, protocolLinksFromEvent);
|
||||||
|
}
|
||||||
|
|
||||||
const pendingWindowOpenablesFromProtocolLinks: IWindowOpenable[] = [];
|
const pendingWindowOpenablesFromProtocolLinks: IWindowOpenable[] = [];
|
||||||
const pendingProtocolLinksToHandle = [
|
const pendingProtocolLinksToHandle = [
|
||||||
|
...protocolLinksFromCommandLine,
|
||||||
// Windows/Linux: protocol handler invokes CLI with --open-url
|
...protocolLinksFromEvent
|
||||||
...this.environmentMainService.args['open-url'] ? this.environmentMainService.args._urls || [] : [],
|
|
||||||
|
|
||||||
// macOS: open-url events
|
|
||||||
...((<any>global).getOpenUrls() || []) as string[]
|
|
||||||
|
|
||||||
].map(url => {
|
].map(url => {
|
||||||
try {
|
try {
|
||||||
return { uri: URI.parse(url), url };
|
return { uri: URI.parse(url), url };
|
||||||
} catch {
|
} catch {
|
||||||
|
logService.trace('app#openFirstWindow() protocol link failed to parse:', url);
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}).filter((obj): obj is { uri: URI; url: string } => {
|
}).filter((obj): obj is { uri: URI; url: string } => {
|
||||||
|
@ -848,6 +856,8 @@ export class CodeApplication extends Disposable {
|
||||||
|
|
||||||
// If URI should be blocked, filter it out
|
// If URI should be blocked, filter it out
|
||||||
if (this.shouldBlockURI(obj.uri)) {
|
if (this.shouldBlockURI(obj.uri)) {
|
||||||
|
logService.trace('app#openFirstWindow() protocol link was blocked:', obj.uri.toString(true));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -856,11 +866,15 @@ export class CodeApplication extends Disposable {
|
||||||
// previous workspace too.
|
// previous workspace too.
|
||||||
const windowOpenable = this.getWindowOpenableFromProtocolLink(obj.uri);
|
const windowOpenable = this.getWindowOpenableFromProtocolLink(obj.uri);
|
||||||
if (windowOpenable) {
|
if (windowOpenable) {
|
||||||
|
logService.trace('app#openFirstWindow() protocol link will be handled as window to open:', obj.uri.toString(true), windowOpenable);
|
||||||
|
|
||||||
pendingWindowOpenablesFromProtocolLinks.push(windowOpenable);
|
pendingWindowOpenablesFromProtocolLinks.push(windowOpenable);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logService.trace('app#openFirstWindow() protocol link will be passed to active window for handling:', obj.uri.toString(true));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -870,11 +884,11 @@ export class CodeApplication extends Disposable {
|
||||||
const app = this;
|
const app = this;
|
||||||
const environmentService = this.environmentMainService;
|
const environmentService = this.environmentMainService;
|
||||||
const productService = this.productService;
|
const productService = this.productService;
|
||||||
const logService = this.logService;
|
|
||||||
urlService.registerHandler({
|
urlService.registerHandler({
|
||||||
async handleURL(uri: URI, options?: IOpenURLOptions): Promise<boolean> {
|
async handleURL(uri: URI, options?: IOpenURLOptions): Promise<boolean> {
|
||||||
logService.trace('app#handleURL: ', uri.toString(true), options);
|
logService.trace('app#handleURL():', uri.toString(true), options);
|
||||||
|
|
||||||
|
// Support 'workspace' URLs (https://github.com/microsoft/vscode/issues/124263)
|
||||||
if (uri.scheme === productService.urlProtocol && uri.path === 'workspace') {
|
if (uri.scheme === productService.urlProtocol && uri.path === 'workspace') {
|
||||||
uri = uri.with({
|
uri = uri.with({
|
||||||
authority: 'file',
|
authority: 'file',
|
||||||
|
@ -885,6 +899,8 @@ export class CodeApplication extends Disposable {
|
||||||
|
|
||||||
// If URI should be blocked, behave as if it's handled
|
// If URI should be blocked, behave as if it's handled
|
||||||
if (app.shouldBlockURI(uri)) {
|
if (app.shouldBlockURI(uri)) {
|
||||||
|
logService.trace('app#handleURL() protocol link was blocked:', uri.toString(true));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -893,26 +909,37 @@ export class CodeApplication extends Disposable {
|
||||||
// We should handle the URI in a new window if the URL contains `windowId=_blank`
|
// We should handle the URI in a new window if the URL contains `windowId=_blank`
|
||||||
const params = new URLSearchParams(uri.query);
|
const params = new URLSearchParams(uri.query);
|
||||||
if (params.get('windowId') === '_blank') {
|
if (params.get('windowId') === '_blank') {
|
||||||
|
logService.trace(`app#handleURL() found 'windowId=_blank' as parameter, setting shouldOpenInNewWindow=true:`, uri.toString(true));
|
||||||
|
|
||||||
params.delete('windowId');
|
params.delete('windowId');
|
||||||
uri = uri.with({ query: params.toString() });
|
uri = uri.with({ query: params.toString() });
|
||||||
|
|
||||||
shouldOpenInNewWindow = true;
|
shouldOpenInNewWindow = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// or if no window is open (macOS only)
|
// or if no window is open (macOS only)
|
||||||
shouldOpenInNewWindow ||= isMacintosh && windowsMainService.getWindowCount() === 0;
|
else if (isMacintosh && windowsMainService.getWindowCount() === 0) {
|
||||||
|
logService.trace(`app#handleURL() running on macOS with no window open, setting shouldOpenInNewWindow=true:`, uri.toString(true));
|
||||||
|
|
||||||
|
shouldOpenInNewWindow = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Pass along whether the application is being opened via a Continue On flow
|
// Pass along whether the application is being opened via a Continue On flow
|
||||||
const continueOn = params.get('continueOn');
|
const continueOn = params.get('continueOn');
|
||||||
if (continueOn !== null) {
|
if (continueOn !== null) {
|
||||||
environmentService.continueOn = continueOn ?? undefined;
|
logService.trace(`app#handleURL() found 'continueOn' as parameter:`, uri.toString(true));
|
||||||
|
|
||||||
params.delete('continueOn');
|
params.delete('continueOn');
|
||||||
uri = uri.with({ query: params.toString() });
|
uri = uri.with({ query: params.toString() });
|
||||||
|
|
||||||
|
environmentService.continueOn = continueOn ?? undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for URIs to open in window
|
// Check if the protocol link is a window openable to open...
|
||||||
const windowOpenableFromProtocolLink = app.getWindowOpenableFromProtocolLink(uri);
|
const windowOpenableFromProtocolLink = app.getWindowOpenableFromProtocolLink(uri);
|
||||||
logService.trace('app#handleURL: windowOpenableFromProtocolLink = ', windowOpenableFromProtocolLink);
|
|
||||||
if (windowOpenableFromProtocolLink) {
|
if (windowOpenableFromProtocolLink) {
|
||||||
|
logService.trace('app#handleURL() opening protocol link as window:', windowOpenableFromProtocolLink, uri.toString(true));
|
||||||
|
|
||||||
const [window] = await windowsMainService.open({
|
const [window] = await windowsMainService.open({
|
||||||
context: OpenContext.API,
|
context: OpenContext.API,
|
||||||
cli: { ...environmentService.args },
|
cli: { ...environmentService.args },
|
||||||
|
@ -927,7 +954,10 @@ export class CodeApplication extends Disposable {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ...or if we should open in a new window and then handle it within that window
|
||||||
if (shouldOpenInNewWindow) {
|
if (shouldOpenInNewWindow) {
|
||||||
|
logService.trace('app#handleURL() opening empty window and passing in protocol link:', uri.toString(true));
|
||||||
|
|
||||||
const [window] = await windowsMainService.open({
|
const [window] = await windowsMainService.open({
|
||||||
context: OpenContext.API,
|
context: OpenContext.API,
|
||||||
cli: { ...environmentService.args },
|
cli: { ...environmentService.args },
|
||||||
|
@ -958,7 +988,7 @@ export class CodeApplication extends Disposable {
|
||||||
urlService.registerHandler(new URLHandlerChannelClient(urlHandlerChannel));
|
urlService.registerHandler(new URLHandlerChannelClient(urlHandlerChannel));
|
||||||
|
|
||||||
// Watch Electron URLs and forward them to the UrlService
|
// Watch Electron URLs and forward them to the UrlService
|
||||||
this._register(new ElectronURLListener(pendingProtocolLinksToHandle, urlService, windowsMainService, this.environmentMainService, this.productService));
|
this._register(new ElectronURLListener(pendingProtocolLinksToHandle, urlService, windowsMainService, this.environmentMainService, this.productService, this.logService));
|
||||||
|
|
||||||
// Open our first window
|
// Open our first window
|
||||||
const args = this.environmentMainService.args;
|
const args = this.environmentMainService.args;
|
||||||
|
|
|
@ -466,6 +466,10 @@ export class TextAreaHandler extends ViewPart {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public writeScreenReaderContent(reason: string): void {
|
||||||
|
this._textAreaInput.writeScreenReaderContent(reason);
|
||||||
|
}
|
||||||
|
|
||||||
public override dispose(): void {
|
public override dispose(): void {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -929,6 +929,11 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||||
*/
|
*/
|
||||||
setAriaOptions(options: IEditorAriaOptions): void;
|
setAriaOptions(options: IEditorAriaOptions): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the screen reader content to be the current selection
|
||||||
|
*/
|
||||||
|
writeScreenReaderContent(reason: string): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -487,6 +487,10 @@ export class View extends ViewEventHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public writeScreenReaderContent(reason: string): void {
|
||||||
|
this._textAreaHandler.writeScreenReaderContent(reason);
|
||||||
|
}
|
||||||
|
|
||||||
public focus(): void {
|
public focus(): void {
|
||||||
this._textAreaHandler.focusTextArea();
|
this._textAreaHandler.focusTextArea();
|
||||||
}
|
}
|
||||||
|
|
|
@ -398,6 +398,10 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
|
||||||
this._codeEditorService.addCodeEditor(this);
|
this._codeEditorService.addCodeEditor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public writeScreenReaderContent(reason: string): void {
|
||||||
|
this._modelData?.view.writeScreenReaderContent(reason);
|
||||||
|
}
|
||||||
|
|
||||||
protected _createConfiguration(isSimpleWidget: boolean, options: Readonly<IEditorConstructionOptions>, accessibilityService: IAccessibilityService): EditorConfiguration {
|
protected _createConfiguration(isSimpleWidget: boolean, options: Readonly<IEditorConstructionOptions>, accessibilityService: IAccessibilityService): EditorConfiguration {
|
||||||
return new EditorConfiguration(isSimpleWidget, options, this._domElement, accessibilityService);
|
return new EditorConfiguration(isSimpleWidget, options, this._domElement, accessibilityService);
|
||||||
}
|
}
|
||||||
|
|
|
@ -292,7 +292,7 @@ export class ModelService extends Disposable implements IModelService {
|
||||||
const language = modelData.model.getLanguageId();
|
const language = modelData.model.getLanguageId();
|
||||||
const uri = modelData.model.uri;
|
const uri = modelData.model.uri;
|
||||||
|
|
||||||
if (e && !e.affectsConfiguration('editor', { overrideIdentifier: language, resource: uri })) {
|
if (e && !e.affectsConfiguration('editor', { overrideIdentifier: language, resource: uri }) && !e.affectsConfiguration('files.eol', { overrideIdentifier: language, resource: uri })) {
|
||||||
continue; // perf: skip if this model is not affected by configuration change
|
continue; // perf: skip if this model is not affected by configuration change
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
src/vs/monaco.d.ts
vendored
4
src/vs/monaco.d.ts
vendored
|
@ -5631,6 +5631,10 @@ declare namespace monaco.editor {
|
||||||
* Get the vertical position (top offset) for the position w.r.t. to the first line.
|
* Get the vertical position (top offset) for the position w.r.t. to the first line.
|
||||||
*/
|
*/
|
||||||
getTopForPosition(lineNumber: number, column: number): number;
|
getTopForPosition(lineNumber: number, column: number): number;
|
||||||
|
/**
|
||||||
|
* Write the screen reader content to be the current selection
|
||||||
|
*/
|
||||||
|
writeScreenReaderContent(reason: string): void;
|
||||||
/**
|
/**
|
||||||
* Returns the editor's container dom node
|
* Returns the editor's container dom node
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -184,7 +184,11 @@ export class ActionList<T extends IActionItem> extends Disposable {
|
||||||
getHeight: element => element.kind === ActionListItemKind.Header ? this._headerLineHeight : this._actionLineHeight,
|
getHeight: element => element.kind === ActionListItemKind.Header ? this._headerLineHeight : this._actionLineHeight,
|
||||||
getTemplateId: element => element.kind
|
getTemplateId: element => element.kind
|
||||||
};
|
};
|
||||||
this._list = this._register(new List(user, this.domNode, virtualDelegate, [new ActionItemRenderer<IListMenuItem<IActionItem>>(preview, this._keybindingService), new HeaderRenderer()], {
|
|
||||||
|
this._list = this._register(new List(user, this.domNode, virtualDelegate, [
|
||||||
|
new ActionItemRenderer<IListMenuItem<IActionItem>>(preview, this._keybindingService),
|
||||||
|
new HeaderRenderer(),
|
||||||
|
], {
|
||||||
keyboardSupport: false,
|
keyboardSupport: false,
|
||||||
accessibilityProvider: {
|
accessibilityProvider: {
|
||||||
getAriaLabel: element => {
|
getAriaLabel: element => {
|
||||||
|
@ -228,8 +232,8 @@ export class ActionList<T extends IActionItem> extends Disposable {
|
||||||
layout(minWidth: number): number {
|
layout(minWidth: number): number {
|
||||||
// Updating list height, depending on how many separators and headers there are.
|
// Updating list height, depending on how many separators and headers there are.
|
||||||
const numHeaders = this._allMenuItems.filter(item => item.kind === 'header').length;
|
const numHeaders = this._allMenuItems.filter(item => item.kind === 'header').length;
|
||||||
const height = this._allMenuItems.length * this._actionLineHeight;
|
const itemsHeight = this._allMenuItems.length * this._actionLineHeight;
|
||||||
const heightWithHeaders = height + numHeaders * this._headerLineHeight - numHeaders * this._actionLineHeight;
|
const heightWithHeaders = itemsHeight + numHeaders * this._headerLineHeight - numHeaders * this._actionLineHeight;
|
||||||
this._list.layout(heightWithHeaders);
|
this._list.layout(heightWithHeaders);
|
||||||
|
|
||||||
// For finding width dynamically (not using resize observer)
|
// For finding width dynamically (not using resize observer)
|
||||||
|
@ -246,9 +250,12 @@ export class ActionList<T extends IActionItem> extends Disposable {
|
||||||
|
|
||||||
// resize observer - can be used in the future since list widget supports dynamic height but not width
|
// resize observer - can be used in the future since list widget supports dynamic height but not width
|
||||||
const width = Math.max(...itemWidths, minWidth);
|
const width = Math.max(...itemWidths, minWidth);
|
||||||
this._list.layout(heightWithHeaders, width);
|
|
||||||
|
|
||||||
this.domNode.style.height = `${heightWithHeaders}px`;
|
const maxVhPrecentage = 0.7;
|
||||||
|
const height = Math.min(heightWithHeaders, document.body.clientHeight * maxVhPrecentage);
|
||||||
|
this._list.layout(height, width);
|
||||||
|
|
||||||
|
this.domNode.style.height = `${height}px`;
|
||||||
|
|
||||||
this._list.domFocus();
|
this._list.domFocus();
|
||||||
return width;
|
return width;
|
||||||
|
|
|
@ -54,10 +54,6 @@
|
||||||
outline: 0 !important;
|
outline: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-widget .monaco-list .monaco-scrollable-element .monaco-list-rows {
|
|
||||||
height: 100% !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.action-widget .monaco-list .monaco-scrollable-element {
|
.action-widget .monaco-list .monaco-scrollable-element {
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
@ -123,7 +119,6 @@
|
||||||
/* Action bar */
|
/* Action bar */
|
||||||
|
|
||||||
.action-widget .action-widget-action-bar {
|
.action-widget .action-widget-action-bar {
|
||||||
margin-top: 4px;
|
|
||||||
background-color: var(--vscode-editorHoverWidget-statusBarBackground);
|
background-color: var(--vscode-editorHoverWidget-statusBarBackground);
|
||||||
border-top: 1px solid var(--vscode-editorHoverWidget-border);
|
border-top: 1px solid var(--vscode-editorHoverWidget-border);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ export class AudioCueService extends Disposable implements IAudioCueService {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.playingSounds.add(sound);
|
this.playingSounds.add(sound);
|
||||||
|
console.log('playing', sound);
|
||||||
const url = FileAccess.asBrowserUri(
|
const url = FileAccess.asBrowserUri(
|
||||||
`vs/platform/audioCues/browser/media/${sound.fileName}`
|
`vs/platform/audioCues/browser/media/${sound.fileName}`
|
||||||
).toString();
|
).toString();
|
||||||
|
@ -77,6 +77,7 @@ export class AudioCueService extends Disposable implements IAudioCueService {
|
||||||
audio.volume = this.getVolumeInPercent() / 100;
|
audio.volume = this.getVolumeInPercent() / 100;
|
||||||
audio.addEventListener('ended', () => {
|
audio.addEventListener('ended', () => {
|
||||||
this.playingSounds.delete(sound);
|
this.playingSounds.delete(sound);
|
||||||
|
console.log('ending', sound);
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -102,8 +102,8 @@ export const OPTIONS: OptionDescriptions<Required<NativeParsedArgs>> = {
|
||||||
'no-cached-data': { type: 'boolean' },
|
'no-cached-data': { type: 'boolean' },
|
||||||
'prof-startup-prefix': { type: 'string' },
|
'prof-startup-prefix': { type: 'string' },
|
||||||
'prof-v8-extensions': { type: 'boolean' },
|
'prof-v8-extensions': { type: 'boolean' },
|
||||||
'disable-extensions': { type: 'boolean', deprecates: ['disableExtensions'], cat: 't', description: localize('disableExtensions', "Disable all installed extensions.") },
|
'disable-extensions': { type: 'boolean', deprecates: ['disableExtensions'], cat: 't', description: localize('disableExtensions', "Disable all installed extensions. This option is not persisted and is effective only when the command opens a new window.") },
|
||||||
'disable-extension': { type: 'string[]', cat: 't', args: 'ext-id', description: localize('disableExtension', "Disable an extension.") },
|
'disable-extension': { type: 'string[]', cat: 't', args: 'ext-id', description: localize('disableExtension', "Disable the provided extension. This option is not persisted and is effective only when the command opens a new window.") },
|
||||||
'sync': { type: 'string', cat: 't', description: localize('turn sync', "Turn sync on or off."), args: ['on | off'] },
|
'sync': { type: 'string', cat: 't', description: localize('turn sync', "Turn sync on or off."), args: ['on | off'] },
|
||||||
|
|
||||||
'inspect-extensions': { type: 'string', allowEmptyValue: true, deprecates: ['debugPluginHost'], args: 'port', cat: 't', description: localize('inspect-extensions', "Allow debugging and profiling of extensions. Check the developer tools for the connection URI.") },
|
'inspect-extensions': { type: 'string', allowEmptyValue: true, deprecates: ['debugPluginHost'], args: 'port', cat: 't', description: localize('inspect-extensions', "Allow debugging and profiling of extensions. Check the developer tools for the connection URI.") },
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { IProcessEnvironment } from 'vs/base/common/platform';
|
||||||
|
|
||||||
export enum EnvironmentVariableMutatorType {
|
export enum EnvironmentVariableMutatorType {
|
||||||
Replace = 1,
|
Replace = 1,
|
||||||
Append = 2,
|
Append = 2,
|
||||||
|
@ -12,8 +14,47 @@ export interface IEnvironmentVariableMutator {
|
||||||
readonly value: string;
|
readonly value: string;
|
||||||
readonly type: EnvironmentVariableMutatorType;
|
readonly type: EnvironmentVariableMutatorType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IEnvironmentVariableCollection {
|
||||||
|
readonly map: ReadonlyMap<string, IEnvironmentVariableMutator>;
|
||||||
|
}
|
||||||
|
|
||||||
/** [variable, mutator] */
|
/** [variable, mutator] */
|
||||||
export type ISerializableEnvironmentVariableCollection = [string, IEnvironmentVariableMutator][];
|
export type ISerializableEnvironmentVariableCollection = [string, IEnvironmentVariableMutator][];
|
||||||
|
|
||||||
/** [extension, collection] */
|
/** [extension, collection] */
|
||||||
export type ISerializableEnvironmentVariableCollections = [string, ISerializableEnvironmentVariableCollection][];
|
export type ISerializableEnvironmentVariableCollections = [string, ISerializableEnvironmentVariableCollection][];
|
||||||
|
|
||||||
|
export interface IExtensionOwnedEnvironmentVariableMutator extends IEnvironmentVariableMutator {
|
||||||
|
readonly extensionIdentifier: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IMergedEnvironmentVariableCollectionDiff {
|
||||||
|
added: ReadonlyMap<string, IExtensionOwnedEnvironmentVariableMutator[]>;
|
||||||
|
changed: ReadonlyMap<string, IExtensionOwnedEnvironmentVariableMutator[]>;
|
||||||
|
removed: ReadonlyMap<string, IExtensionOwnedEnvironmentVariableMutator[]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
type VariableResolver = (str: string) => Promise<string>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an environment variable collection that results from merging several collections
|
||||||
|
* together.
|
||||||
|
*/
|
||||||
|
export interface IMergedEnvironmentVariableCollection {
|
||||||
|
readonly collections: ReadonlyMap<string, IEnvironmentVariableCollection>;
|
||||||
|
readonly map: ReadonlyMap<string, IExtensionOwnedEnvironmentVariableMutator[]>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies this collection to a process environment.
|
||||||
|
* @param variableResolver An optional function to use to resolve variables within the
|
||||||
|
* environment values.
|
||||||
|
*/
|
||||||
|
applyToProcessEnvironment(env: IProcessEnvironment, variableResolver?: VariableResolver): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a diff of this collection against another. Returns undefined if the collections are
|
||||||
|
* the same.
|
||||||
|
*/
|
||||||
|
diff(other: IMergedEnvironmentVariableCollection): IMergedEnvironmentVariableCollectionDiff | undefined;
|
||||||
|
}
|
||||||
|
|
|
@ -4,8 +4,9 @@
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { IProcessEnvironment, isWindows } from 'vs/base/common/platform';
|
import { IProcessEnvironment, isWindows } from 'vs/base/common/platform';
|
||||||
import { EnvironmentVariableMutatorType, IEnvironmentVariableCollection, IExtensionOwnedEnvironmentVariableMutator, IMergedEnvironmentVariableCollection, IMergedEnvironmentVariableCollectionDiff } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
import { EnvironmentVariableMutatorType, IEnvironmentVariableCollection, IExtensionOwnedEnvironmentVariableMutator, IMergedEnvironmentVariableCollection, IMergedEnvironmentVariableCollectionDiff } from 'vs/platform/terminal/common/environmentVariable';
|
||||||
import { VariableResolver } from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
|
|
||||||
|
type VariableResolver = (str: string) => Promise<string>;
|
||||||
|
|
||||||
export class MergedEnvironmentVariableCollection implements IMergedEnvironmentVariableCollection {
|
export class MergedEnvironmentVariableCollection implements IMergedEnvironmentVariableCollection {
|
||||||
readonly map: Map<string, IExtensionOwnedEnvironmentVariableMutator[]> = new Map();
|
readonly map: Map<string, IExtensionOwnedEnvironmentVariableMutator[]> = new Map();
|
|
@ -3,7 +3,7 @@
|
||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { IEnvironmentVariableCollection, IEnvironmentVariableMutator, ISerializableEnvironmentVariableCollection, ISerializableEnvironmentVariableCollections } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
import { IEnvironmentVariableCollection, IEnvironmentVariableMutator, ISerializableEnvironmentVariableCollection, ISerializableEnvironmentVariableCollections } from 'vs/platform/terminal/common/environmentVariable';
|
||||||
|
|
||||||
// This file is shared between the renderer and extension host
|
// This file is shared between the renderer and extension host
|
||||||
|
|
|
@ -7,7 +7,7 @@ import * as os from 'os';
|
||||||
import { FileAccess } from 'vs/base/common/network';
|
import { FileAccess } from 'vs/base/common/network';
|
||||||
import { getCaseInsensitive } from 'vs/base/common/objects';
|
import { getCaseInsensitive } from 'vs/base/common/objects';
|
||||||
import * as path from 'vs/base/common/path';
|
import * as path from 'vs/base/common/path';
|
||||||
import { IProcessEnvironment, isWindows } from 'vs/base/common/platform';
|
import { IProcessEnvironment, isMacintosh, isWindows } from 'vs/base/common/platform';
|
||||||
import * as process from 'vs/base/common/process';
|
import * as process from 'vs/base/common/process';
|
||||||
import { format } from 'vs/base/common/strings';
|
import { format } from 'vs/base/common/strings';
|
||||||
import { isString } from 'vs/base/common/types';
|
import { isString } from 'vs/base/common/types';
|
||||||
|
@ -15,6 +15,9 @@ import * as pfs from 'vs/base/node/pfs';
|
||||||
import { ILogService } from 'vs/platform/log/common/log';
|
import { ILogService } from 'vs/platform/log/common/log';
|
||||||
import { IProductService } from 'vs/platform/product/common/productService';
|
import { IProductService } from 'vs/platform/product/common/productService';
|
||||||
import { IShellLaunchConfig, ITerminalEnvironment, ITerminalProcessOptions } from 'vs/platform/terminal/common/terminal';
|
import { IShellLaunchConfig, ITerminalEnvironment, ITerminalProcessOptions } from 'vs/platform/terminal/common/terminal';
|
||||||
|
import { EnvironmentVariableMutatorType } from 'vs/platform/terminal/common/environmentVariable';
|
||||||
|
import { deserializeEnvironmentVariableCollections } from 'vs/platform/terminal/common/environmentVariableShared';
|
||||||
|
import { MergedEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableCollection';
|
||||||
|
|
||||||
export function getWindowsBuildNumber(): number {
|
export function getWindowsBuildNumber(): number {
|
||||||
const osVersion = (/(\d+)\.(\d+)\.(\d+)/g).exec(os.release());
|
const osVersion = (/(\d+)\.(\d+)\.(\d+)/g).exec(os.release());
|
||||||
|
@ -104,7 +107,7 @@ export interface IShellIntegrationConfigInjection {
|
||||||
*/
|
*/
|
||||||
export function getShellIntegrationInjection(
|
export function getShellIntegrationInjection(
|
||||||
shellLaunchConfig: IShellLaunchConfig,
|
shellLaunchConfig: IShellLaunchConfig,
|
||||||
options: Pick<ITerminalProcessOptions, 'shellIntegration' | 'windowsEnableConpty'>,
|
options: ITerminalProcessOptions,
|
||||||
env: ITerminalEnvironment | undefined,
|
env: ITerminalEnvironment | undefined,
|
||||||
logService: ILogService,
|
logService: ILogService,
|
||||||
productService: IProductService
|
productService: IProductService
|
||||||
|
@ -151,6 +154,7 @@ export function getShellIntegrationInjection(
|
||||||
newArgs = shellIntegrationArgs.get(ShellIntegrationExecutable.Bash);
|
newArgs = shellIntegrationArgs.get(ShellIntegrationExecutable.Bash);
|
||||||
} else if (areZshBashLoginArgs(originalArgs)) {
|
} else if (areZshBashLoginArgs(originalArgs)) {
|
||||||
envMixin['VSCODE_SHELL_LOGIN'] = '1';
|
envMixin['VSCODE_SHELL_LOGIN'] = '1';
|
||||||
|
addEnvMixinPathPrefix(options, envMixin);
|
||||||
newArgs = shellIntegrationArgs.get(ShellIntegrationExecutable.Bash);
|
newArgs = shellIntegrationArgs.get(ShellIntegrationExecutable.Bash);
|
||||||
}
|
}
|
||||||
if (!newArgs) {
|
if (!newArgs) {
|
||||||
|
@ -166,6 +170,7 @@ export function getShellIntegrationInjection(
|
||||||
const oldDataDirs = env?.XDG_DATA_DIRS ?? '/usr/local/share:/usr/share';
|
const oldDataDirs = env?.XDG_DATA_DIRS ?? '/usr/local/share:/usr/share';
|
||||||
const newDataDir = path.join(appRoot, 'out/vs/workbench/contrib/xdg_data');
|
const newDataDir = path.join(appRoot, 'out/vs/workbench/contrib/xdg_data');
|
||||||
envMixin['XDG_DATA_DIRS'] = `${oldDataDirs}:${newDataDir}`;
|
envMixin['XDG_DATA_DIRS'] = `${oldDataDirs}:${newDataDir}`;
|
||||||
|
addEnvMixinPathPrefix(options, envMixin);
|
||||||
return { newArgs: undefined, envMixin };
|
return { newArgs: undefined, envMixin };
|
||||||
}
|
}
|
||||||
case 'pwsh': {
|
case 'pwsh': {
|
||||||
|
@ -186,6 +191,7 @@ export function getShellIntegrationInjection(
|
||||||
newArgs = shellIntegrationArgs.get(ShellIntegrationExecutable.Zsh);
|
newArgs = shellIntegrationArgs.get(ShellIntegrationExecutable.Zsh);
|
||||||
} else if (areZshBashLoginArgs(originalArgs)) {
|
} else if (areZshBashLoginArgs(originalArgs)) {
|
||||||
newArgs = shellIntegrationArgs.get(ShellIntegrationExecutable.ZshLogin);
|
newArgs = shellIntegrationArgs.get(ShellIntegrationExecutable.ZshLogin);
|
||||||
|
addEnvMixinPathPrefix(options, envMixin);
|
||||||
} else if (originalArgs === shellIntegrationArgs.get(ShellIntegrationExecutable.Zsh) || originalArgs === shellIntegrationArgs.get(ShellIntegrationExecutable.ZshLogin)) {
|
} else if (originalArgs === shellIntegrationArgs.get(ShellIntegrationExecutable.Zsh) || originalArgs === shellIntegrationArgs.get(ShellIntegrationExecutable.ZshLogin)) {
|
||||||
newArgs = originalArgs;
|
newArgs = originalArgs;
|
||||||
}
|
}
|
||||||
|
@ -230,6 +236,39 @@ export function getShellIntegrationInjection(
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On macOS the profile calls path_helper which adds a bunch of standard bin directories to the
|
||||||
|
* beginning of the PATH. This causes significant problems for the environment variable
|
||||||
|
* collection API as the custom paths added to the end will now be somewhere in the middle of
|
||||||
|
* the PATH. To combat this, VSCODE_PATH_PREFIX is used to re-apply any prefix after the profile
|
||||||
|
* has run. This will cause duplication in the PATH but should fix the issue.
|
||||||
|
*
|
||||||
|
* See #99878 for more information.
|
||||||
|
*/
|
||||||
|
function addEnvMixinPathPrefix(options: ITerminalProcessOptions, envMixin: IProcessEnvironment): void {
|
||||||
|
if (isMacintosh && options.environmentVariableCollections) {
|
||||||
|
// Deserialize and merge
|
||||||
|
const deserialized = deserializeEnvironmentVariableCollections(options.environmentVariableCollections);
|
||||||
|
const merged = new MergedEnvironmentVariableCollection(deserialized);
|
||||||
|
|
||||||
|
// Get all prepend PATH entries
|
||||||
|
const pathEntry = merged.map.get('PATH');
|
||||||
|
const prependToPath: string[] = [];
|
||||||
|
if (pathEntry) {
|
||||||
|
for (const mutator of pathEntry) {
|
||||||
|
if (mutator.type === EnvironmentVariableMutatorType.Prepend) {
|
||||||
|
prependToPath.push(mutator.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add to the environment mixin to be applied in the shell integration script
|
||||||
|
if (prependToPath.length > 0) {
|
||||||
|
envMixin['VSCODE_PATH_PREFIX'] = prependToPath.join('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum ShellIntegrationExecutable {
|
enum ShellIntegrationExecutable {
|
||||||
WindowsPwsh = 'windows-pwsh',
|
WindowsPwsh = 'windows-pwsh',
|
||||||
WindowsPwshLogin = 'windows-pwsh-login',
|
WindowsPwshLogin = 'windows-pwsh-login',
|
||||||
|
|
|
@ -202,7 +202,7 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
|
||||||
|
|
||||||
let injection: IShellIntegrationConfigInjection | undefined;
|
let injection: IShellIntegrationConfigInjection | undefined;
|
||||||
if (this._options.shellIntegration.enabled) {
|
if (this._options.shellIntegration.enabled) {
|
||||||
injection = getShellIntegrationInjection(this.shellLaunchConfig, { shellIntegration: this._options.shellIntegration, windowsEnableConpty: this._options.windowsEnableConpty }, this._ptyOptions.env, this._logService, this._productService);
|
injection = getShellIntegrationInjection(this.shellLaunchConfig, this._options, this._ptyOptions.env, this._logService, this._productService);
|
||||||
if (injection) {
|
if (injection) {
|
||||||
this._onDidChangeProperty.fire({ type: ProcessPropertyType.UsedShellIntegrationInjection, value: true });
|
this._onDidChangeProperty.fire({ type: ProcessPropertyType.UsedShellIntegrationInjection, value: true });
|
||||||
if (injection.envMixin) {
|
if (injection.envMixin) {
|
||||||
|
|
|
@ -11,9 +11,9 @@ import { IProductService } from 'vs/platform/product/common/productService';
|
||||||
import { ITerminalProcessOptions } from 'vs/platform/terminal/common/terminal';
|
import { ITerminalProcessOptions } from 'vs/platform/terminal/common/terminal';
|
||||||
import { getShellIntegrationInjection, IShellIntegrationConfigInjection } from 'vs/platform/terminal/node/terminalEnvironment';
|
import { getShellIntegrationInjection, IShellIntegrationConfigInjection } from 'vs/platform/terminal/node/terminalEnvironment';
|
||||||
|
|
||||||
const enabledProcessOptions: Pick<ITerminalProcessOptions, 'shellIntegration' | 'windowsEnableConpty'> = { shellIntegration: { enabled: true }, windowsEnableConpty: true };
|
const enabledProcessOptions: ITerminalProcessOptions = { shellIntegration: { enabled: true }, windowsEnableConpty: true, environmentVariableCollections: undefined };
|
||||||
const disabledProcessOptions: Pick<ITerminalProcessOptions, 'shellIntegration' | 'windowsEnableConpty'> = { shellIntegration: { enabled: false }, windowsEnableConpty: true };
|
const disabledProcessOptions: ITerminalProcessOptions = { shellIntegration: { enabled: false }, windowsEnableConpty: true, environmentVariableCollections: undefined };
|
||||||
const winptyProcessOptions: Pick<ITerminalProcessOptions, 'shellIntegration' | 'windowsEnableConpty'> = { shellIntegration: { enabled: true }, windowsEnableConpty: false };
|
const winptyProcessOptions: ITerminalProcessOptions = { shellIntegration: { enabled: true }, windowsEnableConpty: false, environmentVariableCollections: undefined };
|
||||||
const pwshExe = process.platform === 'win32' ? 'pwsh.exe' : 'pwsh';
|
const pwshExe = process.platform === 'win32' ? 'pwsh.exe' : 'pwsh';
|
||||||
const repoRoot = process.platform === 'win32' ? process.cwd()[0].toLowerCase() + process.cwd().substring(1) : process.cwd();
|
const repoRoot = process.platform === 'win32' ? process.cwd()[0].toLowerCase() + process.cwd().substring(1) : process.cwd();
|
||||||
const logService = new NullLogService();
|
const logService = new NullLogService();
|
||||||
|
|
|
@ -10,18 +10,11 @@ import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecyc
|
||||||
import { isWindows } from 'vs/base/common/platform';
|
import { isWindows } from 'vs/base/common/platform';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService';
|
import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService';
|
||||||
|
import { ILogService } from 'vs/platform/log/common/log';
|
||||||
import { IProductService } from 'vs/platform/product/common/productService';
|
import { IProductService } from 'vs/platform/product/common/productService';
|
||||||
import { IURLService } from 'vs/platform/url/common/url';
|
import { IURLService } from 'vs/platform/url/common/url';
|
||||||
import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows';
|
import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows';
|
||||||
|
|
||||||
function uriFromRawUrl(url: string): URI | null {
|
|
||||||
try {
|
|
||||||
return URI.parse(url);
|
|
||||||
} catch (e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A listener for URLs that are opened from the OS and handled by VSCode.
|
* A listener for URLs that are opened from the OS and handled by VSCode.
|
||||||
* Depending on the platform, this works differently:
|
* Depending on the platform, this works differently:
|
||||||
|
@ -37,15 +30,17 @@ export class ElectronURLListener {
|
||||||
private uris: { uri: URI; url: string }[] = [];
|
private uris: { uri: URI; url: string }[] = [];
|
||||||
private retryCount = 0;
|
private retryCount = 0;
|
||||||
private flushDisposable: IDisposable = Disposable.None;
|
private flushDisposable: IDisposable = Disposable.None;
|
||||||
private disposables = new DisposableStore();
|
private readonly disposables = new DisposableStore();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
initialUrisToHandle: { uri: URI; url: string }[],
|
initialUrisToHandle: { uri: URI; url: string }[],
|
||||||
private readonly urlService: IURLService,
|
private readonly urlService: IURLService,
|
||||||
windowsMainService: IWindowsMainService,
|
windowsMainService: IWindowsMainService,
|
||||||
environmentMainService: IEnvironmentMainService,
|
environmentMainService: IEnvironmentMainService,
|
||||||
productService: IProductService
|
productService: IProductService,
|
||||||
|
private readonly logService: ILogService
|
||||||
) {
|
) {
|
||||||
|
logService.trace('ElectronURLListener initialUrisToHandle:', initialUrisToHandle.map(initialUri => initialUri.url));
|
||||||
|
|
||||||
// the initial set of URIs we need to handle once the window is ready
|
// the initial set of URIs we need to handle once the window is ready
|
||||||
this.uris = initialUrisToHandle;
|
this.uris = initialUrisToHandle;
|
||||||
|
@ -62,12 +57,12 @@ export class ElectronURLListener {
|
||||||
Event.fromNodeEventEmitter(app, 'open-url', (event: ElectronEvent, url: string) => ({ event, url })),
|
Event.fromNodeEventEmitter(app, 'open-url', (event: ElectronEvent, url: string) => ({ event, url })),
|
||||||
({ event, url }) => {
|
({ event, url }) => {
|
||||||
event.preventDefault(); // always prevent default and return the url as string
|
event.preventDefault(); // always prevent default and return the url as string
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.disposables.add(onOpenElectronUrl(url => {
|
this.disposables.add(onOpenElectronUrl(url => {
|
||||||
const uri = uriFromRawUrl(url);
|
const uri = this.uriFromRawUrl(url);
|
||||||
|
|
||||||
if (!uri) {
|
if (!uri) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -77,27 +72,46 @@ export class ElectronURLListener {
|
||||||
|
|
||||||
// Send initial links to the window once it has loaded
|
// Send initial links to the window once it has loaded
|
||||||
const isWindowReady = windowsMainService.getWindows()
|
const isWindowReady = windowsMainService.getWindows()
|
||||||
.filter(w => w.isReady)
|
.filter(window => window.isReady)
|
||||||
.length > 0;
|
.length > 0;
|
||||||
|
|
||||||
if (isWindowReady) {
|
if (isWindowReady) {
|
||||||
|
logService.trace('ElectronURLListener: window is ready to handle URLs');
|
||||||
|
|
||||||
this.flush();
|
this.flush();
|
||||||
} else {
|
} else {
|
||||||
|
logService.trace('ElectronURLListener: waiting for window to be ready to handle URLs...');
|
||||||
|
|
||||||
Event.once(windowsMainService.onDidSignalReadyWindow)(this.flush, this, this.disposables);
|
Event.once(windowsMainService.onDidSignalReadyWindow)(this.flush, this, this.disposables);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private uriFromRawUrl(url: string): URI | undefined {
|
||||||
|
try {
|
||||||
|
return URI.parse(url);
|
||||||
|
} catch (e) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async flush(): Promise<void> {
|
private async flush(): Promise<void> {
|
||||||
if (this.retryCount++ > 10) {
|
if (this.retryCount++ > 10) {
|
||||||
|
this.logService.trace('ElectronURLListener#flush(): giving up after 10 retries');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.logService.trace('ElectronURLListener#flush(): flushing URLs');
|
||||||
|
|
||||||
const uris: { uri: URI; url: string }[] = [];
|
const uris: { uri: URI; url: string }[] = [];
|
||||||
|
|
||||||
for (const obj of this.uris) {
|
for (const obj of this.uris) {
|
||||||
const handled = await this.urlService.open(obj.uri, { originalUrl: obj.url });
|
const handled = await this.urlService.open(obj.uri, { originalUrl: obj.url });
|
||||||
|
if (handled) {
|
||||||
|
this.logService.trace('ElectronURLListener#flush(): URL was handled', obj.url);
|
||||||
|
} else {
|
||||||
|
this.logService.trace('ElectronURLListener#flush(): URL was not yet handled', obj.url);
|
||||||
|
|
||||||
if (!handled) {
|
|
||||||
uris.push(obj);
|
uris.push(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,9 @@ import { IGetTerminalLayoutInfoArgs, ISetTerminalLayoutInfoArgs } from 'vs/platf
|
||||||
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||||
import { createURITransformer } from 'vs/workbench/api/node/uriTransformer';
|
import { createURITransformer } from 'vs/workbench/api/node/uriTransformer';
|
||||||
import { CLIServerBase, ICommandsExecuter } from 'vs/workbench/api/node/extHostCLIServer';
|
import { CLIServerBase, ICommandsExecuter } from 'vs/workbench/api/node/extHostCLIServer';
|
||||||
import { IEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
import { IEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable';
|
||||||
import { MergedEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableCollection';
|
import { MergedEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableCollection';
|
||||||
import { deserializeEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableShared';
|
import { deserializeEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableShared';
|
||||||
import { ICreateTerminalProcessArguments, ICreateTerminalProcessResult, IWorkspaceFolderData } from 'vs/workbench/contrib/terminal/common/remoteTerminalChannel';
|
import { ICreateTerminalProcessArguments, ICreateTerminalProcessResult, IWorkspaceFolderData } from 'vs/workbench/contrib/terminal/common/remoteTerminalChannel';
|
||||||
import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
|
import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
|
||||||
import { AbstractVariableResolverService } from 'vs/workbench/services/configurationResolver/common/variableResolver';
|
import { AbstractVariableResolverService } from 'vs/workbench/services/configurationResolver/common/variableResolver';
|
||||||
|
|
|
@ -44,28 +44,40 @@ export class MainThreadNotebooks implements MainThreadNotebookShape {
|
||||||
}
|
}
|
||||||
|
|
||||||
$registerNotebookSerializer(handle: number, extension: NotebookExtensionDescription, viewType: string, options: TransientOptions, data: INotebookContributionData | undefined): void {
|
$registerNotebookSerializer(handle: number, extension: NotebookExtensionDescription, viewType: string, options: TransientOptions, data: INotebookContributionData | undefined): void {
|
||||||
const registration = this._notebookService.registerNotebookSerializer(viewType, extension, {
|
const disposables = new DisposableStore();
|
||||||
|
|
||||||
|
disposables.add(this._notebookService.registerNotebookSerializer(viewType, extension, {
|
||||||
options,
|
options,
|
||||||
dataToNotebook: async (data: VSBuffer): Promise<NotebookData> => {
|
dataToNotebook: async (data: VSBuffer): Promise<NotebookData> => {
|
||||||
const sw = new StopWatch(true);
|
const sw = new StopWatch(true);
|
||||||
const dto = await this._proxy.$dataToNotebook(handle, data, CancellationToken.None);
|
const dto = await this._proxy.$dataToNotebook(handle, data, CancellationToken.None);
|
||||||
const result = NotebookDto.fromNotebookDataDto(dto.value);
|
const result = NotebookDto.fromNotebookDataDto(dto.value);
|
||||||
this._logService.trace('[NotebookSerializer] dataToNotebook DONE', extension.id, sw.elapsed());
|
this._logService.trace(`[NotebookSerializer] dataToNotebook DONE after ${sw.elapsed()}ms`, {
|
||||||
|
viewType,
|
||||||
|
extensionId: extension.id.value,
|
||||||
|
});
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
notebookToData: (data: NotebookData): Promise<VSBuffer> => {
|
notebookToData: (data: NotebookData): Promise<VSBuffer> => {
|
||||||
const sw = new StopWatch(true);
|
const sw = new StopWatch(true);
|
||||||
const result = this._proxy.$notebookToData(handle, new SerializableObjectWithBuffers(NotebookDto.toNotebookDataDto(data)), CancellationToken.None);
|
const result = this._proxy.$notebookToData(handle, new SerializableObjectWithBuffers(NotebookDto.toNotebookDataDto(data)), CancellationToken.None);
|
||||||
this._logService.trace('[NotebookSerializer] notebookToData DONE', extension.id, sw.elapsed());
|
this._logService.trace(`[NotebookSerializer] notebookToData DONE after ${sw.elapsed()}`, {
|
||||||
|
viewType,
|
||||||
|
extensionId: extension.id.value,
|
||||||
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
const disposables = new DisposableStore();
|
|
||||||
disposables.add(registration);
|
|
||||||
if (data) {
|
if (data) {
|
||||||
disposables.add(this._notebookService.registerContributedNotebookType(viewType, data));
|
disposables.add(this._notebookService.registerContributedNotebookType(viewType, data));
|
||||||
}
|
}
|
||||||
this._notebookSerializer.set(handle, disposables);
|
this._notebookSerializer.set(handle, disposables);
|
||||||
|
|
||||||
|
this._logService.trace('[NotebookSerializer] registered notebook serializer', {
|
||||||
|
viewType,
|
||||||
|
extensionId: extension.id.value,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$unregisterNotebookSerializer(handle: number): void {
|
$unregisterNotebookSerializer(handle: number): void {
|
||||||
|
|
|
@ -14,8 +14,8 @@ import { IProcessProperty, IShellLaunchConfig, IShellLaunchConfigDto, ProcessPro
|
||||||
import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering';
|
import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering';
|
||||||
import { ITerminalEditorService, ITerminalExternalLinkProvider, ITerminalGroupService, ITerminalInstance, ITerminalLink, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
import { ITerminalEditorService, ITerminalExternalLinkProvider, ITerminalGroupService, ITerminalInstance, ITerminalLink, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||||
import { TerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/browser/terminalProcessExtHostProxy';
|
import { TerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/browser/terminalProcessExtHostProxy';
|
||||||
import { IEnvironmentVariableService, ISerializableEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
import { IEnvironmentVariableService } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
||||||
import { deserializeEnvironmentVariableCollection, serializeEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableShared';
|
import { deserializeEnvironmentVariableCollection, serializeEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableShared';
|
||||||
import { IStartExtensionTerminalRequest, ITerminalProcessExtHostProxy, ITerminalProfileResolverService, ITerminalProfileService, ITerminalQuickFixService } from 'vs/workbench/contrib/terminal/common/terminal';
|
import { IStartExtensionTerminalRequest, ITerminalProcessExtHostProxy, ITerminalProfileResolverService, ITerminalProfileService, ITerminalQuickFixService } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||||
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||||
|
@ -26,6 +26,7 @@ import { CancellationToken } from 'vs/base/common/cancellation';
|
||||||
import { ITerminalCommand } from 'vs/platform/terminal/common/capabilities/capabilities';
|
import { ITerminalCommand } from 'vs/platform/terminal/common/capabilities/capabilities';
|
||||||
import { ITerminalOutputMatch, ITerminalOutputMatcher, ITerminalQuickFix, ITerminalQuickFixOptions } from 'vs/platform/terminal/common/xterm/terminalQuickFix';
|
import { ITerminalOutputMatch, ITerminalOutputMatcher, ITerminalQuickFix, ITerminalQuickFixOptions } from 'vs/platform/terminal/common/xterm/terminalQuickFix';
|
||||||
import { TerminalQuickFixType } from 'vs/workbench/api/common/extHostTypes';
|
import { TerminalQuickFixType } from 'vs/workbench/api/common/extHostTypes';
|
||||||
|
import { ISerializableEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable';
|
||||||
|
|
||||||
|
|
||||||
@extHostNamedCustomer(MainContext.MainThreadTerminalService)
|
@extHostNamedCustomer(MainContext.MainThreadTerminalService)
|
||||||
|
|
|
@ -55,7 +55,7 @@ import { ICellRange } from 'vs/workbench/contrib/notebook/common/notebookRange';
|
||||||
import { OutputChannelUpdateMode } from 'vs/workbench/services/output/common/output';
|
import { OutputChannelUpdateMode } from 'vs/workbench/services/output/common/output';
|
||||||
import { InputValidationType } from 'vs/workbench/contrib/scm/common/scm';
|
import { InputValidationType } from 'vs/workbench/contrib/scm/common/scm';
|
||||||
import { IWorkspaceSymbol } from 'vs/workbench/contrib/search/common/search';
|
import { IWorkspaceSymbol } from 'vs/workbench/contrib/search/common/search';
|
||||||
import { ISerializableEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
import { ISerializableEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable';
|
||||||
import { CoverageDetails, ExtensionRunTestsRequest, ICallProfileRunHandler, IFileCoverage, ISerializedTestResults, ITestItem, ITestMessage, ITestRunProfile, ITestRunTask, ResolvedTestRunRequest, IStartControllerTests, TestResultState, TestsDiffOp } from 'vs/workbench/contrib/testing/common/testTypes';
|
import { CoverageDetails, ExtensionRunTestsRequest, ICallProfileRunHandler, IFileCoverage, ISerializedTestResults, ITestItem, ITestMessage, ITestRunProfile, ITestRunTask, ResolvedTestRunRequest, IStartControllerTests, TestResultState, TestsDiffOp } from 'vs/workbench/contrib/testing/common/testTypes';
|
||||||
import { Timeline, TimelineChangeEvent, TimelineOptions, TimelineProviderDescriptor } from 'vs/workbench/contrib/timeline/common/timeline';
|
import { Timeline, TimelineChangeEvent, TimelineOptions, TimelineProviderDescriptor } from 'vs/workbench/contrib/timeline/common/timeline';
|
||||||
import { TypeHierarchyItem } from 'vs/workbench/contrib/typeHierarchy/common/typeHierarchy';
|
import { TypeHierarchyItem } from 'vs/workbench/contrib/typeHierarchy/common/typeHierarchy';
|
||||||
|
|
|
@ -16,7 +16,6 @@ import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensio
|
||||||
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
|
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
|
||||||
import * as extHostTypeConverter from 'vs/workbench/api/common/extHostTypeConverters';
|
import * as extHostTypeConverter from 'vs/workbench/api/common/extHostTypeConverters';
|
||||||
import * as types from 'vs/workbench/api/common/extHostTypes';
|
import * as types from 'vs/workbench/api/common/extHostTypes';
|
||||||
import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
|
|
||||||
import type * as vscode from 'vscode';
|
import type * as vscode from 'vscode';
|
||||||
import { ExtHostCommentsShape, IMainContext, MainContext, CommentThreadChanges, CommentChanges } from './extHost.protocol';
|
import { ExtHostCommentsShape, IMainContext, MainContext, CommentThreadChanges, CommentChanges } from './extHost.protocol';
|
||||||
import { ExtHostCommands } from './extHostCommands';
|
import { ExtHostCommands } from './extHostCommands';
|
||||||
|
@ -338,12 +337,10 @@ export function createExtHostComments(mainContext: IMainContext, commands: ExtHo
|
||||||
private _state?: vscode.CommentThreadState;
|
private _state?: vscode.CommentThreadState;
|
||||||
|
|
||||||
get state(): vscode.CommentThreadState {
|
get state(): vscode.CommentThreadState {
|
||||||
checkProposedApiEnabled(this.extensionDescription, 'commentsResolvedState');
|
|
||||||
return this._state!;
|
return this._state!;
|
||||||
}
|
}
|
||||||
|
|
||||||
set state(newState: vscode.CommentThreadState) {
|
set state(newState: vscode.CommentThreadState) {
|
||||||
checkProposedApiEnabled(this.extensionDescription, 'commentsResolvedState');
|
|
||||||
this._state = newState;
|
this._state = newState;
|
||||||
this.modifications.state = newState;
|
this.modifications.state = newState;
|
||||||
this._onDidUpdateCommentThread.fire();
|
this._onDidUpdateCommentThread.fire();
|
||||||
|
|
|
@ -14,10 +14,10 @@ import { Disposable as VSCodeDisposable, EnvironmentVariableMutatorType, Termina
|
||||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
import { NotSupportedError } from 'vs/base/common/errors';
|
import { NotSupportedError } from 'vs/base/common/errors';
|
||||||
import { serializeEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableShared';
|
import { serializeEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableShared';
|
||||||
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||||
import { generateUuid } from 'vs/base/common/uuid';
|
import { generateUuid } from 'vs/base/common/uuid';
|
||||||
import { ISerializableEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
import { ISerializableEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable';
|
||||||
import { ICreateContributedTerminalProfileOptions, IProcessReadyEvent, IShellLaunchConfigDto, ITerminalChildProcess, ITerminalLaunchError, ITerminalProfile, TerminalIcon, TerminalLocation, IProcessProperty, ProcessPropertyType, IProcessPropertyMap } from 'vs/platform/terminal/common/terminal';
|
import { ICreateContributedTerminalProfileOptions, IProcessReadyEvent, IShellLaunchConfigDto, ITerminalChildProcess, ITerminalLaunchError, ITerminalProfile, TerminalIcon, TerminalLocation, IProcessProperty, ProcessPropertyType, IProcessPropertyMap } from 'vs/platform/terminal/common/terminal';
|
||||||
import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering';
|
import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering';
|
||||||
import { ThemeColor } from 'vs/platform/theme/common/themeService';
|
import { ThemeColor } from 'vs/platform/theme/common/themeService';
|
||||||
|
|
|
@ -19,7 +19,7 @@ import { IColorTheme, IThemeService, registerThemingParticipant } from 'vs/platf
|
||||||
import { ActivityAction, ActivityActionViewItem, IActivityActionViewItemOptions, IActivityHoverOptions, ICompositeBar, ICompositeBarColors, ToggleCompositeBadgeAction, ToggleCompositePinnedAction } from 'vs/workbench/browser/parts/compositeBarActions';
|
import { ActivityAction, ActivityActionViewItem, IActivityActionViewItemOptions, IActivityHoverOptions, ICompositeBar, ICompositeBarColors, ToggleCompositeBadgeAction, ToggleCompositePinnedAction } from 'vs/workbench/browser/parts/compositeBarActions';
|
||||||
import { Categories } from 'vs/platform/action/common/actionCommonCategories';
|
import { Categories } from 'vs/platform/action/common/actionCommonCategories';
|
||||||
import { IActivity } from 'vs/workbench/common/activity';
|
import { IActivity } from 'vs/workbench/common/activity';
|
||||||
import { ACTIVITY_BAR_FOREGROUND, ACTIVITY_BAR_ACTIVE_BORDER, ACTIVITY_BAR_ACTIVE_FOCUS_BORDER, ACTIVITY_BAR_ACTIVE_BACKGROUND, ACTIVITY_BAR_PROFILE_BACKGROUND, ACTIVITY_BAR_PROFILE_HOVER_FOREGROUND } from 'vs/workbench/common/theme';
|
import { ACTIVITY_BAR_FOREGROUND, ACTIVITY_BAR_ACTIVE_BORDER, ACTIVITY_BAR_ACTIVE_FOCUS_BORDER, ACTIVITY_BAR_ACTIVE_BACKGROUND, ACTIVITY_BAR_PROFILE_HOVER_FOREGROUND } from 'vs/workbench/common/theme';
|
||||||
import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService';
|
import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService';
|
||||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||||
import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
||||||
|
@ -508,11 +508,6 @@ registerThemingParticipant((theme, collector) => {
|
||||||
const activityBarForegroundColor = theme.getColor(ACTIVITY_BAR_FOREGROUND);
|
const activityBarForegroundColor = theme.getColor(ACTIVITY_BAR_FOREGROUND);
|
||||||
if (activityBarForegroundColor) {
|
if (activityBarForegroundColor) {
|
||||||
collector.addRule(`
|
collector.addRule(`
|
||||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.active .action-label:not(.codicon):not(.profile-activity-item),
|
|
||||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:focus .action-label:not(.codicon):not(.profile-activity-item),
|
|
||||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:hover .action-label:not(.codicon):not(.profile-activity-item) {
|
|
||||||
background-color: ${activityBarForegroundColor} !important;
|
|
||||||
}
|
|
||||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.active .action-label.codicon,
|
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.active .action-label.codicon,
|
||||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:focus .action-label.codicon,
|
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:focus .action-label.codicon,
|
||||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:hover .action-label.codicon {
|
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:hover .action-label.codicon {
|
||||||
|
@ -521,23 +516,12 @@ registerThemingParticipant((theme, collector) => {
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const activityBarProfileBgColor = theme.getColor(ACTIVITY_BAR_PROFILE_BACKGROUND);
|
|
||||||
if (activityBarProfileBgColor) {
|
|
||||||
collector.addRule(`
|
|
||||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item .action-label.profile-activity-item,
|
|
||||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item .action-label.profile-activity-item,
|
|
||||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item .action-label.profile-activity-item {
|
|
||||||
background-color: ${activityBarProfileBgColor} !important;
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const activityBarProfileHoverFgColor = theme.getColor(ACTIVITY_BAR_PROFILE_HOVER_FOREGROUND);
|
const activityBarProfileHoverFgColor = theme.getColor(ACTIVITY_BAR_PROFILE_HOVER_FOREGROUND);
|
||||||
if (activityBarProfileHoverFgColor) {
|
if (activityBarProfileHoverFgColor) {
|
||||||
collector.addRule(`
|
collector.addRule(`
|
||||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.active .action-label.profile-activity-item,
|
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.active.profile-activity-item .action-label,
|
||||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:focus .action-label.profile-activity-item,
|
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.profile-activity-item:focus .action-label,
|
||||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item:hover .action-label.profile-activity-item {
|
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item.profile-activity-item:hover .action-label {
|
||||||
color: ${activityBarProfileHoverFgColor} !important;
|
color: ${activityBarProfileHoverFgColor} !important;
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
|
|
|
@ -43,7 +43,7 @@ import { StringSHA1 } from 'vs/base/common/hash';
|
||||||
import { HoverPosition } from 'vs/base/browser/ui/hover/hoverWidget';
|
import { HoverPosition } from 'vs/base/browser/ui/hover/hoverWidget';
|
||||||
import { GestureEvent } from 'vs/base/browser/touch';
|
import { GestureEvent } from 'vs/base/browser/touch';
|
||||||
import { IPaneCompositePart, IPaneCompositeSelectorPart } from 'vs/workbench/browser/parts/paneCompositePart';
|
import { IPaneCompositePart, IPaneCompositeSelectorPart } from 'vs/workbench/browser/parts/paneCompositePart';
|
||||||
import { IUserDataProfileService, PROFILES_TTILE } from 'vs/workbench/services/userDataProfile/common/userDataProfile';
|
import { IUserDataProfileService, PROFILES_TTILE, defaultUserDataProfileIcon } from 'vs/workbench/services/userDataProfile/common/userDataProfile';
|
||||||
import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
|
import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
|
||||||
|
|
||||||
interface IPlaceholderViewContainer {
|
interface IPlaceholderViewContainer {
|
||||||
|
@ -618,11 +618,11 @@ export class ActivitybarPart extends Part implements IPaneCompositeSelectorPart
|
||||||
|
|
||||||
private createProfilesActivity(): IProfileActivity {
|
private createProfilesActivity(): IProfileActivity {
|
||||||
const shortName = this.userDataProfileService.getShortName(this.userDataProfileService.currentProfile);
|
const shortName = this.userDataProfileService.getShortName(this.userDataProfileService.currentProfile);
|
||||||
const icon = ThemeIcon.fromString(shortName);
|
const icon = ThemeIcon.fromString(shortName) ?? defaultUserDataProfileIcon;
|
||||||
return {
|
return {
|
||||||
id: 'workbench.actions.profiles',
|
id: 'workbench.actions.profiles',
|
||||||
name: icon ? this.userDataProfileService.currentProfile.name : shortName,
|
name: icon ? this.userDataProfileService.currentProfile.name : shortName,
|
||||||
cssClass: icon ? `${ThemeIcon.asClassName(icon)} profile-activity-item` : 'profile-activity-item',
|
cssClass: ThemeIcon.asClassName(icon),
|
||||||
icon: !!icon
|
icon: !!icon
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,26 +176,8 @@
|
||||||
vertical-align: baseline;
|
vertical-align: baseline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-label.profile-activity-item {
|
|
||||||
height: 20px;
|
|
||||||
width: 32px;
|
|
||||||
margin: 14px 8px;
|
|
||||||
padding: 0px;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 11px;
|
|
||||||
font-weight: 600;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Right aligned */
|
/* Right aligned */
|
||||||
|
|
||||||
.monaco-workbench .activitybar.right > .content :not(.monaco-menu) > .monaco-action-bar .action-label:not(.codicon):not(.profile-activity-item) {
|
|
||||||
margin-left: 0;
|
|
||||||
padding: 0 48px 0 0;
|
|
||||||
background-position: calc(100% - 9px) center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.monaco-workbench .activitybar.right > .content :not(.monaco-menu) > .monaco-action-bar .badge {
|
.monaco-workbench .activitybar.right > .content :not(.monaco-menu) > .monaco-action-bar .badge {
|
||||||
left: auto;
|
left: auto;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
|
|
@ -137,7 +137,7 @@ export class DynamicEditorConfigurations extends Disposable implements IWorkbenc
|
||||||
properties: {
|
properties: {
|
||||||
'workbench.editorAssociations': {
|
'workbench.editorAssociations': {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
markdownDescription: localize('editor.editorAssociations', "Configure glob patterns to editors (for example `\"*.hex\": \"hexEditor.hexEdit\"`). These have precedence over the default behavior."),
|
markdownDescription: localize('editor.editorAssociations', "Configure glob patterns to editors (for example `\"*.hex\": \"hexEditor.hexedit\"`). These have precedence over the default behavior."),
|
||||||
patternProperties: {
|
patternProperties: {
|
||||||
'.*': {
|
'.*': {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
|
|
@ -233,8 +233,8 @@ export class TextDiffEditor extends AbstractTextEditor<IDiffEditorViewState> imp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override shouldComputeConfiguration(e: ITextResourceConfigurationChangeEvent, resource: URI): boolean {
|
protected override shouldHandleConfigurationChangeEvent(e: ITextResourceConfigurationChangeEvent, resource: URI): boolean {
|
||||||
if (super.shouldComputeConfiguration(e, resource)) {
|
if (super.shouldHandleConfigurationChangeEvent(e, resource)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,16 +64,8 @@ export abstract class AbstractTextEditor<T extends IEditorViewState> extends Abs
|
||||||
) {
|
) {
|
||||||
super(id, AbstractTextEditor.VIEW_STATE_PREFERENCE_KEY, telemetryService, instantiationService, storageService, textResourceConfigurationService, themeService, editorService, editorGroupService);
|
super(id, AbstractTextEditor.VIEW_STATE_PREFERENCE_KEY, telemetryService, instantiationService, storageService, textResourceConfigurationService, themeService, editorService, editorGroupService);
|
||||||
|
|
||||||
this._register(this.textResourceConfigurationService.onDidChangeConfiguration(e => {
|
// Listen to configuration changes
|
||||||
const resource = this.getActiveResource();
|
this._register(this.textResourceConfigurationService.onDidChangeConfiguration(e => this.handleConfigurationChangeEvent(e)));
|
||||||
if (!this.shouldComputeConfiguration(e, resource)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const value = resource ? this.textResourceConfigurationService.getValue<IEditorConfiguration>(resource) : undefined;
|
|
||||||
|
|
||||||
return this.handleConfigurationChangeEvent(value);
|
|
||||||
}));
|
|
||||||
|
|
||||||
// ARIA: if a group is added or removed, update the editor's ARIA
|
// ARIA: if a group is added or removed, update the editor's ARIA
|
||||||
// label so that it appears in the label for when there are > 1 groups
|
// label so that it appears in the label for when there are > 1 groups
|
||||||
|
@ -90,14 +82,23 @@ export abstract class AbstractTextEditor<T extends IEditorViewState> extends Abs
|
||||||
this._register(this.fileService.onDidChangeFileSystemProviderRegistrations(e => this.onDidChangeFileSystemProvider(e.scheme)));
|
this._register(this.fileService.onDidChangeFileSystemProviderRegistrations(e => this.onDidChangeFileSystemProvider(e.scheme)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleConfigurationChangeEvent(configuration?: IEditorConfiguration): void {
|
private handleConfigurationChangeEvent(e: ITextResourceConfigurationChangeEvent): void {
|
||||||
|
const resource = this.getActiveResource();
|
||||||
|
if (!this.shouldHandleConfigurationChangeEvent(e, resource)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.isVisible()) {
|
if (this.isVisible()) {
|
||||||
this.updateEditorConfiguration(configuration);
|
this.updateEditorConfiguration(resource);
|
||||||
} else {
|
} else {
|
||||||
this.hasPendingConfigurationChange = true;
|
this.hasPendingConfigurationChange = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected shouldHandleConfigurationChangeEvent(e: ITextResourceConfigurationChangeEvent, resource: URI | undefined): boolean {
|
||||||
|
return e.affectsConfiguration(resource, 'editor');
|
||||||
|
}
|
||||||
|
|
||||||
private consumePendingConfigurationChangeEvent(): void {
|
private consumePendingConfigurationChangeEvent(): void {
|
||||||
if (this.hasPendingConfigurationChange) {
|
if (this.hasPendingConfigurationChange) {
|
||||||
this.updateEditorConfiguration();
|
this.updateEditorConfiguration();
|
||||||
|
@ -105,10 +106,6 @@ export abstract class AbstractTextEditor<T extends IEditorViewState> extends Abs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected shouldComputeConfiguration(e: ITextResourceConfigurationChangeEvent, resource: URI | undefined): boolean {
|
|
||||||
return e.affectsConfiguration(resource, 'editor');
|
|
||||||
}
|
|
||||||
|
|
||||||
protected computeConfiguration(configuration: IEditorConfiguration): ICodeEditorOptions {
|
protected computeConfiguration(configuration: IEditorConfiguration): ICodeEditorOptions {
|
||||||
|
|
||||||
// Specific editor options always overwrite user configuration
|
// Specific editor options always overwrite user configuration
|
||||||
|
@ -257,12 +254,10 @@ export abstract class AbstractTextEditor<T extends IEditorViewState> extends Abs
|
||||||
return input.resource;
|
return input.resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateEditorConfiguration(configuration?: IEditorConfiguration): void {
|
private updateEditorConfiguration(resource = this.getActiveResource()): void {
|
||||||
if (!configuration) {
|
let configuration: IEditorConfiguration | undefined = undefined;
|
||||||
const resource = this.getActiveResource();
|
if (resource) {
|
||||||
if (resource) {
|
configuration = this.textResourceConfigurationService.getValue<IEditorConfiguration>(resource);
|
||||||
configuration = this.textResourceConfigurationService.getValue<IEditorConfiguration>(resource);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!configuration) {
|
if (!configuration) {
|
||||||
|
|
|
@ -639,13 +639,6 @@ export const ACTIVITY_BAR_PROFILE_HOVER_FOREGROUND = registerColor('activityBarI
|
||||||
hcLight: ACTIVITY_BAR_FOREGROUND
|
hcLight: ACTIVITY_BAR_FOREGROUND
|
||||||
}, localize('activityBarItem.profilesHoverForeground', "Foreground color for the profile entry on the activity bar when hovering."));
|
}, localize('activityBarItem.profilesHoverForeground', "Foreground color for the profile entry on the activity bar when hovering."));
|
||||||
|
|
||||||
export const ACTIVITY_BAR_PROFILE_BACKGROUND = registerColor('activityBarItem.profilesBackground', {
|
|
||||||
dark: lighten(ACTIVITY_BAR_BACKGROUND, 0.5),
|
|
||||||
light: darken(ACTIVITY_BAR_BACKGROUND, 0.12),
|
|
||||||
hcDark: null,
|
|
||||||
hcLight: null
|
|
||||||
}, localize('activityBarItem.profilesBackground', "Background color for the profile entry on the activity bar."));
|
|
||||||
|
|
||||||
// < --- Remote --- >
|
// < --- Remote --- >
|
||||||
|
|
||||||
export const STATUS_BAR_HOST_NAME_BACKGROUND = registerColor('statusBarItem.remoteBackground', {
|
export const STATUS_BAR_HOST_NAME_BACKGROUND = registerColor('statusBarItem.remoteBackground', {
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import 'vs/css!./media/customEditor';
|
||||||
import { coalesce } from 'vs/base/common/arrays';
|
import { coalesce } from 'vs/base/common/arrays';
|
||||||
import { Emitter, Event } from 'vs/base/common/event';
|
import { Emitter, Event } from 'vs/base/common/event';
|
||||||
import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||||
|
@ -17,8 +18,6 @@ import { FileOperation, IFileService } from 'vs/platform/files/common/files';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { Registry } from 'vs/platform/registry/common/platform';
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||||
import * as colorRegistry from 'vs/platform/theme/common/colorRegistry';
|
|
||||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
|
||||||
import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity';
|
import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity';
|
||||||
import { DEFAULT_EDITOR_ASSOCIATION, EditorExtensions, GroupIdentifier, IEditorFactoryRegistry, IResourceDiffEditorInput } from 'vs/workbench/common/editor';
|
import { DEFAULT_EDITOR_ASSOCIATION, EditorExtensions, GroupIdentifier, IEditorFactoryRegistry, IResourceDiffEditorInput } from 'vs/workbench/common/editor';
|
||||||
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||||
|
@ -262,10 +261,3 @@ export class CustomEditorService extends Disposable implements ICustomEditorServ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
registerThemingParticipant((theme, collector) => {
|
|
||||||
const shadow = theme.getColor(colorRegistry.scrollbarShadow);
|
|
||||||
if (shadow) {
|
|
||||||
collector.addRule(`.webview.modified { box-shadow: -6px 0 5px -5px ${shadow}; }`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
.webview.modified {
|
||||||
|
box-shadow: -6px 0 5px -5px var(--vscode-scrollbar-shadow);
|
||||||
|
}
|
|
@ -317,7 +317,7 @@ export class DebugSession implements IDebugSession {
|
||||||
supportsVariableType: true, // #8858
|
supportsVariableType: true, // #8858
|
||||||
supportsVariablePaging: true, // #9537
|
supportsVariablePaging: true, // #9537
|
||||||
supportsRunInTerminalRequest: true, // #10574
|
supportsRunInTerminalRequest: true, // #10574
|
||||||
locale: platform.locale,
|
locale: platform.language, // #169114
|
||||||
supportsProgressReporting: true, // #92253
|
supportsProgressReporting: true, // #92253
|
||||||
supportsInvalidatedEvent: true, // #106745
|
supportsInvalidatedEvent: true, // #106745
|
||||||
supportsMemoryReferences: true, //#129684
|
supportsMemoryReferences: true, //#129684
|
||||||
|
|
|
@ -30,14 +30,14 @@ import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||||
import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration';
|
import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration';
|
||||||
import { Extensions as ConfigurationExtensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
|
import { Extensions as ConfigurationExtensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
|
||||||
import { IQuickInputButton, IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
|
import { IQuickInputButton, IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput';
|
||||||
import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry';
|
import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry';
|
||||||
import { ContextKeyExpr, ContextKeyExpression, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
import { ContextKeyExpr, ContextKeyExpression, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||||
import { getVirtualWorkspaceLocation } from 'vs/platform/workspace/common/virtualWorkspace';
|
import { getVirtualWorkspaceLocation } from 'vs/platform/workspace/common/virtualWorkspace';
|
||||||
import { Schemas } from 'vs/base/common/network';
|
import { Schemas } from 'vs/base/common/network';
|
||||||
import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys';
|
import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys';
|
||||||
import { isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
|
import { IExtensionService, isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
|
||||||
import { EditSessionsLogService } from 'vs/workbench/contrib/editSessions/common/editSessionsLogService';
|
import { EditSessionsLogService } from 'vs/workbench/contrib/editSessions/common/editSessionsLogService';
|
||||||
import { IViewContainersRegistry, Extensions as ViewExtensions, ViewContainerLocation, IViewsService } from 'vs/workbench/common/views';
|
import { IViewContainersRegistry, Extensions as ViewExtensions, ViewContainerLocation, IViewsService } from 'vs/workbench/common/views';
|
||||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||||
|
@ -61,10 +61,14 @@ import { ILocalizedString } from 'vs/platform/action/common/action';
|
||||||
import { Codicon } from 'vs/base/common/codicons';
|
import { Codicon } from 'vs/base/common/codicons';
|
||||||
import { CancellationError } from 'vs/base/common/errors';
|
import { CancellationError } from 'vs/base/common/errors';
|
||||||
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||||
|
import { IExtensionsViewPaneContainer, VIEWLET_ID } from 'vs/workbench/contrib/extensions/common/extensions';
|
||||||
|
import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite';
|
||||||
|
|
||||||
|
|
||||||
registerSingleton(IEditSessionsLogService, EditSessionsLogService, InstantiationType.Delayed);
|
registerSingleton(IEditSessionsLogService, EditSessionsLogService, InstantiationType.Delayed);
|
||||||
registerSingleton(IEditSessionsStorageService, EditSessionsWorkbenchService, InstantiationType.Delayed);
|
registerSingleton(IEditSessionsStorageService, EditSessionsWorkbenchService, InstantiationType.Delayed);
|
||||||
|
|
||||||
|
|
||||||
const continueWorkingOnCommand: IAction2Options = {
|
const continueWorkingOnCommand: IAction2Options = {
|
||||||
id: '_workbench.editSessions.actions.continueEditSession',
|
id: '_workbench.editSessions.actions.continueEditSession',
|
||||||
title: { value: localize('continue working on', "Continue Working On..."), original: 'Continue Working On...' },
|
title: { value: localize('continue working on', "Continue Working On..."), original: 'Continue Working On...' },
|
||||||
|
@ -82,6 +86,23 @@ const showOutputChannelCommand: IAction2Options = {
|
||||||
title: { value: localize('show log', 'Show Log'), original: 'Show Log' },
|
title: { value: localize('show log', 'Show Log'), original: 'Show Log' },
|
||||||
category: EDIT_SESSION_SYNC_CATEGORY
|
category: EDIT_SESSION_SYNC_CATEGORY
|
||||||
};
|
};
|
||||||
|
const installAdditionalContinueOnOptionsCommand = {
|
||||||
|
id: 'workbench.action.continueOn.extensions',
|
||||||
|
title: localize('continueOn.installAdditional', 'Install additional development environment options'),
|
||||||
|
};
|
||||||
|
registerAction2(class extends Action2 {
|
||||||
|
constructor() {
|
||||||
|
super({ ...installAdditionalContinueOnOptionsCommand, f1: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
async run(accessor: ServicesAccessor): Promise<void> {
|
||||||
|
const paneCompositePartService = accessor.get(IPaneCompositePartService);
|
||||||
|
const viewlet = await paneCompositePartService.openPaneComposite(VIEWLET_ID, ViewContainerLocation.Sidebar, true);
|
||||||
|
const view = viewlet?.getViewPaneContainer() as IExtensionsViewPaneContainer | undefined;
|
||||||
|
view?.search('@tag:continueOn');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const resumeProgressOptionsTitle = `[${localize('resuming working changes window', 'Resuming working changes...')}](command:${showOutputChannelCommand.id})`;
|
const resumeProgressOptionsTitle = `[${localize('resuming working changes window', 'Resuming working changes...')}](command:${showOutputChannelCommand.id})`;
|
||||||
const resumeProgressOptions = {
|
const resumeProgressOptions = {
|
||||||
location: ProgressLocation.Window,
|
location: ProgressLocation.Window,
|
||||||
|
@ -124,6 +145,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
|
||||||
@IActivityService private readonly activityService: IActivityService,
|
@IActivityService private readonly activityService: IActivityService,
|
||||||
@IEditorService private readonly editorService: IEditorService,
|
@IEditorService private readonly editorService: IEditorService,
|
||||||
@IRemoteAgentService private readonly remoteAgentService: IRemoteAgentService,
|
@IRemoteAgentService private readonly remoteAgentService: IRemoteAgentService,
|
||||||
|
@IExtensionService private readonly extensionService: IExtensionService,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
@ -809,7 +831,8 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
|
||||||
if (remoteGroup !== undefined) {
|
if (remoteGroup !== undefined) {
|
||||||
MenuRegistry.appendMenuItem(MenuId.StatusBarRemoteIndicatorMenu, {
|
MenuRegistry.appendMenuItem(MenuId.StatusBarRemoteIndicatorMenu, {
|
||||||
group: remoteGroup,
|
group: remoteGroup,
|
||||||
command: command
|
command: command,
|
||||||
|
when: command.precondition
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -851,14 +874,22 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
|
||||||
: this.contextService.getWorkspace().folders.map((folder) => folder.name).join(', ');
|
: this.contextService.getWorkspace().folders.map((folder) => folder.name).join(', ');
|
||||||
quickPick.placeholder = localize('continueEditSessionPick.title.v2', "Select a development environment to continue working on {0} in", `'${workspaceContext}'`);
|
quickPick.placeholder = localize('continueEditSessionPick.title.v2', "Select a development environment to continue working on {0} in", `'${workspaceContext}'`);
|
||||||
quickPick.items = this.createPickItems();
|
quickPick.items = this.createPickItems();
|
||||||
|
this.extensionService.onDidChangeExtensions(() => {
|
||||||
|
quickPick.items = this.createPickItems();
|
||||||
|
});
|
||||||
|
|
||||||
const command = await new Promise<string | undefined>((resolve, reject) => {
|
const command = await new Promise<string | undefined>((resolve, reject) => {
|
||||||
quickPick.onDidHide(() => resolve(undefined));
|
quickPick.onDidHide(() => resolve(undefined));
|
||||||
|
|
||||||
quickPick.onDidAccept((e) => {
|
quickPick.onDidAccept((e) => {
|
||||||
const selection = quickPick.activeItems[0].command;
|
const selection = quickPick.activeItems[0].command;
|
||||||
resolve(selection);
|
|
||||||
quickPick.hide();
|
if (selection === installAdditionalContinueOnOptionsCommand.id) {
|
||||||
|
void this.commandService.executeCommand(installAdditionalContinueOnOptionsCommand.id);
|
||||||
|
} else {
|
||||||
|
resolve(selection);
|
||||||
|
quickPick.hide();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
quickPick.show();
|
quickPick.show();
|
||||||
|
@ -912,7 +943,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private createPickItems(): ContinueEditSessionItem[] {
|
private createPickItems(): (ContinueEditSessionItem | IQuickPickSeparator)[] {
|
||||||
const items = [...this.continueEditSessionOptions].filter((option) => option.when === undefined || this.contextKeyService.contextMatchesRules(option.when));
|
const items = [...this.continueEditSessionOptions].filter((option) => option.when === undefined || this.contextKeyService.contextMatchesRules(option.when));
|
||||||
|
|
||||||
if (getVirtualWorkspaceLocation(this.contextService.getWorkspace()) !== undefined && isNative) {
|
if (getVirtualWorkspaceLocation(this.contextService.getWorkspace()) !== undefined && isNative) {
|
||||||
|
@ -923,7 +954,8 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
return items.sort((item1, item2) => item1.label.localeCompare(item2.label));
|
const sortedItems: (ContinueEditSessionItem | IQuickPickSeparator)[] = items.sort((item1, item2) => item1.label.localeCompare(item2.label));
|
||||||
|
return sortedItems.concat({ type: 'separator' }, new ContinueEditSessionItem(installAdditionalContinueOnOptionsCommand.title, installAdditionalContinueOnOptionsCommand.id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||||
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
|
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||||
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||||
|
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||||
|
|
||||||
const folderName = 'test-folder';
|
const folderName = 'test-folder';
|
||||||
const folderUri = URI.file(`/${folderName}`);
|
const folderUri = URI.file(`/${folderName}`);
|
||||||
|
@ -75,6 +76,9 @@ suite('Edit session sync', () => {
|
||||||
override onDidSignIn = Event.None;
|
override onDidSignIn = Event.None;
|
||||||
override onDidSignOut = Event.None;
|
override onDidSignOut = Event.None;
|
||||||
});
|
});
|
||||||
|
instantiationService.stub(IExtensionService, new class extends mock<IExtensionService>() {
|
||||||
|
override onDidChangeExtensions = Event.None;
|
||||||
|
});
|
||||||
instantiationService.stub(IProgressService, ProgressService);
|
instantiationService.stub(IProgressService, ProgressService);
|
||||||
instantiationService.stub(ISCMService, SCMService);
|
instantiationService.stub(ISCMService, SCMService);
|
||||||
instantiationService.stub(IEnvironmentService, TestEnvironmentService);
|
instantiationService.stub(IEnvironmentService, TestEnvironmentService);
|
||||||
|
|
|
@ -127,16 +127,20 @@ export class OutputElement extends Disposable {
|
||||||
|
|
||||||
private _renderSearchForMimetype(viewModel: ICellOutputViewModel, mimeType: string): IInsetRenderOutput {
|
private _renderSearchForMimetype(viewModel: ICellOutputViewModel, mimeType: string): IInsetRenderOutput {
|
||||||
const query = `@tag:notebookRenderer ${mimeType}`;
|
const query = `@tag:notebookRenderer ${mimeType}`;
|
||||||
|
|
||||||
|
const p = DOM.$('p', undefined, `No renderer could be found for mimetype "${mimeType}", but one might be available on the Marketplace.`);
|
||||||
|
const a = DOM.$('a', { href: `command:workbench.extensions.search?%22${query}%22`, class: 'monaco-button monaco-text-button', tabindex: 0, role: 'button', style: 'padding: 8px; text-decoration: none; color: rgb(255, 255, 255); background-color: rgb(14, 99, 156); max-width: 200px;' }, `Search Marketplace`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: RenderOutputType.Html,
|
type: RenderOutputType.Html,
|
||||||
source: viewModel,
|
source: viewModel,
|
||||||
htmlContent: `<p>No renderer could be found for mimetype "${mimeType}", but one might be available on the Marketplace.</p>
|
htmlContent: p.outerHTML + a.outerHTML,
|
||||||
<a href="command:workbench.extensions.search?%22${query}%22" class="monaco-button monaco-text-button" tabindex="0" role="button" style="padding: 8px; text-decoration: none; color: rgb(255, 255, 255); background-color: rgb(14, 99, 156); max-width: 200px;">Search Marketplace</a>`
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private _renderMessage(viewModel: ICellOutputViewModel, message: string): IInsetRenderOutput {
|
private _renderMessage(viewModel: ICellOutputViewModel, message: string): IInsetRenderOutput {
|
||||||
return { type: RenderOutputType.Html, source: viewModel, htmlContent: `<p>${message}</p>` };
|
const el = DOM.$('p', undefined, message);
|
||||||
|
return { type: RenderOutputType.Html, source: viewModel, htmlContent: el.outerHTML };
|
||||||
}
|
}
|
||||||
|
|
||||||
private async pickActiveMimeTypeRenderer(notebookTextModel: NotebookTextModel, viewModel: ICellOutputViewModel) {
|
private async pickActiveMimeTypeRenderer(notebookTextModel: NotebookTextModel, viewModel: ICellOutputViewModel) {
|
||||||
|
|
|
@ -29,6 +29,7 @@ import { CodeCellRenderTemplate } from 'vs/workbench/contrib/notebook/browser/vi
|
||||||
import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel';
|
import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel';
|
||||||
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
|
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
|
||||||
import { CellUri, IOrderedMimeType, NotebookCellOutputsSplice, RENDERER_NOT_AVAILABLE } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
import { CellUri, IOrderedMimeType, NotebookCellOutputsSplice, RENDERER_NOT_AVAILABLE } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||||
|
import { INotebookExecutionStateService } from 'vs/workbench/contrib/notebook/common/notebookExecutionStateService';
|
||||||
import { INotebookKernel } from 'vs/workbench/contrib/notebook/common/notebookKernelService';
|
import { INotebookKernel } from 'vs/workbench/contrib/notebook/common/notebookKernelService';
|
||||||
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
|
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
|
||||||
import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite';
|
import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite';
|
||||||
|
@ -236,16 +237,20 @@ class CellOutputElement extends Disposable {
|
||||||
|
|
||||||
private _renderSearchForMimetype(viewModel: ICellOutputViewModel, mimeType: string): IInsetRenderOutput {
|
private _renderSearchForMimetype(viewModel: ICellOutputViewModel, mimeType: string): IInsetRenderOutput {
|
||||||
const query = `@tag:notebookRenderer ${mimeType}`;
|
const query = `@tag:notebookRenderer ${mimeType}`;
|
||||||
|
|
||||||
|
const p = DOM.$('p', undefined, `No renderer could be found for mimetype "${mimeType}", but one might be available on the Marketplace.`);
|
||||||
|
const a = DOM.$('a', { href: `command:workbench.extensions.search?%22${query}%22`, class: 'monaco-button monaco-text-button', tabindex: 0, role: 'button', style: 'padding: 8px; text-decoration: none; color: rgb(255, 255, 255); background-color: rgb(14, 99, 156); max-width: 200px;' }, `Search Marketplace`);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: RenderOutputType.Html,
|
type: RenderOutputType.Html,
|
||||||
source: viewModel,
|
source: viewModel,
|
||||||
htmlContent: `<p>No renderer could be found for mimetype "${mimeType}", but one might be available on the Marketplace.</p>
|
htmlContent: p.outerHTML + a.outerHTML
|
||||||
<a href="command:workbench.extensions.search?%22${query}%22" class="monaco-button monaco-text-button" tabindex="0" role="button" style="padding: 8px; text-decoration: none; color: rgb(255, 255, 255); background-color: rgb(14, 99, 156); max-width: 200px;">Search Marketplace</a>`
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private _renderMessage(viewModel: ICellOutputViewModel, message: string): IInsetRenderOutput {
|
private _renderMessage(viewModel: ICellOutputViewModel, message: string): IInsetRenderOutput {
|
||||||
return { type: RenderOutputType.Html, source: viewModel, htmlContent: `<p>${message}</p>` };
|
const el = DOM.$('p', undefined, message);
|
||||||
|
return { type: RenderOutputType.Html, source: viewModel, htmlContent: el.outerHTML };
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _attachToolbar(outputItemDiv: HTMLElement, notebookTextModel: NotebookTextModel, kernel: INotebookKernel | undefined, index: number, mimeTypes: readonly IOrderedMimeType[]) {
|
private async _attachToolbar(outputItemDiv: HTMLElement, notebookTextModel: NotebookTextModel, kernel: INotebookKernel | undefined, index: number, mimeTypes: readonly IOrderedMimeType[]) {
|
||||||
|
@ -427,6 +432,11 @@ class OutputEntryViewHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const enum CellOutputUpdateContext {
|
||||||
|
Execution = 1,
|
||||||
|
Other = 2
|
||||||
|
}
|
||||||
|
|
||||||
export class CellOutputContainer extends CellContentPart {
|
export class CellOutputContainer extends CellContentPart {
|
||||||
private _outputEntries: OutputEntryViewHandler[] = [];
|
private _outputEntries: OutputEntryViewHandler[] = [];
|
||||||
|
|
||||||
|
@ -440,12 +450,23 @@ export class CellOutputContainer extends CellContentPart {
|
||||||
private readonly templateData: CodeCellRenderTemplate,
|
private readonly templateData: CodeCellRenderTemplate,
|
||||||
private options: { limit: number },
|
private options: { limit: number },
|
||||||
@IOpenerService private readonly openerService: IOpenerService,
|
@IOpenerService private readonly openerService: IOpenerService,
|
||||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
@INotebookExecutionStateService private readonly _notebookExecutionStateService: INotebookExecutionStateService,
|
||||||
|
@IInstantiationService private readonly instantiationService: IInstantiationService
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
this._register(viewCell.onDidStartExecution(() => {
|
||||||
|
viewCell.updateOutputMinHeight(viewCell.layoutInfo.outputTotalHeight);
|
||||||
|
}));
|
||||||
|
|
||||||
|
this._register(viewCell.onDidStopExecution(() => {
|
||||||
|
this._validateFinalOutputHeight(false);
|
||||||
|
}));
|
||||||
|
|
||||||
this._register(viewCell.onDidChangeOutputs(splice => {
|
this._register(viewCell.onDidChangeOutputs(splice => {
|
||||||
this._updateOutputs(splice);
|
const executionState = this._notebookExecutionStateService.getCellExecution(viewCell.uri);
|
||||||
|
const context = executionState ? CellOutputUpdateContext.Execution : CellOutputUpdateContext.Other;
|
||||||
|
this._updateOutputs(splice, context);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._register(viewCell.onDidChangeLayout(() => {
|
this._register(viewCell.onDidChangeLayout(() => {
|
||||||
|
@ -539,7 +560,7 @@ export class CellOutputContainer extends CellContentPart {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _updateOutputs(splice: NotebookCellOutputsSplice) {
|
private _updateOutputs(splice: NotebookCellOutputsSplice, context: CellOutputUpdateContext = CellOutputUpdateContext.Other) {
|
||||||
const previousOutputHeight = this.viewCell.layoutInfo.outputTotalHeight;
|
const previousOutputHeight = this.viewCell.layoutInfo.outputTotalHeight;
|
||||||
|
|
||||||
// for cell output update, we make sure the cell does not shrink before the new outputs are rendered.
|
// for cell output update, we make sure the cell does not shrink before the new outputs are rendered.
|
||||||
|
@ -552,10 +573,10 @@ export class CellOutputContainer extends CellContentPart {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.viewCell.spliceOutputHeights(splice.start, splice.deleteCount, splice.newOutputs.map(_ => 0));
|
this.viewCell.spliceOutputHeights(splice.start, splice.deleteCount, splice.newOutputs.map(_ => 0));
|
||||||
this._renderNow(splice);
|
this._renderNow(splice, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _renderNow(splice: NotebookCellOutputsSplice) {
|
private _renderNow(splice: NotebookCellOutputsSplice, context: CellOutputUpdateContext) {
|
||||||
if (splice.start >= this.options.limit) {
|
if (splice.start >= this.options.limit) {
|
||||||
// splice items out of limit
|
// splice items out of limit
|
||||||
return;
|
return;
|
||||||
|
@ -660,7 +681,8 @@ export class CellOutputContainer extends CellContentPart {
|
||||||
this._relayoutCell();
|
this._relayoutCell();
|
||||||
// if it's clearing all outputs, or outputs are all rendered synchronously
|
// if it's clearing all outputs, or outputs are all rendered synchronously
|
||||||
// shrink immediately as the final output height will be zero.
|
// shrink immediately as the final output height will be zero.
|
||||||
this._validateFinalOutputHeight(false || this.viewCell.outputsViewModels.length === 0);
|
// if it's rerun, then the output clearing might be temporary, so we don't shrink immediately
|
||||||
|
this._validateFinalOutputHeight(false || (context === CellOutputUpdateContext.Other && this.viewCell.outputsViewModels.length === 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
private _generateShowMoreElement(disposables: DisposableStore): HTMLElement {
|
private _generateShowMoreElement(disposables: DisposableStore): HTMLElement {
|
||||||
|
|
|
@ -182,40 +182,6 @@ async function webviewPreloads(ctx: PreloadContext) {
|
||||||
|
|
||||||
document.body.addEventListener('click', handleInnerClick);
|
document.body.addEventListener('click', handleInnerClick);
|
||||||
|
|
||||||
const preservedScriptAttributes: (keyof HTMLScriptElement)[] = [
|
|
||||||
'type', 'src', 'nonce', 'noModule', 'async',
|
|
||||||
];
|
|
||||||
|
|
||||||
// derived from https://github.com/jquery/jquery/blob/d0ce00cdfa680f1f0c38460bc51ea14079ae8b07/src/core/DOMEval.js
|
|
||||||
const domEval = (container: Element) => {
|
|
||||||
const arr = Array.from(container.getElementsByTagName('script'));
|
|
||||||
for (let n = 0; n < arr.length; n++) {
|
|
||||||
const node = arr[n];
|
|
||||||
const scriptTag = document.createElement('script');
|
|
||||||
const trustedScript = ttPolicy?.createScript(node.innerText) ?? node.innerText;
|
|
||||||
scriptTag.text = trustedScript as string;
|
|
||||||
for (const key of preservedScriptAttributes) {
|
|
||||||
const val = node[key] || node.getAttribute && node.getAttribute(key);
|
|
||||||
if (val) {
|
|
||||||
scriptTag.setAttribute(key, val as any);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO@connor4312: should script with src not be removed?
|
|
||||||
container.appendChild(scriptTag).parentNode!.removeChild(scriptTag);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
async function loadScriptSource(url: string, originalUri: string): Promise<string> {
|
|
||||||
const res = await fetch(url);
|
|
||||||
const text = await res.text();
|
|
||||||
if (!res.ok) {
|
|
||||||
throw new Error(`Unexpected ${res.status} requesting ${originalUri}: ${text || res.statusText}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface RendererContext extends rendererApi.RendererContext<unknown> {
|
interface RendererContext extends rendererApi.RendererContext<unknown> {
|
||||||
readonly settings: RenderOptions;
|
readonly settings: RenderOptions;
|
||||||
}
|
}
|
||||||
|
@ -248,24 +214,9 @@ async function webviewPreloads(ctx: PreloadContext) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const invokeSourceWithGlobals = (functionSrc: string, globals: { [name: string]: unknown }) => {
|
async function runKernelPreload(url: string): Promise<void> {
|
||||||
const args = Object.entries(globals);
|
|
||||||
return new Function(...args.map(([k]) => k), functionSrc)(...args.map(([, v]) => v));
|
|
||||||
};
|
|
||||||
|
|
||||||
async function runKernelPreload(url: string, originalUri: string, forceLoadAsModule: boolean): Promise<void> {
|
|
||||||
if (forceLoadAsModule) {
|
|
||||||
return activateModuleKernelPreload(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
const text = await loadScriptSource(url, originalUri);
|
|
||||||
const isModule = /\bexport\b.*\bactivate\b/.test(text);
|
|
||||||
try {
|
try {
|
||||||
if (isModule) {
|
return await activateModuleKernelPreload(url);
|
||||||
return activateModuleKernelPreload(url);
|
|
||||||
} else {
|
|
||||||
return invokeSourceWithGlobals(text, { ...kernelPreloadGlobals, scriptUrl: url });
|
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -842,12 +793,6 @@ async function webviewPreloads(ctx: PreloadContext) {
|
||||||
|
|
||||||
const onDidReceiveKernelMessage = createEmitter<unknown>();
|
const onDidReceiveKernelMessage = createEmitter<unknown>();
|
||||||
|
|
||||||
const kernelPreloadGlobals = {
|
|
||||||
acquireVsCodeApi,
|
|
||||||
onDidReceiveKernelMessage: onDidReceiveKernelMessage.event,
|
|
||||||
postKernelMessage: (data: unknown) => postNotebookMessage('customKernelMessage', { message: data }),
|
|
||||||
};
|
|
||||||
|
|
||||||
const ttPolicy = window.trustedTypes?.createPolicy('notebookRenderer', {
|
const ttPolicy = window.trustedTypes?.createPolicy('notebookRenderer', {
|
||||||
createHTML: value => value,
|
createHTML: value => value,
|
||||||
createScript: value => value,
|
createScript: value => value,
|
||||||
|
@ -1233,8 +1178,8 @@ async function webviewPreloads(ctx: PreloadContext) {
|
||||||
}
|
}
|
||||||
case 'preload': {
|
case 'preload': {
|
||||||
const resources = event.data.resources;
|
const resources = event.data.resources;
|
||||||
for (const { uri, originalUri } of resources) {
|
for (const { uri } of resources) {
|
||||||
kernelPreloads.load(uri, originalUri, false);
|
kernelPreloads.load(uri);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1486,9 +1431,9 @@ async function webviewPreloads(ctx: PreloadContext) {
|
||||||
* @param uri URI to load from
|
* @param uri URI to load from
|
||||||
* @param originalUri URI to show in an error message if the preload is invalid.
|
* @param originalUri URI to show in an error message if the preload is invalid.
|
||||||
*/
|
*/
|
||||||
public load(uri: string, originalUri: string, forceLoadAsModule: boolean) {
|
public load(uri: string) {
|
||||||
const promise = Promise.all([
|
const promise = Promise.all([
|
||||||
runKernelPreload(uri, originalUri, forceLoadAsModule),
|
runKernelPreload(uri),
|
||||||
this.waitForAllCurrent(),
|
this.waitForAllCurrent(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -2253,7 +2198,7 @@ async function webviewPreloads(ctx: PreloadContext) {
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const preload of ctx.staticPreloadsData) {
|
for (const preload of ctx.staticPreloadsData) {
|
||||||
kernelPreloads.load(preload.entrypoint, preload.entrypoint, true);
|
kernelPreloads.load(preload.entrypoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
function postNotebookMessage<T extends webviewMessages.FromWebviewMessage>(
|
function postNotebookMessage<T extends webviewMessages.FromWebviewMessage>(
|
||||||
|
@ -2312,7 +2257,6 @@ async function webviewPreloads(ctx: PreloadContext) {
|
||||||
if (content.type === 0 /* RenderOutputType.Html */) {
|
if (content.type === 0 /* RenderOutputType.Html */) {
|
||||||
const trustedHtml = ttPolicy?.createHTML(content.htmlContent) ?? content.htmlContent;
|
const trustedHtml = ttPolicy?.createHTML(content.htmlContent) ?? content.htmlContent;
|
||||||
this.element.innerHTML = trustedHtml as string;
|
this.element.innerHTML = trustedHtml as string;
|
||||||
domEval(this.element);
|
|
||||||
} else if (preloadErrors.some(e => e instanceof Error)) {
|
} else if (preloadErrors.some(e => e instanceof Error)) {
|
||||||
const errors = preloadErrors.filter((e): e is Error => e instanceof Error);
|
const errors = preloadErrors.filter((e): e is Error => e instanceof Error);
|
||||||
showRenderError(`Error loading preloads`, this.element, errors);
|
showRenderError(`Error loading preloads`, this.element, errors);
|
||||||
|
|
|
@ -21,6 +21,7 @@ import { NotebookOptionsChangeEvent } from 'vs/workbench/contrib/notebook/common
|
||||||
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
|
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
|
||||||
import { BaseCellViewModel } from './baseCellViewModel';
|
import { BaseCellViewModel } from './baseCellViewModel';
|
||||||
import { NotebookLayoutInfo } from 'vs/workbench/contrib/notebook/browser/notebookViewEvents';
|
import { NotebookLayoutInfo } from 'vs/workbench/contrib/notebook/browser/notebookViewEvents';
|
||||||
|
import { INotebookExecutionStateService } from 'vs/workbench/contrib/notebook/common/notebookExecutionStateService';
|
||||||
|
|
||||||
export class CodeCellViewModel extends BaseCellViewModel implements ICellViewModel {
|
export class CodeCellViewModel extends BaseCellViewModel implements ICellViewModel {
|
||||||
readonly cellKind = CellKind.Code;
|
readonly cellKind = CellKind.Code;
|
||||||
|
@ -28,6 +29,11 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
|
||||||
protected readonly _onLayoutInfoRead = this._register(new Emitter<void>());
|
protected readonly _onLayoutInfoRead = this._register(new Emitter<void>());
|
||||||
readonly onLayoutInfoRead = this._onLayoutInfoRead.event;
|
readonly onLayoutInfoRead = this._onLayoutInfoRead.event;
|
||||||
|
|
||||||
|
protected readonly _onDidStartExecution = this._register(new Emitter<void>());
|
||||||
|
readonly onDidStartExecution = this._onDidStartExecution.event;
|
||||||
|
protected readonly _onDidStopExecution = this._register(new Emitter<void>());
|
||||||
|
readonly onDidStopExecution = this._onDidStopExecution.event;
|
||||||
|
|
||||||
protected readonly _onDidChangeOutputs = this._register(new Emitter<NotebookCellOutputsSplice>());
|
protected readonly _onDidChangeOutputs = this._register(new Emitter<NotebookCellOutputsSplice>());
|
||||||
readonly onDidChangeOutputs = this._onDidChangeOutputs.event;
|
readonly onDidChangeOutputs = this._onDidChangeOutputs.event;
|
||||||
|
|
||||||
|
@ -116,6 +122,7 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
|
||||||
readonly viewContext: ViewContext,
|
readonly viewContext: ViewContext,
|
||||||
@IConfigurationService configurationService: IConfigurationService,
|
@IConfigurationService configurationService: IConfigurationService,
|
||||||
@INotebookService private readonly _notebookService: INotebookService,
|
@INotebookService private readonly _notebookService: INotebookService,
|
||||||
|
@INotebookExecutionStateService private readonly _notebookExecutionStateService: INotebookExecutionStateService,
|
||||||
@ITextModelService modelService: ITextModelService,
|
@ITextModelService modelService: ITextModelService,
|
||||||
@IUndoRedoService undoRedoService: IUndoRedoService,
|
@IUndoRedoService undoRedoService: IUndoRedoService,
|
||||||
@ICodeEditorService codeEditorService: ICodeEditorService
|
@ICodeEditorService codeEditorService: ICodeEditorService
|
||||||
|
@ -144,6 +151,16 @@ export class CodeCellViewModel extends BaseCellViewModel implements ICellViewMod
|
||||||
dispose(removedOutputs);
|
dispose(removedOutputs);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
this._register(this._notebookExecutionStateService.onDidChangeCellExecution(e => {
|
||||||
|
if (e.affectsCell(model.uri)) {
|
||||||
|
if (e.changed) {
|
||||||
|
this._onDidStartExecution.fire();
|
||||||
|
} else {
|
||||||
|
this._onDidStopExecution.fire();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
this._outputCollection = new Array(this.model.outputs.length);
|
this._outputCollection = new Array(this.model.outputs.length);
|
||||||
|
|
||||||
this._layoutInfo = {
|
this._layoutInfo = {
|
||||||
|
|
|
@ -25,13 +25,13 @@ export class NotebookCellOutputTextModel extends Disposable implements ICellOutp
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly _rawOutput: IOutputDto
|
private _rawOutput: IOutputDto
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
replaceData(items: IOutputItemDto[]) {
|
replaceData(rawData: IOutputDto) {
|
||||||
this._rawOutput.outputs = items;
|
this._rawOutput = rawData;
|
||||||
this._onDidChangeData.fire();
|
this._onDidChangeData.fire();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -280,23 +280,25 @@ export class NotebookCellTextModel extends Disposable implements ICell {
|
||||||
}
|
}
|
||||||
|
|
||||||
spliceNotebookCellOutputs(splice: NotebookCellOutputsSplice): void {
|
spliceNotebookCellOutputs(splice: NotebookCellOutputsSplice): void {
|
||||||
this.outputs.splice(splice.start, splice.deleteCount, ...splice.newOutputs);
|
if (splice.deleteCount > 0 && splice.newOutputs.length > 0) {
|
||||||
this._onDidChangeOutputs.fire(splice);
|
const commonLen = Math.min(splice.deleteCount, splice.newOutputs.length);
|
||||||
|
// update
|
||||||
|
for (let i = 0; i < commonLen; i++) {
|
||||||
|
const currentOutput = this.outputs[splice.start + i];
|
||||||
|
const newOutput = splice.newOutputs[i];
|
||||||
|
|
||||||
|
this.replaceOutput(currentOutput.outputId, newOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.outputs.splice(splice.start + commonLen, splice.deleteCount - commonLen, ...splice.newOutputs.slice(commonLen));
|
||||||
|
this._onDidChangeOutputs.fire({ start: splice.start + commonLen, deleteCount: splice.deleteCount - commonLen, newOutputs: splice.newOutputs.slice(commonLen) });
|
||||||
|
} else {
|
||||||
|
this.outputs.splice(splice.start, splice.deleteCount, ...splice.newOutputs);
|
||||||
|
this._onDidChangeOutputs.fire(splice);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
changeOutputItems(outputId: string, append: boolean, items: IOutputItemDto[]): boolean {
|
private _optimizeOutputItems(output: ICellOutput) {
|
||||||
const outputIndex = this.outputs.findIndex(output => output.outputId === outputId);
|
|
||||||
|
|
||||||
if (outputIndex < 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const output = this.outputs[outputIndex];
|
|
||||||
if (append) {
|
|
||||||
output.appendData(items);
|
|
||||||
} else {
|
|
||||||
output.replaceData(items);
|
|
||||||
}
|
|
||||||
if (output.outputs.length > 1 && output.outputs.every(item => isTextStreamMime(item.mime))) {
|
if (output.outputs.length > 1 && output.outputs.every(item => isTextStreamMime(item.mime))) {
|
||||||
// Look for the mimes in the items, and keep track of their order.
|
// Look for the mimes in the items, and keep track of their order.
|
||||||
// Merge the streams into one output item, per mime type.
|
// Merge the streams into one output item, per mime type.
|
||||||
|
@ -322,7 +324,37 @@ export class NotebookCellTextModel extends Disposable implements ICell {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
replaceOutput(outputId: string, newOutputItem: ICellOutput) {
|
||||||
|
const outputIndex = this.outputs.findIndex(output => output.outputId === outputId);
|
||||||
|
|
||||||
|
if (outputIndex < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const output = this.outputs[outputIndex];
|
||||||
|
output.replaceData(newOutputItem);
|
||||||
|
this._optimizeOutputItems(output);
|
||||||
|
this._onDidChangeOutputItems.fire();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
changeOutputItems(outputId: string, append: boolean, items: IOutputItemDto[]): boolean {
|
||||||
|
const outputIndex = this.outputs.findIndex(output => output.outputId === outputId);
|
||||||
|
|
||||||
|
if (outputIndex < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const output = this.outputs[outputIndex];
|
||||||
|
if (append) {
|
||||||
|
output.appendData(items);
|
||||||
|
} else {
|
||||||
|
output.replaceData({ outputId: outputId, outputs: items, metadata: output.metadata });
|
||||||
|
}
|
||||||
|
|
||||||
|
this._optimizeOutputItems(output);
|
||||||
this._onDidChangeOutputItems.fire();
|
this._onDidChangeOutputItems.fire();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -205,7 +205,7 @@ export interface ICellOutput {
|
||||||
metadata?: Record<string, any>;
|
metadata?: Record<string, any>;
|
||||||
outputId: string;
|
outputId: string;
|
||||||
onDidChangeData: Event<void>;
|
onDidChangeData: Event<void>;
|
||||||
replaceData(items: IOutputItemDto[]): void;
|
replaceData(items: IOutputDto): void;
|
||||||
appendData(items: IOutputItemDto[]): void;
|
appendData(items: IOutputItemDto[]): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -981,7 +981,7 @@ export class SettingsEditor2 extends EditorPane {
|
||||||
private onDidChangeSetting(key: string, value: any, type: SettingValueType | SettingValueType[], manualReset: boolean, scope: ConfigurationScope | undefined): void {
|
private onDidChangeSetting(key: string, value: any, type: SettingValueType | SettingValueType[], manualReset: boolean, scope: ConfigurationScope | undefined): void {
|
||||||
const parsedQuery = parseQuery(this.searchWidget.getValue());
|
const parsedQuery = parseQuery(this.searchWidget.getValue());
|
||||||
const languageFilter = parsedQuery.languageFilter;
|
const languageFilter = parsedQuery.languageFilter;
|
||||||
if (this.pendingSettingUpdate && this.pendingSettingUpdate.key !== key) {
|
if (manualReset || (this.pendingSettingUpdate && this.pendingSettingUpdate.key !== key)) {
|
||||||
this.updateChangedSetting(key, value, manualReset, languageFilter, scope);
|
this.updateChangedSetting(key, value, manualReset, languageFilter, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,7 @@ import { localize } from 'vs/nls';
|
||||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||||
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
|
import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
|
||||||
import { getIgnoredSettings } from 'vs/platform/userDataSync/common/settingsMerge';
|
import { IUserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync';
|
||||||
import { getDefaultIgnoredSettings, IUserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync';
|
|
||||||
import { SettingsTreeSettingElement } from 'vs/workbench/contrib/preferences/browser/settingsTreeModels';
|
import { SettingsTreeSettingElement } from 'vs/workbench/contrib/preferences/browser/settingsTreeModels';
|
||||||
import { POLICY_SETTING_TAG } from 'vs/workbench/contrib/preferences/common/preferences';
|
import { POLICY_SETTING_TAG } from 'vs/workbench/contrib/preferences/common/preferences';
|
||||||
import { IHoverOptions, IHoverService, IHoverWidget } from 'vs/workbench/services/hover/browser/hover';
|
import { IHoverOptions, IHoverService, IHoverWidget } from 'vs/workbench/services/hover/browser/hover';
|
||||||
|
@ -39,6 +38,19 @@ interface SettingIndicator {
|
||||||
disposables: DisposableStore;
|
disposables: DisposableStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains a set of the sync-ignored settings
|
||||||
|
* to keep the sync ignored indicator and the getIndicatorsLabelAriaLabel() function in sync.
|
||||||
|
* SettingsTreeIndicatorsLabel#updateSyncIgnored provides the source of truth.
|
||||||
|
*/
|
||||||
|
let cachedSyncIgnoredSettingsSet: Set<string> = new Set<string>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains a copy of the sync-ignored settings to determine when to update
|
||||||
|
* cachedSyncIgnoredSettingsSet.
|
||||||
|
*/
|
||||||
|
let cachedSyncIgnoredSettings: string[] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders the indicators next to a setting, such as "Also Modified In".
|
* Renders the indicators next to a setting, such as "Also Modified In".
|
||||||
*/
|
*/
|
||||||
|
@ -214,6 +226,10 @@ export class SettingsTreeIndicatorsLabel implements IDisposable {
|
||||||
this.syncIgnoredIndicator.element.style.display = this.userDataSyncEnablementService.isEnabled()
|
this.syncIgnoredIndicator.element.style.display = this.userDataSyncEnablementService.isEnabled()
|
||||||
&& ignoredSettings.includes(element.setting.key) ? 'inline' : 'none';
|
&& ignoredSettings.includes(element.setting.key) ? 'inline' : 'none';
|
||||||
this.render();
|
this.render();
|
||||||
|
if (cachedSyncIgnoredSettings !== ignoredSettings) {
|
||||||
|
cachedSyncIgnoredSettings = ignoredSettings;
|
||||||
|
cachedSyncIgnoredSettingsSet = new Set<string>(cachedSyncIgnoredSettings);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getInlineScopeDisplayText(completeScope: string): string {
|
private getInlineScopeDisplayText(completeScope: string): string {
|
||||||
|
@ -455,8 +471,7 @@ export function getIndicatorsLabelAriaLabel(element: SettingsTreeSettingElement,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add sync ignored text
|
// Add sync ignored text
|
||||||
const ignoredSettings = getIgnoredSettings(getDefaultIgnoredSettings(), configurationService);
|
if (cachedSyncIgnoredSettingsSet.has(element.setting.key)) {
|
||||||
if (ignoredSettings.includes(element.setting.key)) {
|
|
||||||
ariaLabelSections.push(localize('syncIgnoredAriaLabel', "Setting ignored during sync"));
|
ariaLabelSections.push(localize('syncIgnoredAriaLabel', "Setting ignored during sync"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
|
||||||
import { DEFAULT_EDITOR_ASSOCIATION } from 'vs/workbench/common/editor';
|
import { DEFAULT_EDITOR_ASSOCIATION } from 'vs/workbench/common/editor';
|
||||||
import { FILE_EDITOR_INPUT_ID } from 'vs/workbench/contrib/files/common/files';
|
import { FILE_EDITOR_INPUT_ID } from 'vs/workbench/contrib/files/common/files';
|
||||||
import { AudioCue, IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService';
|
import { AudioCue, IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService';
|
||||||
|
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
||||||
|
|
||||||
class DiffActionRunner extends ActionRunner {
|
class DiffActionRunner extends ActionRunner {
|
||||||
|
|
||||||
|
@ -464,9 +465,11 @@ export class GotoPreviousChangeAction extends EditorAction {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
run(accessor: ServicesAccessor): void {
|
async run(accessor: ServicesAccessor): Promise<void> {
|
||||||
const outerEditor = getOuterEditorFromDiffEditor(accessor);
|
const outerEditor = getOuterEditorFromDiffEditor(accessor);
|
||||||
const audioCueService = accessor.get(IAudioCueService);
|
const audioCueService = accessor.get(IAudioCueService);
|
||||||
|
const accessibilityService = accessor.get(IAccessibilityService);
|
||||||
|
const codeEditorService = accessor.get(ICodeEditorService);
|
||||||
|
|
||||||
if (!outerEditor || !outerEditor.hasModel()) {
|
if (!outerEditor || !outerEditor.hasModel()) {
|
||||||
return;
|
return;
|
||||||
|
@ -486,11 +489,9 @@ export class GotoPreviousChangeAction extends EditorAction {
|
||||||
|
|
||||||
const index = model.findPreviousClosestChange(lineNumber, false);
|
const index = model.findPreviousClosestChange(lineNumber, false);
|
||||||
const change = model.changes[index];
|
const change = model.changes[index];
|
||||||
playAudioCueForChange(change, audioCueService);
|
await playAudioCueForChange(change, audioCueService);
|
||||||
|
// The audio cue can take up to a second to load. Give it a chance to play before we read the line content
|
||||||
const position = new Position(change.modifiedStartLineNumber, 1);
|
await setTimeout(() => setPositionAndSelection(change, outerEditor, accessibilityService, codeEditorService), 500);
|
||||||
outerEditor.setPosition(position);
|
|
||||||
outerEditor.revealPositionInCenter(position);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
registerEditorAction(GotoPreviousChangeAction);
|
registerEditorAction(GotoPreviousChangeAction);
|
||||||
|
@ -507,9 +508,11 @@ export class GotoNextChangeAction extends EditorAction {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
run(accessor: ServicesAccessor): void {
|
async run(accessor: ServicesAccessor): Promise<void> {
|
||||||
const audioCueService = accessor.get(IAudioCueService);
|
const audioCueService = accessor.get(IAudioCueService);
|
||||||
const outerEditor = getOuterEditorFromDiffEditor(accessor);
|
const outerEditor = getOuterEditorFromDiffEditor(accessor);
|
||||||
|
const accessibilityService = accessor.get(IAccessibilityService);
|
||||||
|
const codeEditorService = accessor.get(ICodeEditorService);
|
||||||
|
|
||||||
if (!outerEditor || !outerEditor.hasModel()) {
|
if (!outerEditor || !outerEditor.hasModel()) {
|
||||||
return;
|
return;
|
||||||
|
@ -530,23 +533,31 @@ export class GotoNextChangeAction extends EditorAction {
|
||||||
|
|
||||||
const index = model.findNextClosestChange(lineNumber, false);
|
const index = model.findNextClosestChange(lineNumber, false);
|
||||||
const change = model.changes[index];
|
const change = model.changes[index];
|
||||||
playAudioCueForChange(change, audioCueService);
|
await playAudioCueForChange(change, audioCueService);
|
||||||
|
// The audio cue can take up to a second to load. Give it a chance to play before we read the line content
|
||||||
const position = new Position(change.modifiedStartLineNumber, 1);
|
await setTimeout(() => setPositionAndSelection(change, outerEditor, accessibilityService, codeEditorService), 500);
|
||||||
outerEditor.setPosition(position);
|
|
||||||
outerEditor.revealPositionInCenter(position);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function playAudioCueForChange(change: IChange, audioCueService: IAudioCueService) {
|
function setPositionAndSelection(change: IChange, editor: ICodeEditor, accessibilityService: IAccessibilityService, codeEditorService: ICodeEditorService) {
|
||||||
|
const position = new Position(change.modifiedStartLineNumber, 1);
|
||||||
|
editor.setPosition(position);
|
||||||
|
editor.revealPositionInCenter(position);
|
||||||
|
if (accessibilityService.isScreenReaderOptimized()) {
|
||||||
|
editor.setSelection({ startLineNumber: change.modifiedStartLineNumber, startColumn: 0, endLineNumber: change.modifiedStartLineNumber, endColumn: Number.MAX_VALUE });
|
||||||
|
codeEditorService.getActiveCodeEditor()?.writeScreenReaderContent('diff-navigation');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function playAudioCueForChange(change: IChange, audioCueService: IAudioCueService) {
|
||||||
const changeType = getChangeType(change);
|
const changeType = getChangeType(change);
|
||||||
switch (changeType) {
|
switch (changeType) {
|
||||||
case ChangeType.Add:
|
case ChangeType.Add:
|
||||||
audioCueService.playAudioCue(AudioCue.diffLineInserted);
|
audioCueService.playAudioCue(AudioCue.diffLineInserted, true);
|
||||||
case ChangeType.Delete:
|
case ChangeType.Delete:
|
||||||
audioCueService.playAudioCue(AudioCue.diffLineDeleted);
|
audioCueService.playAudioCue(AudioCue.diffLineDeleted, true);
|
||||||
case ChangeType.Modify:
|
case ChangeType.Modify:
|
||||||
audioCueService.playAudioCue(AudioCue.diffLineModified);
|
audioCueService.playAudioCue(AudioCue.diffLineModified, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
|
||||||
import { IFileService, IFileStatWithPartialMetadata } from 'vs/platform/files/common/files';
|
import { IFileService, IFileStatWithPartialMetadata } from 'vs/platform/files/common/files';
|
||||||
import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { ILabelService } from 'vs/platform/label/common/label';
|
import { ILabelService } from 'vs/platform/label/common/label';
|
||||||
|
import { ILogService, LogLevel } from 'vs/platform/log/common/log';
|
||||||
import { IProgress, IProgressStep } from 'vs/platform/progress/common/progress';
|
import { IProgress, IProgressStep } from 'vs/platform/progress/common/progress';
|
||||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||||
import { minimapFindMatch, overviewRulerFindMatchForeground } from 'vs/platform/theme/common/colorRegistry';
|
import { minimapFindMatch, overviewRulerFindMatchForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||||
|
@ -864,6 +865,7 @@ export class FolderMatchWorkspaceRoot extends FolderMatchWithResource {
|
||||||
@IInstantiationService instantiationService: IInstantiationService,
|
@IInstantiationService instantiationService: IInstantiationService,
|
||||||
@ILabelService labelService: ILabelService,
|
@ILabelService labelService: ILabelService,
|
||||||
@IUriIdentityService uriIdentityService: IUriIdentityService,
|
@IUriIdentityService uriIdentityService: IUriIdentityService,
|
||||||
|
@ILogService private readonly _logService: ILogService,
|
||||||
) {
|
) {
|
||||||
super(_resource, _id, _index, _query, _parent, _searchModel, null, replaceService, instantiationService, labelService, uriIdentityService);
|
super(_resource, _id, _index, _query, _parent, _searchModel, null, replaceService, instantiationService, labelService, uriIdentityService);
|
||||||
}
|
}
|
||||||
|
@ -894,15 +896,29 @@ export class FolderMatchWorkspaceRoot extends FolderMatchWithResource {
|
||||||
const normalizedResource = this.uriIdentityService.extUri.normalizePath(this.resource);
|
const normalizedResource = this.uriIdentityService.extUri.normalizePath(this.resource);
|
||||||
let uri = this.normalizedUriParent(rawFileMatch.resource);
|
let uri = this.normalizedUriParent(rawFileMatch.resource);
|
||||||
|
|
||||||
|
const debug: string[] = ['[search model building]'];
|
||||||
|
|
||||||
|
if (this._logService.getLevel() === LogLevel.Trace) {
|
||||||
|
debug.push(`Starting with normalized resource ${normalizedResource}`);
|
||||||
|
}
|
||||||
|
|
||||||
while (!this.uriEquals(normalizedResource, uri)) {
|
while (!this.uriEquals(normalizedResource, uri)) {
|
||||||
fileMatchParentParts.unshift(uri);
|
fileMatchParentParts.unshift(uri);
|
||||||
const prevUri = uri;
|
const prevUri = uri;
|
||||||
uri = this.normalizedUriParent(uri);
|
uri = this.normalizedUriParent(uri);
|
||||||
|
if (this._logService.getLevel() === LogLevel.Trace) {
|
||||||
|
debug.push(`current uri parent ${uri} comparing with ${prevUri}`);
|
||||||
|
}
|
||||||
if (this.uriEquals(prevUri, uri)) {
|
if (this.uriEquals(prevUri, uri)) {
|
||||||
|
this._logService.trace(debug.join('\n\n'));
|
||||||
throw Error(`${rawFileMatch.resource} is not correctly configured as a child of its ${normalizedResource}`);
|
throw Error(`${rawFileMatch.resource} is not correctly configured as a child of its ${normalizedResource}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this._logService.getLevel() === LogLevel.Trace) {
|
||||||
|
this._logService.trace(debug.join('\n\n'));
|
||||||
|
}
|
||||||
|
|
||||||
const root = this.closestRoot ?? this;
|
const root = this.closestRoot ?? this;
|
||||||
let parent: FolderMatch = this;
|
let parent: FolderMatch = this;
|
||||||
for (let i = 0; i < fileMatchParentParts.length; i++) {
|
for (let i = 0; i < fileMatchParentParts.length; i++) {
|
||||||
|
|
|
@ -284,8 +284,8 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
|
||||||
this._updateSetup(folderSetup);
|
this._updateSetup(folderSetup);
|
||||||
return this._updateWorkspaceTasks(TaskRunSource.FolderOpen);
|
return this._updateWorkspaceTasks(TaskRunSource.FolderOpen);
|
||||||
}));
|
}));
|
||||||
this._register(this._configurationService.onDidChangeConfiguration(() => {
|
this._register(this._configurationService.onDidChangeConfiguration((e) => {
|
||||||
if (!this._taskSystem && !this._workspaceTasksPromise) {
|
if (!e.affectsConfiguration('tasks') || (!this._taskSystem && !this._workspaceTasksPromise)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,14 @@
|
||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { EnvironmentVariableMutatorType, IEnvironmentVariableInfo, IMergedEnvironmentVariableCollection, IMergedEnvironmentVariableCollectionDiff } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
||||||
import { TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal';
|
import { TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||||
import { ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
import { ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||||
import { Codicon } from 'vs/base/common/codicons';
|
import { Codicon } from 'vs/base/common/codicons';
|
||||||
import { IHoverAction } from 'vs/workbench/services/hover/browser/hover';
|
import { IHoverAction } from 'vs/workbench/services/hover/browser/hover';
|
||||||
|
import { EnvironmentVariableMutatorType, IMergedEnvironmentVariableCollection, IMergedEnvironmentVariableCollectionDiff } from 'vs/platform/terminal/common/environmentVariable';
|
||||||
|
|
||||||
export class EnvironmentVariableInfoStale implements IEnvironmentVariableInfo {
|
export class EnvironmentVariableInfoStale implements IEnvironmentVariableInfo {
|
||||||
readonly requiresAction = true;
|
readonly requiresAction = true;
|
||||||
|
|
|
@ -31,6 +31,12 @@ if [ "$VSCODE_INJECTION" == "1" ]; then
|
||||||
. ~/.profile
|
. ~/.profile
|
||||||
fi
|
fi
|
||||||
builtin unset VSCODE_SHELL_LOGIN
|
builtin unset VSCODE_SHELL_LOGIN
|
||||||
|
|
||||||
|
# Apply any explicit path prefix (see #99878)
|
||||||
|
if [ -n "$VSCODE_PATH_PREFIX" ]; then
|
||||||
|
export PATH=$VSCODE_PATH_PREFIX$PATH
|
||||||
|
builtin unset VSCODE_PATH_PREFIX
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
builtin unset VSCODE_INJECTION
|
builtin unset VSCODE_INJECTION
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -7,4 +7,10 @@ if [[ $options[norcs] = off && -o "login" && -f $USER_ZDOTDIR/.zprofile ]]; the
|
||||||
ZDOTDIR=$USER_ZDOTDIR
|
ZDOTDIR=$USER_ZDOTDIR
|
||||||
. $USER_ZDOTDIR/.zprofile
|
. $USER_ZDOTDIR/.zprofile
|
||||||
ZDOTDIR=$VSCODE_ZDOTDIR
|
ZDOTDIR=$VSCODE_ZDOTDIR
|
||||||
|
|
||||||
|
# Apply any explicit path prefix (see #99878)
|
||||||
|
if (( ${+VSCODE_PATH_PREFIX} )); then
|
||||||
|
export PATH=$VSCODE_PATH_PREFIX$PATH
|
||||||
|
fi
|
||||||
|
builtin unset VSCODE_PATH_PREFIX
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -22,6 +22,12 @@ or exit
|
||||||
|
|
||||||
set --global VSCODE_SHELL_INTEGRATION 1
|
set --global VSCODE_SHELL_INTEGRATION 1
|
||||||
|
|
||||||
|
# Apply any explicit path prefix (see #99878)
|
||||||
|
if status --is-login; and set -q VSCODE_PATH_PREFIX
|
||||||
|
fish_add_path -p $VSCODE_PATH_PREFIX
|
||||||
|
end
|
||||||
|
set -e VSCODE_PATH_PREFIX
|
||||||
|
|
||||||
# Helper function
|
# Helper function
|
||||||
function __vsc_esc -d "Emit escape sequences for VS Code shell integration"
|
function __vsc_esc -d "Emit escape sequences for VS Code shell integration"
|
||||||
builtin printf "\e]633;%s\a" (string join ";" $argv)
|
builtin printf "\e]633;%s\a" (string join ";" $argv)
|
||||||
|
|
|
@ -211,6 +211,20 @@ registerSendSequenceKeybinding('\x1b[1;2H', { // Shift+home
|
||||||
mac: { primary: KeyMod.Shift | KeyMod.CtrlCmd | KeyCode.LeftArrow }
|
mac: { primary: KeyMod.Shift | KeyMod.CtrlCmd | KeyCode.LeftArrow }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Map ctrl+alt+r -> ctrl+r when in accessibility mode due to default run recent command keybinding
|
||||||
|
registerSendSequenceKeybinding('\x12', {
|
||||||
|
when: ContextKeyExpr.and(TerminalContextKeys.focus, CONTEXT_ACCESSIBILITY_MODE_ENABLED),
|
||||||
|
primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KeyR,
|
||||||
|
mac: { primary: KeyMod.WinCtrl | KeyMod.Alt | KeyCode.KeyR }
|
||||||
|
});
|
||||||
|
|
||||||
|
// Map ctrl+alt+g -> ctrl+g due to default go to recent directory keybinding
|
||||||
|
registerSendSequenceKeybinding('\x07', {
|
||||||
|
when: TerminalContextKeys.focus,
|
||||||
|
primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KeyG,
|
||||||
|
mac: { primary: KeyMod.WinCtrl | KeyMod.Alt | KeyCode.KeyG }
|
||||||
|
});
|
||||||
|
|
||||||
// send ctrl+c to the iPad when the terminal is focused and ctrl+c is pressed to kill the process (work around for #114009)
|
// send ctrl+c to the iPad when the terminal is focused and ctrl+c is pressed to kill the process (work around for #114009)
|
||||||
if (isIOS) {
|
if (isIOS) {
|
||||||
registerSendSequenceKeybinding(String.fromCharCode('C'.charCodeAt(0) - Constants.CtrlLetterOffset), { // ctrl+c
|
registerSendSequenceKeybinding(String.fromCharCode('C'.charCodeAt(0) - Constants.CtrlLetterOffset), { // ctrl+c
|
||||||
|
|
|
@ -12,7 +12,6 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'
|
||||||
import { IKeyMods } from 'vs/platform/quickinput/common/quickInput';
|
import { IKeyMods } from 'vs/platform/quickinput/common/quickInput';
|
||||||
import { IMarkProperties, ITerminalCapabilityStore, ITerminalCommand } from 'vs/platform/terminal/common/capabilities/capabilities';
|
import { IMarkProperties, ITerminalCapabilityStore, ITerminalCommand } from 'vs/platform/terminal/common/capabilities/capabilities';
|
||||||
import { IExtensionTerminalProfile, IReconnectionProperties, IShellIntegration, IShellLaunchConfig, ITerminalDimensions, ITerminalLaunchError, ITerminalProfile, ITerminalTabLayoutInfoById, TerminalExitReason, TerminalIcon, TerminalLocation, TerminalShellType, TerminalType, TitleEventSource, WaitOnExitValue } from 'vs/platform/terminal/common/terminal';
|
import { IExtensionTerminalProfile, IReconnectionProperties, IShellIntegration, IShellLaunchConfig, ITerminalDimensions, ITerminalLaunchError, ITerminalProfile, ITerminalTabLayoutInfoById, TerminalExitReason, TerminalIcon, TerminalLocation, TerminalShellType, TerminalType, TitleEventSource, WaitOnExitValue } from 'vs/platform/terminal/common/terminal';
|
||||||
import { ITerminalQuickFixOptions } from 'vs/platform/terminal/common/xterm/terminalQuickFix';
|
|
||||||
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||||
import { IEditableData } from 'vs/workbench/common/views';
|
import { IEditableData } from 'vs/workbench/common/views';
|
||||||
|
@ -931,11 +930,6 @@ export interface ITerminalInstance {
|
||||||
*/
|
*/
|
||||||
openRecentLink(type: 'localFile' | 'url'): Promise<void>;
|
openRecentLink(type: 'localFile' | 'url'): Promise<void>;
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers quick fix providers
|
|
||||||
*/
|
|
||||||
registerQuickFixProvider(...options: ITerminalQuickFixOptions[]): void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to detect and kill the process listening on specified port.
|
* Attempts to detect and kill the process listening on specified port.
|
||||||
* If successful, places commandToRun on the command line
|
* If successful, places commandToRun on the command line
|
||||||
|
|
|
@ -325,7 +325,21 @@ export function registerTerminalActions() {
|
||||||
title: { value: localize('workbench.action.terminal.runRecentCommand', "Run Recent Command..."), original: 'Run Recent Command...' },
|
title: { value: localize('workbench.action.terminal.runRecentCommand', "Run Recent Command..."), original: 'Run Recent Command...' },
|
||||||
f1: true,
|
f1: true,
|
||||||
category,
|
category,
|
||||||
precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated)
|
precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated),
|
||||||
|
keybinding: [
|
||||||
|
{
|
||||||
|
primary: KeyMod.CtrlCmd | KeyCode.KeyR,
|
||||||
|
mac: { primary: KeyMod.WinCtrl | KeyCode.KeyR },
|
||||||
|
when: ContextKeyExpr.and(TerminalContextKeys.focus, CONTEXT_ACCESSIBILITY_MODE_ENABLED),
|
||||||
|
weight: KeybindingWeight.WorkbenchContrib
|
||||||
|
},
|
||||||
|
{
|
||||||
|
primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KeyR,
|
||||||
|
mac: { primary: KeyMod.WinCtrl | KeyMod.Alt | KeyCode.KeyR },
|
||||||
|
when: ContextKeyExpr.and(TerminalContextKeys.focus, CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate()),
|
||||||
|
weight: KeybindingWeight.WorkbenchContrib
|
||||||
|
}
|
||||||
|
]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
async run(accessor: ServicesAccessor): Promise<void> {
|
async run(accessor: ServicesAccessor): Promise<void> {
|
||||||
|
@ -375,7 +389,12 @@ export function registerTerminalActions() {
|
||||||
title: { value: localize('workbench.action.terminal.goToRecentDirectory', "Go to Recent Directory..."), original: 'Go to Recent Directory...' },
|
title: { value: localize('workbench.action.terminal.goToRecentDirectory', "Go to Recent Directory..."), original: 'Go to Recent Directory...' },
|
||||||
f1: true,
|
f1: true,
|
||||||
category,
|
category,
|
||||||
precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated)
|
precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated),
|
||||||
|
keybinding: {
|
||||||
|
primary: KeyMod.CtrlCmd | KeyCode.KeyG,
|
||||||
|
when: TerminalContextKeys.focus,
|
||||||
|
weight: KeybindingWeight.WorkbenchContrib
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
async run(accessor: ServicesAccessor): Promise<void> {
|
async run(accessor: ServicesAccessor): Promise<void> {
|
||||||
|
|
|
@ -59,7 +59,7 @@ import { IDetectedLinks, TerminalLinkManager } from 'vs/workbench/contrib/termin
|
||||||
import { TerminalLinkQuickpick } from 'vs/workbench/contrib/terminal/browser/links/terminalLinkQuickpick';
|
import { TerminalLinkQuickpick } from 'vs/workbench/contrib/terminal/browser/links/terminalLinkQuickpick';
|
||||||
import { IRequestAddInstanceToGroupEvent, ITerminalExternalLinkProvider, ITerminalInstance, TerminalDataTransfers } from 'vs/workbench/contrib/terminal/browser/terminal';
|
import { IRequestAddInstanceToGroupEvent, ITerminalExternalLinkProvider, ITerminalInstance, TerminalDataTransfers } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||||
import { TerminalLaunchHelpAction } from 'vs/workbench/contrib/terminal/browser/terminalActions';
|
import { TerminalLaunchHelpAction } from 'vs/workbench/contrib/terminal/browser/terminalActions';
|
||||||
import { freePort, gitCreatePr, gitPushSetUpstream, gitSimilar, gitTwoDashes } from 'vs/workbench/contrib/terminal/browser/terminalQuickFixBuiltinActions';
|
import { freePort, gitCreatePr, gitPushSetUpstream, gitSimilar, gitTwoDashes, pwshGeneralError as pwshGeneralError, pwshUnixCommandNotFoundError } from 'vs/workbench/contrib/terminal/browser/terminalQuickFixBuiltinActions';
|
||||||
import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper';
|
import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper';
|
||||||
import { TerminalEditorInput } from 'vs/workbench/contrib/terminal/browser/terminalEditorInput';
|
import { TerminalEditorInput } from 'vs/workbench/contrib/terminal/browser/terminalEditorInput';
|
||||||
import { TerminalFindWidget } from 'vs/workbench/contrib/terminal/browser/terminalFindWidget';
|
import { TerminalFindWidget } from 'vs/workbench/contrib/terminal/browser/terminalFindWidget';
|
||||||
|
@ -75,8 +75,8 @@ import { ITerminalQuickFixAddon, TerminalQuickFixAddon } from 'vs/workbench/cont
|
||||||
import { LineDataEventAddon } from 'vs/workbench/contrib/terminal/browser/xterm/lineDataEventAddon';
|
import { LineDataEventAddon } from 'vs/workbench/contrib/terminal/browser/xterm/lineDataEventAddon';
|
||||||
import { NavigationModeAddon } from 'vs/workbench/contrib/terminal/browser/xterm/navigationModeAddon';
|
import { NavigationModeAddon } from 'vs/workbench/contrib/terminal/browser/xterm/navigationModeAddon';
|
||||||
import { XtermTerminal } from 'vs/workbench/contrib/terminal/browser/xterm/xtermTerminal';
|
import { XtermTerminal } from 'vs/workbench/contrib/terminal/browser/xterm/xtermTerminal';
|
||||||
import { IEnvironmentVariableCollection, IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
||||||
import { deserializeEnvironmentVariableCollections } from 'vs/workbench/contrib/terminal/common/environmentVariableShared';
|
import { deserializeEnvironmentVariableCollections } from 'vs/platform/terminal/common/environmentVariableShared';
|
||||||
import { getCommandHistory, getDirectoryHistory } from 'vs/workbench/contrib/terminal/common/history';
|
import { getCommandHistory, getDirectoryHistory } from 'vs/workbench/contrib/terminal/common/history';
|
||||||
import { DEFAULT_COMMANDS_TO_SKIP_SHELL, INavigationMode, ITerminalProcessManager, ITerminalProfileResolverService, ProcessState, TerminalCommandId, TERMINAL_CREATION_COMMANDS, TERMINAL_VIEW_ID } from 'vs/workbench/contrib/terminal/common/terminal';
|
import { DEFAULT_COMMANDS_TO_SKIP_SHELL, INavigationMode, ITerminalProcessManager, ITerminalProfileResolverService, ProcessState, TerminalCommandId, TERMINAL_CREATION_COMMANDS, TERMINAL_VIEW_ID } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||||
import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey';
|
import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey';
|
||||||
|
@ -91,6 +91,7 @@ import { IAudioCueService, AudioCue } from 'vs/platform/audioCues/browser/audioC
|
||||||
import { ITerminalQuickFixOptions } from 'vs/platform/terminal/common/xterm/terminalQuickFix';
|
import { ITerminalQuickFixOptions } from 'vs/platform/terminal/common/xterm/terminalQuickFix';
|
||||||
import { FileSystemProviderCapabilities, IFileService } from 'vs/platform/files/common/files';
|
import { FileSystemProviderCapabilities, IFileService } from 'vs/platform/files/common/files';
|
||||||
import { preparePathForShell } from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
|
import { preparePathForShell } from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
|
||||||
|
import { IEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable';
|
||||||
|
|
||||||
const enum Constants {
|
const enum Constants {
|
||||||
/**
|
/**
|
||||||
|
@ -621,9 +622,9 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
registerQuickFixProvider(...options: ITerminalQuickFixOptions[]): void {
|
private _registerQuickFixProvider(quickFixAddon: ITerminalQuickFixAddon, ...options: ITerminalQuickFixOptions[]): void {
|
||||||
for (const actionOption of options) {
|
for (const actionOption of options) {
|
||||||
this.quickFix?.registerCommandFinishedListener(actionOption);
|
quickFixAddon.registerCommandFinishedListener(actionOption);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -738,7 +739,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
||||||
this.xterm = xterm;
|
this.xterm = xterm;
|
||||||
this._quickFixAddon = this._scopedInstantiationService.createInstance(TerminalQuickFixAddon, this._aliases, this.capabilities);
|
this._quickFixAddon = this._scopedInstantiationService.createInstance(TerminalQuickFixAddon, this._aliases, this.capabilities);
|
||||||
this.xterm?.raw.loadAddon(this._quickFixAddon);
|
this.xterm?.raw.loadAddon(this._quickFixAddon);
|
||||||
this.registerQuickFixProvider(gitTwoDashes(), freePort(this), gitSimilar(), gitPushSetUpstream(), gitCreatePr());
|
this._registerQuickFixProvider(this._quickFixAddon, gitTwoDashes(), freePort(this), gitSimilar(), gitPushSetUpstream(), gitCreatePr(), pwshUnixCommandNotFoundError(), pwshGeneralError());
|
||||||
this._register(this._quickFixAddon.onDidRequestRerunCommand(async (e) => await this.runCommand(e.command, e.addNewLine || false)));
|
this._register(this._quickFixAddon.onDidRequestRerunCommand(async (e) => await this.runCommand(e.command, e.addNewLine || false)));
|
||||||
this.updateAccessibilitySupport();
|
this.updateAccessibilitySupport();
|
||||||
this.xterm.onDidRequestRunCommand(e => {
|
this.xterm.onDidRequestRunCommand(e => {
|
||||||
|
|
|
@ -25,9 +25,9 @@ import { TerminalRecorder } from 'vs/platform/terminal/common/terminalRecorder';
|
||||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||||
import { EnvironmentVariableInfoChangesActive, EnvironmentVariableInfoStale } from 'vs/workbench/contrib/terminal/browser/environmentVariableInfo';
|
import { EnvironmentVariableInfoChangesActive, EnvironmentVariableInfoStale } from 'vs/workbench/contrib/terminal/browser/environmentVariableInfo';
|
||||||
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||||
import { IEnvironmentVariableCollection, IEnvironmentVariableInfo, IEnvironmentVariableService, IMergedEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
import { IEnvironmentVariableInfo, IEnvironmentVariableService } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
||||||
import { MergedEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableCollection';
|
import { MergedEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableCollection';
|
||||||
import { serializeEnvironmentVariableCollections } from 'vs/workbench/contrib/terminal/common/environmentVariableShared';
|
import { serializeEnvironmentVariableCollections } from 'vs/platform/terminal/common/environmentVariableShared';
|
||||||
import { IBeforeProcessDataEvent, ITerminalBackend, ITerminalConfigHelper, ITerminalProcessManager, ITerminalProfileResolverService, ProcessState } from 'vs/workbench/contrib/terminal/common/terminal';
|
import { IBeforeProcessDataEvent, ITerminalBackend, ITerminalConfigHelper, ITerminalProcessManager, ITerminalProfileResolverService, ProcessState } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||||
import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
|
import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
|
||||||
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
|
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
|
||||||
|
@ -38,6 +38,7 @@ import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteA
|
||||||
import { TaskSettingId } from 'vs/workbench/contrib/tasks/common/tasks';
|
import { TaskSettingId } from 'vs/workbench/contrib/tasks/common/tasks';
|
||||||
import Severity from 'vs/base/common/severity';
|
import Severity from 'vs/base/common/severity';
|
||||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
|
import { IEnvironmentVariableCollection, IMergedEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable';
|
||||||
|
|
||||||
const enum ProcessConstants {
|
const enum ProcessConstants {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
import { IInternalOptions, ITerminalCommandMatchResult, TerminalQuickFixActionInternal, TerminalQuickFixType } from 'vs/platform/terminal/common/xterm/terminalQuickFix';
|
import { IInternalOptions, ITerminalCommandMatchResult, ITerminalQuickFixCommandAction, TerminalQuickFixActionInternal, TerminalQuickFixType } from 'vs/platform/terminal/common/xterm/terminalQuickFix';
|
||||||
import { ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal';
|
import { ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||||
|
|
||||||
export const GitCommandLineRegex = /git/;
|
export const GitCommandLineRegex = /git/;
|
||||||
|
@ -17,6 +17,8 @@ export const GitPushOutputRegex = /git push --set-upstream origin (?<branchName>
|
||||||
// The previous line starts with "Create a pull request for \'([^\s]+)\' on GitHub by visiting:\s*"
|
// The previous line starts with "Create a pull request for \'([^\s]+)\' on GitHub by visiting:\s*"
|
||||||
// it's safe to assume it's a github pull request if the URL includes `/pull/`
|
// it's safe to assume it's a github pull request if the URL includes `/pull/`
|
||||||
export const GitCreatePrOutputRegex = /remote:\s*(?<link>https:\/\/github\.com\/.+\/.+\/pull\/new\/.+)/;
|
export const GitCreatePrOutputRegex = /remote:\s*(?<link>https:\/\/github\.com\/.+\/.+\/pull\/new\/.+)/;
|
||||||
|
export const PwshGeneralErrorOutputRegex = /Suggestion \[General\]:/;
|
||||||
|
export const PwshUnixCommandNotFoundErrorOutputRegex = /Suggestion \[cmd-not-found\]:/;
|
||||||
|
|
||||||
export const enum QuickFixSource {
|
export const enum QuickFixSource {
|
||||||
Builtin = 'builtin'
|
Builtin = 'builtin'
|
||||||
|
@ -193,3 +195,120 @@ export function gitCreatePr(): IInternalOptions {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function pwshGeneralError(): IInternalOptions {
|
||||||
|
return {
|
||||||
|
id: 'Pwsh General Error',
|
||||||
|
type: 'internal',
|
||||||
|
commandLineMatcher: /.+/,
|
||||||
|
outputMatcher: {
|
||||||
|
lineMatcher: PwshGeneralErrorOutputRegex,
|
||||||
|
anchor: 'bottom',
|
||||||
|
offset: 0,
|
||||||
|
length: 10
|
||||||
|
},
|
||||||
|
commandExitResult: 'error',
|
||||||
|
getQuickFixes: (matchResult: ITerminalCommandMatchResult) => {
|
||||||
|
const lines = matchResult.outputMatch?.regexMatch.input?.split('\n');
|
||||||
|
if (!lines) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the start
|
||||||
|
let i = 0;
|
||||||
|
let inFeedbackProvider = false;
|
||||||
|
for (; i < lines.length; i++) {
|
||||||
|
if (lines[i].match(PwshGeneralErrorOutputRegex)) {
|
||||||
|
inFeedbackProvider = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!inFeedbackProvider) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const suggestions = lines[i + 1].match(/The most similar commands are: (?<values>.+)./)?.groups?.values?.split(', ');
|
||||||
|
if (!suggestions) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const result: ITerminalQuickFixCommandAction[] = [];
|
||||||
|
for (const suggestion of suggestions) {
|
||||||
|
result.push({
|
||||||
|
id: 'Pwsh General Error',
|
||||||
|
type: TerminalQuickFixType.Command,
|
||||||
|
terminalCommand: suggestion,
|
||||||
|
source: QuickFixSource.Builtin
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function pwshUnixCommandNotFoundError(): IInternalOptions {
|
||||||
|
return {
|
||||||
|
id: 'Unix Command Not Found',
|
||||||
|
type: 'internal',
|
||||||
|
commandLineMatcher: /.+/,
|
||||||
|
outputMatcher: {
|
||||||
|
lineMatcher: PwshUnixCommandNotFoundErrorOutputRegex,
|
||||||
|
anchor: 'bottom',
|
||||||
|
offset: 0,
|
||||||
|
length: 10
|
||||||
|
},
|
||||||
|
commandExitResult: 'error',
|
||||||
|
getQuickFixes: (matchResult: ITerminalCommandMatchResult) => {
|
||||||
|
const lines = matchResult.outputMatch?.regexMatch.input?.split('\n');
|
||||||
|
if (!lines) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the start
|
||||||
|
let i = 0;
|
||||||
|
let inFeedbackProvider = false;
|
||||||
|
for (; i < lines.length; i++) {
|
||||||
|
if (lines[i].match(PwshUnixCommandNotFoundErrorOutputRegex)) {
|
||||||
|
inFeedbackProvider = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!inFeedbackProvider) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always remove the first element as it's the "Suggestion [cmd-not-found]"" line
|
||||||
|
const result: ITerminalQuickFixCommandAction[] = [];
|
||||||
|
let inSuggestions = false;
|
||||||
|
for (; i < lines.length; i++) {
|
||||||
|
const line = lines[i].trim();
|
||||||
|
if (line.length === 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const installCommand = line.match(/You also have .+ installed, you can run '(?<command>.+)' instead./)?.groups?.command;
|
||||||
|
if (installCommand) {
|
||||||
|
result.push({
|
||||||
|
id: 'Pwsh Unix Command Not Found Error',
|
||||||
|
type: TerminalQuickFixType.Command,
|
||||||
|
terminalCommand: installCommand,
|
||||||
|
source: QuickFixSource.Builtin
|
||||||
|
});
|
||||||
|
inSuggestions = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (line.match(/Command '.+' not found, but can be installed with:/)) {
|
||||||
|
inSuggestions = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (inSuggestions) {
|
||||||
|
result.push({
|
||||||
|
id: 'Pwsh Unix Command Not Found Error',
|
||||||
|
type: TerminalQuickFixType.Command,
|
||||||
|
terminalCommand: line.trim(),
|
||||||
|
source: QuickFixSource.Builtin
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -290,6 +290,10 @@ export async function getQuickFixesForCommand(
|
||||||
onDidRequestRerunCommand?: Emitter<{ command: string; addNewLine?: boolean }>,
|
onDidRequestRerunCommand?: Emitter<{ command: string; addNewLine?: boolean }>,
|
||||||
getResolvedFixes?: (selector: ITerminalQuickFixOptions, lines?: string[]) => Promise<ITerminalQuickFix | ITerminalQuickFix[] | undefined>
|
getResolvedFixes?: (selector: ITerminalQuickFixOptions, lines?: string[]) => Promise<ITerminalQuickFix | ITerminalQuickFix[] | undefined>
|
||||||
): Promise<ITerminalAction[] | undefined> {
|
): Promise<ITerminalAction[] | undefined> {
|
||||||
|
// Prevent duplicates by tracking added entries
|
||||||
|
const commandQuickFixSet: Set<string> = new Set();
|
||||||
|
const openQuickFixSet: Set<string> = new Set();
|
||||||
|
|
||||||
const fixes: ITerminalAction[] = [];
|
const fixes: ITerminalAction[] = [];
|
||||||
const newCommand = terminalCommand.command;
|
const newCommand = terminalCommand.command;
|
||||||
for (const options of quickFixOptions.values()) {
|
for (const options of quickFixOptions.values()) {
|
||||||
|
@ -329,6 +333,10 @@ export async function getQuickFixesForCommand(
|
||||||
switch (quickFix.type) {
|
switch (quickFix.type) {
|
||||||
case TerminalQuickFixType.Command: {
|
case TerminalQuickFixType.Command: {
|
||||||
const fix = quickFix as ITerminalQuickFixCommandAction;
|
const fix = quickFix as ITerminalQuickFixCommandAction;
|
||||||
|
if (commandQuickFixSet.has(fix.terminalCommand)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
commandQuickFixSet.add(fix.terminalCommand);
|
||||||
const label = localize('quickFix.command', 'Run: {0}', fix.terminalCommand);
|
const label = localize('quickFix.command', 'Run: {0}', fix.terminalCommand);
|
||||||
action = {
|
action = {
|
||||||
type: TerminalQuickFixType.Command,
|
type: TerminalQuickFixType.Command,
|
||||||
|
@ -353,6 +361,10 @@ export async function getQuickFixesForCommand(
|
||||||
if (!fix.uri) {
|
if (!fix.uri) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (openQuickFixSet.has(fix.uri.toString())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
openQuickFixSet.add(fix.uri.toString());
|
||||||
const isUrl = (fix.uri.scheme === Schemas.http || fix.uri.scheme === Schemas.https);
|
const isUrl = (fix.uri.scheme === Schemas.http || fix.uri.scheme === Schemas.https);
|
||||||
const uriLabel = isUrl ? encodeURI(fix.uri.toString(true)) : labelService.getUriLabel(fix.uri);
|
const uriLabel = isUrl ? encodeURI(fix.uri.toString(true)) : labelService.getUriLabel(fix.uri);
|
||||||
const label = localize('quickFix.opener', 'Open: {0}', uriLabel);
|
const label = localize('quickFix.opener', 'Open: {0}', uriLabel);
|
||||||
|
|
|
@ -5,63 +5,11 @@
|
||||||
|
|
||||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { Event } from 'vs/base/common/event';
|
import { Event } from 'vs/base/common/event';
|
||||||
import { IProcessEnvironment } from 'vs/base/common/platform';
|
|
||||||
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||||
import { VariableResolver } from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
|
import { IEnvironmentVariableCollection, IMergedEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable';
|
||||||
|
|
||||||
export const IEnvironmentVariableService = createDecorator<IEnvironmentVariableService>('environmentVariableService');
|
export const IEnvironmentVariableService = createDecorator<IEnvironmentVariableService>('environmentVariableService');
|
||||||
|
|
||||||
export enum EnvironmentVariableMutatorType {
|
|
||||||
Replace = 1,
|
|
||||||
Append = 2,
|
|
||||||
Prepend = 3
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IEnvironmentVariableMutator {
|
|
||||||
readonly value: string;
|
|
||||||
readonly type: EnvironmentVariableMutatorType;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IExtensionOwnedEnvironmentVariableMutator extends IEnvironmentVariableMutator {
|
|
||||||
readonly extensionIdentifier: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IEnvironmentVariableCollection {
|
|
||||||
readonly map: ReadonlyMap<string, IEnvironmentVariableMutator>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IEnvironmentVariableCollectionWithPersistence extends IEnvironmentVariableCollection {
|
|
||||||
readonly persistent: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IMergedEnvironmentVariableCollectionDiff {
|
|
||||||
added: ReadonlyMap<string, IExtensionOwnedEnvironmentVariableMutator[]>;
|
|
||||||
changed: ReadonlyMap<string, IExtensionOwnedEnvironmentVariableMutator[]>;
|
|
||||||
removed: ReadonlyMap<string, IExtensionOwnedEnvironmentVariableMutator[]>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents an environment variable collection that results from merging several collections
|
|
||||||
* together.
|
|
||||||
*/
|
|
||||||
export interface IMergedEnvironmentVariableCollection {
|
|
||||||
readonly collections: ReadonlyMap<string, IEnvironmentVariableCollection>;
|
|
||||||
readonly map: ReadonlyMap<string, IExtensionOwnedEnvironmentVariableMutator[]>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies this collection to a process environment.
|
|
||||||
* @param variableResolver An optional function to use to resolve variables within the
|
|
||||||
* environment values.
|
|
||||||
*/
|
|
||||||
applyToProcessEnvironment(env: IProcessEnvironment, variableResolver?: VariableResolver): Promise<void>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a diff of this connection against another. Returns undefined if the collections are
|
|
||||||
* the same.
|
|
||||||
*/
|
|
||||||
diff(other: IMergedEnvironmentVariableCollection): IMergedEnvironmentVariableCollectionDiff | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tracks and persists environment variable collections as defined by extensions.
|
* Tracks and persists environment variable collections as defined by extensions.
|
||||||
*/
|
*/
|
||||||
|
@ -97,11 +45,9 @@ export interface IEnvironmentVariableService {
|
||||||
delete(extensionIdentifier: string): void;
|
delete(extensionIdentifier: string): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** [variable, mutator] */
|
export interface IEnvironmentVariableCollectionWithPersistence extends IEnvironmentVariableCollection {
|
||||||
export type ISerializableEnvironmentVariableCollection = [string, IEnvironmentVariableMutator][];
|
readonly persistent: boolean;
|
||||||
|
}
|
||||||
/** [extension, collection] */
|
|
||||||
export type ISerializableEnvironmentVariableCollections = [string, ISerializableEnvironmentVariableCollection][];
|
|
||||||
|
|
||||||
export interface IEnvironmentVariableInfo {
|
export interface IEnvironmentVariableInfo {
|
||||||
readonly requiresAction: boolean;
|
readonly requiresAction: boolean;
|
||||||
|
|
|
@ -7,10 +7,11 @@ import { Event, Emitter } from 'vs/base/common/event';
|
||||||
import { debounce, throttle } from 'vs/base/common/decorators';
|
import { debounce, throttle } from 'vs/base/common/decorators';
|
||||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||||
import { MergedEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableCollection';
|
import { MergedEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableCollection';
|
||||||
import { deserializeEnvironmentVariableCollection, serializeEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableShared';
|
import { deserializeEnvironmentVariableCollection, serializeEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableShared';
|
||||||
import { IEnvironmentVariableCollectionWithPersistence, IEnvironmentVariableService, IMergedEnvironmentVariableCollection, ISerializableEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
import { IEnvironmentVariableCollectionWithPersistence, IEnvironmentVariableService } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
||||||
import { TerminalStorageKeys } from 'vs/workbench/contrib/terminal/common/terminalStorageKeys';
|
import { TerminalStorageKeys } from 'vs/workbench/contrib/terminal/common/terminalStorageKeys';
|
||||||
|
import { IMergedEnvironmentVariableCollection, ISerializableEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable';
|
||||||
|
|
||||||
interface ISerializableExtensionEnvironmentVariableCollection {
|
interface ISerializableExtensionEnvironmentVariableCollection {
|
||||||
extensionIdentifier: string;
|
extensionIdentifier: string;
|
||||||
|
|
|
@ -11,18 +11,19 @@ import { IWorkbenchConfigurationService } from 'vs/workbench/services/configurat
|
||||||
import { ILogService } from 'vs/platform/log/common/log';
|
import { ILogService } from 'vs/platform/log/common/log';
|
||||||
import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver';
|
import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver';
|
||||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||||
import { serializeEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableShared';
|
import { serializeEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableShared';
|
||||||
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
|
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
|
||||||
import { SideBySideEditor, EditorResourceAccessor } from 'vs/workbench/common/editor';
|
import { SideBySideEditor, EditorResourceAccessor } from 'vs/workbench/common/editor';
|
||||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||||
import { Schemas } from 'vs/base/common/network';
|
import { Schemas } from 'vs/base/common/network';
|
||||||
import { ILabelService } from 'vs/platform/label/common/label';
|
import { ILabelService } from 'vs/platform/label/common/label';
|
||||||
import { IEnvironmentVariableService, ISerializableEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
import { IEnvironmentVariableService } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
||||||
import { IProcessDataEvent, IRequestResolveVariablesEvent, IShellLaunchConfigDto, ITerminalLaunchError, ITerminalProfile, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalIcon, IProcessProperty, ProcessPropertyType, IProcessPropertyMap, TitleEventSource, ISerializedTerminalState, IPtyHostController, ITerminalProcessOptions } from 'vs/platform/terminal/common/terminal';
|
import { IProcessDataEvent, IRequestResolveVariablesEvent, IShellLaunchConfigDto, ITerminalLaunchError, ITerminalProfile, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalIcon, IProcessProperty, ProcessPropertyType, IProcessPropertyMap, TitleEventSource, ISerializedTerminalState, IPtyHostController, ITerminalProcessOptions } from 'vs/platform/terminal/common/terminal';
|
||||||
import { IGetTerminalLayoutInfoArgs, IProcessDetails, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess';
|
import { IGetTerminalLayoutInfoArgs, IProcessDetails, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess';
|
||||||
import { IProcessEnvironment, OperatingSystem } from 'vs/base/common/platform';
|
import { IProcessEnvironment, OperatingSystem } from 'vs/base/common/platform';
|
||||||
import { ICompleteTerminalConfiguration } from 'vs/workbench/contrib/terminal/common/terminal';
|
import { ICompleteTerminalConfiguration } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||||
import { IPtyHostProcessReplayEvent } from 'vs/platform/terminal/common/capabilities/capabilities';
|
import { IPtyHostProcessReplayEvent } from 'vs/platform/terminal/common/capabilities/capabilities';
|
||||||
|
import { ISerializableEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable';
|
||||||
|
|
||||||
export const REMOTE_TERMINAL_CHANNEL_NAME = 'remoteterminal';
|
export const REMOTE_TERMINAL_CHANNEL_NAME = 'remoteterminal';
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ import { ITerminalCommand, TerminalCapability } from 'vs/platform/terminal/commo
|
||||||
import { CommandDetectionCapability } from 'vs/platform/terminal/common/capabilities/commandDetectionCapability';
|
import { CommandDetectionCapability } from 'vs/platform/terminal/common/capabilities/commandDetectionCapability';
|
||||||
import { TerminalCapabilityStore } from 'vs/platform/terminal/common/capabilities/terminalCapabilityStore';
|
import { TerminalCapabilityStore } from 'vs/platform/terminal/common/capabilities/terminalCapabilityStore';
|
||||||
import { ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal';
|
import { ITerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||||
import { gitSimilar, freePort, FreePortOutputRegex, gitCreatePr, GitCreatePrOutputRegex, GitPushOutputRegex, gitPushSetUpstream, GitSimilarOutputRegex, gitTwoDashes, GitTwoDashesRegex } from 'vs/workbench/contrib/terminal/browser/terminalQuickFixBuiltinActions';
|
import { gitSimilar, freePort, FreePortOutputRegex, gitCreatePr, GitCreatePrOutputRegex, GitPushOutputRegex, gitPushSetUpstream, GitSimilarOutputRegex, gitTwoDashes, GitTwoDashesRegex, pwshUnixCommandNotFoundError, PwshUnixCommandNotFoundErrorOutputRegex, pwshGeneralError, PwshGeneralErrorOutputRegex } from 'vs/workbench/contrib/terminal/browser/terminalQuickFixBuiltinActions';
|
||||||
import { TerminalQuickFixAddon, getQuickFixesForCommand } from 'vs/workbench/contrib/terminal/browser/xterm/quickFixAddon';
|
import { TerminalQuickFixAddon, getQuickFixesForCommand } from 'vs/workbench/contrib/terminal/browser/xterm/quickFixAddon';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { Terminal } from 'xterm';
|
import { Terminal } from 'xterm';
|
||||||
|
@ -333,6 +333,102 @@ suite('QuickFixAddon', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
suite('pwsh feedback providers', () => {
|
||||||
|
suite('General', () => {
|
||||||
|
const expectedMap = new Map();
|
||||||
|
const command = `not important`;
|
||||||
|
const output = [
|
||||||
|
`...`,
|
||||||
|
``,
|
||||||
|
`Suggestion [General]:`,
|
||||||
|
` The most similar commands are: python3, python3m, pamon, python3.6, rtmon, echo, pushd, etsn, pwsh, pwconv.`,
|
||||||
|
``,
|
||||||
|
`Suggestion [cmd-not-found]:`,
|
||||||
|
` Command 'python' not found, but can be installed with:`,
|
||||||
|
` sudo apt install python3`,
|
||||||
|
` sudo apt install python`,
|
||||||
|
` sudo apt install python-minimal`,
|
||||||
|
` You also have python3 installed, you can run 'python3' instead.'`,
|
||||||
|
``,
|
||||||
|
].join('\n');
|
||||||
|
const exitCode = 128;
|
||||||
|
const actions = [
|
||||||
|
'python3',
|
||||||
|
'python3m',
|
||||||
|
'pamon',
|
||||||
|
'python3.6',
|
||||||
|
'rtmon',
|
||||||
|
'echo',
|
||||||
|
'pushd',
|
||||||
|
'etsn',
|
||||||
|
'pwsh',
|
||||||
|
'pwconv',
|
||||||
|
].map(command => {
|
||||||
|
return {
|
||||||
|
id: 'Pwsh General Error',
|
||||||
|
enabled: true,
|
||||||
|
label: `Run: ${command}`,
|
||||||
|
tooltip: `Run: ${command}`,
|
||||||
|
command: command
|
||||||
|
};
|
||||||
|
});
|
||||||
|
setup(() => {
|
||||||
|
const pushCommand = pwshGeneralError();
|
||||||
|
quickFixAddon.registerCommandFinishedListener(pushCommand);
|
||||||
|
expectedMap.set(pushCommand.commandLineMatcher.toString(), [pushCommand]);
|
||||||
|
});
|
||||||
|
test('returns undefined when output does not match', async () => {
|
||||||
|
strictEqual((await getQuickFixesForCommand([], terminal, createCommand(command, `invalid output`, PwshGeneralErrorOutputRegex, exitCode), expectedMap, openerService, labelService)), undefined);
|
||||||
|
});
|
||||||
|
test('returns actions when output matches', async () => {
|
||||||
|
assertMatchOptions((await getQuickFixesForCommand([], terminal, createCommand(command, output, PwshGeneralErrorOutputRegex, exitCode), expectedMap, openerService, labelService)), actions);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
suite('Unix cmd-not-found', () => {
|
||||||
|
const expectedMap = new Map();
|
||||||
|
const command = `not important`;
|
||||||
|
const output = [
|
||||||
|
`...`,
|
||||||
|
``,
|
||||||
|
`Suggestion [General]`,
|
||||||
|
` The most similar commands are: python3, python3m, pamon, python3.6, rtmon, echo, pushd, etsn, pwsh, pwconv.`,
|
||||||
|
``,
|
||||||
|
`Suggestion [cmd-not-found]:`,
|
||||||
|
` Command 'python' not found, but can be installed with:`,
|
||||||
|
` sudo apt install python3`,
|
||||||
|
` sudo apt install python`,
|
||||||
|
` sudo apt install python-minimal`,
|
||||||
|
` You also have python3 installed, you can run 'python3' instead.'`,
|
||||||
|
``,
|
||||||
|
].join('\n');
|
||||||
|
const exitCode = 128;
|
||||||
|
const actions = [
|
||||||
|
'sudo apt install python3',
|
||||||
|
'sudo apt install python',
|
||||||
|
'sudo apt install python-minimal',
|
||||||
|
'python3',
|
||||||
|
].map(command => {
|
||||||
|
return {
|
||||||
|
id: 'Pwsh Unix Command Not Found Error',
|
||||||
|
enabled: true,
|
||||||
|
label: `Run: ${command}`,
|
||||||
|
tooltip: `Run: ${command}`,
|
||||||
|
command: command
|
||||||
|
};
|
||||||
|
});
|
||||||
|
setup(() => {
|
||||||
|
const pushCommand = pwshUnixCommandNotFoundError();
|
||||||
|
quickFixAddon.registerCommandFinishedListener(pushCommand);
|
||||||
|
expectedMap.set(pushCommand.commandLineMatcher.toString(), [pushCommand]);
|
||||||
|
});
|
||||||
|
test('returns undefined when output does not match', async () => {
|
||||||
|
strictEqual((await getQuickFixesForCommand([], terminal, createCommand(command, `invalid output`, PwshUnixCommandNotFoundErrorOutputRegex, exitCode), expectedMap, openerService, labelService)), undefined);
|
||||||
|
});
|
||||||
|
test('returns actions when output matches', async () => {
|
||||||
|
assertMatchOptions((await getQuickFixesForCommand([], terminal, createCommand(command, output, PwshUnixCommandNotFoundErrorOutputRegex, exitCode), expectedMap, openerService, labelService)), actions);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function createCommand(command: string, output: string, outputMatcher?: RegExp | string, exitCode?: number): ITerminalCommand {
|
function createCommand(command: string, output: string, outputMatcher?: RegExp | string, exitCode?: number): ITerminalCommand {
|
||||||
|
@ -357,19 +453,18 @@ function createCommand(command: string, output: string, outputMatcher?: RegExp |
|
||||||
type TestAction = Pick<IAction, 'id' | 'label' | 'tooltip' | 'enabled'> & { command?: string; uri?: URI };
|
type TestAction = Pick<IAction, 'id' | 'label' | 'tooltip' | 'enabled'> & { command?: string; uri?: URI };
|
||||||
function assertMatchOptions(actual: TestAction[] | undefined, expected: TestAction[]): void {
|
function assertMatchOptions(actual: TestAction[] | undefined, expected: TestAction[]): void {
|
||||||
strictEqual(actual?.length, expected.length);
|
strictEqual(actual?.length, expected.length);
|
||||||
let index = 0;
|
for (let i = 0; i < expected.length; i++) {
|
||||||
for (const i of actual) {
|
const expectedItem = expected[i];
|
||||||
const j = expected[index];
|
const actualItem: any = actual[i];
|
||||||
strictEqual(i.id, j.id, `ID`);
|
strictEqual(actualItem.id, expectedItem.id, `ID`);
|
||||||
strictEqual(i.enabled, j.enabled, `enabled`);
|
strictEqual(actualItem.enabled, expectedItem.enabled, `enabled`);
|
||||||
strictEqual(i.label, j.label, `label`);
|
strictEqual(actualItem.label, expectedItem.label, `label`);
|
||||||
strictEqual(i.tooltip, j.tooltip, `tooltip`);
|
strictEqual(actualItem.tooltip, expectedItem.tooltip, `tooltip`);
|
||||||
if (j.command) {
|
if (expectedItem.command) {
|
||||||
strictEqual(i.command, j.command);
|
strictEqual(actualItem.command, expectedItem.command);
|
||||||
}
|
}
|
||||||
if (j.uri) {
|
if (expectedItem.uri) {
|
||||||
strictEqual(i.uri!.toString(), j.uri.toString());
|
strictEqual(actualItem.uri!.toString(), expectedItem.uri.toString());
|
||||||
}
|
}
|
||||||
index++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { deepStrictEqual, strictEqual } from 'assert';
|
import { deepStrictEqual, strictEqual } from 'assert';
|
||||||
import { EnvironmentVariableMutatorType } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
import { EnvironmentVariableMutatorType } from 'vs/platform/terminal/common/environmentVariable';
|
||||||
import { IProcessEnvironment, isWindows } from 'vs/base/common/platform';
|
import { IProcessEnvironment, isWindows } from 'vs/base/common/platform';
|
||||||
import { MergedEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableCollection';
|
import { MergedEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableCollection';
|
||||||
import { deserializeEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableShared';
|
import { deserializeEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableShared';
|
||||||
|
|
||||||
suite('EnvironmentVariable - MergedEnvironmentVariableCollection', () => {
|
suite('EnvironmentVariable - MergedEnvironmentVariableCollection', () => {
|
||||||
suite('ctor', () => {
|
suite('ctor', () => {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import { deepStrictEqual } from 'assert';
|
import { deepStrictEqual } from 'assert';
|
||||||
import { TestExtensionService, TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
|
import { TestExtensionService, TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
|
||||||
import { EnvironmentVariableService } from 'vs/workbench/contrib/terminal/common/environmentVariableService';
|
import { EnvironmentVariableService } from 'vs/workbench/contrib/terminal/common/environmentVariableService';
|
||||||
import { EnvironmentVariableMutatorType, IEnvironmentVariableMutator } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
import { EnvironmentVariableMutatorType, IEnvironmentVariableMutator } from 'vs/platform/terminal/common/environmentVariable';
|
||||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { deepStrictEqual } from 'assert';
|
import { deepStrictEqual } from 'assert';
|
||||||
import { deserializeEnvironmentVariableCollection, serializeEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableShared';
|
import { deserializeEnvironmentVariableCollection, serializeEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariableShared';
|
||||||
import { EnvironmentVariableMutatorType, IEnvironmentVariableMutator } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
import { EnvironmentVariableMutatorType, IEnvironmentVariableMutator } from 'vs/platform/terminal/common/environmentVariable';
|
||||||
|
|
||||||
suite('EnvironmentVariable - deserializeEnvironmentVariableCollection', () => {
|
suite('EnvironmentVariable - deserializeEnvironmentVariableCollection', () => {
|
||||||
test('should construct correctly with 3 arguments', () => {
|
test('should construct correctly with 3 arguments', () => {
|
||||||
|
|
|
@ -19,11 +19,9 @@ import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuratio
|
||||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||||
import { RenameProfileAction } from 'vs/workbench/contrib/userDataProfile/browser/userDataProfileActions';
|
import { RenameProfileAction } from 'vs/workbench/contrib/userDataProfile/browser/userDataProfileActions';
|
||||||
import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
|
import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
|
||||||
import { CURRENT_PROFILE_CONTEXT, HAS_PROFILES_CONTEXT, isUserDataProfileTemplate, IS_CURRENT_PROFILE_TRANSIENT_CONTEXT, IS_PROFILE_IMPORT_IN_PROGRESS_CONTEXT, IUserDataProfileImportExportService, IUserDataProfileManagementService, IUserDataProfileService, IUserDataProfileTemplate, ManageProfilesSubMenu, PROFILES_CATEGORY, PROFILES_ENABLEMENT_CONTEXT, PROFILES_TTILE, PROFILE_FILTER, IS_PROFILE_EXPORT_IN_PROGRESS_CONTEXT } from 'vs/workbench/services/userDataProfile/common/userDataProfile';
|
import { CURRENT_PROFILE_CONTEXT, HAS_PROFILES_CONTEXT, isUserDataProfileTemplate, IS_CURRENT_PROFILE_TRANSIENT_CONTEXT, IS_PROFILE_IMPORT_IN_PROGRESS_CONTEXT, IUserDataProfileImportExportService, IUserDataProfileManagementService, IUserDataProfileService, IUserDataProfileTemplate, ManageProfilesSubMenu, PROFILES_CATEGORY, PROFILES_ENABLEMENT_CONTEXT, PROFILES_TTILE, PROFILE_FILTER, IS_PROFILE_EXPORT_IN_PROGRESS_CONTEXT, defaultUserDataProfileIcon } from 'vs/workbench/services/userDataProfile/common/userDataProfile';
|
||||||
import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
|
import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput';
|
||||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
import { charCount } from 'vs/base/common/strings';
|
|
||||||
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
|
||||||
import { IDialogService, IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
|
import { IDialogService, IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||||
import { Codicon } from 'vs/base/common/codicons';
|
import { Codicon } from 'vs/base/common/codicons';
|
||||||
import { IFileService } from 'vs/platform/files/common/files';
|
import { IFileService } from 'vs/platform/files/common/files';
|
||||||
|
@ -34,9 +32,22 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||||
import { IWorkspaceTagsService } from 'vs/workbench/contrib/tags/common/workspaceTags';
|
import { IWorkspaceTagsService } from 'vs/workbench/contrib/tags/common/workspaceTags';
|
||||||
import { getErrorMessage } from 'vs/base/common/errors';
|
import { getErrorMessage } from 'vs/base/common/errors';
|
||||||
|
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||||
|
|
||||||
const SelectProfileSubMenu = new MenuId('SelectProfile');
|
const SelectProfileSubMenu = new MenuId('SelectProfile');
|
||||||
|
|
||||||
|
const CREATE_EMPTY_PROFILE_ACTION_ID = 'workbench.profiles.actions.createEmptyProfile';
|
||||||
|
const CREATE_EMPTY_PROFILE_ACTION_TITLE = {
|
||||||
|
value: localize('create empty profile', "Create an Empty Profile..."),
|
||||||
|
original: 'Create an Empty Profile...'
|
||||||
|
};
|
||||||
|
|
||||||
|
const CREATE_FROM_CURRENT_PROFILE_ACTION_ID = 'workbench.profiles.actions.createFromCurrentProfile';
|
||||||
|
const CREATE_FROM_CURRENT_PROFILE_ACTION_TITLE = {
|
||||||
|
value: localize('save profile as', "Create from Current Profile..."),
|
||||||
|
original: 'Create from Current Profile...'
|
||||||
|
};
|
||||||
|
|
||||||
export class UserDataProfilesWorkbenchContribution extends Disposable implements IWorkbenchContribution {
|
export class UserDataProfilesWorkbenchContribution extends Disposable implements IWorkbenchContribution {
|
||||||
|
|
||||||
private readonly currentProfileContext: IContextKey<string>;
|
private readonly currentProfileContext: IContextKey<string>;
|
||||||
|
@ -52,6 +63,8 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
||||||
@IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService,
|
@IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService,
|
||||||
@IWorkspaceTagsService private readonly workspaceTagsService: IWorkspaceTagsService,
|
@IWorkspaceTagsService private readonly workspaceTagsService: IWorkspaceTagsService,
|
||||||
@IContextKeyService contextKeyService: IContextKeyService,
|
@IContextKeyService contextKeyService: IContextKeyService,
|
||||||
|
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||||
|
@INotificationService private readonly notificationService: INotificationService,
|
||||||
@ILifecycleService private readonly lifecycleService: ILifecycleService,
|
@ILifecycleService private readonly lifecycleService: ILifecycleService,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
@ -108,6 +121,10 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
||||||
|
|
||||||
this.registerCurrentProfilesActions();
|
this.registerCurrentProfilesActions();
|
||||||
this._register(Event.any(this.userDataProfileService.onDidChangeCurrentProfile, this.userDataProfileService.onDidUpdateCurrentProfile)(() => this.registerCurrentProfilesActions()));
|
this._register(Event.any(this.userDataProfileService.onDidChangeCurrentProfile, this.userDataProfileService.onDidUpdateCurrentProfile)(() => this.registerCurrentProfilesActions()));
|
||||||
|
|
||||||
|
this.registerCreateEmptyProfileAction();
|
||||||
|
this.registerCreateFromCurrentProfileAction();
|
||||||
|
this.registerCreateProfileAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
private registerManageProfilesSubMenu(): void {
|
private registerManageProfilesSubMenu(): void {
|
||||||
|
@ -166,24 +183,22 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
||||||
private readonly currentprofileActionsDisposable = this._register(new MutableDisposable<DisposableStore>());
|
private readonly currentprofileActionsDisposable = this._register(new MutableDisposable<DisposableStore>());
|
||||||
private registerCurrentProfilesActions(): void {
|
private registerCurrentProfilesActions(): void {
|
||||||
this.currentprofileActionsDisposable.value = new DisposableStore();
|
this.currentprofileActionsDisposable.value = new DisposableStore();
|
||||||
this.currentprofileActionsDisposable.value.add(this.registerUpdateCurrentProfileShortNameAction());
|
this.currentprofileActionsDisposable.value.add(this.registerChangeIconForCurrentProfileAction());
|
||||||
this.currentprofileActionsDisposable.value.add(this.registerRenameCurrentProfileAction());
|
this.currentprofileActionsDisposable.value.add(this.registerRenameCurrentProfileAction());
|
||||||
this.currentprofileActionsDisposable.value.add(this.registerShowCurrentProfileContentsAction());
|
this.currentprofileActionsDisposable.value.add(this.registerShowCurrentProfileContentsAction());
|
||||||
this.currentprofileActionsDisposable.value.add(this.registerExportCurrentProfileAction());
|
this.currentprofileActionsDisposable.value.add(this.registerExportCurrentProfileAction());
|
||||||
this.currentprofileActionsDisposable.value.add(this.registerImportProfileAction());
|
this.currentprofileActionsDisposable.value.add(this.registerImportProfileAction());
|
||||||
}
|
}
|
||||||
|
|
||||||
private registerUpdateCurrentProfileShortNameAction(): IDisposable {
|
private registerChangeIconForCurrentProfileAction(): IDisposable {
|
||||||
const that = this;
|
const that = this;
|
||||||
return registerAction2(class UpdateCurrentProfileShortName extends Action2 {
|
return registerAction2(class ChangeIconForCurrentProfileAction extends Action2 {
|
||||||
constructor() {
|
constructor() {
|
||||||
const shortName = that.userDataProfileService.getShortName(that.userDataProfileService.currentProfile);
|
|
||||||
const themeIcon = ThemeIcon.fromString(shortName);
|
|
||||||
super({
|
super({
|
||||||
id: `workbench.profiles.actions.updateCurrentProfileShortName`,
|
id: `workbench.profiles.actions.changeIconForCurrentProfile`,
|
||||||
title: {
|
title: {
|
||||||
value: localize('change short name profile', "Change Profile Short Name ({0})...", themeIcon?.id ?? shortName),
|
value: localize('change icon', "Change Icon..."),
|
||||||
original: `Change Profile Short Name (${themeIcon?.id ?? shortName})...`
|
original: `Change Icon...`
|
||||||
},
|
},
|
||||||
menu: [
|
menu: [
|
||||||
{
|
{
|
||||||
|
@ -196,35 +211,13 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
async run(accessor: ServicesAccessor) {
|
async run(accessor: ServicesAccessor) {
|
||||||
const quickInputService = accessor.get(IQuickInputService);
|
|
||||||
const notificationService = accessor.get(INotificationService);
|
|
||||||
|
|
||||||
const profile = that.userDataProfileService.currentProfile;
|
const profile = that.userDataProfileService.currentProfile;
|
||||||
const shortName = await quickInputService.input({
|
const shortName = await that.pickIcon(profile);
|
||||||
value: that.userDataProfileService.getShortName(profile),
|
|
||||||
title: localize('change short name', "Change Short Name..."),
|
|
||||||
validateInput: async (value: string) => {
|
|
||||||
if (profile.shortName === value) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
const themeIcon = ThemeIcon.fromString(value);
|
|
||||||
if (themeIcon) {
|
|
||||||
if (Codicon.getAll().some(c => c.id === themeIcon.id)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
return localize('invalid codicon', "Invalid codicon. Please use a valid codicon id.");
|
|
||||||
}
|
|
||||||
if (charCount(value) > 2) {
|
|
||||||
return localize('invalid short name', "Short name should be at most 2 characters long.");
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (shortName && shortName !== profile.shortName) {
|
if (shortName && shortName !== profile.shortName) {
|
||||||
try {
|
try {
|
||||||
await that.userDataProfileManagementService.updateProfile(profile, { shortName });
|
await that.userDataProfileManagementService.updateProfile(profile, { shortName });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
notificationService.error(error);
|
that.notificationService.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,8 +231,8 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
||||||
super({
|
super({
|
||||||
id: `workbench.profiles.actions.renameCurrentProfile`,
|
id: `workbench.profiles.actions.renameCurrentProfile`,
|
||||||
title: {
|
title: {
|
||||||
value: localize('rename profile', "Rename Profile ({0})...", that.userDataProfileService.currentProfile.name),
|
value: localize('rename profile', "Rename..."),
|
||||||
original: `Rename Profile (${that.userDataProfileService.currentProfile.name})...`
|
original: `Rename...`
|
||||||
},
|
},
|
||||||
menu: [
|
menu: [
|
||||||
{
|
{
|
||||||
|
@ -258,15 +251,14 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
||||||
}
|
}
|
||||||
|
|
||||||
private registerShowCurrentProfileContentsAction(): IDisposable {
|
private registerShowCurrentProfileContentsAction(): IDisposable {
|
||||||
const that = this;
|
|
||||||
const id = 'workbench.profiles.actions.showProfileContents';
|
const id = 'workbench.profiles.actions.showProfileContents';
|
||||||
return registerAction2(class ShowProfileContentsAction extends Action2 {
|
return registerAction2(class ShowProfileContentsAction extends Action2 {
|
||||||
constructor() {
|
constructor() {
|
||||||
super({
|
super({
|
||||||
id,
|
id,
|
||||||
title: {
|
title: {
|
||||||
value: localize('show profile contents', "Show Profile Contents ({0})...", that.userDataProfileService.currentProfile.name),
|
value: localize('show profile contents', "Show Contents..."),
|
||||||
original: `Show Profile Contents (${that.userDataProfileService.currentProfile.name})...`
|
original: `ShowContents...`
|
||||||
},
|
},
|
||||||
category: PROFILES_CATEGORY,
|
category: PROFILES_CATEGORY,
|
||||||
menu: [
|
menu: [
|
||||||
|
@ -464,6 +456,124 @@ export class UserDataProfilesWorkbenchContribution extends Disposable implements
|
||||||
return disposables;
|
return disposables;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private registerCreateFromCurrentProfileAction(): void {
|
||||||
|
const that = this;
|
||||||
|
this._register(registerAction2(class CreateFromCurrentProfileAction extends Action2 {
|
||||||
|
constructor() {
|
||||||
|
super({
|
||||||
|
id: CREATE_FROM_CURRENT_PROFILE_ACTION_ID,
|
||||||
|
title: CREATE_FROM_CURRENT_PROFILE_ACTION_TITLE,
|
||||||
|
category: PROFILES_CATEGORY,
|
||||||
|
f1: true,
|
||||||
|
precondition: PROFILES_ENABLEMENT_CONTEXT
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
run(accessor: ServicesAccessor) {
|
||||||
|
return that.createProfile(true);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private registerCreateEmptyProfileAction(): void {
|
||||||
|
const that = this;
|
||||||
|
this._register(registerAction2(class CreateEmptyProfileAction extends Action2 {
|
||||||
|
constructor() {
|
||||||
|
super({
|
||||||
|
id: CREATE_EMPTY_PROFILE_ACTION_ID,
|
||||||
|
title: CREATE_EMPTY_PROFILE_ACTION_TITLE,
|
||||||
|
category: PROFILES_CATEGORY,
|
||||||
|
f1: true,
|
||||||
|
precondition: PROFILES_ENABLEMENT_CONTEXT
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
run(accessor: ServicesAccessor) {
|
||||||
|
return that.createProfile(false);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createProfile(fromExisting: boolean): Promise<void> {
|
||||||
|
const name = await this.quickInputService.input({
|
||||||
|
placeHolder: localize('name', "Profile name"),
|
||||||
|
title: fromExisting ? localize('create from current profle', "Create from Current Profile...") : localize('create empty profile', "Create an Empty Profile..."),
|
||||||
|
validateInput: async (value: string) => {
|
||||||
|
if (this.userDataProfilesService.profiles.some(p => p.name === value)) {
|
||||||
|
return localize('profileExists', "Profile with name {0} already exists.", value);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const icon = await this.pickIcon();
|
||||||
|
if (!icon) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await this.userDataProfileManagementService.createAndEnterProfile(name, { shortName: icon }, fromExisting);
|
||||||
|
} catch (error) {
|
||||||
|
this.notificationService.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async pickIcon(profile?: IUserDataProfile): Promise<string | undefined> {
|
||||||
|
const codiconQuickPicks: Array<IQuickPickItem | IQuickPickSeparator> = [];
|
||||||
|
codiconQuickPicks.push({ label: `$(${defaultUserDataProfileIcon.id})`, description: localize('default', "Default") });
|
||||||
|
codiconQuickPicks.push({ label: '', type: 'separator' });
|
||||||
|
const currentIcon = profile?.shortName ? ThemeIcon.fromString(profile.shortName) : undefined;
|
||||||
|
for (const codicon of Codicon.getAll()) {
|
||||||
|
codiconQuickPicks.push({ label: `$(${codicon.id})`, description: `${codicon.id}${currentIcon?.id === codicon.id ? ` (${localize('current', "Current")})` : ''}` });
|
||||||
|
}
|
||||||
|
const result = await this.quickInputService.pick(codiconQuickPicks, {
|
||||||
|
title: profile ? localize('change icon title', "Change icon for {0} Profile", profile.name) : localize('pick icon', "Pick icon..."),
|
||||||
|
matchOnDescription: true,
|
||||||
|
});
|
||||||
|
return result?.label;
|
||||||
|
}
|
||||||
|
|
||||||
|
private registerCreateProfileAction(): void {
|
||||||
|
this._register(registerAction2(class CreateProfileAction extends Action2 {
|
||||||
|
constructor() {
|
||||||
|
super({
|
||||||
|
id: 'workbench.profiles.actions.createProfile',
|
||||||
|
title: {
|
||||||
|
value: localize('create profile', "Create Profile..."),
|
||||||
|
original: 'Create Profile...'
|
||||||
|
},
|
||||||
|
category: PROFILES_CATEGORY,
|
||||||
|
precondition: PROFILES_ENABLEMENT_CONTEXT,
|
||||||
|
menu: [
|
||||||
|
{
|
||||||
|
id: ManageProfilesSubMenu,
|
||||||
|
group: '3_manage_profiles',
|
||||||
|
when: PROFILES_ENABLEMENT_CONTEXT,
|
||||||
|
order: 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async run(accessor: ServicesAccessor) {
|
||||||
|
const quickInputService = accessor.get(IQuickInputService);
|
||||||
|
const commandService = accessor.get(ICommandService);
|
||||||
|
const pick = await quickInputService.pick(
|
||||||
|
[{
|
||||||
|
id: CREATE_EMPTY_PROFILE_ACTION_ID,
|
||||||
|
label: CREATE_EMPTY_PROFILE_ACTION_TITLE.value,
|
||||||
|
}, {
|
||||||
|
id: CREATE_FROM_CURRENT_PROFILE_ACTION_ID,
|
||||||
|
label: CREATE_FROM_CURRENT_PROFILE_ACTION_TITLE.value,
|
||||||
|
}], { hideInput: true, canPickMany: false, title: localize('create profile title', "{0}: Create...", PROFILES_CATEGORY.value) });
|
||||||
|
if (pick?.id) {
|
||||||
|
return commandService.executeCommand(pick.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
private async reportWorkspaceProfileInfo(): Promise<void> {
|
private async reportWorkspaceProfileInfo(): Promise<void> {
|
||||||
await this.lifecycleService.when(LifecyclePhase.Eventually);
|
await this.lifecycleService.when(LifecyclePhase.Eventually);
|
||||||
const workspaceId = await this.workspaceTagsService.getTelemetryWorkspaceId(this.workspaceContextService.getWorkspace(), this.workspaceContextService.getWorkbenchState());
|
const workspaceId = await this.workspaceTagsService.getTelemetryWorkspaceId(this.workspaceContextService.getWorkspace(), this.workspaceContextService.getWorkbenchState());
|
||||||
|
|
|
@ -17,128 +17,6 @@ import { Codicon } from 'vs/base/common/codicons';
|
||||||
import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
||||||
import { IAction, Separator } from 'vs/base/common/actions';
|
import { IAction, Separator } from 'vs/base/common/actions';
|
||||||
|
|
||||||
class CreateFromCurrentProfileAction extends Action2 {
|
|
||||||
static readonly ID = 'workbench.profiles.actions.createFromCurrentProfile';
|
|
||||||
static readonly TITLE = {
|
|
||||||
value: localize('save profile as', "Create from Current Profile..."),
|
|
||||||
original: 'Create from Current Profile...'
|
|
||||||
};
|
|
||||||
constructor() {
|
|
||||||
super({
|
|
||||||
id: CreateFromCurrentProfileAction.ID,
|
|
||||||
title: CreateFromCurrentProfileAction.TITLE,
|
|
||||||
category: PROFILES_CATEGORY,
|
|
||||||
f1: true,
|
|
||||||
precondition: PROFILES_ENABLEMENT_CONTEXT
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async run(accessor: ServicesAccessor) {
|
|
||||||
const quickInputService = accessor.get(IQuickInputService);
|
|
||||||
const notificationService = accessor.get(INotificationService);
|
|
||||||
const userDataProfileManagementService = accessor.get(IUserDataProfileManagementService);
|
|
||||||
const userDataProfilesService = accessor.get(IUserDataProfilesService);
|
|
||||||
const name = await quickInputService.input({
|
|
||||||
placeHolder: localize('name', "Profile name"),
|
|
||||||
title: localize('save profile as', "Create from Current Profile..."),
|
|
||||||
validateInput: async (value: string) => {
|
|
||||||
if (userDataProfilesService.profiles.some(p => p.name === value)) {
|
|
||||||
return localize('profileExists', "Profile with name {0} already exists.", value);
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (name) {
|
|
||||||
try {
|
|
||||||
await userDataProfileManagementService.createAndEnterProfile(name, undefined, true);
|
|
||||||
} catch (error) {
|
|
||||||
notificationService.error(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
registerAction2(CreateFromCurrentProfileAction);
|
|
||||||
|
|
||||||
class CreateEmptyProfileAction extends Action2 {
|
|
||||||
static readonly ID = 'workbench.profiles.actions.createEmptyProfile';
|
|
||||||
static readonly TITLE = {
|
|
||||||
value: localize('create empty profile', "Create an Empty Profile..."),
|
|
||||||
original: 'Create an Empty Profile...'
|
|
||||||
};
|
|
||||||
constructor() {
|
|
||||||
super({
|
|
||||||
id: CreateEmptyProfileAction.ID,
|
|
||||||
title: CreateEmptyProfileAction.TITLE,
|
|
||||||
category: PROFILES_CATEGORY,
|
|
||||||
f1: true,
|
|
||||||
precondition: PROFILES_ENABLEMENT_CONTEXT
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async run(accessor: ServicesAccessor) {
|
|
||||||
const quickInputService = accessor.get(IQuickInputService);
|
|
||||||
const userDataProfileManagementService = accessor.get(IUserDataProfileManagementService);
|
|
||||||
const notificationService = accessor.get(INotificationService);
|
|
||||||
const userDataProfilesService = accessor.get(IUserDataProfilesService);
|
|
||||||
const name = await quickInputService.input({
|
|
||||||
placeHolder: localize('name', "Profile name"),
|
|
||||||
title: localize('create and enter empty profile', "Create an Empty Profile..."),
|
|
||||||
validateInput: async (value: string) => {
|
|
||||||
if (userDataProfilesService.profiles.some(p => p.name === value)) {
|
|
||||||
return localize('profileExists', "Profile with name {0} already exists.", value);
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (name) {
|
|
||||||
try {
|
|
||||||
await userDataProfileManagementService.createAndEnterProfile(name, undefined, undefined);
|
|
||||||
} catch (error) {
|
|
||||||
notificationService.error(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
registerAction2(CreateEmptyProfileAction);
|
|
||||||
|
|
||||||
registerAction2(class CreateProfileAction extends Action2 {
|
|
||||||
constructor() {
|
|
||||||
super({
|
|
||||||
id: 'workbench.profiles.actions.createProfile',
|
|
||||||
title: {
|
|
||||||
value: localize('create profile', "Create Profile..."),
|
|
||||||
original: 'Create Profile...'
|
|
||||||
},
|
|
||||||
category: PROFILES_CATEGORY,
|
|
||||||
precondition: PROFILES_ENABLEMENT_CONTEXT,
|
|
||||||
menu: [
|
|
||||||
{
|
|
||||||
id: ManageProfilesSubMenu,
|
|
||||||
group: '3_manage_profiles',
|
|
||||||
when: PROFILES_ENABLEMENT_CONTEXT,
|
|
||||||
order: 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async run(accessor: ServicesAccessor) {
|
|
||||||
const quickInputService = accessor.get(IQuickInputService);
|
|
||||||
const commandService = accessor.get(ICommandService);
|
|
||||||
const pick = await quickInputService.pick(
|
|
||||||
[{
|
|
||||||
id: CreateEmptyProfileAction.ID,
|
|
||||||
label: CreateEmptyProfileAction.TITLE.value,
|
|
||||||
}, {
|
|
||||||
id: CreateFromCurrentProfileAction.ID,
|
|
||||||
label: CreateFromCurrentProfileAction.TITLE.value,
|
|
||||||
}], { hideInput: true, canPickMany: false, title: localize('create profile title', "{0}: Create...", PROFILES_CATEGORY.value) });
|
|
||||||
if (pick?.id) {
|
|
||||||
return commandService.executeCommand(pick.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
class CreateTransientProfileAction extends Action2 {
|
class CreateTransientProfileAction extends Action2 {
|
||||||
static readonly ID = 'workbench.profiles.actions.createTemporaryProfile';
|
static readonly ID = 'workbench.profiles.actions.createTemporaryProfile';
|
||||||
static readonly TITLE = {
|
static readonly TITLE = {
|
||||||
|
|
|
@ -43,7 +43,7 @@ const editorAssociationsConfigurationNode: IConfigurationNode = {
|
||||||
properties: {
|
properties: {
|
||||||
'workbench.editorAssociations': {
|
'workbench.editorAssociations': {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
markdownDescription: localize('editor.editorAssociations', "Configure glob patterns to editors (for example `\"*.hex\": \"hexEditor.hexEdit\"`). These have precedence over the default behavior."),
|
markdownDescription: localize('editor.editorAssociations', "Configure glob patterns to editors (for example `\"*.hex\": \"hexEditor.hexedit\"`). These have precedence over the default behavior."),
|
||||||
additionalProperties: {
|
additionalProperties: {
|
||||||
type: 'string'
|
type: 'string'
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
export const allApiProposals = Object.freeze({
|
export const allApiProposals = Object.freeze({
|
||||||
authSession: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.authSession.d.ts',
|
authSession: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.authSession.d.ts',
|
||||||
codiconDecoration: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.codiconDecoration.d.ts',
|
codiconDecoration: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.codiconDecoration.d.ts',
|
||||||
commentsResolvedState: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.commentsResolvedState.d.ts',
|
|
||||||
contribCommentEditorActionsMenu: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribCommentEditorActionsMenu.d.ts',
|
contribCommentEditorActionsMenu: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribCommentEditorActionsMenu.d.ts',
|
||||||
contribCommentPeekContext: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribCommentPeekContext.d.ts',
|
contribCommentPeekContext: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribCommentPeekContext.d.ts',
|
||||||
contribCommentThreadAdditionalMenu: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribCommentThreadAdditionalMenu.d.ts',
|
contribCommentThreadAdditionalMenu: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribCommentThreadAdditionalMenu.d.ts',
|
||||||
|
|
|
@ -478,6 +478,7 @@ export abstract class AbstractTimerService implements ITimerService {
|
||||||
|
|
||||||
private readonly _barrier = new Barrier();
|
private readonly _barrier = new Barrier();
|
||||||
private readonly _marks = new PerfMarks();
|
private readonly _marks = new PerfMarks();
|
||||||
|
private readonly rndValueShouldSendTelemetry = Math.random() < .3;
|
||||||
|
|
||||||
private _startupMetrics?: IStartupMetrics;
|
private _startupMetrics?: IStartupMetrics;
|
||||||
|
|
||||||
|
@ -581,13 +582,15 @@ export abstract class AbstractTimerService implements ITimerService {
|
||||||
this._telemetryService.publicLog('startupTimeVaried', metrics);
|
this._telemetryService.publicLog('startupTimeVaried', metrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly _shouldReportPerfMarks = Math.random() < .3;
|
protected _shouldReportPerfMarks(): boolean {
|
||||||
|
return this.rndValueShouldSendTelemetry;
|
||||||
|
}
|
||||||
|
|
||||||
private _reportPerformanceMarks(source: string, marks: perf.PerformanceMark[]) {
|
private _reportPerformanceMarks(source: string, marks: perf.PerformanceMark[]) {
|
||||||
|
|
||||||
if (!this._shouldReportPerfMarks) {
|
if (!this._shouldReportPerfMarks()) {
|
||||||
// the `startup.timer.mark` event is send very often. In order to save resources
|
// the `startup.timer.mark` event is send very often. In order to save resources
|
||||||
// we let only a third of our instances send this event
|
// we let some of our instances/sessions send this event
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,11 @@ export class TimerService extends AbstractTimerService {
|
||||||
// ignore, be on the safe side with these hardware method calls
|
// ignore, be on the safe side with these hardware method calls
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override _shouldReportPerfMarks(): boolean {
|
||||||
|
// always send when running with the prof-append-timers flag
|
||||||
|
return super._shouldReportPerfMarks() || Boolean(this._environmentService.args['prof-append-timers']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
registerSingleton(ITimerService, TimerService, InstantiationType.Delayed);
|
registerSingleton(ITimerService, TimerService, InstantiationType.Delayed);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
import { Promises } from 'vs/base/common/async';
|
import { Promises } from 'vs/base/common/async';
|
||||||
import { Emitter } from 'vs/base/common/event';
|
import { Emitter } from 'vs/base/common/event';
|
||||||
import { Disposable } from 'vs/base/common/lifecycle';
|
import { Disposable } from 'vs/base/common/lifecycle';
|
||||||
|
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||||
import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
|
import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
|
||||||
import { defaultUserDataProfileIcon, DidChangeUserDataProfileEvent, IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile';
|
import { defaultUserDataProfileIcon, DidChangeUserDataProfileEvent, IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile';
|
||||||
|
|
||||||
|
@ -56,16 +57,10 @@ export class UserDataProfileService extends Disposable implements IUserDataProfi
|
||||||
}
|
}
|
||||||
|
|
||||||
getShortName(profile: IUserDataProfile): string {
|
getShortName(profile: IUserDataProfile): string {
|
||||||
if (profile.isDefault) {
|
if (!profile.isDefault && profile.shortName && ThemeIcon.fromId(profile.shortName)) {
|
||||||
return `$(${defaultUserDataProfileIcon.id})`;
|
|
||||||
}
|
|
||||||
if (profile.shortName) {
|
|
||||||
return profile.shortName;
|
return profile.shortName;
|
||||||
}
|
}
|
||||||
if (profile.isTransient) {
|
return `$(${defaultUserDataProfileIcon.id})`;
|
||||||
return `T${profile.name.charAt(profile.name.length - 1)}`;
|
|
||||||
}
|
|
||||||
return profile.name.substring(0, 2).toUpperCase();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
13
src/vscode-dts/vscode.d.ts
vendored
13
src/vscode-dts/vscode.d.ts
vendored
|
@ -15222,6 +15222,14 @@ declare module 'vscode' {
|
||||||
Preview = 1
|
Preview = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The state of a comment thread.
|
||||||
|
*/
|
||||||
|
export enum CommentThreadState {
|
||||||
|
Unresolved = 0,
|
||||||
|
Resolved = 1
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A collection of {@link Comment comments} representing a conversation at a particular range in a document.
|
* A collection of {@link Comment comments} representing a conversation at a particular range in a document.
|
||||||
*/
|
*/
|
||||||
|
@ -15279,6 +15287,11 @@ declare module 'vscode' {
|
||||||
*/
|
*/
|
||||||
label?: string;
|
label?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The optional state of a comment thread, which may affect how the comment is displayed.
|
||||||
|
*/
|
||||||
|
state?: CommentThreadState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispose this comment thread.
|
* Dispose this comment thread.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
||||||
*--------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
declare module 'vscode' {
|
|
||||||
|
|
||||||
// https://github.com/microsoft/vscode/issues/127473
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The state of a comment thread.
|
|
||||||
*/
|
|
||||||
export enum CommentThreadState {
|
|
||||||
Unresolved = 0,
|
|
||||||
Resolved = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CommentThread {
|
|
||||||
/**
|
|
||||||
* The optional state of a comment thread, which may affect how the comment is displayed.
|
|
||||||
*/
|
|
||||||
state?: CommentThreadState;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1321,10 +1321,10 @@
|
||||||
resolved "https://registry.yarnpkg.com/@vscode/vscode-languagedetection/-/vscode-languagedetection-1.0.21.tgz#89b48f293f6aa3341bb888c1118d16ff13b032d3"
|
resolved "https://registry.yarnpkg.com/@vscode/vscode-languagedetection/-/vscode-languagedetection-1.0.21.tgz#89b48f293f6aa3341bb888c1118d16ff13b032d3"
|
||||||
integrity sha512-zSUH9HYCw5qsCtd7b31yqkpaCU6jhtkKLkvOOA8yTrIRfBSOFb8PPhgmMicD7B/m+t4PwOJXzU1XDtrM9Fd3/g==
|
integrity sha512-zSUH9HYCw5qsCtd7b31yqkpaCU6jhtkKLkvOOA8yTrIRfBSOFb8PPhgmMicD7B/m+t4PwOJXzU1XDtrM9Fd3/g==
|
||||||
|
|
||||||
"@vscode/vscode-perf@^0.0.1":
|
"@vscode/vscode-perf@^0.0.2":
|
||||||
version "0.0.1"
|
version "0.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@vscode/vscode-perf/-/vscode-perf-0.0.1.tgz#8378057d86003d8823d7404734adc64cfae80780"
|
resolved "https://registry.yarnpkg.com/@vscode/vscode-perf/-/vscode-perf-0.0.2.tgz#d5a1c506c5ff57ab2b9cb74d349f66c5e5e98fdf"
|
||||||
integrity sha512-7xzVgkWAqFAFMTbHNGY6WiIKHEn0X0ARvIJmDEv2fDKjIB9W76R67Ft25jn3rf2/Gi0HfTPeJwjPTXm6ih5juw==
|
integrity sha512-C8RrB+aRGXE5iSjm69zLRpLMMsoti+MonciR9xjzSj4lW9/NWNmQY2kH3Ktkoyci2zhUrTN+0OSmmuyDhhFDVg==
|
||||||
dependencies:
|
dependencies:
|
||||||
chalk "^4.x"
|
chalk "^4.x"
|
||||||
commander "^9.4.0"
|
commander "^9.4.0"
|
||||||
|
|
Loading…
Reference in a new issue