mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-13 17:22:15 -05:00
Merge from vscode 70dc55955d586ebd427658b43cdb344f2047f9c2 (#6789)
This commit is contained in:
@@ -107,6 +107,16 @@ steps:
|
||||
displayName: Run integration tests
|
||||
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
|
||||
|
||||
- script: |
|
||||
set -e
|
||||
cd test/smoke
|
||||
yarn compile
|
||||
cd -
|
||||
yarn smoketest --web --headless
|
||||
continueOnError: true
|
||||
displayName: Run web smoke tests
|
||||
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
|
||||
|
||||
- script: |
|
||||
set -e
|
||||
cd test/smoke
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"version": "0.0.1",
|
||||
"description": "Dependencies shared by all extensions",
|
||||
"dependencies": {
|
||||
"typescript": "3.6.0-dev.20190810"
|
||||
"typescript": "3.6.1-rc"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "node ./postinstall"
|
||||
|
||||
@@ -32,7 +32,8 @@ let nonBuiltInLanguages = { // { fileNames, extensions }
|
||||
"haml": { extensions: ['haml'] },
|
||||
"stylus": { extensions: ['styl'] },
|
||||
"vala": { extensions: ['vala'] },
|
||||
"todo": { fileNames: ['todo'] }
|
||||
"todo": { fileNames: ['todo'] },
|
||||
"jsonc": { extensions: ['json'] }
|
||||
};
|
||||
|
||||
let FROM_DISK = true; // set to true to take content from a repo checked out next to the vscode repo
|
||||
@@ -109,7 +110,7 @@ function downloadBinary(source, dest) {
|
||||
return new Promise((c, e) => {
|
||||
https.get(source, function (response) {
|
||||
switch (response.statusCode) {
|
||||
case 200:
|
||||
case 200: {
|
||||
let file = fs.createWriteStream(dest);
|
||||
response.on('data', function (chunk) {
|
||||
file.write(chunk);
|
||||
@@ -121,6 +122,7 @@ function downloadBinary(source, dest) {
|
||||
e(err.message);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 301:
|
||||
case 302:
|
||||
case 303:
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"git": {
|
||||
"name": "seti-ui",
|
||||
"repositoryUrl": "https://github.com/jesseweed/seti-ui",
|
||||
"commitHash": "904c16acced1134a81b31d71d60293288c31334b"
|
||||
"commitHash": "85a222708824c6f19bbecbec71633d2c97077dad"
|
||||
}
|
||||
},
|
||||
"version": "0.1.0"
|
||||
|
||||
@@ -1580,6 +1580,7 @@
|
||||
"version.md": "_clock",
|
||||
"version": "_clock",
|
||||
"mvnw": "_maven",
|
||||
"tsconfig.json": "_tsconfig",
|
||||
"swagger.json": "_json_1",
|
||||
"swagger.yml": "_json_1",
|
||||
"swagger.yaml": "_json_1",
|
||||
@@ -1589,6 +1590,8 @@
|
||||
"docker-healthcheck": "_docker_2",
|
||||
"docker-compose.yml": "_docker_3",
|
||||
"docker-compose.yaml": "_docker_3",
|
||||
"docker-compose.override.yml": "_docker_3",
|
||||
"docker-compose.override.yaml": "_docker_3",
|
||||
"firebase.json": "_firebase",
|
||||
"geckodriver": "_firefox",
|
||||
"gruntfile.js": "_grunt",
|
||||
@@ -1968,6 +1971,7 @@
|
||||
"version.md": "_clock_light",
|
||||
"version": "_clock_light",
|
||||
"mvnw": "_maven_light",
|
||||
"tsconfig.json": "_tsconfig_light",
|
||||
"swagger.json": "_json_1_light",
|
||||
"swagger.yml": "_json_1_light",
|
||||
"swagger.yaml": "_json_1_light",
|
||||
@@ -1977,6 +1981,8 @@
|
||||
"docker-healthcheck": "_docker_2_light",
|
||||
"docker-compose.yml": "_docker_3_light",
|
||||
"docker-compose.yaml": "_docker_3_light",
|
||||
"docker-compose.override.yml": "_docker_3_light",
|
||||
"docker-compose.override.yaml": "_docker_3_light",
|
||||
"firebase.json": "_firebase_light",
|
||||
"geckodriver": "_firefox_light",
|
||||
"gruntfile.js": "_grunt_light",
|
||||
@@ -2011,5 +2017,5 @@
|
||||
"Schema Compare": "scmp"
|
||||
}
|
||||
},
|
||||
"version": "https://github.com/jesseweed/seti-ui/commit/904c16acced1134a81b31d71d60293288c31334b"
|
||||
}
|
||||
"version": "https://github.com/jesseweed/seti-ui/commit/85a222708824c6f19bbecbec71633d2c97077dad"
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
typescript@3.6.0-dev.20190810:
|
||||
version "3.6.0-dev.20190810"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.0-dev.20190810.tgz#dda80279480131eec9b05e3b78182a1ba1efe105"
|
||||
integrity sha512-gubcQ8Sn2G5AO1KhjvLpoFrutV7o/ZJ7wCDBC1IKgNI8R2vadIxTystJxAFqkb9boQ7tyRrZ6FwM5EL5ZYfJrg==
|
||||
typescript@3.6.1-rc:
|
||||
version "3.6.1-rc"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.1-rc.tgz#9db650b25d8ef033d9e25b3057bdd1e102bb434b"
|
||||
integrity sha512-u6AQN9AoocZKYSz8zcc1Qh/V/mbAO+BHc73fTiKlIdjzU60A8TesrK9/7kg3GM8o2RxNyCeOFpcevEtnfUyaLg==
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
"vscode-sqlite3": "4.0.8",
|
||||
"vscode-textmate": "^4.2.2",
|
||||
"xterm": "3.15.0-beta99",
|
||||
"xterm-addon-search": "0.2.0-beta3",
|
||||
"xterm-addon-search": "0.2.0-beta5",
|
||||
"xterm-addon-web-links": "0.1.0-beta10",
|
||||
"yauzl": "^2.9.2",
|
||||
"yazl": "^2.4.3",
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"vscode-ripgrep": "^1.5.6",
|
||||
"vscode-textmate": "^4.2.2",
|
||||
"xterm": "3.15.0-beta99",
|
||||
"xterm-addon-search": "0.2.0-beta3",
|
||||
"xterm-addon-search": "0.2.0-beta5",
|
||||
"xterm-addon-web-links": "0.1.0-beta10",
|
||||
"yauzl": "^2.9.2",
|
||||
"yazl": "^2.4.3"
|
||||
|
||||
@@ -1217,10 +1217,10 @@ vscode-windows-registry@1.0.1:
|
||||
dependencies:
|
||||
nan "^2.12.1"
|
||||
|
||||
xterm-addon-search@0.2.0-beta3:
|
||||
version "0.2.0-beta3"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.2.0-beta3.tgz#710ce14658e269c5a4791f5a9e2f520883a2e62b"
|
||||
integrity sha512-KzVdkEtGbKJe9ER2TmrI7XjF/wUq1lir9U63vPJi0t2ymQvIECl1V63f9QtOp1vvpdhbZiXBxO+vGTj+y0tRow==
|
||||
xterm-addon-search@0.2.0-beta5:
|
||||
version "0.2.0-beta5"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.2.0-beta5.tgz#258d7cb1511d9060cd4520f0f82e408000fd4f53"
|
||||
integrity sha512-Tg+d8scch0rYOVmzBbX35Y1GXtq+eu/YlzbXznmTo/yD83j3BQlXOhgECu/Yv8EX5JwFmzbfVRWC+JWnfigwGg==
|
||||
|
||||
xterm-addon-web-links@0.1.0-beta10:
|
||||
version "0.1.0-beta10"
|
||||
|
||||
@@ -26,7 +26,7 @@ exports.serviceWorker = [{
|
||||
exports.workerExtensionHost = [{
|
||||
name: 'vs/workbench/services/extensions/worker/extensionHostWorker',
|
||||
// include: [],
|
||||
prepend: ['vs/loader.js'],
|
||||
prepend: ['vs/loader.js', 'vs/nls.js'],
|
||||
append: ['vs/workbench/services/extensions/worker/extensionHostWorkerMain'],
|
||||
dest: 'vs/workbench/services/extensions/worker/extensionHostWorkerMain.js'
|
||||
}];
|
||||
|
||||
@@ -15,7 +15,7 @@ import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { Schemas, RemoteAuthorities } from 'vs/base/common/network';
|
||||
|
||||
export function clearNode(node: HTMLElement): void {
|
||||
while (node.firstChild) {
|
||||
@@ -1193,14 +1193,21 @@ export function asDomUri(uri: URI): URI {
|
||||
if (!uri) {
|
||||
return uri;
|
||||
}
|
||||
if (!platform.isWeb) {
|
||||
//todo@joh remove this once we have sw in electron going
|
||||
return uri;
|
||||
}
|
||||
if (Schemas.vscodeRemote === uri.scheme) {
|
||||
// rewrite vscode-remote-uris to uris of the window location
|
||||
// so that they can be intercepted by the service worker
|
||||
return _location.with({ path: '/vscode-remote', query: JSON.stringify(uri) });
|
||||
if (platform.isWeb) {
|
||||
// rewrite vscode-remote-uris to uris of the window location
|
||||
// so that they can be intercepted by the service worker
|
||||
return _location.with({ path: '/vscode-remote', query: JSON.stringify(uri) });
|
||||
} else {
|
||||
return RemoteAuthorities.rewrite(uri.authority, uri.path);
|
||||
}
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns url('...')
|
||||
*/
|
||||
export function asCSSUrl(uri: URI): string {
|
||||
return `url('${asDomUri(uri).toString(true).replace(/'/g, '%27')}')`;
|
||||
}
|
||||
|
||||
@@ -157,8 +157,9 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
|
||||
};
|
||||
}
|
||||
|
||||
if (options.actionHandler) {
|
||||
options.actionHandler.disposeables.add(DOM.addStandardDisposableListener(element, 'click', event => {
|
||||
const actionHandler = options.actionHandler;
|
||||
if (actionHandler) {
|
||||
actionHandler.disposeables.add(DOM.addStandardDisposableListener(element, 'click', event => {
|
||||
let target: HTMLElement | null = event.target;
|
||||
if (target.tagName !== 'A') {
|
||||
target = target.parentElement;
|
||||
@@ -169,7 +170,7 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
|
||||
try {
|
||||
const href = target.dataset['href'];
|
||||
if (href) {
|
||||
options.actionHandler!.callback(href, event);
|
||||
actionHandler.callback(href, event);
|
||||
}
|
||||
} catch (err) {
|
||||
onUnexpectedError(err);
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./octicons/octicons';
|
||||
import 'vs/css!./octicons/octicons2';
|
||||
import 'vs/css!./octicons/octicons-main';
|
||||
import 'vs/css!./octicons/octicons-animations';
|
||||
import { escape } from 'vs/base/common/strings';
|
||||
|
||||
@@ -30,4 +32,4 @@ export class OcticonLabel {
|
||||
set title(title: string) {
|
||||
this._container.title = title;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
body[data-octicons-update="enabled"] {
|
||||
--version: octicons2;
|
||||
}
|
||||
|
||||
body {
|
||||
--version: octicons;
|
||||
}
|
||||
|
||||
.octicon, .mega-octicon {
|
||||
font-family: var(--version) !important;
|
||||
}
|
||||
|
||||
body[data-octicons-update="enabled"] .monaco-workbench .part.statusbar > .items-container > .statusbar-item span.octicon {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
body[data-octicons-update="enabled"] .monaco-workbench .part.statusbar > .items-container > .statusbar-item > a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
@font-face {
|
||||
font-family: "octicons";
|
||||
src: url("./octicons.ttf?1b0f2a9535896866c74dd24eedeb4374") format("truetype"),
|
||||
url("./octicons.svg?1b0f2a9535896866c74dd24eedeb4374#octicons") format("svg");
|
||||
src: url("./octicons.ttf?dda6b6d46f87b1fa91a76fc0389eeb1d") format("truetype"),
|
||||
url("./octicons.svg?dda6b6d46f87b1fa91a76fc0389eeb1d#octicons") format("svg");
|
||||
}
|
||||
|
||||
.octicon, .mega-octicon {
|
||||
@@ -169,7 +169,7 @@ url("./octicons.svg?1b0f2a9535896866c74dd24eedeb4374#octicons") format("svg");
|
||||
.octicon-person-outline:before { content: "\f018" }
|
||||
.octicon-pin:before { content: "\f041" }
|
||||
.octicon-plug:before { content: "\f0d4" }
|
||||
.octicon-plus-small:before { content: "\f28a" }
|
||||
.octicon-plus-small:before { content: "\f05d" }
|
||||
.octicon-plus:before { content: "\f05d" }
|
||||
.octicon-primitive-dot:before { content: "\f052" }
|
||||
.octicon-primitive-square:before { content: "\f053" }
|
||||
@@ -233,16 +233,19 @@ url("./octicons.svg?1b0f2a9535896866c74dd24eedeb4374#octicons") format("svg");
|
||||
.octicon-watch:before { content: "\f0e0" }
|
||||
.octicon-x:before { content: "\f081" }
|
||||
.octicon-zap:before { content: "\26a1" }
|
||||
.octicon-error:before { content: "\26a2" }
|
||||
.octicon-eye-closed:before { content: "\26a3" }
|
||||
.octicon-fold-down:before { content: "\26a4" }
|
||||
.octicon-fold-up:before { content: "\26a5" }
|
||||
.octicon-github-action:before { content: "\26a6" }
|
||||
.octicon-info-outline:before { content: "\26a7" }
|
||||
.octicon-play:before { content: "\26a8" }
|
||||
.octicon-remote:before { content: "\26a9" }
|
||||
.octicon-request-changes:before { content: "\26aa" }
|
||||
.octicon-smiley-outline:before { content: "\f27d" }
|
||||
.octicon-warning:before { content: "\f02d" }
|
||||
.octicon-controls:before { content: "\26ad" }
|
||||
.octicon-event:before { content: "\26ae" }
|
||||
.octicon-record-keys:before { content: "\26af" }
|
||||
.octicon-archive:before { content: "\f101" }
|
||||
.octicon-arrow-both:before { content: "\f102" }
|
||||
.octicon-error:before { content: "\f103" }
|
||||
.octicon-eye-closed:before { content: "\f104" }
|
||||
.octicon-fold-down:before { content: "\f105" }
|
||||
.octicon-fold-up:before { content: "\f106" }
|
||||
.octicon-github-action:before { content: "\f107" }
|
||||
.octicon-info-outline:before { content: "\f108" }
|
||||
.octicon-play:before { content: "\f109" }
|
||||
.octicon-remote:before { content: "\f10a" }
|
||||
.octicon-request-changes:before { content: "\f10b" }
|
||||
.octicon-smiley-outline:before { content: "\f10c" }
|
||||
.octicon-warning:before { content: "\f10d" }
|
||||
|
||||
@@ -167,10 +167,10 @@
|
||||
unicode=""
|
||||
horiz-adv-x="750" d=" M687.5 507.5H62.5C28.125 507.5 0 479.375 0 445V195C0 160.625 28.125 132.5 62.5 132.5H687.5C721.875 132.5 750 160.625 750 195V445C750 479.375 721.875 507.5 687.5 507.5zM250 257.5H125V382.5H250V257.5zM437.5 257.5H312.5V382.5H437.5V257.5zM625 257.5H500V382.5H625V257.5z" />
|
||||
<glyph glyph-name="error"
|
||||
unicode=""
|
||||
unicode="⚢"
|
||||
horiz-adv-x="1000" d=" M500 757.5C258.365625 757.5 62.5 561.6343750000001 62.5 320C62.5 78.3625000000001 258.365625 -117.5 500 -117.5C741.6374999999999 -117.5 937.5 78.3625000000001 937.5 320C937.5 561.6343750000001 741.6374999999999 757.5 500 757.5zM762.5 145L675 57.5L500 232.5L325 57.5L237.5 145L412.5 322.355625L237.5 495L325 582.5L500 407.5L675 582.5L762.5 495L587.5 322.355625L762.5 145z" />
|
||||
<glyph glyph-name="eye-closed"
|
||||
unicode=""
|
||||
unicode="⚣"
|
||||
horiz-adv-x="1142.857142857143" d=" M1057.142857142857 812.8571428571429C1042.857142857143 827.1428571428571 1021.4285714285716 827.1428571428571 1007.1428571428572 812.8571428571429L857.1428571428573 655.7142857142857C778.5714285714288 712.8571428571429 685.7142857142858 748.5714285714286 578.5714285714287 748.5714285714286C214.2857142857144 755.7142857142857 1e-13 327.1428571428571 1e-13 327.1428571428571S85.7142857142858 162.8571428571429 235.7142857142859 34.2857142857142L85.7142857142858 -115.7142857142857C71.4285714285716 -130 71.4285714285716 -151.4285714285714 85.7142857142858 -165.7142857142857S121.4285714285716 -179.9999999999999 135.7142857142858 -165.7142857142857L1057.1428571428573 755.7142857142858C1071.4285714285716 770.0000000000001 1071.4285714285716 798.5714285714287 1057.1428571428573 812.857142857143zM642.8571428571429 448.5714285714286C621.4285714285714 462.8571428571429 600 470 571.4285714285714 470C492.8571428571429 470 428.5714285714286 405.7142857142857 428.5714285714286 327.1428571428572C428.5714285714286 298.5714285714286 435.7142857142857 277.1428571428571 450 255.7142857142858L350.0000000000001 148.5714285714287C307.1428571428572 198.5714285714286 285.7142857142857 255.7142857142858 285.7142857142857 327.1428571428572C285.7142857142857 484.2857142857144 414.2857142857143 612.8571428571429 571.4285714285714 612.8571428571429C635.7142857142858 612.8571428571429 700.0000000000001 591.4285714285716 750 548.5714285714287z M992.8571428571428 541.4285714285714L850 398.5714285714286C857.1428571428571 377.1428571428571 857.1428571428571 348.5714285714285 857.1428571428571 327.1428571428571C857.1428571428571 169.9999999999999 728.5714285714286 41.4285714285713 571.4285714285714 41.4285714285713C542.8571428571429 41.4285714285713 521.4285714285714 41.4285714285713 500 48.5714285714286L385.7142857142857 -65.7142857142858C442.8571428571429 -94.2857142857143 507.1428571428572 -108.5714285714285 578.5714285714287 -108.5714285714285C928.5714285714286 -108.5714285714285 1142.857142857143 320 1142.857142857143 320C1100 405.7142857142857 1050 477.1428571428572 992.8571428571428 541.4285714285714z" />
|
||||
<glyph glyph-name="eye"
|
||||
unicode=""
|
||||
@@ -209,10 +209,10 @@
|
||||
unicode=""
|
||||
horiz-adv-x="750" d=" M315.625 800.625C366.25 665 341.25 589.375 283.125 531.25C221.875 465.625 123.75 416.875 56.25 321.25C-34.375 193.1249999999999 -50 -86.8750000000001 276.875 -160C139.375 -87.5 110 122.5 258.125 253.125C220 126.25 291.25 45 379.375 74.375C466.25 103.7500000000001 523.1250000000001 41.2500000000001 521.25 -30C520 -78.7499999999999 501.8749999999999 -120 450.625 -143.125C664.3749999999999 -106.25 749.375 70.625 749.375 204.3749999999999C749.375 381.8749999999999 591.25 405.625 671.25 555C576.25 546.875 544.375 484.3749999999999 553.125 383.125C558.75 315.625 489.375 270.6249999999999 436.875 300C395 325.625 395.625 374.375 433.125 411.25C511.25 488.125 542.5 666.875 315.625 800L314.375 801.25L315.625 800.625z" />
|
||||
<glyph glyph-name="fold-down"
|
||||
unicode=""
|
||||
unicode="⚤"
|
||||
horiz-adv-x="875" d=" M250 132.5L437.5 -55L625 132.5H500V507.5H375V132.5H250zM0 132.5C0 98.125 28.125 70 62.5 70H218.75L156.25 132.5H93.75L218.75 257.5H312.5V320H218.75L93.75 445H312.5V507.5H62.5C28.125 507.5 0 479.375 0 445L156.25 288.75L0 132.5zM656.25 257.5H562.5V320H656.25L781.25 445H562.5V507.5H812.5C846.875 507.5 875 479.375 875 445L718.75 288.75L875 132.5C875 98.125 846.875 70 812.5 70H656.25L718.75 132.5H781.25L656.25 257.5z" />
|
||||
<glyph glyph-name="fold-up"
|
||||
unicode=""
|
||||
unicode="⚥"
|
||||
horiz-adv-x="875" d=" M625 445L437.5 632.5L250 445H375V70H500V445H625zM875 445C875 479.375 846.875 507.5 812.5 507.5H656.25L718.75 445H781.25L656.25 320H562.5V257.5H656.25L781.25 132.5H562.5V70H812.5C846.875 70 875 98.125 875 132.5L718.75 288.75L875 445zM218.75 320H312.5V257.5H218.75L93.75 132.5H312.5V70H62.5C28.125 70 0 98.125 0 132.5L156.25 288.75L0 445C0 479.375 28.125 507.5 62.5 507.5H218.75L156.25 445H93.75L218.75 320z" />
|
||||
<glyph glyph-name="fold"
|
||||
unicode=""
|
||||
@@ -245,7 +245,7 @@
|
||||
unicode=""
|
||||
horiz-adv-x="750" d=" M687.5 115V507.5C685.625 556.25 666.25 599.375 628.75 636.25C591.25 673.125 548.75 693.125 500 695H437.5V820L250 632.5L437.5 445V570H500C516.875 568.75 530 563.125 543.125 550.625C556.25 538.125 561.875 524.375 562.5 507.5V114.9999999999999A124.56250000000001 124.56250000000001 0 0 1 625 -117.5A124.56250000000001 124.56250000000001 0 0 1 687.5 115zM625 -67.5C583.75 -67.5 550 -33.1249999999999 550 7.5C550 48.125 584.3750000000001 82.5 625 82.5C665.625 82.5 700 48.1249999999999 700 7.5C700 -33.125 665.6249999999999 -67.5 625 -67.5zM250 632.5C250 701.875 194.375 757.5 125 757.5A124.56250000000001 124.56250000000001 0 0 1 62.5 525V114.9999999999999A124.56250000000001 124.56250000000001 0 0 1 125 -117.5A124.56250000000001 124.56250000000001 0 0 1 187.5 115V525C224.375 546.25 250 586.25 250 632.5zM200 7.5C200 -33.75 165.625 -67.5 125 -67.5C84.375 -67.5 50 -33.1249999999999 50 7.5C50 48.125 84.375 82.5 125 82.5C165.625 82.5 200 48.1249999999999 200 7.5zM125 557.5C83.75 557.5 50 591.875 50 632.5C50 673.125 84.375 707.5 125 707.5C165.625 707.5 200 673.125 200 632.5C200 591.875 165.625 557.5 125 557.5z" />
|
||||
<glyph glyph-name="github-action"
|
||||
unicode=""
|
||||
unicode="⚦"
|
||||
horiz-adv-x="1000" d=" M687.5 476.25C687.5 424.4733047033631 729.4733047033632 382.5 781.25 382.5C833.0266952966368 382.5 875 424.4733047033631 875 476.25C875 528.026695296637 833.0266952966368 570 781.25 570C729.4733047033632 570 687.5 528.026695296637 687.5 476.25z M937.5 695H562.5C562.5 732.5 537.5 757.5 500 757.5S437.5 732.5 437.5 695H62.5C31.25 695 0 663.75 0 632.5V7.5C0 -23.75 31.25 -55 62.5 -55H437.5C437.5 -92.5 462.5 -117.5 500 -117.5S562.5 -92.5 562.5 -55H937.5C968.75 -55 1000 -23.75 1000 7.5V632.5C1000 663.75 968.75 695 937.5 695zM937.5 7.5H62.5V632.5H937.5z" />
|
||||
<glyph glyph-name="globe"
|
||||
unicode=""
|
||||
@@ -275,7 +275,7 @@
|
||||
unicode=""
|
||||
horiz-adv-x="875" d=" M875 257.5L804.3750000000001 703.75C799.3750000000001 733.75 773.1250000000001 757.5 741.8750000000001 757.5H133.125C101.875 757.5 75.625 733.75 70.625 703.75L0 257.5V-55C0 -89.375 28.125 -117.5 62.5 -117.5H812.5C846.875 -117.5 875 -89.375 875 -55V257.5zM670 223.125L642.5000000000001 167.4999999999999C631.8750000000001 146.2499999999999 610.0000000000001 132.4999999999999 585.6250000000001 132.4999999999999H288.125C264.375 132.4999999999999 243.1250000000001 146.2499999999999 232.5 166.8749999999999L205 223.7499999999999C194.375 244.375 172.5 258.125 149.375 258.125H62.5L125 695.625H750L812.5 258.125H726.2500000000001C701.875 258.125 680.625 244.375 669.375 223.7499999999999L670 223.125z" />
|
||||
<glyph glyph-name="info-outline"
|
||||
unicode=""
|
||||
unicode="⚧"
|
||||
horiz-adv-x="875" d=" M393.75 464.37625C381.875 476.25125 376.25 490.62625 376.25 508.12625C376.25 525.62625 381.875 540.62625 393.75 551.87625C405.625 563.12625 420 569.37625 437.5 569.37625C455 569.37625 470 563.75125 481.25 551.87625C492.5 540.00125 498.75 525.62625 498.75 508.12625C498.75 490.62625 493.125 475.62625 481.25 464.37625C469.375 453.12625 455 445.62625 437.5 445.62625C420 445.62625 405 452.50125 393.75 464.37625zM500 320.6268750000001C498.75 336.2518750000001 493.125 350.626875 480.625 363.751875C468.125 375.6268750000001 454.375 382.5012500000001 437.5 383.1268750000001H375C358.125 381.876875 345 375.0012500000001 331.875 363.751875C319.375 351.2512500000001 313.125 336.2518750000001 312.5 320.6268750000001H375V133.125C376.25 116.25 381.875 101.875 394.375 90C406.875 77.5 420.625 70.625 437.5 70.625H500C516.875 70.625 530 77.5 543.125 90C555.625 101.875 561.875 116.25 562.5 133.125H500V321.2518750000001V320.6268750000001zM437.5 676.25125C241.25 676.25125 81.25 517.50125 81.25 321.25125C81.25 125 241.25 -35 437.5 -35C633.75 -35 793.75 124.375 793.75 321.25125C793.75 518.12625 633.75 676.87625 437.5 676.87625V676.25125zM437.5 758.75125C678.75 758.75125 875 562.50125 875 321.25125C875 80 678.75 -116.25 437.5 -116.25C196.25 -116.25 0 78.75 0 321.25125C0 563.75125 196.25 758.75125 437.5 758.75125z" />
|
||||
<glyph glyph-name="info"
|
||||
unicode=""
|
||||
@@ -398,7 +398,7 @@
|
||||
unicode=""
|
||||
horiz-adv-x="1000" d=" M625 745V695L656.25 632.5L375 445H137.5C110 445 95.625 411.875 116.25 391.25L312.5 195L62.5 -117.5L375 132.5L571.25 -63.75A31.25 31.25 0 0 1 625 -42.5V195L812.5 476.25L875 445H925C952.5 445 966.875 478.125 946.25 498.75L678.75 766.25A31.25 31.25 0 0 1 625 745z" />
|
||||
<glyph glyph-name="play"
|
||||
unicode=""
|
||||
unicode="⚨"
|
||||
horiz-adv-x="875" d=" M875 320A437.49999999999994 437.49999999999994 0 1 0 0 320A437.49999999999994 437.49999999999994 0 0 0 875 320zM361.0625 102.375L648.5 294A31.25 31.25 0 0 1 648.5 346L361.0625 537.625A31.25 31.25 0 0 1 312.5 511.625V128.3750000000001A31.25 31.25 0 0 1 361.0625 102.375z" />
|
||||
<glyph glyph-name="plug"
|
||||
unicode=""
|
||||
@@ -428,7 +428,7 @@
|
||||
unicode=""
|
||||
horiz-adv-x="1000" d=" M299.375 438.125C315 453.75 315 480 299.375 495.625C279.375 516.25 269.3750000000001 543.125 269.3750000000001 570C269.3750000000001 596.875 279.3750000000001 623.75 299.3750000000001 644.375C315.0000000000001 660.625 315.0000000000001 686.25 299.3750000000001 701.875A38.3125 38.3125 0 0 1 271.2500000000001 713.75C261.2500000000001 713.75 250.6250000000001 710 243.1250000000001 701.875C207.5000000000001 665.625 190 617.5 190 570C190 522.5 208.125 474.375 243.1250000000001 438.1250000000001C258.7500000000001 422.5000000000001 284.3750000000001 422.5000000000001 299.3750000000001 438.1250000000001zM145.625 787.5A40.6875 40.6875 0 0 1 88.125 787.5C30 727.5 0.625 648.75 0.625 570.625C0.625 491.875 30 413.125 88.125 353.125C103.75 336.875 129.375 336.875 145 353.125S160.625 395.625 145 411.875C102.5 455.6249999999999 81.25 513.125 81.25 570.625C81.25 628.1249999999999 102.5 685.6249999999999 145 729.3749999999999A41.25 41.25 0 0 1 145.625 787.4999999999999zM501.25 468.7500000000001A101.25 101.25 0 1 1 400 570C399.3750000000001 514.375 445 468.75 501.25 468.75zM911.875 786.875A39.25 39.25 0 0 1 855 786.875C839.375 770.625 839.375 744.375 855 728.125C897.5 684.375 918.75 626.875 918.75 569.375C918.75 511.875 897.5 455 855 410.625C839.375 394.375 839.375 368.1250000000001 855 351.875A40.6875 40.6875 0 0 1 912.5 351.875C970.625 411.875 1000 490.625 1000 569.375A315.5 315.5 0 0 1 911.875 786.875zM501.25 387.5C475.6249999999999 387.5 449.375 393.75 426.25 406.25L229.375 -116.8749999999999H322.5L376.25 -54.3749999999999H626.25L678.75 -116.8749999999999H771.875L575.625 406.25C551.875 393.75 526.8750000000001 387.5 501.2500000000001 387.5zM500.625 357.5L563.75 132.5H438.75L500.625 357.5zM376.25 8.125L438.75 70.625H563.75L626.25 8.125H376.25zM700.625 701.875C685 686.25 685 660 700.625 644.375C720.6250000000001 623.75 730.6250000000001 596.875 730.6250000000001 570C730.6250000000001 543.125 720.6250000000001 516.25 700.625 495.6250000000001C685 479.3750000000001 685 453.7500000000001 700.625 438.1250000000001A39.375 39.375 0 0 1 756.8750000000001 438.1250000000001C792.5000000000001 474.3750000000001 810 522.5 810 570C810 617.5 792.5000000000001 665.625 756.8750000000001 701.875A39.625 39.625 0 0 1 700.625 701.875z" />
|
||||
<glyph glyph-name="remote"
|
||||
unicode=""
|
||||
unicode="⚩"
|
||||
horiz-adv-x="1000" d=" M524.97125 425.9231250000001L794.09375 156.8L875 237.615625L686.69375 425.9231250000001L875 614.184375L794.09375 695L524.97125 425.9231250000001zM313.3075 225.89875L125 414.20625L205.9075 495.02125L474.984375 225.89875L205.9075 -43.2687500000001L125 37.59375L313.3075 225.89875z" />
|
||||
<glyph glyph-name="reply"
|
||||
unicode=""
|
||||
@@ -455,7 +455,7 @@
|
||||
unicode=""
|
||||
horiz-adv-x="1000" d=" M437.5 320H562.5V195H437.5z M437.5 632.5H562.5V382.5H437.5z M937.5 757.5H62.5C25 757.5 0 732.5 0 695V132.5C0 95 25 70 62.5 70H187.5V-180L437.5 70H937.5C975 70 1000 95 1000 132.5V695C1000 732.5 975 757.5 937.5 757.5zM937.5 132.5H406.25L250 -23.75V132.5H62.5V695H937.5z" />
|
||||
<glyph glyph-name="request-changes"
|
||||
unicode=""
|
||||
unicode="⚪"
|
||||
horiz-adv-x="1000" d=" M0 757.5A62.5 62.5 0 0 0 62.5 820H937.5A62.5 62.5 0 0 0 1000 757.5V132.5A62.5 62.5 0 0 0 937.5 70H468.75L250 -148.75V70H62.5A62.5 62.5 0 0 0 0 132.5V757.5zM62.5 757.5V132.5H312.5V7.5L437.5 132.5H937.5V757.5H62.5zM531.25 570H656.25V507.5H531.25V382.5H468.75V507.5H343.75V570H468.75V695H531.25V570zM656.25 257.5H343.75V320H656.25V257.5z" />
|
||||
<glyph glyph-name="rocket"
|
||||
unicode=""
|
||||
@@ -491,7 +491,7 @@
|
||||
unicode=""
|
||||
horiz-adv-x="941.1764705882352" d=" M705.8823529411765 290.5882352941177V408.2352941176471H470.5882352941176V525.8823529411765H705.8823529411765V643.5294117647059L941.1764705882352 467.0588235294118L705.8823529411765 290.5882352941177zM588.2352941176471 114.1176470588235H352.9411764705883V643.5294117647059L117.6470588235294 761.1764705882352H588.2352941176471V584.7058823529412H647.0588235294117V761.1764705882352C647.0588235294117 793.5294117647059 620.5882352941177 820 588.2352941176471 820H58.8235294117647C26.4705882352941 820 0 793.5294117647059 0 761.1764705882352V91.7647058823529C0 68.8235294117646 12.9411764705882 48.8235294117646 32.3529411764706 38.2352941176471L352.9411764705883 -121.764705882353V55.2941176470589H588.2352941176471C620.5882352941177 55.2941176470589 647.0588235294117 81.7647058823529 647.0588235294117 114.1176470588235V349.4117647058824H588.2352941176471V114.1176470588235z" />
|
||||
<glyph glyph-name="smiley-outline"
|
||||
unicode=""
|
||||
unicode=""
|
||||
horiz-adv-x="1000" d=" M500 820C223.75 820 0 596.25 0 320C0 43.75 223.75 -180 500 -180C776.25 -180 1000 43.75 1000 320C1000 596.25 776.25 820 500 820zM800.625 19.375C761.25 -20 715.625 -50 665 -71.25C613.125 -93.75 557.5 -104.375 500 -104.375C442.5 -104.375 386.875 -93.75 335 -71.25C284.375 -50 238.125 -19.375 199.375 19.375C160.625 58.125 130 104.375 108.75 155C86.25 206.875 75.625 262.5 75.625 320C75.625 377.5 86.25 433.125 108.75 485C130 535.625 160.625 581.875 199.375 620.625C238.125 659.375 284.375 690 335 711.25C386.875 733.75 442.5 744.375 500 744.375C557.5 744.375 613.125 733.75 665 711.25C715.625 690 761.875 659.375 800.625 620.625C839.375 581.875 870 535.625 891.25 485C913.75 433.125 924.375 377.5 924.375 320C924.375 262.5 913.75 206.875 891.25 155C870 104.375 839.375 58.125 800.625 19.375zM250 395V431.875C250 473.125 283.125 506.25 325 506.25H361.875C403.125 506.25 436.25 473.125 436.25 431.875V395C436.25 353.125 403.125 320 361.875 320H325C283.125 320 250 353.125 250 395zM562.5 395V431.875C562.5 473.125 595.625 506.25 637.5 506.25H674.375C715.625 506.25 748.75 473.125 748.75 431.875V395C748.75 353.125 715.625 320 674.375 320H637.5C595.625 320 562.5 353.125 562.5 395zM812.5 195C767.5 77.5 630.625 7.5 500 7.5C369.375 7.5 232.5 78.125 187.5 195C178.75 219.375 201.875 257.5 228.75 257.5H765.625C791.25 257.5 821.25 219.375 812.5 195z" />
|
||||
<glyph glyph-name="smiley"
|
||||
unicode=""
|
||||
@@ -566,7 +566,7 @@
|
||||
unicode=""
|
||||
horiz-adv-x="875" d=" M812.5 632.5H437.5C403.125 632.5 375 604.375 375 570V70C375 35.625 403.125 7.5 437.5 7.5H812.5C846.875 7.5 875 35.625 875 70V570C875 604.375 846.875 632.5 812.5 632.5zM750 132.5H500V507.5H750V132.5zM250 570H312.5V507.5H250V132.5H312.5V70H250C215.625 70 187.5 98.125 187.5 132.5V507.5C187.5 541.875 215.625 570 250 570zM62.5 507.5H125V445H62.5V195H125V132.5H62.5C28.125 132.5 0 160.625 0 195V445C0 479.375 28.125 507.5 62.5 507.5z" />
|
||||
<glyph glyph-name="warning"
|
||||
unicode=""
|
||||
unicode=""
|
||||
horiz-adv-x="1000" d=" M543.75 757.5H456.25L62.5 -30L150 -117.5H850L937.5 -30L543.75 757.5zM543.75 -30H456.25V57.5H543.75V-30zM543.75 145H456.25V495H543.75V145z" />
|
||||
<glyph glyph-name="watch"
|
||||
unicode=""
|
||||
|
||||
|
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 130 KiB |
Binary file not shown.
251
src/vs/base/browser/ui/octiconLabel/octicons/octicons2.css
Normal file
251
src/vs/base/browser/ui/octiconLabel/octicons/octicons2.css
Normal file
@@ -0,0 +1,251 @@
|
||||
@font-face {
|
||||
font-family: "octicons2";
|
||||
src: url("./octicons2.ttf?064476e75412ccad4ae99d4bf24539b4") format("truetype"),
|
||||
url("./octicons2.svg?064476e75412ccad4ae99d4bf24539b4#octicons2") format("svg");
|
||||
}
|
||||
|
||||
.octicon, .mega-octicon {
|
||||
font: normal normal normal 16px/1 octicons2;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
text-rendering: auto;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.mega-octicon { font-size: 32px; }
|
||||
|
||||
|
||||
|
||||
.octicon-alert:before { content: "\f02d" }
|
||||
.octicon-arrow-down:before { content: "\f03f" }
|
||||
.octicon-arrow-left:before { content: "\f040" }
|
||||
.octicon-arrow-right:before { content: "\f03e" }
|
||||
.octicon-arrow-small-down:before { content: "\f0a0" }
|
||||
.octicon-arrow-small-left:before { content: "\f0a1" }
|
||||
.octicon-arrow-small-right:before { content: "\f071" }
|
||||
.octicon-arrow-small-up:before { content: "\f09f" }
|
||||
.octicon-arrow-up:before { content: "\f03d" }
|
||||
.octicon-beaker:before { content: "\f0dd" }
|
||||
.octicon-bell:before { content: "\f0de" }
|
||||
.octicon-bold:before { content: "\f282" }
|
||||
.octicon-book:before { content: "\f007" }
|
||||
.octicon-bookmark:before { content: "\f07b" }
|
||||
.octicon-briefcase:before { content: "\f0d3" }
|
||||
.octicon-broadcast:before { content: "\f048" }
|
||||
.octicon-browser:before { content: "\f0c5" }
|
||||
.octicon-bug:before { content: "\f091" }
|
||||
.octicon-calendar:before { content: "\f068" }
|
||||
.octicon-check:before { content: "\f03a" }
|
||||
.octicon-checklist:before { content: "\f076" }
|
||||
.octicon-chevron-down:before { content: "\f0a3" }
|
||||
.octicon-chevron-left:before { content: "\f0a4" }
|
||||
.octicon-chevron-right:before { content: "\f078" }
|
||||
.octicon-chevron-up:before { content: "\f0a2" }
|
||||
.octicon-circle-slash:before { content: "\f084" }
|
||||
.octicon-circuit-board:before { content: "\f0d6" }
|
||||
.octicon-clippy:before { content: "\f035" }
|
||||
.octicon-clock:before { content: "\f046" }
|
||||
.octicon-clone:before { content: "\f0dc" }
|
||||
.octicon-cloud-download:before { content: "\f00b" }
|
||||
.octicon-cloud-upload:before { content: "\f00c" }
|
||||
.octicon-code:before { content: "\f05f" }
|
||||
.octicon-color-mode:before { content: "\f065" }
|
||||
.octicon-comment-add:before { content: "\f02b" }
|
||||
.octicon-comment-discussion:before { content: "\f04f" }
|
||||
.octicon-comment:before { content: "\f02b" }
|
||||
.octicon-credit-card:before { content: "\f045" }
|
||||
.octicon-dash:before { content: "\f0ca" }
|
||||
.octicon-dashboard:before { content: "\f07d" }
|
||||
.octicon-database:before { content: "\f096" }
|
||||
.octicon-desktop-download:before { content: "\f0dc" }
|
||||
.octicon-device-camera-video:before { content: "\f057" }
|
||||
.octicon-device-camera:before { content: "\f056" }
|
||||
.octicon-device-desktop:before { content: "\f27c" }
|
||||
.octicon-device-mobile:before { content: "\f038" }
|
||||
.octicon-diff-added:before { content: "\f06b" }
|
||||
.octicon-diff-ignored:before { content: "\f099" }
|
||||
.octicon-diff-modified:before { content: "\f06d" }
|
||||
.octicon-diff-removed:before { content: "\f06c" }
|
||||
.octicon-diff-renamed:before { content: "\f06e" }
|
||||
.octicon-diff:before { content: "\f04d" }
|
||||
.octicon-ellipsis:before { content: "\f09a" }
|
||||
.octicon-eye-unwatch:before { content: "\f04e" }
|
||||
.octicon-eye-watch:before { content: "\f04e" }
|
||||
.octicon-eye:before { content: "\f04e" }
|
||||
.octicon-file-add:before { content: "\f05d" }
|
||||
.octicon-file-binary:before { content: "\f094" }
|
||||
.octicon-file-code:before { content: "\f010" }
|
||||
.octicon-file-directory-create:before { content: "\f05d" }
|
||||
.octicon-file-directory:before { content: "\f016" }
|
||||
.octicon-file-media:before { content: "\f012" }
|
||||
.octicon-file-pdf:before { content: "\f014" }
|
||||
.octicon-file-submodule:before { content: "\f017" }
|
||||
.octicon-file-symlink-directory:before { content: "\f0b1" }
|
||||
.octicon-file-symlink-file:before { content: "\f0b0" }
|
||||
.octicon-file-text:before { content: "\f283" }
|
||||
.octicon-file-zip:before { content: "\f013" }
|
||||
.octicon-file:before { content: "\f283" }
|
||||
.octicon-flame:before { content: "\f0d2" }
|
||||
.octicon-fold:before { content: "\f0cc" }
|
||||
.octicon-gear:before { content: "\f02f" }
|
||||
.octicon-gift:before { content: "\f042" }
|
||||
.octicon-gist-fork:before { content: "\f002" }
|
||||
.octicon-gist-new:before { content: "\f05d" }
|
||||
.octicon-gist-private:before { content: "\f06a" }
|
||||
.octicon-gist-secret:before { content: "\f08c" }
|
||||
.octicon-gist:before { content: "\f00e" }
|
||||
.octicon-git-branch-create:before { content: "\f020" }
|
||||
.octicon-git-branch-delete:before { content: "\f020" }
|
||||
.octicon-git-branch:before { content: "\f020" }
|
||||
.octicon-git-commit:before { content: "\f01f" }
|
||||
.octicon-git-compare:before { content: "\f0ac" }
|
||||
.octicon-git-fork-private:before { content: "\f06a" }
|
||||
.octicon-git-merge:before { content: "\f023" }
|
||||
.octicon-git-pull-request-abandoned:before { content: "\f009" }
|
||||
.octicon-git-pull-request:before { content: "\f009" }
|
||||
.octicon-globe:before { content: "\f0b6" }
|
||||
.octicon-grabber:before { content: "\f284" }
|
||||
.octicon-graph:before { content: "\f043" }
|
||||
.octicon-heart:before { content: "\2665" }
|
||||
.octicon-history:before { content: "\f07e" }
|
||||
.octicon-home:before { content: "\f08d" }
|
||||
.octicon-horizontal-rule:before { content: "\f070" }
|
||||
.octicon-hubot:before { content: "\f09d" }
|
||||
.octicon-inbox:before { content: "\f0cf" }
|
||||
.octicon-info:before { content: "\f059" }
|
||||
.octicon-issue-closed:before { content: "\f028" }
|
||||
.octicon-issue-opened:before { content: "\f026" }
|
||||
.octicon-issue-reopened:before { content: "\f027" }
|
||||
.octicon-italic:before { content: "\f285" }
|
||||
.octicon-jersey:before { content: "\f019" }
|
||||
.octicon-kebab-horizontal:before { content: "\f286" }
|
||||
.octicon-kebab-vertical:before { content: "\f287" }
|
||||
.octicon-key:before { content: "\f049" }
|
||||
.octicon-keyboard:before { content: "\f00d" }
|
||||
.octicon-law:before { content: "\f0d8" }
|
||||
.octicon-light-bulb:before { content: "\f000" }
|
||||
.octicon-link-external:before { content: "\f07f" }
|
||||
.octicon-link:before { content: "\f05c" }
|
||||
.octicon-list-ordered:before { content: "\f062" }
|
||||
.octicon-list-unordered:before { content: "\f061" }
|
||||
.octicon-location:before { content: "\f060" }
|
||||
.octicon-lock:before { content: "\f06a" }
|
||||
.octicon-log-in:before { content: "\f036" }
|
||||
.octicon-log-out:before { content: "\f032" }
|
||||
.octicon-logo-gist:before { content: "\f288" }
|
||||
.octicon-logo-github:before { content: "\f092" }
|
||||
.octicon-mail-read:before { content: "\f03c" }
|
||||
.octicon-mail-reply:before { content: "\f28c" }
|
||||
.octicon-mail:before { content: "\f03b" }
|
||||
.octicon-mark-github:before { content: "\f00a" }
|
||||
.octicon-markdown:before { content: "\f0c9" }
|
||||
.octicon-megaphone:before { content: "\f077" }
|
||||
.octicon-mention:before { content: "\f0be" }
|
||||
.octicon-microscope:before { content: "\f0dd" }
|
||||
.octicon-milestone:before { content: "\f075" }
|
||||
.octicon-mirror-private:before { content: "\f06a" }
|
||||
.octicon-mirror-public:before { content: "\f024" }
|
||||
.octicon-mirror:before { content: "\f024" }
|
||||
.octicon-mortar-board:before { content: "\f0d7" }
|
||||
.octicon-mute:before { content: "\f080" }
|
||||
.octicon-no-newline:before { content: "\f09c" }
|
||||
.octicon-note:before { content: "\f289" }
|
||||
.octicon-octoface:before { content: "\f008" }
|
||||
.octicon-organization:before { content: "\f037" }
|
||||
.octicon-organization-filled:before { content: "\26a2" }
|
||||
.octicon-organization-outline:before { content: "\f037" }
|
||||
.octicon-package:before { content: "\f0c4" }
|
||||
.octicon-paintcan:before { content: "\f0d1" }
|
||||
.octicon-pencil:before { content: "\f058" }
|
||||
.octicon-person-add:before { content: "\f018" }
|
||||
.octicon-person-follow:before { content: "\f018" }
|
||||
.octicon-person:before { content: "\f018" }
|
||||
.octicon-person-filled:before { content: "\26a3" }
|
||||
.octicon-person-outline:before { content: "\f018" }
|
||||
.octicon-pin:before { content: "\f041" }
|
||||
.octicon-plug:before { content: "\f0d4" }
|
||||
.octicon-plus-small:before { content: "\f28a" }
|
||||
.octicon-plus:before { content: "\f05d" }
|
||||
.octicon-primitive-dot:before { content: "\f052" }
|
||||
.octicon-primitive-square:before { content: "\f053" }
|
||||
.octicon-project:before { content: "\f28b" }
|
||||
.octicon-pulse:before { content: "\f085" }
|
||||
.octicon-question:before { content: "\f02c" }
|
||||
.octicon-quote:before { content: "\f063" }
|
||||
.octicon-radio-tower:before { content: "\f030" }
|
||||
.octicon-remove-close:before { content: "\f081" }
|
||||
.octicon-reply:before { content: "\f28c" }
|
||||
.octicon-repo-clone:before { content: "\f04c" }
|
||||
.octicon-repo-create:before { content: "\f05d" }
|
||||
.octicon-repo-delete:before { content: "\f001" }
|
||||
.octicon-repo-force-push:before { content: "\f04a" }
|
||||
.octicon-repo-forked:before { content: "\f002" }
|
||||
.octicon-repo-pull:before { content: "\f006" }
|
||||
.octicon-repo-push:before { content: "\f005" }
|
||||
.octicon-repo-sync:before { content: "\f087" }
|
||||
.octicon-repo:before { content: "\f001" }
|
||||
.octicon-report:before { content: "\f28d" }
|
||||
.octicon-rocket:before { content: "\f033" }
|
||||
.octicon-rss:before { content: "\f034" }
|
||||
.octicon-ruby:before { content: "\f047" }
|
||||
.octicon-screen-full:before { content: "\f066" }
|
||||
.octicon-screen-normal:before { content: "\f067" }
|
||||
.octicon-search-save:before { content: "\f02e" }
|
||||
.octicon-search:before { content: "\f02e" }
|
||||
.octicon-server:before { content: "\f097" }
|
||||
.octicon-settings:before { content: "\f07c" }
|
||||
.octicon-shield:before { content: "\f0e1" }
|
||||
.octicon-sign-in:before { content: "\f036" }
|
||||
.octicon-sign-out:before { content: "\f032" }
|
||||
.octicon-smiley:before { content: "\f27d" }
|
||||
.octicon-squirrel:before { content: "\f0b2" }
|
||||
.octicon-star-add:before { content: "\f02a" }
|
||||
.octicon-star-delete:before { content: "\f02a" }
|
||||
.octicon-star:before { content: "\f02a" }
|
||||
.octicon-stop:before { content: "\f08f" }
|
||||
.octicon-sync:before { content: "\f087" }
|
||||
.octicon-tag-add:before { content: "\f015" }
|
||||
.octicon-tag-remove:before { content: "\f015" }
|
||||
.octicon-tag:before { content: "\f015" }
|
||||
.octicon-tasklist:before { content: "\f27e" }
|
||||
.octicon-telescope:before { content: "\f088" }
|
||||
.octicon-terminal:before { content: "\f0c8" }
|
||||
.octicon-text-size:before { content: "\f27f" }
|
||||
.octicon-three-bars:before { content: "\f05e" }
|
||||
.octicon-thumbsdown:before { content: "\f0db" }
|
||||
.octicon-thumbsup:before { content: "\f0da" }
|
||||
.octicon-tools:before { content: "\f031" }
|
||||
.octicon-trashcan:before { content: "\f0d0" }
|
||||
.octicon-triangle-down:before { content: "\f05b" }
|
||||
.octicon-triangle-left:before { content: "\f044" }
|
||||
.octicon-triangle-right:before { content: "\f05a" }
|
||||
.octicon-triangle-up:before { content: "\f0aa" }
|
||||
.octicon-unfold:before { content: "\f039" }
|
||||
.octicon-unmute:before { content: "\f0ba" }
|
||||
.octicon-unverified:before { content: "\f280" }
|
||||
.octicon-verified:before { content: "\f281" }
|
||||
.octicon-versions:before { content: "\f064" }
|
||||
.octicon-watch:before { content: "\f0e0" }
|
||||
.octicon-x:before { content: "\f081" }
|
||||
.octicon-zap:before { content: "\26a1" }
|
||||
.octicon-error:before { content: "\26a2" }
|
||||
.octicon-eye-closed:before { content: "\26a3" }
|
||||
.octicon-fold-down:before { content: "\26a4" }
|
||||
.octicon-fold-up:before { content: "\26a5" }
|
||||
.octicon-github-action:before { content: "\26a6" }
|
||||
.octicon-info-outline:before { content: "\26a7" }
|
||||
.octicon-play:before { content: "\26a8" }
|
||||
.octicon-remote:before { content: "\26a9" }
|
||||
.octicon-request-changes:before { content: "\26aa" }
|
||||
.octicon-smiley-outline:before { content: "\f27d" }
|
||||
.octicon-warning:before { content: "\f02d" }
|
||||
.octicon-controls:before { content: "\26ad" }
|
||||
.octicon-event:before { content: "\26ae" }
|
||||
.octicon-record-keys:before { content: "\26af" }
|
||||
.octicon-archive:before { content: "\f101" }
|
||||
.octicon-arrow-both:before { content: "\f102" }
|
||||
570
src/vs/base/browser/ui/octiconLabel/octicons/octicons2.svg
Normal file
570
src/vs/base/browser/ui/octiconLabel/octicons/octicons2.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 222 KiB |
BIN
src/vs/base/browser/ui/octiconLabel/octicons/octicons2.ttf
Normal file
BIN
src/vs/base/browser/ui/octiconLabel/octicons/octicons2.ttf
Normal file
Binary file not shown.
@@ -194,3 +194,13 @@ export function getErrorMessage(err: any): string {
|
||||
|
||||
return String(err);
|
||||
}
|
||||
|
||||
|
||||
export class NotImplementedError extends Error {
|
||||
constructor(message?: string) {
|
||||
super('NotImplemented');
|
||||
if (message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
export namespace Schemas {
|
||||
|
||||
/**
|
||||
@@ -62,13 +64,26 @@ class RemoteAuthoritiesImpl {
|
||||
}
|
||||
|
||||
public set(authority: string, host: string, port: number): void {
|
||||
this._hosts[authority] = host;
|
||||
this._hosts[authority] = (host === 'localhost' ? '127.0.0.1' : host);
|
||||
this._ports[authority] = port;
|
||||
}
|
||||
|
||||
public setConnectionToken(authority: string, connectionToken: string): void {
|
||||
this._connectionTokens[authority] = connectionToken;
|
||||
}
|
||||
|
||||
public rewrite(authority: string, path: string): URI {
|
||||
const host = this._hosts[authority];
|
||||
const port = this._ports[authority];
|
||||
const connectionToken = this._connectionTokens[authority];
|
||||
const scheme = (host === '127.0.0.1' ? Schemas.http : Schemas.vscodeRemote);
|
||||
return URI.from({
|
||||
scheme: scheme,
|
||||
authority: `${host}:${port}`,
|
||||
path: `/vscode-remote2`,
|
||||
query: `path=${encodeURIComponent(path)}&tkn=${encodeURIComponent(connectionToken)}`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const RemoteAuthorities = new RemoteAuthoritiesImpl();
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<!-- {{SQL CARBON EDIT}} @anthonydresser add 'unsafe-eval' under script src; since its required by angular -->
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self' https: data: blob: vscode-remote:; media-src 'none'; frame-src 'self' https://*.vscode-webview-test.com; object-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self' https:; font-src 'self' https: vscode-remote:;">
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self' https: data: blob: vscode-remote: http://127.0.0.1:*; media-src 'none'; frame-src 'self' https://*.vscode-webview-test.com; object-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self' https:; font-src 'self' https: vscode-remote: http://127.0.0.1:*;">
|
||||
</head>
|
||||
<body class="vs-dark" aria-label="">
|
||||
</body>
|
||||
|
||||
@@ -39,7 +39,6 @@ import { ProxyAuthHandler } from 'vs/code/electron-main/auth';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IWindowsMainService, ICodeWindow } from 'vs/platform/windows/electron-main/windows';
|
||||
import { IHistoryMainService } from 'vs/platform/history/common/history';
|
||||
import { withUndefinedAsNull } from 'vs/base/common/types';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { WorkspacesChannel } from 'vs/platform/workspaces/node/workspacesIpc';
|
||||
import { IWorkspacesMainService, hasWorkspaceFileExtension } from 'vs/platform/workspaces/common/workspaces';
|
||||
@@ -54,7 +53,6 @@ import { LogLevelSetterChannel } from 'vs/platform/log/common/logIpc';
|
||||
import { setUnexpectedErrorHandler, onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { ElectronURLListener } from 'vs/platform/url/electron-main/electronUrlListener';
|
||||
import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver';
|
||||
import { connectRemoteAgentManagement, ManagementPersistentConnection, IConnectionOptions } from 'vs/platform/remote/common/remoteAgentConnection';
|
||||
import { IMenubarService } from 'vs/platform/menubar/common/menubar';
|
||||
import { MenubarService } from 'vs/platform/menubar/electron-main/menubarService';
|
||||
import { MenubarChannel } from 'vs/platform/menubar/node/menubarIpc';
|
||||
@@ -65,8 +63,6 @@ import { homedir } from 'os';
|
||||
import { join, sep } from 'vs/base/common/path';
|
||||
import { localize } from 'vs/nls';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { REMOTE_FILE_SYSTEM_CHANNEL_NAME } from 'vs/platform/remote/common/remoteAgentFileSystemChannel';
|
||||
import { ResolvedAuthority } from 'vs/platform/remote/common/remoteAuthorityResolver';
|
||||
import { SnapUpdateService } from 'vs/platform/update/electron-main/updateService.snap';
|
||||
import { IStorageMainService, StorageMainService } from 'vs/platform/storage/node/storageMainService';
|
||||
import { GlobalStorageDatabaseChannel } from 'vs/platform/storage/node/storageIpc';
|
||||
@@ -76,11 +72,7 @@ import { IBackupMainService } from 'vs/platform/backup/common/backup';
|
||||
import { HistoryMainService } from 'vs/platform/history/electron-main/historyMainService';
|
||||
import { URLService } from 'vs/platform/url/common/urlService';
|
||||
import { WorkspacesMainService } from 'vs/platform/workspaces/electron-main/workspacesMainService';
|
||||
import { RemoteAgentConnectionContext } from 'vs/platform/remote/common/remoteAgentEnvironment';
|
||||
import { nodeSocketFactory } from 'vs/platform/remote/node/nodeSocketFactory';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { statSync } from 'fs';
|
||||
import { ISignService } from 'vs/platform/sign/common/sign';
|
||||
import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsIpc';
|
||||
import { IDiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsService';
|
||||
import { FileService } from 'vs/platform/files/common/fileService';
|
||||
@@ -103,8 +95,7 @@ export class CodeApplication extends Disposable {
|
||||
@IEnvironmentService private readonly environmentService: IEnvironmentService,
|
||||
@ILifecycleService private readonly lifecycleService: ILifecycleService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IStateService private readonly stateService: IStateService,
|
||||
@ISignService private readonly signService: ISignService
|
||||
@IStateService private readonly stateService: IStateService
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -167,11 +158,13 @@ export class CodeApplication extends Disposable {
|
||||
event.preventDefault();
|
||||
});
|
||||
app.on('remote-get-current-web-contents', event => {
|
||||
// The driver needs access to web contents
|
||||
if (!this.environmentService.args.driver) {
|
||||
this.logService.trace(`App#on(remote-get-current-web-contents): prevented`);
|
||||
event.preventDefault();
|
||||
if (this.environmentService.args.driver) {
|
||||
return; // the driver needs access to web contents
|
||||
}
|
||||
|
||||
this.logService.trace(`App#on(remote-get-current-web-contents): prevented`);
|
||||
|
||||
event.preventDefault();
|
||||
});
|
||||
app.on('web-contents-created', (_event: Electron.Event, contents) => {
|
||||
contents.on('will-attach-webview', (event: Electron.Event, webPreferences, params) => {
|
||||
@@ -695,112 +688,11 @@ export class CodeApplication extends Disposable {
|
||||
}
|
||||
|
||||
private handleRemoteAuthorities(): void {
|
||||
const connectionPool: Map<string, ActiveConnection> = new Map<string, ActiveConnection>();
|
||||
|
||||
class ActiveConnection {
|
||||
private readonly _authority: string;
|
||||
private readonly _connection: Promise<ManagementPersistentConnection>;
|
||||
private readonly _disposeRunner: RunOnceScheduler;
|
||||
|
||||
constructor(authority: string, host: string, port: number, signService: ISignService) {
|
||||
this._authority = authority;
|
||||
|
||||
const options: IConnectionOptions = {
|
||||
commit: product.commit,
|
||||
socketFactory: nodeSocketFactory,
|
||||
addressProvider: {
|
||||
getAddress: () => {
|
||||
return Promise.resolve({ host, port });
|
||||
}
|
||||
},
|
||||
signService
|
||||
};
|
||||
|
||||
this._connection = connectRemoteAgentManagement(options, authority, `main`);
|
||||
this._disposeRunner = new RunOnceScheduler(() => this.dispose(), 5000);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._disposeRunner.dispose();
|
||||
connectionPool.delete(this._authority);
|
||||
this._connection.then(connection => connection.dispose());
|
||||
}
|
||||
|
||||
async getClient(): Promise<Client<RemoteAgentConnectionContext>> {
|
||||
this._disposeRunner.schedule();
|
||||
const connection = await this._connection;
|
||||
|
||||
return connection.client;
|
||||
}
|
||||
}
|
||||
|
||||
const resolvedAuthorities = new Map<string, ResolvedAuthority>();
|
||||
ipc.on('vscode:remoteAuthorityResolved', (event: Electron.Event, data: ResolvedAuthority) => {
|
||||
this.logService.info('Received resolved authority', data.authority);
|
||||
|
||||
resolvedAuthorities.set(data.authority, data);
|
||||
|
||||
// Make sure to close and remove any existing connections
|
||||
if (connectionPool.has(data.authority)) {
|
||||
connectionPool.get(data.authority)!.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
const resolveAuthority = (authority: string): ResolvedAuthority | null => {
|
||||
this.logService.info('Resolving authority', authority);
|
||||
|
||||
if (authority.indexOf('+') >= 0) {
|
||||
if (resolvedAuthorities.has(authority)) {
|
||||
return withUndefinedAsNull(resolvedAuthorities.get(authority));
|
||||
}
|
||||
|
||||
this.logService.info('Didnot find resolved authority for', authority);
|
||||
|
||||
return null;
|
||||
} else {
|
||||
const [host, strPort] = authority.split(':');
|
||||
const port = parseInt(strPort, 10);
|
||||
|
||||
return { authority, host, port };
|
||||
}
|
||||
};
|
||||
|
||||
protocol.registerBufferProtocol(Schemas.vscodeRemote, async (request, callback) => {
|
||||
if (request.method !== 'GET') {
|
||||
return callback(undefined);
|
||||
}
|
||||
|
||||
const uri = URI.parse(request.url);
|
||||
|
||||
let activeConnection: ActiveConnection | undefined;
|
||||
if (connectionPool.has(uri.authority)) {
|
||||
activeConnection = connectionPool.get(uri.authority);
|
||||
} else {
|
||||
const resolvedAuthority = resolveAuthority(uri.authority);
|
||||
if (!resolvedAuthority) {
|
||||
callback(undefined);
|
||||
return;
|
||||
}
|
||||
|
||||
activeConnection = new ActiveConnection(uri.authority, resolvedAuthority.host, resolvedAuthority.port, this.signService);
|
||||
connectionPool.set(uri.authority, activeConnection);
|
||||
}
|
||||
|
||||
try {
|
||||
const rawClient = await activeConnection!.getClient();
|
||||
if (connectionPool.has(uri.authority)) { // not disposed in the meantime
|
||||
const channel = rawClient.getChannel(REMOTE_FILE_SYSTEM_CHANNEL_NAME);
|
||||
|
||||
// TODO@alex don't use call directly, wrap it around a `RemoteExtensionsFileSystemProvider`
|
||||
const fileContents = await channel.call<VSBuffer>('readFile', [uri]);
|
||||
callback(<Buffer>fileContents.buffer);
|
||||
} else {
|
||||
callback(undefined);
|
||||
}
|
||||
} catch (err) {
|
||||
onUnexpectedError(err);
|
||||
callback(undefined);
|
||||
}
|
||||
protocol.registerHttpProtocol(Schemas.vscodeRemote, (request, callback) => {
|
||||
callback({
|
||||
url: request.url.replace(/^vscode-remote:/, 'http:'),
|
||||
method: request.method
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,11 +229,11 @@ const _CSS_MAP: { [prop: string]: string; } = {
|
||||
cursor: 'cursor:{0};',
|
||||
letterSpacing: 'letter-spacing:{0};',
|
||||
|
||||
gutterIconPath: 'background:url(\'{0}\') center center no-repeat;',
|
||||
gutterIconPath: 'background:{0} center center no-repeat;',
|
||||
gutterIconSize: 'background-size:{0};',
|
||||
|
||||
contentText: 'content:\'{0}\';',
|
||||
contentIconPath: 'content:url(\'{0}\');',
|
||||
contentIconPath: 'content:{0};',
|
||||
margin: 'margin:{0};',
|
||||
width: 'width:{0};',
|
||||
height: 'height:{0};'
|
||||
@@ -399,7 +399,7 @@ class DecorationCSSRules {
|
||||
if (typeof opts !== 'undefined') {
|
||||
this.collectBorderSettingsCSSText(opts, cssTextArr);
|
||||
if (typeof opts.contentIconPath !== 'undefined') {
|
||||
cssTextArr.push(strings.format(_CSS_MAP.contentIconPath, dom.asDomUri(URI.revive(opts.contentIconPath)).toString(true).replace(/'/g, '%27')));
|
||||
cssTextArr.push(strings.format(_CSS_MAP.contentIconPath, dom.asCSSUrl(URI.revive(opts.contentIconPath))));
|
||||
}
|
||||
if (typeof opts.contentText === 'string') {
|
||||
const truncated = opts.contentText.match(/^.*$/m)![0]; // only take first line
|
||||
@@ -426,7 +426,7 @@ class DecorationCSSRules {
|
||||
const cssTextArr: string[] = [];
|
||||
|
||||
if (typeof opts.gutterIconPath !== 'undefined') {
|
||||
cssTextArr.push(strings.format(_CSS_MAP.gutterIconPath, dom.asDomUri(URI.revive(opts.gutterIconPath)).toString(true).replace(/'/g, '%27')));
|
||||
cssTextArr.push(strings.format(_CSS_MAP.gutterIconPath, dom.asCSSUrl(URI.revive(opts.gutterIconPath))));
|
||||
if (typeof opts.gutterIconSize !== 'undefined') {
|
||||
cssTextArr.push(strings.format(_CSS_MAP.gutterIconSize, opts.gutterIconSize));
|
||||
}
|
||||
|
||||
@@ -192,9 +192,6 @@ export abstract class ZoneWidget implements IHorizontalSashLayoutProvider {
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
|
||||
this._disposables.dispose();
|
||||
|
||||
if (this._overlayWidget) {
|
||||
this.editor.removeOverlayWidget(this._overlayWidget);
|
||||
this._overlayWidget = null;
|
||||
@@ -211,6 +208,8 @@ export abstract class ZoneWidget implements IHorizontalSashLayoutProvider {
|
||||
|
||||
this.editor.deltaDecorations(this._positionMarkerId, []);
|
||||
this._positionMarkerId = [];
|
||||
|
||||
this._disposables.dispose();
|
||||
}
|
||||
|
||||
public create(): void {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { addClasses, createCSSRule, removeClasses, asDomUri } from 'vs/base/browser/dom';
|
||||
import { addClasses, createCSSRule, removeClasses, asCSSUrl } from 'vs/base/browser/dom';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { ActionViewItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
@@ -245,8 +245,8 @@ export class MenuEntryActionViewItem extends ActionViewItem {
|
||||
iconClass = MenuEntryActionViewItem.ICON_PATH_TO_CSS_RULES.get(iconPathMapKey)!;
|
||||
} else {
|
||||
iconClass = ids.nextId();
|
||||
createCSSRule(`.icon.${iconClass}`, `background-image: url("${asDomUri(item.iconLocation.light || item.iconLocation.dark).toString()}")`);
|
||||
createCSSRule(`.vs-dark .icon.${iconClass}, .hc-black .icon.${iconClass}`, `background-image: url("${asDomUri(item.iconLocation.dark).toString()}")`);
|
||||
createCSSRule(`.icon.${iconClass}`, `background-image: ${asCSSUrl(item.iconLocation.light || item.iconLocation.dark)}`);
|
||||
createCSSRule(`.vs-dark .icon.${iconClass}, .hc-black .icon.${iconClass}`, `background-image: ${asCSSUrl(item.iconLocation.dark)}`);
|
||||
MenuEntryActionViewItem.ICON_PATH_TO_CSS_RULES.set(iconPathMapKey, iconClass);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,19 @@ export interface INotificationProperties {
|
||||
neverShowAgain?: INeverShowAgainOptions;
|
||||
}
|
||||
|
||||
export enum NeverShowAgainScope {
|
||||
|
||||
/**
|
||||
* Will never show this notification on the current workspace again.
|
||||
*/
|
||||
WORKSPACE,
|
||||
|
||||
/**
|
||||
* Will never show this notification on any workspace again.
|
||||
*/
|
||||
GLOBAL
|
||||
}
|
||||
|
||||
export interface INeverShowAgainOptions {
|
||||
|
||||
/**
|
||||
@@ -49,6 +62,12 @@ export interface INeverShowAgainOptions {
|
||||
* make it a secondary action instead.
|
||||
*/
|
||||
isSecondary?: boolean;
|
||||
|
||||
/**
|
||||
* Wether to persist the choice in the current workspace or for all workspaces. By
|
||||
* default it will be persisted for all workspaces.
|
||||
*/
|
||||
scope?: NeverShowAgainScope;
|
||||
}
|
||||
|
||||
export interface INotification extends INotificationProperties {
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ResolvedAuthority, IRemoteAuthorityResolverService, ResolverResult, ResolvedOptions } from 'vs/platform/remote/common/remoteAuthorityResolver';
|
||||
import { ipcRenderer as ipc } from 'electron';
|
||||
import * as errors from 'vs/base/common/errors';
|
||||
import { RemoteAuthorities } from 'vs/base/common/network';
|
||||
|
||||
@@ -50,7 +49,6 @@ export class RemoteAuthorityResolverService implements IRemoteAuthorityResolverS
|
||||
setResolvedAuthority(resolvedAuthority: ResolvedAuthority, options?: ResolvedOptions) {
|
||||
if (this._resolveAuthorityRequests[resolvedAuthority.authority]) {
|
||||
let request = this._resolveAuthorityRequests[resolvedAuthority.authority];
|
||||
ipc.send('vscode:remoteAuthorityResolved', resolvedAuthority);
|
||||
RemoteAuthorities.set(resolvedAuthority.authority, resolvedAuthority.host, resolvedAuthority.port);
|
||||
request.resolve({ authority: resolvedAuthority, options });
|
||||
}
|
||||
|
||||
@@ -5,15 +5,17 @@
|
||||
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IWorkspaceStorageChangeEvent, IStorageService, StorageScope, IWillSaveStateEvent, WillSaveStateReason, logStorage, FileStorageDatabase } from 'vs/platform/storage/common/storage';
|
||||
import { IWorkspaceStorageChangeEvent, IStorageService, StorageScope, IWillSaveStateEvent, WillSaveStateReason, logStorage } from 'vs/platform/storage/common/storage';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IWorkspaceInitializationPayload } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IStorage, Storage } from 'vs/base/parts/storage/common/storage';
|
||||
import { IFileService, FileChangeType } from 'vs/platform/files/common/files';
|
||||
import { IStorage, Storage, IStorageDatabase, IStorageItemsChangeEvent, IUpdateRequest } from 'vs/base/parts/storage/common/storage';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { joinPath } from 'vs/base/common/resources';
|
||||
import { runWhenIdle } from 'vs/base/common/async';
|
||||
import { runWhenIdle, RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { serializableToMap, mapToSerializable } from 'vs/base/common/map';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
|
||||
export class BrowserStorageService extends Disposable implements IStorageService {
|
||||
|
||||
@@ -35,6 +37,7 @@ export class BrowserStorageService extends Disposable implements IStorageService
|
||||
private workspaceStorageFile: URI;
|
||||
|
||||
private initializePromise: Promise<void>;
|
||||
private periodicSaveScheduler = this._register(new RunOnceScheduler(() => this.saveState(), 5000));
|
||||
|
||||
get hasPendingUpdate(): boolean {
|
||||
return this.globalStorageDatabase.hasPendingUpdate || this.workspaceStorageDatabase.hasPendingUpdate;
|
||||
@@ -51,20 +54,23 @@ export class BrowserStorageService extends Disposable implements IStorageService
|
||||
// long running operation.
|
||||
// Instead, periodically ask customers to save save. The library will be clever enough
|
||||
// to only save state that has actually changed.
|
||||
this.saveStatePeriodically();
|
||||
this.periodicSaveScheduler.schedule();
|
||||
}
|
||||
|
||||
private saveStatePeriodically(): void {
|
||||
setTimeout(() => {
|
||||
runWhenIdle(() => {
|
||||
private saveState(): void {
|
||||
runWhenIdle(() => {
|
||||
|
||||
// this event will potentially cause new state to be stored
|
||||
// this event will potentially cause new state to be stored
|
||||
// since new state will only be created while the document
|
||||
// has focus, one optimization is to not run this when the
|
||||
// document has no focus, assuming that state has not changed
|
||||
if (document.hasFocus()) {
|
||||
this._onWillSaveState.fire({ reason: WillSaveStateReason.NONE });
|
||||
}
|
||||
|
||||
// repeat
|
||||
this.saveStatePeriodically();
|
||||
});
|
||||
}, 5000);
|
||||
// repeat
|
||||
this.periodicSaveScheduler.schedule();
|
||||
});
|
||||
}
|
||||
|
||||
initialize(payload: IWorkspaceInitializationPayload): Promise<void> {
|
||||
@@ -83,14 +89,14 @@ export class BrowserStorageService extends Disposable implements IStorageService
|
||||
|
||||
// Workspace Storage
|
||||
this.workspaceStorageFile = joinPath(stateRoot, `${payload.id}.json`);
|
||||
this.workspaceStorageDatabase = this._register(new FileStorageDatabase(this.workspaceStorageFile, this.fileService));
|
||||
this.workspaceStorage = new Storage(this.workspaceStorageDatabase);
|
||||
this.workspaceStorageDatabase = this._register(new FileStorageDatabase(this.workspaceStorageFile, false /* do not watch for external changes */, this.fileService));
|
||||
this.workspaceStorage = this._register(new Storage(this.workspaceStorageDatabase));
|
||||
this._register(this.workspaceStorage.onDidChangeStorage(key => this._onDidChangeStorage.fire({ key, scope: StorageScope.WORKSPACE })));
|
||||
|
||||
// Global Storage
|
||||
this.globalStorageFile = joinPath(stateRoot, 'global.json');
|
||||
this.globalStorageDatabase = this._register(new FileStorageDatabase(this.globalStorageFile, this.fileService));
|
||||
this.globalStorage = new Storage(this.globalStorageDatabase);
|
||||
this.globalStorageDatabase = this._register(new FileStorageDatabase(this.globalStorageFile, true /* watch for external changes */, this.fileService));
|
||||
this.globalStorage = this._register(new Storage(this.globalStorageDatabase));
|
||||
this._register(this.globalStorage.onDidChangeStorage(key => this._onDidChangeStorage.fire({ key, scope: StorageScope.GLOBAL })));
|
||||
|
||||
// Init both
|
||||
@@ -140,14 +146,125 @@ export class BrowserStorageService extends Disposable implements IStorageService
|
||||
}
|
||||
|
||||
close(): void {
|
||||
|
||||
// Signal as event so that clients can still store data
|
||||
this._onWillSaveState.fire({ reason: WillSaveStateReason.SHUTDOWN });
|
||||
|
||||
// We explicitly do not close our DBs because writing data onBeforeUnload()
|
||||
// can result in unexpected results. Namely, it seems that - even though this
|
||||
// operation is async - sometimes it is being triggered on unload and
|
||||
// succeeds. Often though, the DBs turn out to be empty because the write
|
||||
// never had a chance to complete.
|
||||
//
|
||||
// Instead we trigger dispose() to ensure that no timeouts or callbacks
|
||||
// get triggered in this phase.
|
||||
this.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
export class FileStorageDatabase extends Disposable implements IStorageDatabase {
|
||||
|
||||
private readonly _onDidChangeItemsExternal: Emitter<IStorageItemsChangeEvent> = this._register(new Emitter<IStorageItemsChangeEvent>());
|
||||
readonly onDidChangeItemsExternal: Event<IStorageItemsChangeEvent> = this._onDidChangeItemsExternal.event;
|
||||
|
||||
private cache: Map<string, string> | undefined;
|
||||
|
||||
private pendingUpdate: Promise<void> = Promise.resolve();
|
||||
|
||||
private _hasPendingUpdate = false;
|
||||
get hasPendingUpdate(): boolean {
|
||||
return this._hasPendingUpdate;
|
||||
}
|
||||
|
||||
private isWatching = false;
|
||||
|
||||
constructor(
|
||||
private readonly file: URI,
|
||||
private readonly watchForExternalChanges: boolean,
|
||||
@IFileService private readonly fileService: IFileService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
private async ensureWatching(): Promise<void> {
|
||||
if (this.isWatching || !this.watchForExternalChanges) {
|
||||
return;
|
||||
}
|
||||
|
||||
const exists = await this.fileService.exists(this.file);
|
||||
if (this.isWatching || !exists) {
|
||||
return; // file must exist to be watched
|
||||
}
|
||||
|
||||
this.isWatching = true;
|
||||
|
||||
this._register(this.fileService.watch(this.file));
|
||||
this._register(this.fileService.onFileChanges(e => {
|
||||
if (document.hasFocus()) {
|
||||
return; // ignore changes from ourselves by checking for focus
|
||||
}
|
||||
|
||||
if (!e.contains(this.file, FileChangeType.UPDATED)) {
|
||||
return; // not our file
|
||||
}
|
||||
|
||||
this.onDidStorageChangeExternal();
|
||||
}));
|
||||
}
|
||||
|
||||
private async onDidStorageChangeExternal(): Promise<void> {
|
||||
const items = await this.doGetItemsFromFile();
|
||||
|
||||
this.cache = items;
|
||||
|
||||
this._onDidChangeItemsExternal.fire({ items });
|
||||
}
|
||||
|
||||
async getItems(): Promise<Map<string, string>> {
|
||||
if (!this.cache) {
|
||||
try {
|
||||
this.cache = await this.doGetItemsFromFile();
|
||||
} catch (error) {
|
||||
this.cache = new Map();
|
||||
}
|
||||
}
|
||||
|
||||
return this.cache;
|
||||
}
|
||||
|
||||
private async doGetItemsFromFile(): Promise<Map<string, string>> {
|
||||
await this.pendingUpdate;
|
||||
|
||||
const itemsRaw = await this.fileService.readFile(this.file);
|
||||
|
||||
this.ensureWatching(); // now that the file must exist, ensure we watch it for changes
|
||||
|
||||
return serializableToMap(JSON.parse(itemsRaw.value.toString()));
|
||||
}
|
||||
|
||||
async updateItems(request: IUpdateRequest): Promise<void> {
|
||||
const items = await this.getItems();
|
||||
|
||||
if (request.insert) {
|
||||
request.insert.forEach((value, key) => items.set(key, value));
|
||||
}
|
||||
|
||||
if (request.delete) {
|
||||
request.delete.forEach(key => items.delete(key));
|
||||
}
|
||||
|
||||
await this.pendingUpdate;
|
||||
|
||||
this._hasPendingUpdate = true;
|
||||
|
||||
this.pendingUpdate = this.fileService.writeFile(this.file, VSBuffer.fromString(JSON.stringify(mapToSerializable(items))))
|
||||
.then(() => {
|
||||
this.ensureWatching(); // now that the file must exist, ensure we watch it for changes
|
||||
})
|
||||
.finally(() => {
|
||||
this._hasPendingUpdate = false;
|
||||
});
|
||||
|
||||
return this.pendingUpdate;
|
||||
}
|
||||
|
||||
close(): Promise<void> {
|
||||
return this.pendingUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,11 +7,6 @@ import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/co
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { isUndefinedOrNull } from 'vs/base/common/types';
|
||||
import { IUpdateRequest, IStorageDatabase } from 'vs/base/parts/storage/common/storage';
|
||||
import { serializableToMap, mapToSerializable } from 'vs/base/common/map';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
|
||||
export const IStorageService = createDecorator<IStorageService>('storageService');
|
||||
|
||||
@@ -212,75 +207,6 @@ export class InMemoryStorageService extends Disposable implements IStorageServic
|
||||
}
|
||||
}
|
||||
|
||||
export class FileStorageDatabase extends Disposable implements IStorageDatabase {
|
||||
|
||||
readonly onDidChangeItemsExternal = Event.None; // TODO@Ben implement global UI storage events
|
||||
|
||||
private cache: Map<string, string> | undefined;
|
||||
|
||||
private pendingUpdate: Promise<void> = Promise.resolve();
|
||||
|
||||
private _hasPendingUpdate = false;
|
||||
get hasPendingUpdate(): boolean {
|
||||
return this._hasPendingUpdate;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly file: URI,
|
||||
private readonly fileService: IFileService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async getItems(): Promise<Map<string, string>> {
|
||||
if (!this.cache) {
|
||||
try {
|
||||
this.cache = await this.doGetItemsFromFile();
|
||||
} catch (error) {
|
||||
this.cache = new Map();
|
||||
}
|
||||
}
|
||||
|
||||
return this.cache;
|
||||
}
|
||||
|
||||
private async doGetItemsFromFile(): Promise<Map<string, string>> {
|
||||
await this.pendingUpdate;
|
||||
|
||||
const itemsRaw = await this.fileService.readFile(this.file);
|
||||
|
||||
return serializableToMap(JSON.parse(itemsRaw.value.toString()));
|
||||
}
|
||||
|
||||
async updateItems(request: IUpdateRequest): Promise<void> {
|
||||
const items = await this.getItems();
|
||||
|
||||
if (request.insert) {
|
||||
request.insert.forEach((value, key) => items.set(key, value));
|
||||
}
|
||||
|
||||
if (request.delete) {
|
||||
request.delete.forEach(key => items.delete(key));
|
||||
}
|
||||
|
||||
await this.pendingUpdate;
|
||||
|
||||
this._hasPendingUpdate = true;
|
||||
|
||||
this.pendingUpdate = this.fileService.writeFile(this.file, VSBuffer.fromString(JSON.stringify(mapToSerializable(items))))
|
||||
.then(() => undefined)
|
||||
.finally(() => {
|
||||
this._hasPendingUpdate = false;
|
||||
});
|
||||
|
||||
return this.pendingUpdate;
|
||||
}
|
||||
|
||||
close(): Promise<void> {
|
||||
return this.pendingUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
export async function logStorage(global: Map<string, string>, workspace: Map<string, string>, globalPath: string, workspacePath: string): Promise<void> {
|
||||
const safeParse = (value: string) => {
|
||||
try {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { equal } from 'assert';
|
||||
import { FileStorageDatabase } from 'vs/platform/storage/common/storage';
|
||||
import { FileStorageDatabase } from 'vs/platform/storage/browser/storageService';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { join } from 'vs/base/common/path';
|
||||
import { tmpdir } from 'os';
|
||||
@@ -49,7 +49,7 @@ suite('Storage', () => {
|
||||
});
|
||||
|
||||
test('File Based Storage', async () => {
|
||||
let storage = new Storage(new FileStorageDatabase(URI.file(join(testDir, 'storage.json')), fileService));
|
||||
let storage = new Storage(new FileStorageDatabase(URI.file(join(testDir, 'storage.json')), false, fileService));
|
||||
|
||||
await storage.init();
|
||||
|
||||
@@ -63,7 +63,7 @@ suite('Storage', () => {
|
||||
|
||||
await storage.close();
|
||||
|
||||
storage = new Storage(new FileStorageDatabase(URI.file(join(testDir, 'storage.json')), fileService));
|
||||
storage = new Storage(new FileStorageDatabase(URI.file(join(testDir, 'storage.json')), false, fileService));
|
||||
|
||||
await storage.init();
|
||||
|
||||
@@ -81,7 +81,7 @@ suite('Storage', () => {
|
||||
|
||||
await storage.close();
|
||||
|
||||
storage = new Storage(new FileStorageDatabase(URI.file(join(testDir, 'storage.json')), fileService));
|
||||
storage = new Storage(new FileStorageDatabase(URI.file(join(testDir, 'storage.json')), false, fileService));
|
||||
|
||||
await storage.init();
|
||||
|
||||
@@ -89,4 +89,4 @@ suite('Storage', () => {
|
||||
equal(storage.get('barNumber', 'undefinedNumber'), 'undefinedNumber');
|
||||
equal(storage.get('barBoolean', 'undefinedBoolean'), 'undefinedBoolean');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { URI as uri } from 'vs/base/common/uri';
|
||||
import { IDebugService, IConfig, IDebugConfigurationProvider, IBreakpoint, IFunctionBreakpoint, IBreakpointData, IDebugAdapter, IDebugAdapterDescriptorFactory, IDebugSession, IDebugAdapterFactory } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { IDebugService, IConfig, IDebugConfigurationProvider, IBreakpoint, IFunctionBreakpoint, IBreakpointData, IDebugAdapter, IDebugAdapterDescriptorFactory, IDebugSession, IDebugAdapterFactory, IDataBreakpoint } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import {
|
||||
ExtHostContext, ExtHostDebugServiceShape, MainThreadDebugServiceShape, DebugSessionUUID, MainContext,
|
||||
IExtHostContext, IBreakpointsDeltaDto, ISourceMultiBreakpointDto, ISourceBreakpointDto, IFunctionBreakpointDto, IDebugSessionDto
|
||||
IExtHostContext, IBreakpointsDeltaDto, ISourceMultiBreakpointDto, ISourceBreakpointDto, IFunctionBreakpointDto, IDebugSessionDto, IDataBreakpointDto
|
||||
} from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import severity from 'vs/base/common/severity';
|
||||
@@ -110,15 +110,16 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb
|
||||
// send all breakpoints
|
||||
const bps = this.debugService.getModel().getBreakpoints();
|
||||
const fbps = this.debugService.getModel().getFunctionBreakpoints();
|
||||
const dbps = this.debugService.getModel().getDataBreakpoints();
|
||||
if (bps.length > 0 || fbps.length > 0) {
|
||||
this._proxy.$acceptBreakpointsDelta({
|
||||
added: this.convertToDto(bps).concat(this.convertToDto(fbps))
|
||||
added: this.convertToDto(bps).concat(this.convertToDto(fbps)).concat(this.convertToDto(dbps))
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public $registerBreakpoints(DTOs: Array<ISourceMultiBreakpointDto | IFunctionBreakpointDto>): Promise<void> {
|
||||
public $registerBreakpoints(DTOs: Array<ISourceMultiBreakpointDto | IFunctionBreakpointDto | IDataBreakpointDto>): Promise<void> {
|
||||
|
||||
for (let dto of DTOs) {
|
||||
if (dto.type === 'sourceMulti') {
|
||||
@@ -136,14 +137,17 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb
|
||||
this.debugService.addBreakpoints(uri.revive(dto.uri), rawbps, 'extension');
|
||||
} else if (dto.type === 'function') {
|
||||
this.debugService.addFunctionBreakpoint(dto.functionName, dto.id);
|
||||
} else if (dto.type === 'data') {
|
||||
this.debugService.addDataBreakpoint(dto.label, dto.dataId, dto.canPersist);
|
||||
}
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
public $unregisterBreakpoints(breakpointIds: string[], functionBreakpointIds: string[]): Promise<void> {
|
||||
public $unregisterBreakpoints(breakpointIds: string[], functionBreakpointIds: string[], dataBreakpointIds: string[]): Promise<void> {
|
||||
breakpointIds.forEach(id => this.debugService.removeBreakpoints(id));
|
||||
functionBreakpointIds.forEach(id => this.debugService.removeFunctionBreakpoints(id));
|
||||
dataBreakpointIds.forEach(id => this.debugService.removeDataBreakpoints(id));
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
@@ -294,7 +298,7 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private convertToDto(bps: (ReadonlyArray<IBreakpoint | IFunctionBreakpoint>)): Array<ISourceBreakpointDto | IFunctionBreakpointDto> {
|
||||
private convertToDto(bps: (ReadonlyArray<IBreakpoint | IFunctionBreakpoint | IDataBreakpoint>)): Array<ISourceBreakpointDto | IFunctionBreakpointDto | IDataBreakpointDto> {
|
||||
return bps.map(bp => {
|
||||
if ('name' in bp) {
|
||||
const fbp = <IFunctionBreakpoint>bp;
|
||||
@@ -307,6 +311,19 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb
|
||||
logMessage: fbp.logMessage,
|
||||
functionName: fbp.name
|
||||
};
|
||||
} else if ('dataId' in bp) {
|
||||
const dbp = <IDataBreakpoint>bp;
|
||||
return <IDataBreakpointDto>{
|
||||
type: 'data',
|
||||
id: dbp.getId(),
|
||||
dataId: dbp.dataId,
|
||||
enabled: dbp.enabled,
|
||||
condition: dbp.condition,
|
||||
hitCondition: dbp.hitCondition,
|
||||
logMessage: dbp.logMessage,
|
||||
label: dbp.label,
|
||||
canPersist: dbp.canPersist
|
||||
};
|
||||
} else {
|
||||
const sbp = <IBreakpoint>bp;
|
||||
return <ISourceBreakpointDto>{
|
||||
|
||||
@@ -37,7 +37,7 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions';
|
||||
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
|
||||
import { createCSSRule, asDomUri } from 'vs/base/browser/dom';
|
||||
import { createCSSRule, asCSSUrl } from 'vs/base/browser/dom';
|
||||
|
||||
export interface IUserFriendlyViewsContainerDescriptor {
|
||||
id: string;
|
||||
@@ -210,7 +210,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution {
|
||||
});
|
||||
}
|
||||
|
||||
private addCustomViewContainers(extensionPoints: IExtensionPointUser<ViewContainerExtensionPointType>[], existingViewContainers: ViewContainer[]): void {
|
||||
private addCustomViewContainers(extensionPoints: readonly IExtensionPointUser<ViewContainerExtensionPointType>[], existingViewContainers: ViewContainer[]): void {
|
||||
const viewContainersRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry);
|
||||
let order = TEST_VIEW_CONTAINER_ORDER + viewContainersRegistry.all.filter(v => !!v.extensionId).length + 1;
|
||||
for (let { value, collector, description } of extensionPoints) {
|
||||
@@ -227,7 +227,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution {
|
||||
}
|
||||
}
|
||||
|
||||
private removeCustomViewContainers(extensionPoints: IExtensionPointUser<ViewContainerExtensionPointType>[]): void {
|
||||
private removeCustomViewContainers(extensionPoints: readonly IExtensionPointUser<ViewContainerExtensionPointType>[]): void {
|
||||
const viewContainersRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry);
|
||||
const removedExtensions: Set<string> = extensionPoints.reduce((result, e) => { result.add(ExtensionIdentifier.toKey(e.description.identifier)); return result; }, new Set<string>());
|
||||
for (const viewContainer of viewContainersRegistry.all) {
|
||||
@@ -356,7 +356,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution {
|
||||
|
||||
// Generate CSS to show the icon in the activity bar
|
||||
const iconClass = `.monaco-workbench .activitybar .monaco-action-bar .action-label.${cssClass}`;
|
||||
createCSSRule(iconClass, `-webkit-mask: url('${asDomUri(icon)}') no-repeat 50% 50%; -webkit-mask-size: 24px;`);
|
||||
createCSSRule(iconClass, `-webkit-mask: ${asCSSUrl(icon)} no-repeat 50% 50%; -webkit-mask-size: 24px;`);
|
||||
}
|
||||
|
||||
return viewContainer;
|
||||
@@ -378,7 +378,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution {
|
||||
});
|
||||
}
|
||||
|
||||
private addViews(extensions: IExtensionPointUser<ViewExtensionPointType>[]): void {
|
||||
private addViews(extensions: readonly IExtensionPointUser<ViewExtensionPointType>[]): void {
|
||||
for (const extension of extensions) {
|
||||
const { value, collector } = extension;
|
||||
|
||||
@@ -442,7 +442,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution {
|
||||
return this.viewContainersRegistry.get(EXPLORER)!;
|
||||
}
|
||||
|
||||
private removeViews(extensions: IExtensionPointUser<ViewExtensionPointType>[]): void {
|
||||
private removeViews(extensions: readonly IExtensionPointUser<ViewExtensionPointType>[]): void {
|
||||
const removedExtensions: Set<string> = extensions.reduce((result, e) => { result.add(ExtensionIdentifier.toKey(e.description.identifier)); return result; }, new Set<string>());
|
||||
for (const viewContainer of this.viewContainersRegistry.all) {
|
||||
const removedViews = this.viewsRegistry.getViews(viewContainer).filter((v: ICustomViewDescriptor) => v.extensionId && removedExtensions.has(ExtensionIdentifier.toKey(v.extensionId)));
|
||||
|
||||
@@ -719,8 +719,8 @@ export interface MainThreadDebugServiceShape extends IDisposable {
|
||||
$customDebugAdapterRequest(id: DebugSessionUUID, command: string, args: any): Promise<any>;
|
||||
$appendDebugConsole(value: string): void;
|
||||
$startBreakpointEvents(): void;
|
||||
$registerBreakpoints(breakpoints: Array<ISourceMultiBreakpointDto | IFunctionBreakpointDto>): Promise<void>;
|
||||
$unregisterBreakpoints(breakpointIds: string[], functionBreakpointIds: string[]): Promise<void>;
|
||||
$registerBreakpoints(breakpoints: Array<ISourceMultiBreakpointDto | IFunctionBreakpointDto | IDataBreakpointDto>): Promise<void>;
|
||||
$unregisterBreakpoints(breakpointIds: string[], functionBreakpointIds: string[], dataBreakpointIds: string[]): Promise<void>;
|
||||
}
|
||||
|
||||
export interface IOpenUriOptions {
|
||||
@@ -1203,6 +1203,13 @@ export interface IFunctionBreakpointDto extends IBreakpointDto {
|
||||
functionName: string;
|
||||
}
|
||||
|
||||
export interface IDataBreakpointDto extends IBreakpointDto {
|
||||
type: 'data';
|
||||
dataId: string;
|
||||
canPersist: boolean;
|
||||
label: string;
|
||||
}
|
||||
|
||||
export interface ISourceBreakpointDto extends IBreakpointDto {
|
||||
type: 'source';
|
||||
uri: UriComponents;
|
||||
@@ -1211,9 +1218,9 @@ export interface ISourceBreakpointDto extends IBreakpointDto {
|
||||
}
|
||||
|
||||
export interface IBreakpointsDeltaDto {
|
||||
added?: Array<ISourceBreakpointDto | IFunctionBreakpointDto>;
|
||||
added?: Array<ISourceBreakpointDto | IFunctionBreakpointDto | IDataBreakpointDto>;
|
||||
removed?: string[];
|
||||
changed?: Array<ISourceBreakpointDto | IFunctionBreakpointDto>;
|
||||
changed?: Array<ISourceBreakpointDto | IFunctionBreakpointDto | IDataBreakpointDto>;
|
||||
}
|
||||
|
||||
export interface ISourceMultiBreakpointDto {
|
||||
|
||||
@@ -2166,6 +2166,24 @@ export class FunctionBreakpoint extends Breakpoint {
|
||||
}
|
||||
}
|
||||
|
||||
@es5ClassCompat
|
||||
export class DataBreakpoint extends Breakpoint {
|
||||
readonly label: string;
|
||||
readonly dataId: string;
|
||||
readonly canPersist: boolean;
|
||||
|
||||
constructor(label: string, dataId: string, canPersist: boolean, enabled?: boolean, condition?: string, hitCondition?: string, logMessage?: string) {
|
||||
super(enabled, condition, hitCondition, logMessage);
|
||||
if (!dataId) {
|
||||
throw illegalArgument('dataId');
|
||||
}
|
||||
this.label = label;
|
||||
this.dataId = dataId;
|
||||
this.canPersist = canPersist;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@es5ClassCompat
|
||||
export class DebugAdapterExecutable implements vscode.DebugAdapterExecutable {
|
||||
readonly command: string;
|
||||
|
||||
@@ -12,7 +12,7 @@ import { IExtensionPointUser, ExtensionMessageCollector, ExtensionsRegistry } fr
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { MenuId, MenuRegistry, ILocalizedString, IMenuItem } from 'vs/platform/actions/common/actions';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
|
||||
namespace schema {
|
||||
|
||||
@@ -334,7 +334,7 @@ namespace schema {
|
||||
};
|
||||
}
|
||||
|
||||
let _commandRegistrations: IDisposable[] = [];
|
||||
const _commandRegistrations = new DisposableStore();
|
||||
|
||||
export const commandsExtensionPoint = ExtensionsRegistry.registerExtensionPoint<schema.IUserFriendlyCommand | schema.IUserFriendlyCommand[]>({
|
||||
extensionPoint: 'commands',
|
||||
@@ -343,7 +343,7 @@ export const commandsExtensionPoint = ExtensionsRegistry.registerExtensionPoint<
|
||||
|
||||
commandsExtensionPoint.setHandler(extensions => {
|
||||
|
||||
function handleCommand(userFriendlyCommand: schema.IUserFriendlyCommand, extension: IExtensionPointUser<any>, disposables: IDisposable[]) {
|
||||
function handleCommand(userFriendlyCommand: schema.IUserFriendlyCommand, extension: IExtensionPointUser<any>) {
|
||||
|
||||
if (!schema.isValidCommand(userFriendlyCommand, extension.collector)) {
|
||||
return;
|
||||
@@ -373,20 +373,20 @@ commandsExtensionPoint.setHandler(extensions => {
|
||||
precondition: ContextKeyExpr.deserialize(enablement),
|
||||
iconLocation: absoluteIcon
|
||||
});
|
||||
disposables.push(registration);
|
||||
_commandRegistrations.add(registration);
|
||||
}
|
||||
|
||||
// remove all previous command registrations
|
||||
_commandRegistrations = dispose(_commandRegistrations);
|
||||
_commandRegistrations.clear();
|
||||
|
||||
for (let extension of extensions) {
|
||||
for (const extension of extensions) {
|
||||
const { value } = extension;
|
||||
if (Array.isArray<schema.IUserFriendlyCommand>(value)) {
|
||||
for (let command of value) {
|
||||
handleCommand(command, extension, _commandRegistrations);
|
||||
if (Array.isArray(value)) {
|
||||
for (const command of value) {
|
||||
handleCommand(command, extension);
|
||||
}
|
||||
} else {
|
||||
handleCommand(value, extension, _commandRegistrations);
|
||||
handleCommand(value, extension);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
IBreakpointsDeltaDto, ISourceMultiBreakpointDto, IFunctionBreakpointDto, IDebugSessionDto
|
||||
} from 'vs/workbench/api/common/extHost.protocol';
|
||||
import * as vscode from 'vscode';
|
||||
import { Disposable, Position, Location, SourceBreakpoint, FunctionBreakpoint, DebugAdapterServer, DebugAdapterExecutable } from 'vs/workbench/api/common/extHostTypes';
|
||||
import { Disposable, Position, Location, SourceBreakpoint, FunctionBreakpoint, DebugAdapterServer, DebugAdapterExecutable, DataBreakpoint } from 'vs/workbench/api/common/extHostTypes';
|
||||
import { ExecutableDebugAdapter, SocketDebugAdapter } from 'vs/workbench/contrib/debug/node/debugAdapter';
|
||||
import { AbstractDebugAdapter } from 'vs/workbench/contrib/debug/common/abstractDebugAdapter';
|
||||
import { IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
|
||||
@@ -248,7 +248,8 @@ export class ExtHostDebugService implements IExtHostDebugService, ExtHostDebugSe
|
||||
// unregister with VS Code
|
||||
const ids = breakpoints.filter(bp => bp instanceof SourceBreakpoint).map(bp => bp.id);
|
||||
const fids = breakpoints.filter(bp => bp instanceof FunctionBreakpoint).map(bp => bp.id);
|
||||
return this._debugServiceProxy.$unregisterBreakpoints(ids, fids);
|
||||
const dids = breakpoints.filter(bp => bp instanceof DataBreakpoint).map(bp => bp.id);
|
||||
return this._debugServiceProxy.$unregisterBreakpoints(ids, fids, dids);
|
||||
}
|
||||
|
||||
public startDebugging(folder: vscode.WorkspaceFolder | undefined, nameOrConfig: string | vscode.DebugConfiguration, parentSession?: vscode.DebugSession): Promise<boolean> {
|
||||
@@ -554,6 +555,8 @@ export class ExtHostDebugService implements IExtHostDebugService, ExtHostDebugSe
|
||||
let bp: vscode.Breakpoint;
|
||||
if (bpd.type === 'function') {
|
||||
bp = new FunctionBreakpoint(bpd.functionName, bpd.enabled, bpd.condition, bpd.hitCondition, bpd.logMessage);
|
||||
} else if (bpd.type === 'data') {
|
||||
bp = new DataBreakpoint(bpd.label, bpd.dataId, bpd.canPersist, bpd.enabled, bpd.hitCondition, bpd.condition, bpd.logMessage);
|
||||
} else {
|
||||
const uri = URI.revive(bpd.uri);
|
||||
bp = new SourceBreakpoint(new Location(uri, new Position(bpd.line, bpd.character)), bpd.enabled, bpd.condition, bpd.hitCondition, bpd.logMessage);
|
||||
|
||||
@@ -46,6 +46,9 @@ enum Settings {
|
||||
PANEL_POSITION = 'workbench.panel.defaultLocation',
|
||||
|
||||
ZEN_MODE_RESTORE = 'zenMode.restore',
|
||||
|
||||
// TODO @misolori update this when finished
|
||||
OCTICONS_UPDATE_ENABLED = 'workbench.octiconsUpdate.enabled',
|
||||
}
|
||||
|
||||
enum Storage {
|
||||
@@ -173,6 +176,11 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
wasSideBarVisible: false,
|
||||
wasPanelVisible: false,
|
||||
transitionDisposables: new DisposableStore()
|
||||
},
|
||||
|
||||
// TODO @misolori update this when finished
|
||||
octiconsUpdate: {
|
||||
enabled: false
|
||||
}
|
||||
};
|
||||
|
||||
@@ -314,6 +322,10 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
const newMenubarVisibility = this.configurationService.getValue<MenuBarVisibility>(Settings.MENUBAR_VISIBLE);
|
||||
this.setMenubarVisibility(newMenubarVisibility, !!skipLayout);
|
||||
|
||||
// TODO @misolori update this when finished
|
||||
const newOcticonsUpdate = this.configurationService.getValue<boolean>(Settings.OCTICONS_UPDATE_ENABLED);
|
||||
this.setOcticonsUpdate(newOcticonsUpdate);
|
||||
|
||||
}
|
||||
|
||||
private setSideBarPosition(position: Position): void {
|
||||
@@ -426,6 +438,10 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
// Zen mode enablement
|
||||
this.state.zenMode.restore = this.storageService.getBoolean(Storage.ZEN_MODE_ENABLED, StorageScope.WORKSPACE, false) && this.configurationService.getValue(Settings.ZEN_MODE_RESTORE);
|
||||
|
||||
// TODO @misolori update this when finished
|
||||
this.state.octiconsUpdate.enabled = this.configurationService.getValue<boolean>(Settings.OCTICONS_UPDATE_ENABLED);
|
||||
this.setOcticonsUpdate(this.state.octiconsUpdate.enabled);
|
||||
|
||||
}
|
||||
|
||||
private resolveEditorsToOpen(fileService: IFileService): Promise<IResourceEditor[]> | IResourceEditor[] {
|
||||
@@ -729,6 +745,19 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
}
|
||||
}
|
||||
|
||||
// TODO @misolori update this when finished
|
||||
private setOcticonsUpdate(enabled: boolean): void {
|
||||
this.state.octiconsUpdate.enabled = enabled;
|
||||
|
||||
// Update DOM
|
||||
if (enabled) {
|
||||
document.body.dataset.octiconsUpdate = 'enabled';
|
||||
} else {
|
||||
document.body.dataset.octiconsUpdate = '';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected createWorkbenchLayout(instantiationService: IInstantiationService): void {
|
||||
const titleBar = this.getPart(Parts.TITLEBAR_PART);
|
||||
const editorPart = this.getPart(Parts.EDITOR_PART);
|
||||
|
||||
@@ -171,7 +171,7 @@ export class PlaceHolderViewletActivityAction extends ViewletActivityAction {
|
||||
super({ id, name: id, cssClass: `extensionViewlet-placeholder-${id.replace(/\./g, '-')}` }, viewletService, layoutService, telemetryService);
|
||||
|
||||
const iconClass = `.monaco-workbench .activitybar .monaco-action-bar .action-label.${this.class}`; // Generate Placeholder CSS to show the icon in the activity bar
|
||||
DOM.createCSSRule(iconClass, `-webkit-mask: url('${DOM.asDomUri(iconUrl) || ''}') no-repeat 50% 50%; -webkit-mask-size: 24px;`);
|
||||
DOM.createCSSRule(iconClass, `-webkit-mask: ${DOM.asCSSUrl(iconUrl)} no-repeat 50% 50%; -webkit-mask-size: 24px;`);
|
||||
}
|
||||
|
||||
setActivity(activity: IActivity): void {
|
||||
|
||||
@@ -22,8 +22,8 @@ export function getIconClass(iconPath: { dark: URI; light?: URI; } | undefined):
|
||||
iconClass = iconPathToClass[key];
|
||||
} else {
|
||||
iconClass = iconClassGenerator.nextId();
|
||||
dom.createCSSRule(`.${iconClass}`, `background-image: url("${dom.asDomUri(iconPath.light || iconPath.dark).toString()}")`);
|
||||
dom.createCSSRule(`.vs-dark .${iconClass}, .hc-black .${iconClass}`, `background-image: url("${dom.asDomUri(iconPath.dark).toString()}")`);
|
||||
dom.createCSSRule(`.${iconClass}`, `background-image: ${dom.asCSSUrl(iconPath.light || iconPath.dark)}`);
|
||||
dom.createCSSRule(`.vs-dark .${iconClass}, .hc-black .${iconClass}`, `background-image: ${dom.asCSSUrl(iconPath.dark)}`);
|
||||
iconPathToClass[key] = iconClass;
|
||||
}
|
||||
|
||||
|
||||
@@ -756,7 +756,7 @@ class TreeRenderer extends Disposable implements ITreeRenderer<ITreeItem, FuzzyS
|
||||
templateData.resourceLabel.setResource({ name: label, description }, { title, hideIcon: true, extraClasses: ['custom-view-tree-node-item-resourceLabel'], matches: createMatches(element.filterData) });
|
||||
}
|
||||
|
||||
templateData.icon.style.backgroundImage = iconUrl ? `url('${DOM.asDomUri(iconUrl).toString(true)}')` : '';
|
||||
templateData.icon.style.backgroundImage = iconUrl ? DOM.asCSSUrl(iconUrl) : '';
|
||||
DOM.toggleClass(templateData.icon, 'custom-view-tree-node-item-icon', !!iconUrl);
|
||||
templateData.actionBar.context = <TreeViewItemHandleArg>{ $treeViewId: this.treeViewId, $treeItemHandle: node.handle };
|
||||
templateData.actionBar.push(this.menus.getResourceActions(node), { icon: true, label: false });
|
||||
|
||||
@@ -41,6 +41,7 @@ import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { getThemeTypeSelector, DARK, HIGH_CONTRAST, LIGHT } from 'vs/platform/theme/common/themeService';
|
||||
import { InMemoryUserDataProvider } from 'vs/workbench/services/userData/common/inMemoryUserDataProvider';
|
||||
import { registerWindowDriver } from 'vs/platform/driver/browser/driver';
|
||||
import { StaticExtensionsService, IStaticExtensionsService } from 'vs/workbench/services/extensions/common/staticExtensions';
|
||||
|
||||
class CodeRendererMain extends Disposable {
|
||||
|
||||
@@ -145,6 +146,10 @@ class CodeRendererMain extends Disposable {
|
||||
const fileService = this._register(new FileService(logService));
|
||||
serviceCollection.set(IFileService, fileService);
|
||||
|
||||
// Static Extensions
|
||||
const staticExtensions = new StaticExtensionsService(this.configuration.staticExtensions || []);
|
||||
serviceCollection.set(IStaticExtensionsService, staticExtensions);
|
||||
|
||||
let userDataProvider: IFileSystemProvider | undefined = this.configuration.userDataProvider;
|
||||
const connection = remoteAgentService.getConnection();
|
||||
if (connection) {
|
||||
|
||||
@@ -239,6 +239,11 @@ import { isMacintosh, isWindows, isLinux, isWeb } from 'vs/base/common/platform'
|
||||
'description': nls.localize('workbench.useExperimentalGridLayout', "Enables the grid layout for the workbench. This setting may enable additional layout options for workbench components."),
|
||||
'default': true,
|
||||
'scope': ConfigurationScope.APPLICATION
|
||||
},
|
||||
'workbench.octiconsUpdate.enabled': {
|
||||
'type': 'boolean',
|
||||
'default': true,
|
||||
'description': nls.localize('workbench.octiconsUpdate.enabled', "Controls the visibility of the new Octicons style in the workbench.")
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as resources from 'vs/base/common/resources';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { IAction, Action } from 'vs/base/common/actions';
|
||||
import { IDebugService, IBreakpoint, CONTEXT_BREAKPOINTS_FOCUSED, EDITOR_CONTRIBUTION_ID, State, DEBUG_SCHEME, IFunctionBreakpoint, IExceptionBreakpoint, IEnablement, IDebugEditorContribution } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { ExceptionBreakpoint, FunctionBreakpoint, Breakpoint } from 'vs/workbench/contrib/debug/common/debugModel';
|
||||
import { ExceptionBreakpoint, FunctionBreakpoint, Breakpoint, DataBreakpoint } from 'vs/workbench/contrib/debug/common/debugModel';
|
||||
import { AddFunctionBreakpointAction, ToggleBreakpointsActivatedAction, RemoveAllBreakpointsAction, RemoveBreakpointAction, EnableAllBreakpointsAction, DisableAllBreakpointsAction, ReapplyBreakpointsAction } from 'vs/workbench/contrib/debug/browser/debugActions';
|
||||
import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
@@ -74,6 +74,7 @@ export class BreakpointsView extends ViewletPanel {
|
||||
this.instantiationService.createInstance(BreakpointsRenderer),
|
||||
new ExceptionBreakpointsRenderer(this.debugService),
|
||||
this.instantiationService.createInstance(FunctionBreakpointsRenderer),
|
||||
this.instantiationService.createInstance(DataBreakpointsRenderer),
|
||||
new FunctionBreakpointInputRenderer(this.debugService, this.contextViewService, this.themeService)
|
||||
], {
|
||||
identityProvider: { getId: (element: IEnablement) => element.getId() },
|
||||
@@ -91,7 +92,7 @@ export class BreakpointsView extends ViewletPanel {
|
||||
|
||||
this._register(this.list.onContextMenu(this.onListContextMenu, this));
|
||||
|
||||
this._register(this.list.onDidOpen(e => {
|
||||
this._register(this.list.onDidOpen(async e => {
|
||||
let isSingleClick = false;
|
||||
let isDoubleClick = false;
|
||||
let isMiddleClick = false;
|
||||
@@ -110,9 +111,11 @@ export class BreakpointsView extends ViewletPanel {
|
||||
|
||||
if (isMiddleClick) {
|
||||
if (element instanceof Breakpoint) {
|
||||
this.debugService.removeBreakpoints(element.getId());
|
||||
await this.debugService.removeBreakpoints(element.getId());
|
||||
} else if (element instanceof FunctionBreakpoint) {
|
||||
this.debugService.removeFunctionBreakpoints(element.getId());
|
||||
await this.debugService.removeFunctionBreakpoints(element.getId());
|
||||
} else if (element instanceof DataBreakpoint) {
|
||||
await this.debugService.removeDataBreakpoints(element.getId());
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -222,14 +225,14 @@ export class BreakpointsView extends ViewletPanel {
|
||||
|
||||
private get elements(): IEnablement[] {
|
||||
const model = this.debugService.getModel();
|
||||
const elements = (<ReadonlyArray<IEnablement>>model.getExceptionBreakpoints()).concat(model.getFunctionBreakpoints()).concat(model.getBreakpoints());
|
||||
const elements = (<ReadonlyArray<IEnablement>>model.getExceptionBreakpoints()).concat(model.getFunctionBreakpoints()).concat(model.getDataBreakpoints()).concat(model.getBreakpoints());
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
private getExpandedBodySize(): number {
|
||||
const model = this.debugService.getModel();
|
||||
const length = model.getBreakpoints().length + model.getExceptionBreakpoints().length + model.getFunctionBreakpoints().length;
|
||||
const length = model.getBreakpoints().length + model.getExceptionBreakpoints().length + model.getFunctionBreakpoints().length + model.getDataBreakpoints().length;
|
||||
return Math.min(BreakpointsView.MAX_VISIBLE_FILES, length) * 22;
|
||||
}
|
||||
}
|
||||
@@ -259,6 +262,9 @@ class BreakpointsDelegate implements IListVirtualDelegate<IEnablement> {
|
||||
if (element instanceof ExceptionBreakpoint) {
|
||||
return ExceptionBreakpointsRenderer.ID;
|
||||
}
|
||||
if (element instanceof DataBreakpoint) {
|
||||
return DataBreakpointsRenderer.ID;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
@@ -454,6 +460,61 @@ class FunctionBreakpointsRenderer implements IListRenderer<FunctionBreakpoint, I
|
||||
}
|
||||
}
|
||||
|
||||
class DataBreakpointsRenderer implements IListRenderer<DataBreakpoint, IBaseBreakpointWithIconTemplateData> {
|
||||
|
||||
constructor(
|
||||
@IDebugService private readonly debugService: IDebugService
|
||||
) {
|
||||
// noop
|
||||
}
|
||||
|
||||
static readonly ID = 'databreakpoints';
|
||||
|
||||
get templateId() {
|
||||
return DataBreakpointsRenderer.ID;
|
||||
}
|
||||
|
||||
renderTemplate(container: HTMLElement): IBaseBreakpointWithIconTemplateData {
|
||||
const data: IBreakpointTemplateData = Object.create(null);
|
||||
data.breakpoint = dom.append(container, $('.breakpoint'));
|
||||
|
||||
data.icon = $('.icon');
|
||||
data.checkbox = createCheckbox();
|
||||
data.toDispose = [];
|
||||
data.toDispose.push(dom.addStandardDisposableListener(data.checkbox, 'change', (e) => {
|
||||
this.debugService.enableOrDisableBreakpoints(!data.context.enabled, data.context);
|
||||
}));
|
||||
|
||||
dom.append(data.breakpoint, data.icon);
|
||||
dom.append(data.breakpoint, data.checkbox);
|
||||
|
||||
data.name = dom.append(data.breakpoint, $('span.name'));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
renderElement(dataBreakpoint: DataBreakpoint, index: number, data: IBaseBreakpointWithIconTemplateData): void {
|
||||
data.context = dataBreakpoint;
|
||||
data.name.textContent = dataBreakpoint.label;
|
||||
const { className, message } = getBreakpointMessageAndClassName(this.debugService, dataBreakpoint);
|
||||
data.icon.className = className + ' icon';
|
||||
data.icon.title = message ? message : '';
|
||||
data.checkbox.checked = dataBreakpoint.enabled;
|
||||
data.breakpoint.title = dataBreakpoint.label;
|
||||
|
||||
// Mark function breakpoints as disabled if deactivated or if debug type does not support them #9099
|
||||
const session = this.debugService.getViewModel().focusedSession;
|
||||
dom.toggleClass(data.breakpoint, 'disabled', (session && !session.capabilities.supportsDataBreakpoints) || !this.debugService.getModel().areBreakpointsActivated());
|
||||
if (session && !session.capabilities.supportsDataBreakpoints) {
|
||||
data.breakpoint.title = nls.localize('dataBreakpointsNotSupported', "Data breakpoints are not supported by this debug type");
|
||||
}
|
||||
}
|
||||
|
||||
disposeTemplate(templateData: IBaseBreakpointWithIconTemplateData): void {
|
||||
dispose(templateData.toDispose);
|
||||
}
|
||||
}
|
||||
|
||||
class FunctionBreakpointInputRenderer implements IListRenderer<IFunctionBreakpoint, IInputTemplateData> {
|
||||
|
||||
constructor(
|
||||
@@ -572,7 +633,7 @@ export function openBreakpointSource(breakpoint: IBreakpoint, sideBySide: boolea
|
||||
}, sideBySide ? SIDE_GROUP : ACTIVE_GROUP);
|
||||
}
|
||||
|
||||
export function getBreakpointMessageAndClassName(debugService: IDebugService, breakpoint: IBreakpoint | FunctionBreakpoint): { message?: string, className: string } {
|
||||
export function getBreakpointMessageAndClassName(debugService: IDebugService, breakpoint: IBreakpoint | FunctionBreakpoint | DataBreakpoint): { message?: string, className: string } {
|
||||
const state = debugService.state;
|
||||
const debugActive = state === State.Running || state === State.Stopped;
|
||||
|
||||
@@ -584,7 +645,7 @@ export function getBreakpointMessageAndClassName(debugService: IDebugService, br
|
||||
}
|
||||
|
||||
const appendMessage = (text: string): string => {
|
||||
return !(breakpoint instanceof FunctionBreakpoint) && breakpoint.message ? text.concat(', ' + breakpoint.message) : text;
|
||||
return !(breakpoint instanceof FunctionBreakpoint) && !(breakpoint instanceof DataBreakpoint) && breakpoint.message ? text.concat(', ' + breakpoint.message) : text;
|
||||
};
|
||||
if (debugActive && !breakpoint.verified) {
|
||||
return {
|
||||
@@ -607,6 +668,19 @@ export function getBreakpointMessageAndClassName(debugService: IDebugService, br
|
||||
};
|
||||
}
|
||||
|
||||
if (breakpoint instanceof DataBreakpoint) {
|
||||
if (session && !session.capabilities.supportsDataBreakpoints) {
|
||||
return {
|
||||
className: 'debug-data-breakpoint-unverified',
|
||||
message: nls.localize('dataBreakpointUnsupported', "Data breakpoints not supported by this debug type"),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
className: 'debug-data-breakpoint',
|
||||
};
|
||||
}
|
||||
|
||||
if (breakpoint.logMessage || breakpoint.condition || breakpoint.hitCondition) {
|
||||
const messages: string[] = [];
|
||||
if (breakpoint.logMessage) {
|
||||
|
||||
@@ -9,7 +9,7 @@ import * as lifecycle from 'vs/base/common/lifecycle';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
||||
import { IDebugService, State, IEnablement, IBreakpoint, IDebugSession } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { Variable, Breakpoint } from 'vs/workbench/contrib/debug/common/debugModel';
|
||||
import { Variable, Breakpoint, FunctionBreakpoint } from 'vs/workbench/contrib/debug/common/debugModel';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
@@ -191,7 +191,7 @@ export class RemoveBreakpointAction extends AbstractDebugAction {
|
||||
|
||||
public run(breakpoint: IBreakpoint): Promise<any> {
|
||||
return breakpoint instanceof Breakpoint ? this.debugService.removeBreakpoints(breakpoint.getId())
|
||||
: this.debugService.removeFunctionBreakpoints(breakpoint.getId());
|
||||
: breakpoint instanceof FunctionBreakpoint ? this.debugService.removeFunctionBreakpoints(breakpoint.getId()) : this.debugService.removeDataBreakpoints(breakpoint.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ export class RemoveAllBreakpointsAction extends AbstractDebugAction {
|
||||
}
|
||||
|
||||
public run(): Promise<any> {
|
||||
return Promise.all([this.debugService.removeBreakpoints(), this.debugService.removeFunctionBreakpoints()]);
|
||||
return Promise.all([this.debugService.removeBreakpoints(), this.debugService.removeFunctionBreakpoints(), this.debugService.removeDataBreakpoints()]);
|
||||
}
|
||||
|
||||
protected isEnabled(state: State): boolean {
|
||||
|
||||
@@ -10,7 +10,7 @@ import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/co
|
||||
import { IListService } from 'vs/platform/list/browser/listService';
|
||||
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
||||
import { IDebugService, IEnablement, CONTEXT_BREAKPOINTS_FOCUSED, CONTEXT_WATCH_EXPRESSIONS_FOCUSED, CONTEXT_VARIABLES_FOCUSED, EDITOR_CONTRIBUTION_ID, IDebugEditorContribution, CONTEXT_IN_DEBUG_MODE, CONTEXT_EXPRESSION_SELECTED, CONTEXT_BREAKPOINT_SELECTED, IConfig, IStackFrame, IThread, IDebugSession, CONTEXT_DEBUG_STATE, REPL_ID, IDebugConfiguration, CONTEXT_JUMP_TO_CURSOR_SUPPORTED } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { Expression, Variable, Breakpoint, FunctionBreakpoint, Thread } from 'vs/workbench/contrib/debug/common/debugModel';
|
||||
import { Expression, Variable, Breakpoint, FunctionBreakpoint, Thread, DataBreakpoint } from 'vs/workbench/contrib/debug/common/debugModel';
|
||||
import { IExtensionsViewlet, VIEWLET_ID as EXTENSIONS_VIEWLET_ID } from 'vs/workbench/contrib/extensions/common/extensions';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { ICodeEditor, isCodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
@@ -410,6 +410,8 @@ export function registerCommands(): void {
|
||||
debugService.removeBreakpoints(element.getId());
|
||||
} else if (element instanceof FunctionBreakpoint) {
|
||||
debugService.removeFunctionBreakpoints(element.getId());
|
||||
} else if (element instanceof DataBreakpoint) {
|
||||
debugService.removeDataBreakpoints(element.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
|
||||
import { FileChangesEvent, FileChangeType, IFileService } from 'vs/platform/files/common/files';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { DebugModel, ExceptionBreakpoint, FunctionBreakpoint, Breakpoint, Expression } from 'vs/workbench/contrib/debug/common/debugModel';
|
||||
import { DebugModel, ExceptionBreakpoint, FunctionBreakpoint, Breakpoint, Expression, DataBreakpoint } from 'vs/workbench/contrib/debug/common/debugModel';
|
||||
import { ViewModel } from 'vs/workbench/contrib/debug/common/debugViewModel';
|
||||
import * as debugactions from 'vs/workbench/contrib/debug/browser/debugActions';
|
||||
import { ConfigurationManager } from 'vs/workbench/contrib/debug/browser/debugConfigurationManager';
|
||||
@@ -52,6 +52,7 @@ import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
const DEBUG_BREAKPOINTS_KEY = 'debug.breakpoint';
|
||||
const DEBUG_BREAKPOINTS_ACTIVATED_KEY = 'debug.breakpointactivated';
|
||||
const DEBUG_FUNCTION_BREAKPOINTS_KEY = 'debug.functionbreakpoint';
|
||||
const DEBUG_DATA_BREAKPOINTS_KEY = 'debug.databreakpoint';
|
||||
const DEBUG_EXCEPTION_BREAKPOINTS_KEY = 'debug.exceptionbreakpoint';
|
||||
const DEBUG_WATCH_EXPRESSIONS_KEY = 'debug.watchexpressions';
|
||||
|
||||
@@ -129,7 +130,7 @@ export class DebugService implements IDebugService {
|
||||
this.inDebugMode = CONTEXT_IN_DEBUG_MODE.bindTo(contextKeyService);
|
||||
|
||||
this.model = new DebugModel(this.loadBreakpoints(), this.storageService.getBoolean(DEBUG_BREAKPOINTS_ACTIVATED_KEY, StorageScope.WORKSPACE, true), this.loadFunctionBreakpoints(),
|
||||
this.loadExceptionBreakpoints(), this.loadWatchExpressions(), this.textFileService);
|
||||
this.loadExceptionBreakpoints(), this.loadDataBreakpoints(), this.loadWatchExpressions(), this.textFileService);
|
||||
this.toDispose.push(this.model);
|
||||
|
||||
this.viewModel = new ViewModel(contextKeyService);
|
||||
@@ -851,6 +852,8 @@ export class DebugService implements IDebugService {
|
||||
await this.sendBreakpoints(breakpoint.uri);
|
||||
} else if (breakpoint instanceof FunctionBreakpoint) {
|
||||
await this.sendFunctionBreakpoints();
|
||||
} else if (breakpoint instanceof DataBreakpoint) {
|
||||
await this.sendDataBreakpoints();
|
||||
} else {
|
||||
await this.sendExceptionBreakpoints();
|
||||
}
|
||||
@@ -920,6 +923,19 @@ export class DebugService implements IDebugService {
|
||||
this.storeBreakpoints();
|
||||
}
|
||||
|
||||
async addDataBreakpoint(label: string, dataId: string, canPersist: boolean): Promise<void> {
|
||||
this.model.addDataBreakpoint(label, dataId, canPersist);
|
||||
await this.sendDataBreakpoints();
|
||||
|
||||
this.storeBreakpoints();
|
||||
}
|
||||
|
||||
async removeDataBreakpoints(id?: string): Promise<void> {
|
||||
this.model.removeDataBreakpoints(id);
|
||||
await this.sendDataBreakpoints();
|
||||
this.storeBreakpoints();
|
||||
}
|
||||
|
||||
sendAllBreakpoints(session?: IDebugSession): Promise<any> {
|
||||
return Promise.all(distinct(this.model.getBreakpoints(), bp => bp.uri.toString()).map(bp => this.sendBreakpoints(bp.uri, false, session)))
|
||||
.then(() => this.sendFunctionBreakpoints(session))
|
||||
@@ -943,6 +959,14 @@ export class DebugService implements IDebugService {
|
||||
});
|
||||
}
|
||||
|
||||
private sendDataBreakpoints(session?: IDebugSession): Promise<void> {
|
||||
const breakpointsToSend = this.model.getDataBreakpoints().filter(fbp => fbp.enabled && this.model.areBreakpointsActivated());
|
||||
|
||||
return this.sendToOneOrAllSessions(session, s => {
|
||||
return s.capabilities.supportsDataBreakpoints ? s.sendDataBreakpoints(breakpointsToSend) : Promise.resolve(undefined);
|
||||
});
|
||||
}
|
||||
|
||||
private sendExceptionBreakpoints(session?: IDebugSession): Promise<void> {
|
||||
const enabledExceptionBps = this.model.getExceptionBreakpoints().filter(exb => exb.enabled);
|
||||
|
||||
@@ -1006,6 +1030,17 @@ export class DebugService implements IDebugService {
|
||||
return result || [];
|
||||
}
|
||||
|
||||
private loadDataBreakpoints(): DataBreakpoint[] {
|
||||
let result: DataBreakpoint[] | undefined;
|
||||
try {
|
||||
result = JSON.parse(this.storageService.get(DEBUG_DATA_BREAKPOINTS_KEY, StorageScope.WORKSPACE, '[]')).map((dbp: any) => {
|
||||
return new DataBreakpoint(dbp.label, dbp.dataId, true, dbp.enabled, dbp.hitCondition, dbp.condition, dbp.logMessage);
|
||||
});
|
||||
} catch (e) { }
|
||||
|
||||
return result || [];
|
||||
}
|
||||
|
||||
private loadWatchExpressions(): Expression[] {
|
||||
let result: Expression[] | undefined;
|
||||
try {
|
||||
@@ -1041,6 +1076,13 @@ export class DebugService implements IDebugService {
|
||||
this.storageService.remove(DEBUG_FUNCTION_BREAKPOINTS_KEY, StorageScope.WORKSPACE);
|
||||
}
|
||||
|
||||
const dataBreakpoints = this.model.getDataBreakpoints().filter(dbp => dbp.canPersist);
|
||||
if (dataBreakpoints.length) {
|
||||
this.storageService.store(DEBUG_DATA_BREAKPOINTS_KEY, JSON.stringify(dataBreakpoints), StorageScope.WORKSPACE);
|
||||
} else {
|
||||
this.storageService.remove(DEBUG_DATA_BREAKPOINTS_KEY, StorageScope.WORKSPACE);
|
||||
}
|
||||
|
||||
const exceptionBreakpoints = this.model.getExceptionBreakpoints();
|
||||
if (exceptionBreakpoints.length) {
|
||||
this.storageService.store(DEBUG_EXCEPTION_BREAKPOINTS_KEY, JSON.stringify(exceptionBreakpoints), StorageScope.WORKSPACE);
|
||||
|
||||
@@ -12,7 +12,7 @@ import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { CompletionItem, completionKindFromString } from 'vs/editor/common/modes';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import * as aria from 'vs/base/browser/ui/aria/aria';
|
||||
import { IDebugSession, IConfig, IThread, IRawModelUpdate, IDebugService, IRawStoppedDetails, State, LoadedSourceEvent, IFunctionBreakpoint, IExceptionBreakpoint, IBreakpoint, IExceptionInfo, AdapterEndEvent, IDebugger, VIEWLET_ID, IDebugConfiguration, IReplElement, IStackFrame, IExpression, IReplElementSource } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { IDebugSession, IConfig, IThread, IRawModelUpdate, IDebugService, IRawStoppedDetails, State, LoadedSourceEvent, IFunctionBreakpoint, IExceptionBreakpoint, IBreakpoint, IExceptionInfo, AdapterEndEvent, IDebugger, VIEWLET_ID, IDebugConfiguration, IReplElement, IStackFrame, IExpression, IReplElementSource, IDataBreakpoint } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { Source } from 'vs/workbench/contrib/debug/common/debugSource';
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
import { Thread, ExpressionContainer, DebugModel } from 'vs/workbench/contrib/debug/common/debugModel';
|
||||
@@ -327,6 +327,34 @@ export class DebugSession implements IDebugSession {
|
||||
return Promise.reject(new Error('no debug adapter'));
|
||||
}
|
||||
|
||||
dataBreakpointInfo(name: string, variablesReference?: number): Promise<{ dataId: string | null, description: string, canPersist?: boolean }> {
|
||||
if (this.raw) {
|
||||
if (this.raw.readyForBreakpoints) {
|
||||
return this.raw.dataBreakpointInfo({ name, variablesReference }).then(response => response.body);
|
||||
}
|
||||
return Promise.reject(new Error(nls.localize('sessionNotReadyForBreakpoints', "Session is not ready for breakpoints")));
|
||||
}
|
||||
return Promise.reject(new Error('no debug adapter'));
|
||||
}
|
||||
|
||||
sendDataBreakpoints(dataBreakpoints: IDataBreakpoint[]): Promise<void> {
|
||||
if (this.raw) {
|
||||
if (this.raw.readyForBreakpoints) {
|
||||
return this.raw.setDataBreakpoints({ breakpoints: dataBreakpoints }).then(response => {
|
||||
if (response && response.body) {
|
||||
const data = new Map<string, DebugProtocol.Breakpoint>();
|
||||
for (let i = 0; i < dataBreakpoints.length; i++) {
|
||||
data.set(dataBreakpoints[i].getId(), response.body.breakpoints[i]);
|
||||
}
|
||||
this.model.setBreakpointSessionData(this.getId(), data);
|
||||
}
|
||||
});
|
||||
}
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
return Promise.reject(new Error('no debug adapter'));
|
||||
}
|
||||
|
||||
customRequest(request: string, args: any): Promise<DebugProtocol.Response> {
|
||||
if (this.raw) {
|
||||
return this.raw.custom(request, args);
|
||||
|
||||
@@ -357,6 +357,20 @@ export class RawDebugSession {
|
||||
return Promise.reject(new Error('setFunctionBreakpoints not supported'));
|
||||
}
|
||||
|
||||
dataBreakpointInfo(args: DebugProtocol.DataBreakpointInfoArguments): Promise<DebugProtocol.DataBreakpointInfoResponse> {
|
||||
if (this.capabilities.supportsDataBreakpoints) {
|
||||
return this.send<DebugProtocol.DataBreakpointInfoResponse>('dataBreakpointInfo', args);
|
||||
}
|
||||
return Promise.reject(new Error('dataBreakpointInfo not supported'));
|
||||
}
|
||||
|
||||
setDataBreakpoints(args: DebugProtocol.SetDataBreakpointsArguments): Promise<DebugProtocol.SetDataBreakpointsResponse> {
|
||||
if (this.capabilities.supportsDataBreakpoints) {
|
||||
return this.send<DebugProtocol.SetDataBreakpointsResponse>('setDataBreakpoints', args);
|
||||
}
|
||||
return Promise.reject(new Error('setDataBreakpoints not supported'));
|
||||
}
|
||||
|
||||
setExceptionBreakpoints(args: DebugProtocol.SetExceptionBreakpointsArguments): Promise<DebugProtocol.SetExceptionBreakpointsResponse> {
|
||||
return this.send<DebugProtocol.SetExceptionBreakpointsResponse>('setExceptionBreakpoints', args);
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ export class VariablesView extends ViewletPanel {
|
||||
this.tree.updateChildren();
|
||||
}));
|
||||
this._register(this.tree.onMouseDblClick(e => this.onMouseDblClick(e)));
|
||||
this._register(this.tree.onContextMenu(e => this.onContextMenu(e)));
|
||||
this._register(this.tree.onContextMenu(async e => await this.onContextMenu(e)));
|
||||
|
||||
this._register(this.onDidChangeBodyVisibility(visible => {
|
||||
if (visible && this.needsRefresh) {
|
||||
@@ -152,7 +152,7 @@ export class VariablesView extends ViewletPanel {
|
||||
}
|
||||
}
|
||||
|
||||
private onContextMenu(e: ITreeContextMenuEvent<IExpression | IScope>): void {
|
||||
private async onContextMenu(e: ITreeContextMenuEvent<IExpression | IScope>): Promise<void> {
|
||||
const variable = e.element;
|
||||
if (variable instanceof Variable && !!variable.value) {
|
||||
const actions: IAction[] = [];
|
||||
@@ -174,6 +174,16 @@ export class VariablesView extends ViewletPanel {
|
||||
return Promise.resolve(undefined);
|
||||
}));
|
||||
}
|
||||
if (session && session.capabilities.supportsDataBreakpoints) {
|
||||
const response = await session.dataBreakpointInfo(variable.name, variable.parent.reference);
|
||||
const dataid = response.dataId;
|
||||
if (dataid) {
|
||||
actions.push(new Separator());
|
||||
actions.push(new Action('debug.addDataBreakpoint', nls.localize('setDataBreakpoint', "Set Data Breakpoint"), undefined, true, () => {
|
||||
return this.debugService.addDataBreakpoint(response.description, dataid, !!response.canPersist);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
this.contextMenuService.showContextMenu({
|
||||
getAnchor: () => e.anchor,
|
||||
|
||||
@@ -103,6 +103,7 @@ export interface IReplElementSource {
|
||||
export interface IExpressionContainer extends ITreeElement {
|
||||
readonly hasChildren: boolean;
|
||||
getChildren(): Promise<IExpression[]>;
|
||||
readonly reference?: number;
|
||||
}
|
||||
|
||||
export interface IExpression extends IReplElement, IExpressionContainer {
|
||||
@@ -201,6 +202,8 @@ export interface IDebugSession extends ITreeElement {
|
||||
|
||||
sendBreakpoints(modelUri: uri, bpts: IBreakpoint[], sourceModified: boolean): Promise<void>;
|
||||
sendFunctionBreakpoints(fbps: IFunctionBreakpoint[]): Promise<void>;
|
||||
dataBreakpointInfo(name: string, variablesReference?: number): Promise<{ dataId: string | null, description: string, canPersist?: boolean }>;
|
||||
sendDataBreakpoints(dbps: IDataBreakpoint[]): Promise<void>;
|
||||
sendExceptionBreakpoints(exbpts: IExceptionBreakpoint[]): Promise<void>;
|
||||
|
||||
stackTrace(threadId: number, startFrame: number, levels: number): Promise<DebugProtocol.StackTraceResponse>;
|
||||
@@ -357,6 +360,12 @@ export interface IExceptionBreakpoint extends IEnablement {
|
||||
readonly label: string;
|
||||
}
|
||||
|
||||
export interface IDataBreakpoint extends IBaseBreakpoint {
|
||||
readonly label: string;
|
||||
readonly dataId: string;
|
||||
readonly canPersist: boolean;
|
||||
}
|
||||
|
||||
export interface IExceptionInfo {
|
||||
readonly id?: string;
|
||||
readonly description?: string;
|
||||
@@ -404,6 +413,7 @@ export interface IDebugModel extends ITreeElement {
|
||||
getBreakpoints(filter?: { uri?: uri, lineNumber?: number, column?: number, enabledOnly?: boolean }): ReadonlyArray<IBreakpoint>;
|
||||
areBreakpointsActivated(): boolean;
|
||||
getFunctionBreakpoints(): ReadonlyArray<IFunctionBreakpoint>;
|
||||
getDataBreakpoints(): ReadonlyArray<IDataBreakpoint>;
|
||||
getExceptionBreakpoints(): ReadonlyArray<IExceptionBreakpoint>;
|
||||
getWatchExpressions(): ReadonlyArray<IExpression & IEvaluate>;
|
||||
|
||||
@@ -416,9 +426,9 @@ export interface IDebugModel extends ITreeElement {
|
||||
* An event describing a change to the set of [breakpoints](#debug.Breakpoint).
|
||||
*/
|
||||
export interface IBreakpointsChangeEvent {
|
||||
added?: Array<IBreakpoint | IFunctionBreakpoint>;
|
||||
removed?: Array<IBreakpoint | IFunctionBreakpoint>;
|
||||
changed?: Array<IBreakpoint | IFunctionBreakpoint>;
|
||||
added?: Array<IBreakpoint | IFunctionBreakpoint | IDataBreakpoint>;
|
||||
removed?: Array<IBreakpoint | IFunctionBreakpoint | IDataBreakpoint>;
|
||||
changed?: Array<IBreakpoint | IFunctionBreakpoint | IDataBreakpoint>;
|
||||
sessionOnly?: boolean;
|
||||
}
|
||||
|
||||
@@ -754,6 +764,17 @@ export interface IDebugService {
|
||||
*/
|
||||
removeFunctionBreakpoints(id?: string): Promise<void>;
|
||||
|
||||
/**
|
||||
* Adds a new data breakpoint.
|
||||
*/
|
||||
addDataBreakpoint(label: string, dataId: string, canPersist: boolean): Promise<void>;
|
||||
|
||||
/**
|
||||
* Removes all data breakpoints. If id is passed only removes the data breakpoint with the passed id.
|
||||
* Notifies debug adapter of breakpoint changes.
|
||||
*/
|
||||
removeDataBreakpoints(id?: string): Promise<void>;
|
||||
|
||||
/**
|
||||
* Sends all breakpoints to the passed session.
|
||||
* If session is not passed, sends all breakpoints to each session.
|
||||
|
||||
@@ -16,7 +16,7 @@ import { distinct, lastIndex } from 'vs/base/common/arrays';
|
||||
import { Range, IRange } from 'vs/editor/common/core/range';
|
||||
import {
|
||||
ITreeElement, IExpression, IExpressionContainer, IDebugSession, IStackFrame, IExceptionBreakpoint, IBreakpoint, IFunctionBreakpoint, IDebugModel, IReplElementSource,
|
||||
IThread, IRawModelUpdate, IScope, IRawStoppedDetails, IEnablement, IBreakpointData, IExceptionInfo, IReplElement, IBreakpointsChangeEvent, IBreakpointUpdateData, IBaseBreakpoint, State
|
||||
IThread, IRawModelUpdate, IScope, IRawStoppedDetails, IEnablement, IBreakpointData, IExceptionInfo, IReplElement, IBreakpointsChangeEvent, IBreakpointUpdateData, IBaseBreakpoint, State, IDataBreakpoint
|
||||
} from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { Source, UNKNOWN_SOURCE_LABEL } from 'vs/workbench/contrib/debug/common/debugSource';
|
||||
import { commonSuffixLength } from 'vs/base/common/strings';
|
||||
@@ -735,6 +735,34 @@ export class FunctionBreakpoint extends BaseBreakpoint implements IFunctionBreak
|
||||
}
|
||||
}
|
||||
|
||||
export class DataBreakpoint extends BaseBreakpoint implements IDataBreakpoint {
|
||||
|
||||
constructor(
|
||||
public label: string,
|
||||
public dataId: string,
|
||||
public canPersist: boolean,
|
||||
enabled: boolean,
|
||||
hitCondition: string | undefined,
|
||||
condition: string | undefined,
|
||||
logMessage: string | undefined,
|
||||
id = generateUuid()
|
||||
) {
|
||||
super(enabled, hitCondition, condition, logMessage, id);
|
||||
}
|
||||
|
||||
toJSON(): any {
|
||||
const result = super.toJSON();
|
||||
result.label = this.label;
|
||||
result.dataid = this.dataId;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return this.label;
|
||||
}
|
||||
}
|
||||
|
||||
export class ExceptionBreakpoint extends Enablement implements IExceptionBreakpoint {
|
||||
|
||||
constructor(public filter: string, public label: string, enabled: boolean) {
|
||||
@@ -778,6 +806,7 @@ export class DebugModel implements IDebugModel {
|
||||
private breakpointsActivated: boolean,
|
||||
private functionBreakpoints: FunctionBreakpoint[],
|
||||
private exceptionBreakpoints: ExceptionBreakpoint[],
|
||||
private dataBreakopints: DataBreakpoint[],
|
||||
private watchExpressions: Expression[],
|
||||
private textFileService: ITextFileService
|
||||
) {
|
||||
@@ -918,6 +947,10 @@ export class DebugModel implements IDebugModel {
|
||||
return this.functionBreakpoints;
|
||||
}
|
||||
|
||||
getDataBreakpoints(): IDataBreakpoint[] {
|
||||
return this.dataBreakopints;
|
||||
}
|
||||
|
||||
getExceptionBreakpoints(): IExceptionBreakpoint[] {
|
||||
return this.exceptionBreakpoints;
|
||||
}
|
||||
@@ -991,6 +1024,12 @@ export class DebugModel implements IDebugModel {
|
||||
fbp.setSessionData(sessionId, fbpData);
|
||||
}
|
||||
});
|
||||
this.dataBreakopints.forEach(dbp => {
|
||||
const dbpData = data.get(dbp.getId());
|
||||
if (dbpData) {
|
||||
dbp.setSessionData(sessionId, dbpData);
|
||||
}
|
||||
});
|
||||
|
||||
this._onDidChangeBreakpoints.fire({
|
||||
sessionOnly: true
|
||||
@@ -1001,6 +1040,7 @@ export class DebugModel implements IDebugModel {
|
||||
this.breakpointsSessionId = sessionId;
|
||||
this.breakpoints.forEach(bp => bp.setSessionId(sessionId));
|
||||
this.functionBreakpoints.forEach(fbp => fbp.setSessionId(sessionId));
|
||||
this.dataBreakopints.forEach(dbp => dbp.setSessionId(sessionId));
|
||||
|
||||
this._onDidChangeBreakpoints.fire({
|
||||
sessionOnly: true
|
||||
@@ -1038,7 +1078,7 @@ export class DebugModel implements IDebugModel {
|
||||
}
|
||||
|
||||
enableOrDisableAllBreakpoints(enable: boolean): void {
|
||||
const changed: Array<IBreakpoint | IFunctionBreakpoint> = [];
|
||||
const changed: Array<IBreakpoint | IFunctionBreakpoint | IDataBreakpoint> = [];
|
||||
|
||||
this.breakpoints.forEach(bp => {
|
||||
if (bp.enabled !== enable) {
|
||||
@@ -1052,6 +1092,12 @@ export class DebugModel implements IDebugModel {
|
||||
}
|
||||
fbp.enabled = enable;
|
||||
});
|
||||
this.dataBreakopints.forEach(dbp => {
|
||||
if (dbp.enabled !== enable) {
|
||||
changed.push(dbp);
|
||||
}
|
||||
dbp.enabled = enable;
|
||||
});
|
||||
|
||||
this._onDidChangeBreakpoints.fire({ changed: changed });
|
||||
}
|
||||
@@ -1073,7 +1119,6 @@ export class DebugModel implements IDebugModel {
|
||||
}
|
||||
|
||||
removeFunctionBreakpoints(id?: string): void {
|
||||
|
||||
let removed: FunctionBreakpoint[];
|
||||
if (id) {
|
||||
removed = this.functionBreakpoints.filter(fbp => fbp.getId() === id);
|
||||
@@ -1082,7 +1127,25 @@ export class DebugModel implements IDebugModel {
|
||||
removed = this.functionBreakpoints;
|
||||
this.functionBreakpoints = [];
|
||||
}
|
||||
this._onDidChangeBreakpoints.fire({ removed: removed });
|
||||
this._onDidChangeBreakpoints.fire({ removed });
|
||||
}
|
||||
|
||||
addDataBreakpoint(label: string, dataId: string, canPersist: boolean): void {
|
||||
const newDataBreakpoint = new DataBreakpoint(label, dataId, canPersist, true, undefined, undefined, undefined);
|
||||
this.dataBreakopints.push(newDataBreakpoint);
|
||||
this._onDidChangeBreakpoints.fire({ added: [newDataBreakpoint] });
|
||||
}
|
||||
|
||||
removeDataBreakpoints(id?: string): void {
|
||||
let removed: DataBreakpoint[];
|
||||
if (id) {
|
||||
removed = this.dataBreakopints.filter(fbp => fbp.getId() === id);
|
||||
this.dataBreakopints = this.dataBreakopints.filter(fbp => fbp.getId() !== id);
|
||||
} else {
|
||||
removed = this.dataBreakopints;
|
||||
this.dataBreakopints = [];
|
||||
}
|
||||
this._onDidChangeBreakpoints.fire({ removed });
|
||||
}
|
||||
|
||||
getWatchExpressions(): Expression[] {
|
||||
|
||||
@@ -23,7 +23,7 @@ suite('Debug - Model', () => {
|
||||
let rawSession: MockRawSession;
|
||||
|
||||
setup(() => {
|
||||
model = new DebugModel([], true, [], [], [], <any>{ isDirty: (e: any) => false });
|
||||
model = new DebugModel([], true, [], [], [], [], <any>{ isDirty: (e: any) => false });
|
||||
rawSession = new MockRawSession();
|
||||
});
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { URI as uri } from 'vs/base/common/uri';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { ILaunch, IDebugService, State, IDebugSession, IConfigurationManager, IStackFrame, IBreakpointData, IBreakpointUpdateData, IConfig, IDebugModel, IViewModel, IBreakpoint, LoadedSourceEvent, IThread, IRawModelUpdate, IFunctionBreakpoint, IExceptionBreakpoint, IDebugger, IExceptionInfo, AdapterEndEvent, IReplElement, IExpression, IReplElementSource } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { ILaunch, IDebugService, State, IDebugSession, IConfigurationManager, IStackFrame, IBreakpointData, IBreakpointUpdateData, IConfig, IDebugModel, IViewModel, IBreakpoint, LoadedSourceEvent, IThread, IRawModelUpdate, IFunctionBreakpoint, IExceptionBreakpoint, IDebugger, IExceptionInfo, AdapterEndEvent, IReplElement, IExpression, IReplElementSource, IDataBreakpoint } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { Source } from 'vs/workbench/contrib/debug/common/debugSource';
|
||||
import { CompletionItem } from 'vs/editor/common/modes';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
@@ -79,6 +79,13 @@ export class MockDebugService implements IDebugService {
|
||||
throw new Error('not implemented');
|
||||
}
|
||||
|
||||
addDataBreakpoint(label: string, dataId: string, canPersist: boolean): Promise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
removeDataBreakpoints(id?: string | undefined): Promise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
public addReplExpression(name: string): Promise<void> {
|
||||
throw new Error('not implemented');
|
||||
}
|
||||
@@ -125,6 +132,13 @@ export class MockDebugService implements IDebugService {
|
||||
}
|
||||
|
||||
export class MockSession implements IDebugSession {
|
||||
dataBreakpointInfo(name: string, variablesReference?: number | undefined): Promise<{ dataId: string | null; description: string; canPersist?: boolean | undefined; }> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
sendDataBreakpoints(dbps: IDataBreakpoint[]): Promise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
subId: string | undefined;
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ import { timeout } from 'vs/base/common/async';
|
||||
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry'; // {{SQL CARBON EDIT}}
|
||||
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys'; // {{SQL CARBON EDIT}}
|
||||
import { IWorkspaceStatsService } from 'vs/workbench/contrib/stats/common/workspaceStats';
|
||||
import { Platform, setImmediate } from 'vs/base/common/platform';
|
||||
import { setImmediate, isWeb } from 'vs/base/common/platform';
|
||||
import { platform, env as processEnv } from 'vs/base/common/process';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
|
||||
@@ -996,7 +996,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
* If user has any of the tools listed in this.productService.exeBasedExtensionTips, fetch corresponding recommendations
|
||||
*/
|
||||
private async fetchExecutableRecommendations(important: boolean): Promise<void> {
|
||||
if (Platform.Web) {
|
||||
if (isWeb) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ class Extension implements IExtension {
|
||||
|
||||
private get localIconUrl(): string | null {
|
||||
if (this.local && this.local.manifest.icon) {
|
||||
return asDomUri(resources.joinPath(this.local.location, this.local.manifest.icon)).toString();
|
||||
return asDomUri(resources.joinPath(this.local.location, this.local.manifest.icon)).toString(true);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -236,7 +236,6 @@ class ResolveSaveConflictAction extends Action {
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@IEnvironmentService private readonly environmentService: IEnvironmentService
|
||||
) {
|
||||
super('workbench.files.action.resolveConflict', nls.localize('compareChanges', "Compare"));
|
||||
@@ -250,21 +249,15 @@ class ResolveSaveConflictAction extends Action {
|
||||
|
||||
await TextFileContentProvider.open(resource, CONFLICT_RESOLUTION_SCHEME, editorLabel, this.editorService, { pinned: true });
|
||||
|
||||
if (this.storageService.getBoolean(LEARN_MORE_DIRTY_WRITE_IGNORE_KEY, StorageScope.GLOBAL)) {
|
||||
return; // return if this message is ignored
|
||||
}
|
||||
|
||||
// Show additional help how to resolve the save conflict
|
||||
const primaryActions: IAction[] = [
|
||||
this.instantiationService.createInstance(ResolveConflictLearnMoreAction)
|
||||
];
|
||||
const secondaryActions: IAction[] = [
|
||||
this.instantiationService.createInstance(DoNotShowResolveConflictLearnMoreAction)
|
||||
];
|
||||
|
||||
const actions: INotificationActions = { primary: primaryActions, secondary: secondaryActions };
|
||||
const handle = this.notificationService.notify({ severity: Severity.Info, message: conflictEditorHelp, actions });
|
||||
Event.once(handle.onDidClose)(() => { dispose(primaryActions); dispose(secondaryActions); });
|
||||
const actions: INotificationActions = { primary: [this.instantiationService.createInstance(ResolveConflictLearnMoreAction)] };
|
||||
const handle = this.notificationService.notify({
|
||||
severity: Severity.Info,
|
||||
message: conflictEditorHelp,
|
||||
actions,
|
||||
neverShowAgain: { id: LEARN_MORE_DIRTY_WRITE_IGNORE_KEY, isSecondary: true }
|
||||
});
|
||||
Event.once(handle.onDidClose)(() => dispose(actions.primary!));
|
||||
pendingResolveSaveConflictMessages.push(handle);
|
||||
}
|
||||
|
||||
|
||||
@@ -218,56 +218,46 @@ export class FilesRenderer implements ITreeRenderer<ExplorerItem, FuzzyScore, IF
|
||||
const lastDot = value.lastIndexOf('.');
|
||||
|
||||
inputBox.value = value;
|
||||
inputBox.focus();
|
||||
inputBox.select({ start: 0, end: lastDot > 0 && !stat.isDirectory ? lastDot : value.length });
|
||||
|
||||
let isFinishableDisposeEvent = false;
|
||||
setTimeout(() => {
|
||||
// Check if disposed
|
||||
if (!inputBox.inputElement) {
|
||||
return;
|
||||
}
|
||||
inputBox.focus();
|
||||
inputBox.select({ start: 0, end: lastDot > 0 && !stat.isDirectory ? lastDot : value.length });
|
||||
isFinishableDisposeEvent = true;
|
||||
}, 0);
|
||||
|
||||
const done = once(async (success: boolean) => {
|
||||
const done = once(async (success: boolean, blur: boolean) => {
|
||||
label.element.style.display = 'none';
|
||||
const value = inputBox.value;
|
||||
dispose(toDispose);
|
||||
label.element.remove();
|
||||
// Timeout: once done rendering only then re-render #70902
|
||||
setTimeout(() => editableData.onFinish(value, success), 0);
|
||||
container.removeChild(label.element);
|
||||
editableData.onFinish(value, success);
|
||||
});
|
||||
|
||||
const blurDisposable = DOM.addDisposableListener(inputBox.inputElement, DOM.EventType.BLUR, () => {
|
||||
done(inputBox.isInputValid());
|
||||
});
|
||||
// It can happen that the tree re-renders this node. When that happens,
|
||||
// we're gonna get a blur event first and only after an element disposable.
|
||||
// Because of that, we should setTimeout the blur handler to differentiate
|
||||
// between the blur happening because of a unrender or because of a user action.
|
||||
let ignoreBlur = false;
|
||||
|
||||
const toDispose = [
|
||||
inputBox,
|
||||
DOM.addStandardDisposableListener(inputBox.inputElement, DOM.EventType.KEY_DOWN, (e: IKeyboardEvent) => {
|
||||
if (e.equals(KeyCode.Enter)) {
|
||||
if (inputBox.validate()) {
|
||||
done(true);
|
||||
done(true, false);
|
||||
}
|
||||
} else if (e.equals(KeyCode.Escape)) {
|
||||
done(false);
|
||||
done(false, false);
|
||||
}
|
||||
}),
|
||||
blurDisposable,
|
||||
DOM.addDisposableListener(inputBox.inputElement, DOM.EventType.BLUR, () => {
|
||||
setTimeout(() => {
|
||||
if (!ignoreBlur) {
|
||||
done(inputBox.isInputValid(), true);
|
||||
}
|
||||
}, 0);
|
||||
}),
|
||||
label,
|
||||
styler
|
||||
];
|
||||
|
||||
return toDisposable(() => {
|
||||
if (isFinishableDisposeEvent) {
|
||||
done(false);
|
||||
}
|
||||
else {
|
||||
dispose(toDispose);
|
||||
label.element.remove();
|
||||
}
|
||||
});
|
||||
return toDisposable(() => ignoreBlur = true);
|
||||
}
|
||||
|
||||
disposeElement?(element: ITreeNode<ExplorerItem, FuzzyScore>, index: number, templateData: IFileTemplateData): void {
|
||||
|
||||
@@ -68,8 +68,7 @@ export class LocalizationWorkbenchContribution extends Disposable implements IWo
|
||||
}
|
||||
|
||||
private onDidInstallExtension(e: DidInstallExtensionEvent): void {
|
||||
const donotAskUpdateKey = 'langugage.update.donotask';
|
||||
if (!this.storageService.getBoolean(donotAskUpdateKey, StorageScope.GLOBAL) && e.local && e.operation === InstallOperation.Install && e.local.manifest.contributes && e.local.manifest.contributes.localizations && e.local.manifest.contributes.localizations.length) {
|
||||
if (e.local && e.operation === InstallOperation.Install && e.local.manifest.contributes && e.local.manifest.contributes.localizations && e.local.manifest.contributes.localizations.length) {
|
||||
const locale = e.local.manifest.contributes.localizations[0].languageId;
|
||||
if (platform.language !== locale) {
|
||||
const updateAndRestart = platform.locale !== locale;
|
||||
@@ -83,12 +82,11 @@ export class LocalizationWorkbenchContribution extends Disposable implements IWo
|
||||
const updatePromise = updateAndRestart ? this.jsonEditingService.write(this.environmentService.localeResource, { key: 'locale', value: locale }, true) : Promise.resolve(undefined);
|
||||
updatePromise.then(() => this.windowsService.relaunch({}), e => this.notificationService.error(e));
|
||||
}
|
||||
}, {
|
||||
label: localize('neverAgain', "Don't Show Again"),
|
||||
isSecondary: true,
|
||||
run: () => this.storageService.store(donotAskUpdateKey, true, StorageScope.GLOBAL)
|
||||
}],
|
||||
{ sticky: true }
|
||||
{
|
||||
sticky: true,
|
||||
neverShowAgain: { id: 'langugage.update.donotask', isSecondary: true }
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -302,4 +300,4 @@ ExtensionsRegistry.registerExtensionPoint({
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -168,13 +168,14 @@ class InsertSnippetAction extends EditorAction {
|
||||
return quickInputService.pick(picks, { matchOnDetail: true }).then(pick => resolve(pick && pick.snippet), reject);
|
||||
}
|
||||
}).then(async snippet => {
|
||||
if (!snippet) {
|
||||
return;
|
||||
}
|
||||
let clipboardText: string | undefined;
|
||||
if (snippet.needsClipboard) {
|
||||
clipboardText = await clipboardService.readText();
|
||||
}
|
||||
if (snippet) {
|
||||
SnippetController2.get(editor).insert(snippet.codeSnippet, { clipboardText });
|
||||
}
|
||||
SnippetController2.get(editor).insert(snippet.codeSnippet, { clipboardText });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,9 +8,8 @@ import { IFileService, IResolveFileResult, IFileStat } from 'vs/platform/files/c
|
||||
import { IWorkspaceContextService, WorkbenchState, IWorkspace } from 'vs/platform/workspace/common/workspace';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { IWindowService, IWindowConfiguration } from 'vs/platform/windows/common/windows';
|
||||
import { INotificationService, IPromptChoice } from 'vs/platform/notification/common/notification';
|
||||
import { INotificationService, NeverShowAgainScope, INeverShowAgainOptions } from 'vs/platform/notification/common/notification';
|
||||
import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { ITextFileService, ITextFileContent } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
@@ -22,8 +21,6 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { IWorkspaceStatsService, Tags } from 'vs/workbench/contrib/stats/common/workspaceStats';
|
||||
import { getHashedRemotesFromConfig } from 'vs/workbench/contrib/stats/electron-browser/workspaceStats';
|
||||
|
||||
const DISABLE_WORKSPACE_PROMPT_KEY = 'workspaces.dontPromptToOpen';
|
||||
|
||||
const ModulesToLookFor = [
|
||||
// Packages that suggest a node server
|
||||
'express',
|
||||
@@ -103,7 +100,6 @@ export class WorkspaceStatsService implements IWorkspaceStatsService {
|
||||
@IWindowService private readonly windowService: IWindowService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@ITextFileService private readonly textFileService: ITextFileService
|
||||
) { }
|
||||
|
||||
@@ -449,15 +445,7 @@ export class WorkspaceStatsService implements IWorkspaceStatsService {
|
||||
}
|
||||
|
||||
private doHandleWorkspaceFiles(folder: URI, workspaces: string[]): void {
|
||||
if (this.storageService.getBoolean(DISABLE_WORKSPACE_PROMPT_KEY, StorageScope.WORKSPACE)) {
|
||||
return; // prompt disabled by user
|
||||
}
|
||||
|
||||
const doNotShowAgain: IPromptChoice = {
|
||||
label: localize('never again', "Don't Show Again"),
|
||||
isSecondary: true,
|
||||
run: () => this.storageService.store(DISABLE_WORKSPACE_PROMPT_KEY, true, StorageScope.WORKSPACE)
|
||||
};
|
||||
const neverShowAgain: INeverShowAgainOptions = { id: 'workspaces.dontPromptToOpen', scope: NeverShowAgainScope.WORKSPACE, isSecondary: true };
|
||||
|
||||
// Prompt to open one workspace
|
||||
if (workspaces.length === 1) {
|
||||
@@ -466,7 +454,7 @@ export class WorkspaceStatsService implements IWorkspaceStatsService {
|
||||
this.notificationService.prompt(Severity.Info, localize('workspaceFound', "This folder contains a workspace file '{0}'. Do you want to open it? [Learn more]({1}) about workspace files.", workspaceFile, 'https://go.microsoft.com/fwlink/?linkid=2025315'), [{
|
||||
label: localize('openWorkspace', "Open Workspace"),
|
||||
run: () => this.windowService.openWindow([{ workspaceUri: joinPath(folder, workspaceFile) }])
|
||||
}, doNotShowAgain]);
|
||||
}], { neverShowAgain });
|
||||
}
|
||||
|
||||
// Prompt to select a workspace from many
|
||||
@@ -482,7 +470,7 @@ export class WorkspaceStatsService implements IWorkspaceStatsService {
|
||||
}
|
||||
});
|
||||
}
|
||||
}, doNotShowAgain]);
|
||||
}], { neverShowAgain });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag
|
||||
import { ITerminalConfiguration, ITerminalFont, IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, TERMINAL_CONFIG_SECTION, DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, MINIMUM_LETTER_SPACING, LinuxDistro, IShellLaunchConfig } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { Terminal as XTermTerminal } from 'xterm';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { INotificationService, NeverShowAgainScope } from 'vs/platform/notification/common/notification';
|
||||
import { IBrowserTerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { basename } from 'vs/base/common/path';
|
||||
@@ -254,7 +254,6 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper {
|
||||
return r;
|
||||
}
|
||||
|
||||
private readonly NO_RECOMMENDATIONS_KEY = 'terminalConfigHelper/launchRecommendationsIgnore';
|
||||
private recommendationsShown = false;
|
||||
|
||||
public async showRecommendations(shellLaunchConfig: IShellLaunchConfig): Promise<void> {
|
||||
@@ -264,10 +263,6 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper {
|
||||
this.recommendationsShown = true;
|
||||
|
||||
if (platform.isWindows && shellLaunchConfig.executable && basename(shellLaunchConfig.executable).toLowerCase() === 'wsl.exe') {
|
||||
if (this._storageService.getBoolean(this.NO_RECOMMENDATIONS_KEY, StorageScope.WORKSPACE, false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! await this.isExtensionInstalled('ms-vscode-remote.remote-wsl')) {
|
||||
this._notificationService.prompt(
|
||||
Severity.Info,
|
||||
@@ -276,16 +271,10 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper {
|
||||
"Check out the 'Visual Studio Code Remote - WSL' extension for a great development experience in WSL. Click [here]({0}) to learn more.",
|
||||
'https://go.microsoft.com/fwlink/?linkid=2097212'
|
||||
),
|
||||
[
|
||||
{
|
||||
label: nls.localize('doNotShowAgain', "Don't Show Again"),
|
||||
run: () => {
|
||||
this._storageService.store(this.NO_RECOMMENDATIONS_KEY, true, StorageScope.WORKSPACE);
|
||||
}
|
||||
}
|
||||
],
|
||||
[],
|
||||
{
|
||||
sticky: true
|
||||
sticky: true,
|
||||
neverShowAgain: { id: 'terminalConfigHelper/launchRecommendationsIgnore', scope: NeverShowAgainScope.WORKSPACE }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -144,18 +144,20 @@ export function getCwd(
|
||||
try {
|
||||
customCwd = configurationResolverService.resolve(lastActiveWorkspace, customCwd);
|
||||
} catch (e) {
|
||||
// There was an issue resolving a variable, just use the unresolved customCwd which
|
||||
// which will fail, and log the error in the console.
|
||||
// There was an issue resolving a variable, log the error in the console and
|
||||
// fallback to the default.
|
||||
if (logService) {
|
||||
logService.error('Could not resolve terminal.integrated.cwd', e);
|
||||
}
|
||||
return customCwd;
|
||||
customCwd = undefined;
|
||||
}
|
||||
}
|
||||
if (path.isAbsolute(customCwd)) {
|
||||
cwd = customCwd;
|
||||
} else if (root) {
|
||||
cwd = path.join(root.fsPath, customCwd);
|
||||
if (customCwd) {
|
||||
if (path.isAbsolute(customCwd)) {
|
||||
cwd = customCwd;
|
||||
} else if (root) {
|
||||
cwd = path.join(root.fsPath, customCwd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,33 +210,33 @@ export function getDefaultShell(
|
||||
if (!maybeExecutable) {
|
||||
maybeExecutable = getShellSetting(fetchSetting, isWorkspaceShellAllowed, 'shell', platformOverride);
|
||||
}
|
||||
maybeExecutable = maybeExecutable || defaultShell;
|
||||
let executable: string = maybeExecutable || defaultShell;
|
||||
|
||||
// Change Sysnative to System32 if the OS is Windows but NOT WoW64. It's
|
||||
// safe to assume that this was used by accident as Sysnative does not
|
||||
// exist and will break the terminal in non-WoW64 environments.
|
||||
if ((platformOverride === platform.Platform.Windows) && !isWoW64 && windir) {
|
||||
const sysnativePath = path.join(windir, 'Sysnative').replace(/\//g, '\\').toLowerCase();
|
||||
if (maybeExecutable && maybeExecutable.toLowerCase().indexOf(sysnativePath) === 0) {
|
||||
maybeExecutable = path.join(windir, 'System32', maybeExecutable.substr(sysnativePath.length + 1));
|
||||
if (executable && executable.toLowerCase().indexOf(sysnativePath) === 0) {
|
||||
executable = path.join(windir, 'System32', executable.substr(sysnativePath.length + 1));
|
||||
}
|
||||
}
|
||||
|
||||
// Convert / to \ on Windows for convenience
|
||||
if (maybeExecutable && platformOverride === platform.Platform.Windows) {
|
||||
maybeExecutable = maybeExecutable.replace(/\//g, '\\');
|
||||
if (executable && platformOverride === platform.Platform.Windows) {
|
||||
executable = executable.replace(/\//g, '\\');
|
||||
}
|
||||
|
||||
if (configurationResolverService) {
|
||||
try {
|
||||
maybeExecutable = configurationResolverService.resolve(lastActiveWorkspace, maybeExecutable);
|
||||
executable = configurationResolverService.resolve(lastActiveWorkspace, executable);
|
||||
} catch (e) {
|
||||
logService.error(`Could not resolve shell`, e);
|
||||
maybeExecutable = maybeExecutable;
|
||||
executable = executable;
|
||||
}
|
||||
}
|
||||
|
||||
return maybeExecutable;
|
||||
return executable;
|
||||
}
|
||||
|
||||
export function getDefaultShellArgs(
|
||||
|
||||
@@ -19,7 +19,7 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag
|
||||
import { IUpdateService, State as UpdateState, StateType, IUpdate } from 'vs/platform/update/common/update';
|
||||
import * as semver from 'semver-umd';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { INotificationService, INotificationHandle, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { ReleaseNotesManager } from './releaseNotesEditor';
|
||||
@@ -165,32 +165,8 @@ export class ProductContribution implements IWorkbenchContribution {
|
||||
}
|
||||
}
|
||||
|
||||
class NeverShowAgain {
|
||||
|
||||
private readonly key: string;
|
||||
|
||||
readonly action = new Action(`neverShowAgain:${this.key}`, nls.localize('neveragain', "Don't Show Again"), undefined, true, (notification: INotificationHandle) => {
|
||||
|
||||
// Hide notification
|
||||
notification.close();
|
||||
|
||||
this.storageService.store(this.key, true, StorageScope.GLOBAL);
|
||||
|
||||
return Promise.resolve(true);
|
||||
});
|
||||
|
||||
constructor(key: string, @IStorageService private readonly storageService: IStorageService) {
|
||||
this.key = `neverShowAgain:${key}`;
|
||||
}
|
||||
|
||||
shouldShow(): boolean {
|
||||
return !this.storageService.getBoolean(this.key, StorageScope.GLOBAL, false);
|
||||
}
|
||||
}
|
||||
|
||||
export class Win3264BitContribution implements IWorkbenchContribution {
|
||||
|
||||
private static readonly KEY = 'update/win32-64bits';
|
||||
private static readonly URL = 'https://code.visualstudio.com/updates/v1_15#_windows-64-bit';
|
||||
private static readonly INSIDER_URL = 'https://github.com/Microsoft/vscode-docs/blob/vnext/release-notes/v1_15.md#windows-64-bit';
|
||||
|
||||
@@ -203,28 +179,18 @@ export class Win3264BitContribution implements IWorkbenchContribution {
|
||||
return;
|
||||
}
|
||||
|
||||
const neverShowAgain = new NeverShowAgain(Win3264BitContribution.KEY, storageService);
|
||||
|
||||
if (!neverShowAgain.shouldShow()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const url = product.quality === 'insider'
|
||||
? Win3264BitContribution.INSIDER_URL
|
||||
: Win3264BitContribution.URL;
|
||||
|
||||
const handle = notificationService.prompt(
|
||||
notificationService.prompt(
|
||||
severity.Info,
|
||||
nls.localize('64bitisavailable', "{0} for 64-bit Windows is now available! Click [here]({1}) to learn more.", product.nameShort, url),
|
||||
[{
|
||||
label: nls.localize('neveragain', "Don't Show Again"),
|
||||
isSecondary: true,
|
||||
run: () => {
|
||||
neverShowAgain.action.run(handle);
|
||||
neverShowAgain.action.dispose();
|
||||
}
|
||||
}],
|
||||
{ sticky: true }
|
||||
[],
|
||||
{
|
||||
sticky: true,
|
||||
neverShowAgain: { id: 'neverShowAgain:update/win32-64bits', isSecondary: true }
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -401,23 +367,13 @@ export class UpdateContribution extends Disposable implements IWorkbenchContribu
|
||||
}
|
||||
|
||||
// windows fast updates (target === system)
|
||||
const neverShowAgain = new NeverShowAgain('update/win32-fast-updates', this.storageService);
|
||||
|
||||
if (!neverShowAgain.shouldShow()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const handle = this.notificationService.prompt(
|
||||
this.notificationService.prompt(
|
||||
severity.Info,
|
||||
nls.localize('updateInstalling', "{0} {1} is being installed in the background; we'll let you know when it's done.", product.nameLong, update.productVersion),
|
||||
[{
|
||||
label: nls.localize('neveragain', "Don't Show Again"),
|
||||
isSecondary: true,
|
||||
run: () => {
|
||||
neverShowAgain.action.run(handle);
|
||||
neverShowAgain.action.dispose();
|
||||
}
|
||||
}]
|
||||
[],
|
||||
{
|
||||
neverShowAgain: { id: 'neverShowAgain:update/win32-fast-updates', isSecondary: true }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,11 +39,11 @@ class WebviewIconsManager {
|
||||
this._icons.forEach((value, key) => {
|
||||
const webviewSelector = `.show-file-icons .webview-${key}-name-file-icon::before`;
|
||||
if (URI.isUri(value)) {
|
||||
cssRules.push(`${webviewSelector} { content: ""; background-image: url(${dom.asDomUri(value).toString()}); }`);
|
||||
cssRules.push(`${webviewSelector} { content: ""; background-image: ${dom.asCSSUrl(value)}; }`);
|
||||
}
|
||||
else {
|
||||
cssRules.push(`.vs ${webviewSelector} { content: ""; background-image: url(${dom.asDomUri(value.light).toString()}); }`);
|
||||
cssRules.push(`.vs-dark ${webviewSelector} { content: ""; background-image: url(${dom.asDomUri(value.dark).toString()}); }`);
|
||||
cssRules.push(`.vs ${webviewSelector} { content: ""; background-image: ${dom.asCSSUrl(value.light)}; }`);
|
||||
cssRules.push(`.vs-dark ${webviewSelector} { content: ""; background-image: ${dom.asCSSUrl(value.dark)}; }`);
|
||||
}
|
||||
});
|
||||
this._styleElement.innerHTML = cssRules.join('\n');
|
||||
|
||||
@@ -22,10 +22,16 @@ import { WebWorkerExtensionHostStarter } from 'vs/workbench/services/extensions/
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { isWebExtension } from 'vs/workbench/services/extensions/common/extensionsUtil';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { FetchFileSystemProvider } from 'vs/workbench/services/extensions/browser/webWorkerFileSystemProvider';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IStaticExtensionsService } from 'vs/workbench/services/extensions/common/staticExtensions';
|
||||
|
||||
export class ExtensionService extends AbstractExtensionService implements IExtensionService {
|
||||
|
||||
private _remoteExtensionsEnvironmentData: IRemoteAgentEnvironment | null;
|
||||
private _disposables = new DisposableStore();
|
||||
private _remoteExtensionsEnvironmentData: IRemoteAgentEnvironment | null = null;
|
||||
|
||||
constructor(
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@@ -37,6 +43,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
@IProductService productService: IProductService,
|
||||
@IRemoteAgentService private readonly _remoteAgentService: IRemoteAgentService,
|
||||
@IConfigurationService private readonly _configService: IConfigurationService,
|
||||
@IStaticExtensionsService private readonly _staticExtensions: IStaticExtensionsService,
|
||||
) {
|
||||
super(
|
||||
instantiationService,
|
||||
@@ -48,8 +55,19 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
productService,
|
||||
);
|
||||
|
||||
this._remoteExtensionsEnvironmentData = null;
|
||||
this._initialize();
|
||||
this._initFetchFileSystem();
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._disposables.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
private _initFetchFileSystem(): void {
|
||||
const provider = new FetchFileSystemProvider();
|
||||
this._disposables.add(this._fileService.registerProvider(Schemas.http, provider));
|
||||
this._disposables.add(this._fileService.registerProvider(Schemas.https, provider));
|
||||
}
|
||||
|
||||
private _createProvider(remoteAuthority: string): IInitDataProvider {
|
||||
@@ -84,23 +102,31 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
|
||||
protected async _scanAndHandleExtensions(): Promise<void> {
|
||||
// fetch the remote environment
|
||||
const remoteEnv = (await this._remoteAgentService.getEnvironment())!;
|
||||
let [remoteEnv, localExtensions] = await Promise.all([
|
||||
<Promise<IRemoteAgentEnvironment>>this._remoteAgentService.getEnvironment(),
|
||||
this._staticExtensions.getExtensions()
|
||||
]);
|
||||
|
||||
// enable or disable proposed API per extension
|
||||
// local: only enabled and web'ish extension
|
||||
localExtensions = localExtensions.filter(ext => this._isEnabled(ext) && isWebExtension(ext, this._configService));
|
||||
this._checkEnableProposedApi(localExtensions);
|
||||
|
||||
// remote: only enabled and none-web'ish extension
|
||||
remoteEnv.extensions = remoteEnv.extensions.filter(extension => this._isEnabled(extension) && !isWebExtension(extension, this._configService));
|
||||
this._checkEnableProposedApi(remoteEnv.extensions);
|
||||
|
||||
// remove disabled extensions
|
||||
remoteEnv.extensions = remoteEnv.extensions.filter(extension => this._isEnabled(extension));
|
||||
// in case of overlap, the remote wins
|
||||
const isRemoteExtension = new Set<string>();
|
||||
remoteEnv.extensions.forEach(extension => isRemoteExtension.add(ExtensionIdentifier.toKey(extension.identifier)));
|
||||
localExtensions = localExtensions.filter(extension => !isRemoteExtension.has(ExtensionIdentifier.toKey(extension.identifier)));
|
||||
|
||||
// save for remote extension's init data
|
||||
this._remoteExtensionsEnvironmentData = remoteEnv;
|
||||
|
||||
// this._handleExtensionPoints((<IExtensionDescription[]>[]).concat(remoteEnv.extensions).concat(localExtensions));
|
||||
const result = this._registry.deltaExtensions(remoteEnv.extensions, []);
|
||||
const result = this._registry.deltaExtensions(remoteEnv.extensions.concat(localExtensions), []);
|
||||
if (result.removedDueToLooping.length > 0) {
|
||||
this._logOrShowMessage(Severity.Error, nls.localize('looping', "The following extensions contain dependency loops and have been disabled: {0}", result.removedDueToLooping.map(e => `'${e.identifier.value}'`).join(', ')));
|
||||
}
|
||||
|
||||
this._doHandleExtensionPoints(this._registry.getAllExtensionDescriptions());
|
||||
}
|
||||
|
||||
|
||||
@@ -65,8 +65,8 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter {
|
||||
};
|
||||
|
||||
worker.onerror = (event) => {
|
||||
console.error(event.error);
|
||||
this._onDidExit.fire([81, event.error]);
|
||||
console.error(event.message, event.error);
|
||||
this._onDidExit.fire([81, event.message || event.error]);
|
||||
};
|
||||
|
||||
// keep for cleanup
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IFileSystemProvider, FileSystemProviderCapabilities, IStat, FileType, FileDeleteOptions, FileOverwriteOptions, FileWriteOptions, FileSystemProviderError, FileSystemProviderErrorCode } from 'vs/platform/files/common/files';
|
||||
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { NotImplementedError } from 'vs/base/common/errors';
|
||||
|
||||
export class FetchFileSystemProvider implements IFileSystemProvider {
|
||||
|
||||
readonly capabilities = FileSystemProviderCapabilities.Readonly + FileSystemProviderCapabilities.FileReadWrite + FileSystemProviderCapabilities.PathCaseSensitive;
|
||||
readonly onDidChangeCapabilities = Event.None;
|
||||
readonly onDidChangeFile = Event.None;
|
||||
|
||||
// working implementations
|
||||
async readFile(resource: URI): Promise<Uint8Array> {
|
||||
try {
|
||||
const res = await fetch(resource.toString(true));
|
||||
if (res.status === 200) {
|
||||
return new Uint8Array(await res.arrayBuffer());
|
||||
}
|
||||
throw new FileSystemProviderError(res.statusText, FileSystemProviderErrorCode.Unknown);
|
||||
} catch (err) {
|
||||
throw new FileSystemProviderError(err, FileSystemProviderErrorCode.Unknown);
|
||||
}
|
||||
}
|
||||
|
||||
// fake implementations
|
||||
async stat(_resource: URI): Promise<IStat> {
|
||||
return {
|
||||
type: FileType.File,
|
||||
size: 0,
|
||||
mtime: 0,
|
||||
ctime: 0
|
||||
};
|
||||
}
|
||||
|
||||
watch(): IDisposable {
|
||||
return Disposable.None;
|
||||
}
|
||||
|
||||
// error implementations
|
||||
writeFile(_resource: URI, _content: Uint8Array, _opts: FileWriteOptions): Promise<void> {
|
||||
throw new NotImplementedError();
|
||||
}
|
||||
readdir(_resource: URI): Promise<[string, FileType][]> {
|
||||
throw new NotImplementedError();
|
||||
}
|
||||
mkdir(_resource: URI): Promise<void> {
|
||||
throw new NotImplementedError();
|
||||
}
|
||||
delete(_resource: URI, _opts: FileDeleteOptions): Promise<void> {
|
||||
throw new NotImplementedError();
|
||||
}
|
||||
rename(_from: URI, _to: URI, _opts: FileOverwriteOptions): Promise<void> {
|
||||
throw new NotImplementedError();
|
||||
}
|
||||
}
|
||||
@@ -61,9 +61,7 @@ export interface IExtensionPointUser<T> {
|
||||
collector: ExtensionMessageCollector;
|
||||
}
|
||||
|
||||
export interface IExtensionPointHandler<T> {
|
||||
(extensions: IExtensionPointUser<T>[], delta: ExtensionPointUserDelta<T>): void;
|
||||
}
|
||||
export type IExtensionPointHandler<T> = (extensions: readonly IExtensionPointUser<T>[], delta: ExtensionPointUserDelta<T>) => void;
|
||||
|
||||
export interface IExtensionPoint<T> {
|
||||
name: string;
|
||||
@@ -73,7 +71,7 @@ export interface IExtensionPoint<T> {
|
||||
|
||||
export class ExtensionPointUserDelta<T> {
|
||||
|
||||
private static _toSet<T>(arr: IExtensionPointUser<T>[]): Set<string> {
|
||||
private static _toSet<T>(arr: readonly IExtensionPointUser<T>[]): Set<string> {
|
||||
const result = new Set<string>();
|
||||
for (let i = 0, len = arr.length; i < len; i++) {
|
||||
result.add(ExtensionIdentifier.toKey(arr[i].description.identifier));
|
||||
@@ -81,7 +79,7 @@ export class ExtensionPointUserDelta<T> {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static compute<T>(previous: IExtensionPointUser<T>[] | null, current: IExtensionPointUser<T>[]): ExtensionPointUserDelta<T> {
|
||||
public static compute<T>(previous: readonly IExtensionPointUser<T>[] | null, current: readonly IExtensionPointUser<T>[]): ExtensionPointUserDelta<T> {
|
||||
if (!previous || !previous.length) {
|
||||
return new ExtensionPointUserDelta<T>(current, []);
|
||||
}
|
||||
@@ -99,8 +97,8 @@ export class ExtensionPointUserDelta<T> {
|
||||
}
|
||||
|
||||
constructor(
|
||||
public readonly added: IExtensionPointUser<T>[],
|
||||
public readonly removed: IExtensionPointUser<T>[],
|
||||
public readonly added: readonly IExtensionPointUser<T>[],
|
||||
public readonly removed: readonly IExtensionPointUser<T>[],
|
||||
) { }
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IExtensionDescription, IExtensionManifest, ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { UriComponents, URI } from 'vs/base/common/uri';
|
||||
|
||||
export const IStaticExtensionsService = createDecorator<IStaticExtensionsService>('IStaticExtensionsService');
|
||||
|
||||
export interface IStaticExtensionsService {
|
||||
_serviceBrand: any;
|
||||
getExtensions(): Promise<IExtensionDescription[]>;
|
||||
}
|
||||
|
||||
export class StaticExtensionsService implements IStaticExtensionsService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
private readonly _descriptions: IExtensionDescription[] = [];
|
||||
|
||||
constructor(staticExtensions: { packageJSON: IExtensionManifest, extensionLocation: UriComponents }[]) {
|
||||
this._descriptions = staticExtensions.map(data => <IExtensionDescription>{
|
||||
identifier: new ExtensionIdentifier(`${data.packageJSON.publisher}.${data.packageJSON.name}`),
|
||||
extensionLocation: URI.revive(data.extensionLocation),
|
||||
...data.packageJSON,
|
||||
});
|
||||
}
|
||||
|
||||
async getExtensions(): Promise<IExtensionDescription[]> {
|
||||
return this._descriptions;
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,8 @@ import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { PersistentConnectionEventType } from 'vs/platform/remote/common/remoteAgentConnection';
|
||||
import { IProductService } from 'vs/platform/product/common/product';
|
||||
import { Logger } from 'vs/workbench/services/extensions/common/extensionPoints';
|
||||
import { flatten } from 'vs/base/common/arrays';
|
||||
import { IStaticExtensionsService } from 'vs/workbench/services/extensions/common/staticExtensions';
|
||||
|
||||
class DeltaExtensionsQueueItem {
|
||||
constructor(
|
||||
@@ -64,6 +66,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
@IConfigurationService private readonly _configurationService: IConfigurationService,
|
||||
@ILifecycleService private readonly _lifecycleService: ILifecycleService,
|
||||
@IWindowService protected readonly _windowService: IWindowService,
|
||||
@IStaticExtensionsService private readonly _staticExtensions: IStaticExtensionsService,
|
||||
) {
|
||||
super(
|
||||
instantiationService,
|
||||
@@ -72,7 +75,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
telemetryService,
|
||||
extensionEnablementService,
|
||||
fileService,
|
||||
productService,
|
||||
productService
|
||||
);
|
||||
|
||||
if (this._extensionEnablementService.allUserExtensionsDisabled) {
|
||||
@@ -437,7 +440,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
const remoteAuthority = this._environmentService.configuration.remoteAuthority;
|
||||
const extensionHost = this._extensionHostProcessManagers[0];
|
||||
|
||||
let localExtensions = await this._extensionScanner.scannedExtensions;
|
||||
let localExtensions = flatten(await Promise.all([this._extensionScanner.scannedExtensions, this._staticExtensions.getExtensions()]));
|
||||
|
||||
// enable or disable proposed API per extension
|
||||
this._checkEnableProposedApi(localExtensions);
|
||||
@@ -463,7 +466,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
this._remoteAuthorityResolverService.setResolvedAuthorityError(remoteAuthority, err);
|
||||
|
||||
// Proceed with the local extension host
|
||||
await this._startLocalExtensionHost(extensionHost, localExtensions);
|
||||
await this._startLocalExtensionHost(extensionHost, localExtensions, localExtensions.map(extension => extension.identifier));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -508,20 +511,18 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
// save for remote extension's init data
|
||||
this._remoteExtensionsEnvironmentData.set(remoteAuthority, remoteEnv);
|
||||
|
||||
this._handleExtensionPoints((<IExtensionDescription[]>[]).concat(remoteEnv.extensions).concat(localExtensions));
|
||||
extensionHost.start(localExtensions.map(extension => extension.identifier));
|
||||
|
||||
await this._startLocalExtensionHost(extensionHost, remoteEnv.extensions.concat(localExtensions), localExtensions.map(extension => extension.identifier));
|
||||
} else {
|
||||
await this._startLocalExtensionHost(extensionHost, localExtensions);
|
||||
await this._startLocalExtensionHost(extensionHost, localExtensions, localExtensions.map(extension => extension.identifier));
|
||||
}
|
||||
}
|
||||
|
||||
private async _startLocalExtensionHost(extensionHost: ExtensionHostProcessManager, localExtensions: IExtensionDescription[]): Promise<void> {
|
||||
this._handleExtensionPoints(localExtensions);
|
||||
extensionHost.start(localExtensions.map(extension => extension.identifier).filter(id => this._registry.containsExtension(id)));
|
||||
private async _startLocalExtensionHost(extensionHost: ExtensionHostProcessManager, allExtensions: IExtensionDescription[], localExtensions: ExtensionIdentifier[]): Promise<void> {
|
||||
this._registerAndHandleExtensions(allExtensions);
|
||||
extensionHost.start(localExtensions.filter(id => this._registry.containsExtension(id)));
|
||||
}
|
||||
|
||||
private _handleExtensionPoints(allExtensions: IExtensionDescription[]): void {
|
||||
private _registerAndHandleExtensions(allExtensions: IExtensionDescription[]): void {
|
||||
const result = this._registry.deltaExtensions(allExtensions, []);
|
||||
if (result.removedDueToLooping.length > 0) {
|
||||
this._logOrShowMessage(Severity.Error, nls.localize('looping', "The following extensions contain dependency loops and have been disabled: {0}", result.removedDueToLooping.map(e => `'${e.identifier.value}'`).join(', ')));
|
||||
|
||||
@@ -13,8 +13,7 @@ import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
|
||||
import { ResourceMap } from 'vs/base/common/map';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { StorageScope, IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { INotificationService, Severity, NeverShowAgainScope } from 'vs/platform/notification/common/notification';
|
||||
import { localize } from 'vs/nls';
|
||||
import { FileService } from 'vs/platform/files/common/fileService';
|
||||
|
||||
@@ -26,8 +25,7 @@ export class WorkspaceWatcher extends Disposable {
|
||||
@IFileService private readonly fileService: FileService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IStorageService private readonly storageService: IStorageService
|
||||
@INotificationService private readonly notificationService: INotificationService
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -73,38 +71,34 @@ export class WorkspaceWatcher extends Disposable {
|
||||
onUnexpectedError(msg);
|
||||
|
||||
// Detect if we run < .NET Framework 4.5
|
||||
if (msg.indexOf('System.MissingMethodException') >= 0 && !this.storageService.getBoolean('ignoreNetVersionError', StorageScope.WORKSPACE)) {
|
||||
if (msg.indexOf('System.MissingMethodException') >= 0) {
|
||||
this.notificationService.prompt(
|
||||
Severity.Warning,
|
||||
localize('netVersionError', "The Microsoft .NET Framework 4.5 is required. Please follow the link to install it."),
|
||||
[{
|
||||
label: localize('installNet', "Download .NET Framework 4.5"),
|
||||
run: () => window.open('https://go.microsoft.com/fwlink/?LinkId=786533')
|
||||
},
|
||||
{
|
||||
label: localize('neverShowAgain', "Don't Show Again"),
|
||||
isSecondary: true,
|
||||
run: () => this.storageService.store('ignoreNetVersionError', true, StorageScope.WORKSPACE)
|
||||
}],
|
||||
{ sticky: true }
|
||||
{
|
||||
sticky: true,
|
||||
neverShowAgain: { id: 'ignoreNetVersionError', isSecondary: true, scope: NeverShowAgainScope.WORKSPACE }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Detect if we run into ENOSPC issues
|
||||
if (msg.indexOf('ENOSPC') >= 0 && !this.storageService.getBoolean('ignoreEnospcError', StorageScope.WORKSPACE)) {
|
||||
if (msg.indexOf('ENOSPC') >= 0) {
|
||||
this.notificationService.prompt(
|
||||
Severity.Warning,
|
||||
localize('enospcError', "Unable to watch for file changes in this large workspace. Please follow the instructions link to resolve this issue."),
|
||||
[{
|
||||
label: localize('learnMore', "Instructions"),
|
||||
run: () => window.open('https://go.microsoft.com/fwlink/?linkid=867693')
|
||||
},
|
||||
{
|
||||
label: localize('neverShowAgain', "Don't Show Again"),
|
||||
isSecondary: true,
|
||||
run: () => this.storageService.store('ignoreEnospcError', true, StorageScope.WORKSPACE)
|
||||
}],
|
||||
{ sticky: true }
|
||||
{
|
||||
sticky: true,
|
||||
neverShowAgain: { id: 'ignoreEnospcError', isSecondary: true, scope: NeverShowAgainScope.WORKSPACE }
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -157,4 +151,4 @@ export class WorkspaceWatcher extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(WorkspaceWatcher, LifecyclePhase.Restored);
|
||||
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(WorkspaceWatcher, LifecyclePhase.Restored);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import { INotificationService, INotification, INotificationHandle, Severity, NotificationMessage, INotificationActions, IPromptChoice, IPromptOptions, IStatusMessageOptions, NoOpNotification } from 'vs/platform/notification/common/notification';
|
||||
import { INotificationService, INotification, INotificationHandle, Severity, NotificationMessage, INotificationActions, IPromptChoice, IPromptOptions, IStatusMessageOptions, NoOpNotification, NeverShowAgainScope } from 'vs/platform/notification/common/notification';
|
||||
import { INotificationsModel, NotificationsModel, ChoiceAction } from 'vs/workbench/common/notifications';
|
||||
import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
@@ -63,11 +63,12 @@ export class NotificationService extends Disposable implements INotificationServ
|
||||
// Handle neverShowAgain option accordingly
|
||||
let handle: INotificationHandle;
|
||||
if (notification.neverShowAgain) {
|
||||
const scope = notification.neverShowAgain.scope === NeverShowAgainScope.WORKSPACE ? StorageScope.WORKSPACE : StorageScope.GLOBAL;
|
||||
|
||||
// If the user already picked to not show the notification
|
||||
// again, we return with a no-op notification here
|
||||
const id = notification.neverShowAgain.id;
|
||||
if (this.storageService.getBoolean(id, StorageScope.GLOBAL)) {
|
||||
if (this.storageService.getBoolean(id, scope)) {
|
||||
return new NoOpNotification();
|
||||
}
|
||||
|
||||
@@ -80,7 +81,7 @@ export class NotificationService extends Disposable implements INotificationServ
|
||||
handle.close();
|
||||
|
||||
// Remember choice
|
||||
this.storageService.store(id, true, StorageScope.GLOBAL);
|
||||
this.storageService.store(id, true, scope);
|
||||
|
||||
return Promise.resolve();
|
||||
}));
|
||||
@@ -110,17 +111,18 @@ export class NotificationService extends Disposable implements INotificationServ
|
||||
|
||||
// Handle neverShowAgain option accordingly
|
||||
if (options && options.neverShowAgain) {
|
||||
const scope = options.neverShowAgain.scope === NeverShowAgainScope.WORKSPACE ? StorageScope.WORKSPACE : StorageScope.GLOBAL;
|
||||
|
||||
// If the user already picked to not show the notification
|
||||
// again, we return with a no-op notification here
|
||||
const id = options.neverShowAgain.id;
|
||||
if (this.storageService.getBoolean(id, StorageScope.GLOBAL)) {
|
||||
if (this.storageService.getBoolean(id, scope)) {
|
||||
return new NoOpNotification();
|
||||
}
|
||||
|
||||
const neverShowAgainChoice = {
|
||||
label: nls.localize('neverShowAgain', "Don't Show Again"),
|
||||
run: () => this.storageService.store(id, true, StorageScope.GLOBAL),
|
||||
run: () => this.storageService.store(id, true, scope),
|
||||
isSecondary: options.neverShowAgain.isSecondary
|
||||
};
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import * as Json from 'vs/base/common/json';
|
||||
import { ExtensionData, IThemeExtensionPoint, IFileIconTheme } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { getParseErrorMessage } from 'vs/base/common/jsonErrorMessages';
|
||||
import { asDomUri } from 'vs/base/browser/dom';
|
||||
import { asCSSUrl } from 'vs/base/browser/dom';
|
||||
|
||||
export class FileIconThemeData implements IFileIconTheme {
|
||||
id: string;
|
||||
@@ -332,7 +332,7 @@ function _processIconThemeDocument(id: string, iconThemeDocumentLocation: URI, i
|
||||
let fonts = iconThemeDocument.fonts;
|
||||
if (Array.isArray(fonts)) {
|
||||
fonts.forEach(font => {
|
||||
let src = font.src.map(l => `url('${asDomUri(resolvePath(l.path))}') format('${l.format}')`).join(', ');
|
||||
let src = font.src.map(l => `${asCSSUrl(resolvePath(l.path))} format('${l.format}')`).join(', ');
|
||||
cssRules.push(`@font-face { src: ${src}; font-family: '${font.id}'; font-weight: ${font.weight}; font-style: ${font.style}; }`);
|
||||
});
|
||||
cssRules.push(`.show-file-icons .file-icon::before, .show-file-icons .folder-icon::before, .show-file-icons .rootfolder-icon::before { font-family: '${fonts[0].id}'; font-size: ${fonts[0].size || '150%'}}`);
|
||||
@@ -343,7 +343,7 @@ function _processIconThemeDocument(id: string, iconThemeDocumentLocation: URI, i
|
||||
let definition = iconThemeDocument.iconDefinitions[defId];
|
||||
if (definition) {
|
||||
if (definition.iconPath) {
|
||||
cssRules.push(`${selectors.join(', ')} { content: ' '; background-image: url("${asDomUri(resolvePath(definition.iconPath))}"); }`);
|
||||
cssRules.push(`${selectors.join(', ')} { content: ' '; background-image: ${asCSSUrl(resolvePath(definition.iconPath))}; }`);
|
||||
}
|
||||
if (definition.fontCharacter || definition.fontColor) {
|
||||
let body = '';
|
||||
|
||||
@@ -74,6 +74,7 @@ import { IMenubarService } from 'vs/platform/menubar/common/menubar';
|
||||
import { MenubarService } from 'vs/platform/menubar/electron-browser/menubarService';
|
||||
import { IURLService } from 'vs/platform/url/common/url';
|
||||
import { RelayURLService } from 'vs/platform/url/electron-browser/urlService';
|
||||
import { StaticExtensionsService, IStaticExtensionsService } from 'vs/workbench/services/extensions/common/staticExtensions';
|
||||
|
||||
registerSingleton(IClipboardService, ClipboardService, true);
|
||||
registerSingleton(IRequestService, RequestService, true);
|
||||
@@ -86,6 +87,7 @@ registerSingleton(IIssueService, IssueService);
|
||||
registerSingleton(IWorkspacesService, WorkspacesService);
|
||||
registerSingleton(IMenubarService, MenubarService);
|
||||
registerSingleton(IURLService, RelayURLService);
|
||||
registerSingleton(IStaticExtensionsService, class extends StaticExtensionsService { constructor() { super([]); } });
|
||||
|
||||
//#endregion
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import { UriComponents } from 'vs/base/common/uri';
|
||||
import { IFileSystemProvider } from 'vs/platform/files/common/files';
|
||||
import { IWebSocketFactory } from 'vs/platform/remote/browser/browserSocketFactory';
|
||||
import { ICredentialsProvider } from 'vs/workbench/services/credentials/browser/credentialsService';
|
||||
import { IExtensionManifest } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
export interface IWorkbenchConstructionOptions {
|
||||
|
||||
@@ -59,6 +60,11 @@ export interface IWorkbenchConstructionOptions {
|
||||
* Experimental: The credentials provider to store and retrieve secrets.
|
||||
*/
|
||||
credentialsProvider?: ICredentialsProvider;
|
||||
|
||||
/**
|
||||
* Experimental: Add static extensions that cannot be uninstalled but only be disabled.
|
||||
*/
|
||||
staticExtensions?: { packageJSON: IExtensionManifest, extensionLocation: UriComponents }[];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -95,6 +95,7 @@ export async function launch(_args: string[]): Promise<void> {
|
||||
await promisify(mkdir)(webUserDataDir);
|
||||
server = spawn(join(args[0], `resources/server/web.${process.platform === 'win32' ? 'bat' : 'sh'}`), ['--browser', 'none', '--driver', 'web', '--web-user-data-dir', webUserDataDir]);
|
||||
server.stderr.on('data', e => console.log('Server stderr: ' + e));
|
||||
server.stdout.on('data', e => console.log('Server stdout: ' + e));
|
||||
process.on('exit', teardown);
|
||||
process.on('SIGINT', teardown);
|
||||
endpoint = await waitForEndpoint();
|
||||
@@ -129,8 +130,7 @@ export function connect(headless: boolean, outPath: string, handle: string): Pro
|
||||
});
|
||||
const page = (await browser.pages())[0];
|
||||
await page.setViewport({ width, height });
|
||||
const endpointSplit = endpoint!.split('#');
|
||||
await page.goto(`${endpointSplit[0]}?folder=${args![1]}#${endpointSplit[1]}`);
|
||||
await page.goto(`${endpoint}&folder=${args![1]}`);
|
||||
const result = {
|
||||
client: { dispose: () => teardown },
|
||||
driver: buildDriver(browser, page)
|
||||
|
||||
@@ -10328,10 +10328,10 @@ xtend@~2.1.1:
|
||||
dependencies:
|
||||
object-keys "~0.4.0"
|
||||
|
||||
xterm-addon-search@0.2.0-beta3:
|
||||
version "0.2.0-beta3"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.2.0-beta3.tgz#710ce14658e269c5a4791f5a9e2f520883a2e62b"
|
||||
integrity sha512-KzVdkEtGbKJe9ER2TmrI7XjF/wUq1lir9U63vPJi0t2ymQvIECl1V63f9QtOp1vvpdhbZiXBxO+vGTj+y0tRow==
|
||||
xterm-addon-search@0.2.0-beta5:
|
||||
version "0.2.0-beta5"
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.2.0-beta5.tgz#258d7cb1511d9060cd4520f0f82e408000fd4f53"
|
||||
integrity sha512-Tg+d8scch0rYOVmzBbX35Y1GXtq+eu/YlzbXznmTo/yD83j3BQlXOhgECu/Yv8EX5JwFmzbfVRWC+JWnfigwGg==
|
||||
|
||||
xterm-addon-web-links@0.1.0-beta10:
|
||||
version "0.1.0-beta10"
|
||||
|
||||
Reference in New Issue
Block a user