mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-18 09:35:39 -05:00
Merge from vscode 64980ea1f3f532c82bb6c28d27bba9ef2c5b4463 (#7206)
* Merge from vscode 64980ea1f3f532c82bb6c28d27bba9ef2c5b4463 * fix config changes * fix strictnull checks
This commit is contained in:
79
src/vs/code/browser/workbench/callback.html
Normal file
79
src/vs/code/browser/workbench/callback.html
Normal file
@@ -0,0 +1,79 @@
|
||||
<!-- Copyright (C) Microsoft Corporation. All rights reserved. -->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<!-- Disable pinch zooming -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
|
||||
|
||||
<!-- Content Security Policy -->
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="
|
||||
default-src 'self';
|
||||
img-src 'self' https: data: blob:;
|
||||
media-src 'none';
|
||||
script-src 'self';
|
||||
style-src 'self' 'unsafe-inline';
|
||||
font-src 'self' blob:;
|
||||
">
|
||||
|
||||
<title>Visual Studio Code</title>
|
||||
|
||||
<!-- Styling -->
|
||||
<style type="text/css">
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
box-sizing: border-box;
|
||||
min-height: 100%;
|
||||
margin: 0;
|
||||
padding: 15px 30px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
color: white;
|
||||
font-family: "Segoe UI", "Helvetica Neue", "Helvetica", Arial, sans-serif;
|
||||
background-color: #373277;
|
||||
}
|
||||
|
||||
.branding {
|
||||
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PGRlZnM+PHN0eWxlPi5pY29uLWNhbnZhcy10cmFuc3BhcmVudHtmaWxsOiNmNmY2ZjY7b3BhY2l0eTowO30uaWNvbi13aGl0ZXtmaWxsOiNmZmY7fTwvc3R5bGU+PC9kZWZzPjx0aXRsZT5CcmFuZFZpc3VhbFN0dWRpb0NvZGUyMDE3UlRXXzI0eF93aGl0ZV8yNHg8L3RpdGxlPjxwYXRoIGNsYXNzPSJpY29uLWNhbnZhcy10cmFuc3BhcmVudCIgZD0iTTI0LDBWMjRIMFYwWiIvPjxwYXRoIGNsYXNzPSJpY29uLXdoaXRlIiBkPSJNMjQsMi41VjIxLjVMMTgsMjQsMCwxOC41di0uNTYxbDE4LDEuNTQ1VjBaTTEsMTMuMTExLDQuMzg1LDEwLDEsNi44ODlsMS40MTgtLjgyN0w1Ljg1Myw4LjY1LDEyLDNsMywxLjQ1NlYxNS41NDRMMTIsMTcsNS44NTMsMTEuMzUsMi40MTksMTMuOTM5Wk03LjY0NCwxMCwxMiwxMy4yODNWNi43MTdaIi8+PC9zdmc+");
|
||||
background-size: 24px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: left 50%;
|
||||
padding-left: 36px;
|
||||
font-size: 20px;
|
||||
letter-spacing: -0.04rem;
|
||||
font-weight: 400;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.message-container {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 0 30px;
|
||||
}
|
||||
|
||||
.message {
|
||||
font-weight: 300;
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<span class="branding">
|
||||
Visual Studio Code
|
||||
</span>
|
||||
<div class="message-container">
|
||||
<div class="message">
|
||||
You can close this page now.
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
62
src/vs/code/browser/workbench/workbench-dev.html
Normal file
62
src/vs/code/browser/workbench/workbench-dev.html
Normal file
@@ -0,0 +1,62 @@
|
||||
<!-- Copyright (C) Microsoft Corporation. All rights reserved. -->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<!-- Disable pinch zooming -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
|
||||
|
||||
<!-- Content Security Policy -->
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="
|
||||
default-src 'self';
|
||||
img-src 'self' https: data: blob:;
|
||||
media-src 'none';
|
||||
script-src 'self' https://az416426.vo.msecnd.net 'unsafe-eval' https: 'sha256-4DqvCTjCHj2KW4QxC/Yt6uBwMRyYiEg7kOoykSEkonQ=' 'sha256-meDZW3XhN5JmdjFUrWGhTouRKBiWYtXHltaKnqn/WMo=';
|
||||
child-src 'self';
|
||||
frame-src 'self' https://*.vscode-webview-test.com;
|
||||
worker-src 'self';
|
||||
style-src 'self' 'unsafe-inline';
|
||||
connect-src 'self' ws: wss: https:;
|
||||
font-src 'self' blob:;
|
||||
manifest-src 'self';
|
||||
">
|
||||
|
||||
<!-- Workbench Configuration -->
|
||||
<meta id="vscode-workbench-web-configuration" data-settings="{{WORKBENCH_WEB_CONGIGURATION}}">
|
||||
|
||||
<!-- Workarounds/Hacks (remote user data uri) -->
|
||||
<meta id="vscode-remote-user-data-uri" data-settings="{{REMOTE_USER_DATA_URI}}">
|
||||
|
||||
<!-- Workbench Icon/Manifest/CSS -->
|
||||
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
</head>
|
||||
|
||||
<body aria-label="">
|
||||
</body>
|
||||
|
||||
<!-- Startup (do not modify order of script tags!) -->
|
||||
<script>
|
||||
// NOTE: Changes to inline scripts require update of content security policy
|
||||
self.require = {
|
||||
baseUrl: `${window.location.origin}/static/out`,
|
||||
paths: {
|
||||
'vscode-textmate': `${window.location.origin}/static/node_modules/vscode-textmate/release/main`,
|
||||
'onigasm-umd': `${window.location.origin}/static/node_modules/onigasm-umd/release/main`,
|
||||
'xterm': `${window.location.origin}/static/node_modules/xterm/lib/xterm.js`,
|
||||
'xterm-addon-search': `${window.location.origin}/static/node_modules/xterm-addon-search/lib/xterm-addon-search.js`,
|
||||
'xterm-addon-web-links': `${window.location.origin}/static/node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js`,
|
||||
'semver-umd': `${window.location.origin}/static/node_modules/semver-umd/lib/semver-umd.js`,
|
||||
'@microsoft/applicationinsights-web': `${window.location.origin}/static/node_modules/@microsoft/applicationinsights-web/dist/applicationinsights-web.js`,
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<script src="./static/out/vs/loader.js"></script>
|
||||
<script>
|
||||
// NOTE: Changes to inline scripts require update of content security policy
|
||||
require(['vs/code/browser/workbench/workbench'], function() {});
|
||||
</script>
|
||||
</html>
|
||||
@@ -10,8 +10,19 @@
|
||||
<!-- Content Security Policy -->
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="default-src 'none'; img-src 'self' https: data: blob:; media-src 'none'; frame-src 'self' {{WEBVIEW_ENDPOINT}} https://*.vscode-webview-test.com; script-src 'self' https://az416426.vo.msecnd.net 'unsafe-eval' https:; style-src 'self' 'unsafe-inline'; connect-src 'self' ws: wss: https:; font-src 'self' blob:; manifest-src 'self';"
|
||||
>
|
||||
content="
|
||||
default-src 'self';
|
||||
img-src 'self' https: data: blob:;
|
||||
media-src 'none';
|
||||
script-src 'self' https://az416426.vo.msecnd.net 'unsafe-eval' https: 'sha256-4DqvCTjCHj2KW4QxC/Yt6uBwMRyYiEg7kOoykSEkonQ=';
|
||||
child-src 'self';
|
||||
frame-src 'self' https://*.vscode-webview-test.com;
|
||||
worker-src 'self';
|
||||
style-src 'self' 'unsafe-inline';
|
||||
connect-src 'self' ws: wss: https:;
|
||||
font-src 'self' blob:;
|
||||
manifest-src 'self';
|
||||
">
|
||||
|
||||
<!-- Workbench Configuration -->
|
||||
<meta id="vscode-workbench-web-configuration" data-settings="{{WORKBENCH_WEB_CONGIGURATION}}">
|
||||
@@ -23,13 +34,33 @@
|
||||
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<link data-name="vs/workbench/workbench.web.api" rel="stylesheet" href="./static/out/vs/workbench/workbench.web.api.css">
|
||||
|
||||
<!-- Prefetch to avoid waterfall -->
|
||||
<link rel="prefetch" href="./static/node_modules/semver-umd/lib/semver-umd.js">
|
||||
<link rel="prefetch" href="./static/node_modules/@microsoft/applicationinsights-web/dist/applicationinsights-web.js">
|
||||
</head>
|
||||
|
||||
<body aria-label="">
|
||||
</body>
|
||||
|
||||
<!-- Startup (do not modify order of script tags!) -->
|
||||
<script>
|
||||
// NOTE: Changes to inline scripts require update of content security policy
|
||||
self.require = {
|
||||
baseUrl: `${window.location.origin}/static/out`,
|
||||
paths: {
|
||||
'vscode-textmate': `${window.location.origin}/static/node_modules/vscode-textmate/release/main`,
|
||||
'onigasm-umd': `${window.location.origin}/static/node_modules/onigasm-umd/release/main`,
|
||||
'xterm': `${window.location.origin}/static/node_modules/xterm/lib/xterm.js`,
|
||||
'xterm-addon-search': `${window.location.origin}/static/node_modules/xterm-addon-search/lib/xterm-addon-search.js`,
|
||||
'xterm-addon-web-links': `${window.location.origin}/static/node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js`,
|
||||
'semver-umd': `${window.location.origin}/static/node_modules/semver-umd/lib/semver-umd.js`,
|
||||
'@microsoft/applicationinsights-web': `${window.location.origin}/static/node_modules/@microsoft/applicationinsights-web/dist/applicationinsights-web.js`,
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<script src="./static/out/vs/loader.js"></script>
|
||||
<script src="./static/out/vs/workbench/workbench.web.api.nls.js"></script>
|
||||
<script src="./static/out/vs/workbench/workbench.web.api.js"></script>
|
||||
<script src="./static/out/vs/code/browser/workbench/workbench.js"></script>
|
||||
</html>
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
//@ts-check
|
||||
'use strict';
|
||||
|
||||
(function () {
|
||||
|
||||
/** @type any */
|
||||
const amdLoader = require;
|
||||
|
||||
amdLoader.config({
|
||||
baseUrl: `${window.location.origin}/static/out`,
|
||||
paths: {
|
||||
'vscode-textmate': `${window.location.origin}/static/node_modules/vscode-textmate/release/main`,
|
||||
'onigasm-umd': `${window.location.origin}/static/node_modules/onigasm-umd/release/main`,
|
||||
'xterm': `${window.location.origin}/static/node_modules/xterm/lib/xterm.js`,
|
||||
'xterm-addon-search': `${window.location.origin}/static/node_modules/xterm-addon-search/lib/xterm-addon-search.js`,
|
||||
'xterm-addon-web-links': `${window.location.origin}/static/node_modules/xterm-addon-web-links/lib/xterm-addon-web-links.js`,
|
||||
'semver-umd': `${window.location.origin}/static/node_modules/semver-umd/lib/semver-umd.js`,
|
||||
'@microsoft/applicationinsights-web': `${window.location.origin}/static/node_modules/@microsoft/applicationinsights-web/dist/applicationinsights-web.js`,
|
||||
}
|
||||
});
|
||||
|
||||
amdLoader(['vs/workbench/workbench.web.api'], function (api) {
|
||||
const options = JSON.parse(document.getElementById('vscode-workbench-web-configuration').getAttribute('data-settings'));
|
||||
|
||||
api.create(document.body, options);
|
||||
});
|
||||
})();
|
||||
208
src/vs/code/browser/workbench/workbench.ts
Normal file
208
src/vs/code/browser/workbench/workbench.ts
Normal file
@@ -0,0 +1,208 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IWorkbenchConstructionOptions, create } from 'vs/workbench/workbench.web.api';
|
||||
import { IURLCallbackProvider } from 'vs/workbench/services/url/browser/urlService';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { streamToBuffer } from 'vs/base/common/buffer';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { request } from 'vs/base/parts/request/browser/request';
|
||||
import { ICredentialsProvider } from 'vs/workbench/services/credentials/browser/credentialsService';
|
||||
|
||||
interface ICredential {
|
||||
service: string;
|
||||
account: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
class LocalStorageCredentialsProvider implements ICredentialsProvider {
|
||||
|
||||
static readonly CREDENTIALS_OPENED_KEY = 'credentials.provider';
|
||||
|
||||
private _credentials: ICredential[];
|
||||
private get credentials(): ICredential[] {
|
||||
if (!this._credentials) {
|
||||
try {
|
||||
const serializedCredentials = window.localStorage.getItem(LocalStorageCredentialsProvider.CREDENTIALS_OPENED_KEY);
|
||||
if (serializedCredentials) {
|
||||
this._credentials = JSON.parse(serializedCredentials);
|
||||
}
|
||||
} catch (error) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (!Array.isArray(this._credentials)) {
|
||||
this._credentials = [];
|
||||
}
|
||||
}
|
||||
|
||||
return this._credentials;
|
||||
}
|
||||
|
||||
private save(): void {
|
||||
window.localStorage.setItem(LocalStorageCredentialsProvider.CREDENTIALS_OPENED_KEY, JSON.stringify(this.credentials));
|
||||
}
|
||||
|
||||
async getPassword(service: string, account: string): Promise<string | null> {
|
||||
return this.doGetPassword(service, account);
|
||||
}
|
||||
|
||||
private async doGetPassword(service: string, account?: string): Promise<string | null> {
|
||||
for (const credential of this.credentials) {
|
||||
if (credential.service === service) {
|
||||
if (typeof account !== 'string' || account === credential.account) {
|
||||
return credential.password;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
async setPassword(service: string, account: string, password: string): Promise<void> {
|
||||
this.deletePassword(service, account);
|
||||
|
||||
this.credentials.push({ service, account, password });
|
||||
|
||||
this.save();
|
||||
}
|
||||
|
||||
async deletePassword(service: string, account: string): Promise<boolean> {
|
||||
let found = false;
|
||||
|
||||
this._credentials = this.credentials.filter(credential => {
|
||||
if (credential.service === service && credential.account === account) {
|
||||
found = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (found) {
|
||||
this.save();
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
async findPassword(service: string): Promise<string | null> {
|
||||
return this.doGetPassword(service);
|
||||
}
|
||||
|
||||
async findCredentials(service: string): Promise<Array<{ account: string, password: string }>> {
|
||||
return this.credentials
|
||||
.filter(credential => credential.service === service)
|
||||
.map(({ account, password }) => ({ account, password }));
|
||||
}
|
||||
}
|
||||
|
||||
class PollingURLCallbackProvider extends Disposable implements IURLCallbackProvider {
|
||||
|
||||
static FETCH_INTERVAL = 500; // fetch every 500ms
|
||||
static FETCH_TIMEOUT = 5 * 60 * 1000; // ...but stop after 5min
|
||||
|
||||
static QUERY_KEYS = {
|
||||
REQUEST_ID: 'vscode-requestId',
|
||||
SCHEME: 'vscode-scheme',
|
||||
AUTHORITY: 'vscode-authority',
|
||||
PATH: 'vscode-path',
|
||||
QUERY: 'vscode-query',
|
||||
FRAGMENT: 'vscode-fragment'
|
||||
};
|
||||
|
||||
private readonly _onCallback: Emitter<URI> = this._register(new Emitter<URI>());
|
||||
readonly onCallback: Event<URI> = this._onCallback.event;
|
||||
|
||||
create(options?: Partial<UriComponents>): URI {
|
||||
const queryValues: Map<string, string> = new Map();
|
||||
|
||||
const requestId = generateUuid();
|
||||
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.REQUEST_ID, requestId);
|
||||
|
||||
const { scheme, authority, path, query, fragment } = options ? options : { scheme: undefined, authority: undefined, path: undefined, query: undefined, fragment: undefined };
|
||||
|
||||
if (scheme) {
|
||||
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.SCHEME, scheme);
|
||||
}
|
||||
|
||||
if (authority) {
|
||||
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.AUTHORITY, authority);
|
||||
}
|
||||
|
||||
if (path) {
|
||||
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.PATH, path);
|
||||
}
|
||||
|
||||
if (query) {
|
||||
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.QUERY, query);
|
||||
}
|
||||
|
||||
if (fragment) {
|
||||
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.FRAGMENT, fragment);
|
||||
}
|
||||
|
||||
// Start to poll on the callback being fired
|
||||
this.periodicFetchCallback(requestId, Date.now());
|
||||
|
||||
return this.doCreateUri('/callback', queryValues);
|
||||
}
|
||||
|
||||
private async periodicFetchCallback(requestId: string, startTime: number): Promise<void> {
|
||||
|
||||
// Ask server for callback results
|
||||
const queryValues: Map<string, string> = new Map();
|
||||
queryValues.set(PollingURLCallbackProvider.QUERY_KEYS.REQUEST_ID, requestId);
|
||||
|
||||
const result = await request({
|
||||
url: this.doCreateUri('/fetch-callback', queryValues).toString(true)
|
||||
}, CancellationToken.None);
|
||||
|
||||
// Check for callback results
|
||||
const content = await streamToBuffer(result.stream);
|
||||
if (content.byteLength > 0) {
|
||||
try {
|
||||
this._onCallback.fire(URI.revive(JSON.parse(content.toString())));
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
return; // done
|
||||
}
|
||||
|
||||
// Continue fetching unless we hit the timeout
|
||||
if (Date.now() - startTime < PollingURLCallbackProvider.FETCH_TIMEOUT) {
|
||||
setTimeout(() => this.periodicFetchCallback(requestId, startTime), PollingURLCallbackProvider.FETCH_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
private doCreateUri(path: string, queryValues: Map<string, string>): URI {
|
||||
let query: string | undefined = undefined;
|
||||
|
||||
if (queryValues) {
|
||||
let index = 0;
|
||||
queryValues.forEach((value, key) => {
|
||||
if (!query) {
|
||||
query = '';
|
||||
}
|
||||
|
||||
const prefix = (index++ === 0) ? '' : '&';
|
||||
query += `${prefix}${key}=${encodeURIComponent(value)}`;
|
||||
});
|
||||
}
|
||||
|
||||
return URI.parse(window.location.href).with({ path, query });
|
||||
}
|
||||
}
|
||||
|
||||
const options: IWorkbenchConstructionOptions = JSON.parse(document.getElementById('vscode-workbench-web-configuration')!.getAttribute('data-settings')!);
|
||||
options.urlCallbackProvider = new PollingURLCallbackProvider();
|
||||
options.credentialsProvider = new LocalStorageCredentialsProvider();
|
||||
|
||||
create(document.body, options);
|
||||
@@ -311,7 +311,7 @@ export class IssueReporter extends Disposable {
|
||||
if (!this.environmentService.isExtensionDevelopment && !this.environmentService.args['disable-telemetry'] && !!product.enableTelemetry) {
|
||||
const channel = getDelayedChannel(sharedProcess.then(c => c.getChannel('telemetryAppender')));
|
||||
const appender = combinedAppender(new TelemetryAppenderClient(channel), new LogAppender(logService));
|
||||
const commonProperties = resolveCommonProperties(product.commit || 'Commit unknown', pkg.version, configuration.machineId, this.environmentService.installSourcePath);
|
||||
const commonProperties = resolveCommonProperties(product.commit || 'Commit unknown', pkg.version, configuration.machineId, product.msftInternalDomains, this.environmentService.installSourcePath);
|
||||
const piiPaths = this.environmentService.extensionsPath ? [this.environmentService.appRoot, this.environmentService.extensionsPath] : [this.environmentService.appRoot];
|
||||
const config: ITelemetryServiceConfig = { appender, commonProperties, piiPaths };
|
||||
|
||||
@@ -941,8 +941,7 @@ export class IssueReporter extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
const queryStringPrefix = repositoryUrl.indexOf('?') === -1 ? '?' : '&';
|
||||
const queryStringPrefix = product.reportIssueUrl && product.reportIssueUrl.indexOf('?') === -1 ? '?' : '&';
|
||||
return `${repositoryUrl}${queryStringPrefix}title=${encodeURIComponent(issueTitle)}`;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProper
|
||||
import { TelemetryAppenderChannel } from 'vs/platform/telemetry/node/telemetryIpc';
|
||||
import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService';
|
||||
import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender';
|
||||
import { IWindowsService, ActiveWindowManager } from 'vs/platform/windows/common/windows';
|
||||
import { IWindowsService } from 'vs/platform/windows/common/windows';
|
||||
import { WindowsService } from 'vs/platform/windows/electron-browser/windowsService';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import { ILogService, LogLevel } from 'vs/platform/log/common/log';
|
||||
@@ -35,8 +35,6 @@ import { LogLevelSetterChannelClient, FollowerLogService } from 'vs/platform/log
|
||||
import { LocalizationsService } from 'vs/platform/localizations/node/localizations';
|
||||
import { ILocalizationsService } from 'vs/platform/localizations/common/localizations';
|
||||
import { LocalizationsChannel } from 'vs/platform/localizations/node/localizationsIpc';
|
||||
import { DialogChannelClient } from 'vs/platform/dialogs/node/dialogIpc';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { combinedDisposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { DownloadService } from 'vs/platform/download/common/downloadService';
|
||||
import { IDownloadService } from 'vs/platform/download/common/download';
|
||||
@@ -46,7 +44,6 @@ import { LanguagePackCachedDataCleaner } from 'vs/code/electron-browser/sharedPr
|
||||
import { StorageDataCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/storageDataCleaner';
|
||||
import { LogsDataCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/logsDataCleaner';
|
||||
import { IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService';
|
||||
import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { SpdLogService } from 'vs/platform/log/node/spdlogService';
|
||||
import { DiagnosticsService, IDiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsService';
|
||||
import { DiagnosticsChannel } from 'vs/platform/diagnostics/node/diagnosticsIpc';
|
||||
@@ -75,7 +72,7 @@ const eventPrefix = product.quality !== 'stable' ? 'adsworkbench' : 'monacoworkb
|
||||
class MainProcessService implements IMainProcessService {
|
||||
constructor(private server: Server, private mainRouter: StaticRouter) { }
|
||||
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
_serviceBrand: undefined;
|
||||
|
||||
getChannel(channelName: string): IChannel {
|
||||
return this.server.getChannel(channelName, this.mainRouter);
|
||||
@@ -121,11 +118,6 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat
|
||||
const windowsService = new WindowsService(mainProcessService);
|
||||
services.set(IWindowsService, windowsService);
|
||||
|
||||
const activeWindowManager = new ActiveWindowManager(windowsService);
|
||||
const activeWindowRouter = new StaticRouter(ctx => activeWindowManager.getActiveClientId().then(id => ctx === id));
|
||||
const dialogChannel = server.getChannel('dialog', activeWindowRouter);
|
||||
services.set(IDialogService, new DialogChannelClient(dialogChannel));
|
||||
|
||||
// Files
|
||||
const fileService = new FileService(logService);
|
||||
services.set(IFileService, fileService);
|
||||
@@ -156,7 +148,7 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat
|
||||
}
|
||||
const config: ITelemetryServiceConfig = {
|
||||
appender: combinedAppender(appInsightsAppender, new LogAppender(logService)),
|
||||
commonProperties: resolveCommonProperties(product.commit, pkg.version, configuration.machineId, installSourcePath),
|
||||
commonProperties: resolveCommonProperties(product.commit, pkg.version, configuration.machineId, product.msftInternalDomains, installSourcePath),
|
||||
piiPaths: extensionsPath ? [appRoot, extensionsPath] : [appRoot]
|
||||
};
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ bootstrapWindow.load([
|
||||
* @param {{
|
||||
* partsSplashPath?: string,
|
||||
* highContrast?: boolean,
|
||||
* extensionDevelopmentPath?: string | string[],
|
||||
* extensionDevelopmentPath?: string[],
|
||||
* folderUri?: object,
|
||||
* workspace?: object
|
||||
* }} configuration
|
||||
|
||||
@@ -12,7 +12,7 @@ import { WindowsService } from 'vs/platform/windows/electron-main/windowsService
|
||||
import { ILifecycleService, LifecycleMainPhase } from 'vs/platform/lifecycle/electron-main/lifecycleMain';
|
||||
import { getShellEnvironment } from 'vs/code/node/shellEnv';
|
||||
import { IUpdateService } from 'vs/platform/update/common/update';
|
||||
import { UpdateChannel } from 'vs/platform/update/node/updateIpc';
|
||||
import { UpdateChannel } from 'vs/platform/update/electron-main/updateIpc';
|
||||
import { Server as ElectronIPCServer } from 'vs/base/parts/ipc/electron-main/ipc.electron-main';
|
||||
import { Client } from 'vs/base/parts/ipc/common/ipc.net';
|
||||
import { Server, connect } from 'vs/base/parts/ipc/node/ipc.net';
|
||||
@@ -26,7 +26,7 @@ import { IStateService } from 'vs/platform/state/common/state';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IURLService } from 'vs/platform/url/common/url';
|
||||
import { URLHandlerChannelClient, URLServiceChannel } from 'vs/platform/url/node/urlIpc';
|
||||
import { URLHandlerChannelClient, URLServiceChannel, URLHandlerRouter } from 'vs/platform/url/common/urlIpc';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { NullTelemetryService, combinedAppender, LogAppender } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { TelemetryAppenderClient } from 'vs/platform/telemetry/node/telemetryIpc';
|
||||
@@ -56,7 +56,6 @@ import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver';
|
||||
import { IMenubarService } from 'vs/platform/menubar/node/menubar';
|
||||
import { MenubarService } from 'vs/platform/menubar/electron-main/menubarService';
|
||||
import { MenubarChannel } from 'vs/platform/menubar/node/menubarIpc';
|
||||
import { hasArgs } from 'vs/platform/environment/node/argv';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { registerContextMenuListener } from 'vs/base/parts/contextmenu/electron-main/contextmenu';
|
||||
import { homedir } from 'os';
|
||||
@@ -332,8 +331,9 @@ export class CodeApplication extends Disposable {
|
||||
// This will help Windows to associate the running program with
|
||||
// any shortcut that is pinned to the taskbar and prevent showing
|
||||
// two icons in the taskbar for the same app.
|
||||
if (isWindows && product.win32AppUserModelId) {
|
||||
app.setAppUserModelId(product.win32AppUserModelId);
|
||||
const win32AppUserModelId = product.win32AppUserModelId;
|
||||
if (isWindows && win32AppUserModelId) {
|
||||
app.setAppUserModelId(win32AppUserModelId);
|
||||
}
|
||||
|
||||
// Fix native tabs on macOS 10.13
|
||||
@@ -474,7 +474,7 @@ export class CodeApplication extends Disposable {
|
||||
if (!this.environmentService.isExtensionDevelopment && !this.environmentService.args['disable-telemetry'] && !!product.enableTelemetry) {
|
||||
const channel = getDelayedChannel(sharedProcessClient.then(client => client.getChannel('telemetryAppender')));
|
||||
const appender = combinedAppender(new TelemetryAppenderClient(channel), new LogAppender(this.logService));
|
||||
const commonProperties = resolveCommonProperties(product.commit, pkg.version, machineId, this.environmentService.installSourcePath);
|
||||
const commonProperties = resolveCommonProperties(product.commit, pkg.version, machineId, product.msftInternalDomains, this.environmentService.installSourcePath);
|
||||
const piiPaths = this.environmentService.extensionsPath ? [this.environmentService.appRoot, this.environmentService.extensionsPath] : [this.environmentService.appRoot];
|
||||
const config: ITelemetryServiceConfig = { appender, commonProperties, piiPaths, trueMachineId };
|
||||
|
||||
@@ -580,7 +580,8 @@ export class CodeApplication extends Disposable {
|
||||
// Create a URL handler which forwards to the last active window
|
||||
const activeWindowManager = new ActiveWindowManager(windowsService);
|
||||
const activeWindowRouter = new StaticRouter(ctx => activeWindowManager.getActiveClientId().then(id => ctx === id));
|
||||
const urlHandlerChannel = electronIpcServer.getChannel('urlHandler', activeWindowRouter);
|
||||
const urlHandlerRouter = new URLHandlerRouter(activeWindowRouter);
|
||||
const urlHandlerChannel = electronIpcServer.getChannel('urlHandler', urlHandlerRouter);
|
||||
const multiplexURLHandler = new URLHandlerChannelClient(urlHandlerChannel);
|
||||
|
||||
// On Mac, Code can be running without any open windows, so we must create a window to handle urls,
|
||||
@@ -616,9 +617,9 @@ export class CodeApplication extends Disposable {
|
||||
// Open our first window
|
||||
const macOpenFiles: string[] = (<any>global).macOpenFiles;
|
||||
const context = !!process.env['VSCODE_CLI'] ? OpenContext.CLI : OpenContext.DESKTOP;
|
||||
const hasCliArgs = hasArgs(args._);
|
||||
const hasFolderURIs = hasArgs(args['folder-uri']);
|
||||
const hasFileURIs = hasArgs(args['file-uri']);
|
||||
const hasCliArgs = args._.length;
|
||||
const hasFolderURIs = !!args['folder-uri'];
|
||||
const hasFileURIs = !!args['file-uri'];
|
||||
const noRecentEntry = args['skip-add-to-recently-opened'] === true;
|
||||
const waitMarkerFileURI = args.wait && args.waitMarkerFilePath ? URI.file(args.waitMarkerFilePath) : undefined;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ type Credentials = {
|
||||
|
||||
export class ProxyAuthHandler {
|
||||
|
||||
_serviceBrand: any;
|
||||
_serviceBrand: undefined;
|
||||
|
||||
private retryCount = 0;
|
||||
private disposables: IDisposable[] = [];
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/platform/update/node/update.config.contribution';
|
||||
import 'vs/platform/update/common/update.config.contribution';
|
||||
import { app, dialog } from 'electron';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
|
||||
@@ -11,7 +11,7 @@ import { screen, BrowserWindow, systemPreferences, app, TouchBar, nativeImage, R
|
||||
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { parseArgs } from 'vs/platform/environment/node/argv';
|
||||
import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv';
|
||||
import product from 'vs/platform/product/node/product';
|
||||
import { IWindowSettings, MenuBarVisibility, IWindowConfiguration, ReadyState, getTitleBarStyle } from 'vs/platform/windows/common/windows';
|
||||
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
@@ -32,7 +32,7 @@ const RUN_TEXTMATE_IN_WORKER = false;
|
||||
|
||||
export interface IWindowCreationOptions {
|
||||
state: IWindowState;
|
||||
extensionDevelopmentPath?: string | string[];
|
||||
extensionDevelopmentPath?: string[];
|
||||
isExtensionTestHost?: boolean;
|
||||
}
|
||||
|
||||
@@ -574,7 +574,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
||||
windowConfiguration.partsSplashPath = path.join(this.environmentService.userDataPath, 'rapid_render.json');
|
||||
|
||||
// Config (combination of process.argv and window configuration)
|
||||
const environment = parseArgs(process.argv);
|
||||
const environment = parseArgs(process.argv, OPTIONS);
|
||||
const config = objects.assign(environment, windowConfiguration);
|
||||
for (const key in config) {
|
||||
const configValue = (config as any)[key];
|
||||
|
||||
@@ -12,7 +12,6 @@ import { IBackupMainService, IEmptyWindowBackupInfo } from 'vs/platform/backup/c
|
||||
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
import { IStateService } from 'vs/platform/state/common/state';
|
||||
import { CodeWindow, defaultWindowState } from 'vs/code/electron-main/window';
|
||||
import { hasArgs, asArray } from 'vs/platform/environment/node/argv';
|
||||
import { ipcMain as ipc, screen, BrowserWindow, dialog, systemPreferences, FileFilter } from 'electron';
|
||||
import { parseLineAndColumnAware } from 'vs/code/node/paths';
|
||||
import { ILifecycleService, UnloadReason, LifecycleService, LifecycleMainPhase } from 'vs/platform/lifecycle/electron-main/lifecycleMain';
|
||||
@@ -157,7 +156,7 @@ interface IWorkspacePathToOpen {
|
||||
|
||||
export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
|
||||
_serviceBrand: any;
|
||||
_serviceBrand: undefined;
|
||||
|
||||
private static readonly windowsStateStorageKey = 'windowsState';
|
||||
|
||||
@@ -211,10 +210,11 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
}
|
||||
|
||||
private installWindowsMutex(): void {
|
||||
if (isWindows) {
|
||||
const win32MutexName = product.win32MutexName;
|
||||
if (isWindows && win32MutexName) {
|
||||
try {
|
||||
const WindowsMutex = (require.__$__nodeRequire('windows-mutex') as typeof import('windows-mutex')).Mutex;
|
||||
const mutex = new WindowsMutex(product.win32MutexName);
|
||||
const mutex = new WindowsMutex(win32MutexName);
|
||||
once(this.lifecycleService.onWillShutdown)(() => mutex.release());
|
||||
} catch (e) {
|
||||
this.logService.error(e);
|
||||
@@ -309,7 +309,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
if (!currentWindowsState.lastActiveWindow) {
|
||||
let activeWindow = this.getLastActiveWindow();
|
||||
if (!activeWindow || activeWindow.isExtensionDevelopmentHost) {
|
||||
activeWindow = WindowsManager.WINDOWS.filter(w => !w.isExtensionDevelopmentHost)[0];
|
||||
activeWindow = WindowsManager.WINDOWS.filter(window => !window.isExtensionDevelopmentHost)[0];
|
||||
}
|
||||
|
||||
if (activeWindow) {
|
||||
@@ -318,7 +318,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
}
|
||||
|
||||
// 2.) Find extension host window
|
||||
const extensionHostWindow = WindowsManager.WINDOWS.filter(w => w.isExtensionDevelopmentHost && !w.isExtensionTestHost)[0];
|
||||
const extensionHostWindow = WindowsManager.WINDOWS.filter(window => window.isExtensionDevelopmentHost && !window.isExtensionTestHost)[0];
|
||||
if (extensionHostWindow) {
|
||||
currentWindowsState.lastPluginDevelopmentHostWindow = this.toWindowState(extensionHostWindow);
|
||||
}
|
||||
@@ -329,7 +329,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
// so if we ever want to persist the UI state of the last closed window (window count === 1), it has
|
||||
// to come from the stored lastClosedWindowState on Win/Linux at least
|
||||
if (this.getWindowCount() > 1) {
|
||||
currentWindowsState.openedWindows = WindowsManager.WINDOWS.filter(w => !w.isExtensionDevelopmentHost).map(w => this.toWindowState(w));
|
||||
currentWindowsState.openedWindows = WindowsManager.WINDOWS.filter(window => !window.isExtensionDevelopmentHost).map(window => this.toWindowState(window));
|
||||
}
|
||||
|
||||
// Persist
|
||||
@@ -450,13 +450,13 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
// Make sure to pass focus to the most relevant of the windows if we open multiple
|
||||
if (usedWindows.length > 1) {
|
||||
|
||||
const focusLastActive = this.windowsState.lastActiveWindow && !openConfig.forceEmpty && !hasArgs(openConfig.cli._) && !hasArgs(openConfig.cli['file-uri']) && !hasArgs(openConfig.cli['folder-uri']) && !(openConfig.urisToOpen && openConfig.urisToOpen.length);
|
||||
const focusLastActive = this.windowsState.lastActiveWindow && !openConfig.forceEmpty && openConfig.cli._.length && !openConfig.cli['file-uri'] && !openConfig.cli['folder-uri'] && !(openConfig.urisToOpen && openConfig.urisToOpen.length);
|
||||
let focusLastOpened = true;
|
||||
let focusLastWindow = true;
|
||||
|
||||
// 1.) focus last active window if we are not instructed to open any paths
|
||||
if (focusLastActive) {
|
||||
const lastActiveWindow = usedWindows.filter(w => w.backupPath === this.windowsState.lastActiveWindow!.backupPath);
|
||||
const lastActiveWindow = usedWindows.filter(window => window.backupPath === this.windowsState.lastActiveWindow!.backupPath);
|
||||
if (lastActiveWindow.length) {
|
||||
lastActiveWindow[0].focus();
|
||||
focusLastOpened = false;
|
||||
@@ -490,7 +490,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
|
||||
// Remember in recent document list (unless this opens for extension development)
|
||||
// Also do not add paths when files are opened for diffing, only if opened individually
|
||||
if (!usedWindows.some(w => w.isExtensionDevelopmentHost) && !openConfig.diffMode && !openConfig.noRecentEntry) {
|
||||
if (!usedWindows.some(window => window.isExtensionDevelopmentHost) && !openConfig.diffMode && !openConfig.noRecentEntry) {
|
||||
const recents: IRecent[] = [];
|
||||
for (let pathToOpen of pathsToOpen) {
|
||||
if (pathToOpen.workspace) {
|
||||
@@ -556,7 +556,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
const fileToCheck = fileInputs.filesToOpenOrCreate[0] || fileInputs.filesToDiff[0];
|
||||
|
||||
// only look at the windows with correct authority
|
||||
const windows = WindowsManager.WINDOWS.filter(w => w.remoteAuthority === fileInputs!.remoteAuthority);
|
||||
const windows = WindowsManager.WINDOWS.filter(window => window.remoteAuthority === fileInputs!.remoteAuthority);
|
||||
|
||||
const bestWindowOrFolder = findBestWindowOrFolderForFile({
|
||||
windows,
|
||||
@@ -811,7 +811,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
}
|
||||
|
||||
// Extract paths: from CLI
|
||||
else if (hasArgs(openConfig.cli._) || hasArgs(openConfig.cli['folder-uri']) || hasArgs(openConfig.cli['file-uri'])) {
|
||||
else if (openConfig.cli._.length || openConfig.cli['folder-uri'] || openConfig.cli['file-uri']) {
|
||||
windowsToOpen = this.doExtractPathsFromCLI(openConfig.cli);
|
||||
isCommandLineOrAPICall = true;
|
||||
}
|
||||
@@ -885,31 +885,36 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
const parseOptions: IPathParseOptions = { ignoreFileNotFound: true, gotoLineMode: cli.goto, remoteAuthority: cli.remote || undefined };
|
||||
|
||||
// folder uris
|
||||
const folderUris = asArray(cli['folder-uri']);
|
||||
for (let f of folderUris) {
|
||||
const folderUri = this.argToUri(f);
|
||||
if (folderUri) {
|
||||
const path = this.parseUri({ folderUri }, parseOptions);
|
||||
if (path) {
|
||||
pathsToOpen.push(path);
|
||||
const folderUris = cli['folder-uri'];
|
||||
if (folderUris) {
|
||||
for (let f of folderUris) {
|
||||
const folderUri = this.argToUri(f);
|
||||
if (folderUri) {
|
||||
const path = this.parseUri({ folderUri }, parseOptions);
|
||||
if (path) {
|
||||
pathsToOpen.push(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// file uris
|
||||
const fileUris = asArray(cli['file-uri']);
|
||||
for (let f of fileUris) {
|
||||
const fileUri = this.argToUri(f);
|
||||
if (fileUri) {
|
||||
const path = this.parseUri(hasWorkspaceFileExtension(f) ? { workspaceUri: fileUri } : { fileUri }, parseOptions);
|
||||
if (path) {
|
||||
pathsToOpen.push(path);
|
||||
const fileUris = cli['file-uri'];
|
||||
if (fileUris) {
|
||||
for (let f of fileUris) {
|
||||
const fileUri = this.argToUri(f);
|
||||
if (fileUri) {
|
||||
const path = this.parseUri(hasWorkspaceFileExtension(f) ? { workspaceUri: fileUri } : { fileUri }, parseOptions);
|
||||
if (path) {
|
||||
pathsToOpen.push(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// folder or file paths
|
||||
const cliArgs = asArray(cli._);
|
||||
const cliArgs = cli._;
|
||||
for (let cliArg of cliArgs) {
|
||||
const path = this.parsePath(cliArg, parseOptions);
|
||||
if (path) {
|
||||
@@ -1166,7 +1171,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
return { openFolderInNewWindow: !!openFolderInNewWindow, openFilesInNewWindow };
|
||||
}
|
||||
|
||||
openExtensionDevelopmentHostWindow(extensionDevelopmentPath: string | string[], openConfig: IOpenConfiguration): void {
|
||||
openExtensionDevelopmentHostWindow(extensionDevelopmentPath: string[], openConfig: IOpenConfiguration): void {
|
||||
|
||||
// Reload an existing extension development host window on the same path
|
||||
// We currently do not allow more than one extension development window
|
||||
@@ -1178,8 +1183,8 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
|
||||
return;
|
||||
}
|
||||
let folderUris = asArray(openConfig.cli['folder-uri']);
|
||||
let fileUris = asArray(openConfig.cli['file-uri']);
|
||||
let folderUris = openConfig.cli['folder-uri'] || [];
|
||||
let fileUris = openConfig.cli['file-uri'] || [];
|
||||
let cliArgs = openConfig.cli._;
|
||||
|
||||
// Fill in previously opened workspace unless an explicit path is provided and we are not unit testing
|
||||
@@ -1203,10 +1208,6 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
}
|
||||
}
|
||||
|
||||
if (!Array.isArray(extensionDevelopmentPath)) {
|
||||
extensionDevelopmentPath = [extensionDevelopmentPath];
|
||||
}
|
||||
|
||||
let authority = '';
|
||||
for (let p of extensionDevelopmentPath) {
|
||||
if (p.match(/^[a-zA-Z][a-zA-Z0-9\+\-\.]+:/)) {
|
||||
@@ -1599,7 +1600,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
}
|
||||
|
||||
getLastActiveWindowForAuthority(remoteAuthority: string | undefined): ICodeWindow | undefined {
|
||||
return getLastActiveWindow(WindowsManager.WINDOWS.filter(w => w.remoteAuthority === remoteAuthority));
|
||||
return getLastActiveWindow(WindowsManager.WINDOWS.filter(window => window.remoteAuthority === remoteAuthority));
|
||||
}
|
||||
|
||||
openNewWindow(context: OpenContext, options?: INewWindowOptions): ICodeWindow[] {
|
||||
@@ -1642,13 +1643,13 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
}
|
||||
|
||||
sendToAll(channel: string, payload?: any, windowIdsToIgnore?: number[]): void {
|
||||
WindowsManager.WINDOWS.forEach(w => {
|
||||
if (windowIdsToIgnore && windowIdsToIgnore.indexOf(w.id) >= 0) {
|
||||
return; // do not send if we are instructed to ignore it
|
||||
for (const window of WindowsManager.WINDOWS) {
|
||||
if (windowIdsToIgnore && windowIdsToIgnore.indexOf(window.id) >= 0) {
|
||||
continue; // do not send if we are instructed to ignore it
|
||||
}
|
||||
|
||||
w.sendWhenReady(channel, payload);
|
||||
});
|
||||
window.sendWhenReady(channel, payload);
|
||||
}
|
||||
}
|
||||
|
||||
getFocusedWindow(): ICodeWindow | undefined {
|
||||
@@ -1661,7 +1662,7 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
|
||||
}
|
||||
|
||||
getWindowById(windowId: number): ICodeWindow | undefined {
|
||||
const res = WindowsManager.WINDOWS.filter(w => w.id === windowId);
|
||||
const res = WindowsManager.WINDOWS.filter(window => window.id === windowId);
|
||||
if (res && res.length === 1) {
|
||||
return res[0];
|
||||
}
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { spawn, ChildProcess, SpawnOptions } from 'child_process';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { buildHelpMessage, buildVersionMessage, addArg, createWaitMarkerFile } from 'vs/platform/environment/node/argv';
|
||||
import { buildHelpMessage, buildVersionMessage, addArg, createWaitMarkerFile, OPTIONS } from 'vs/platform/environment/node/argv';
|
||||
import { parseCLIProcessArgv } from 'vs/platform/environment/node/argvHelper';
|
||||
import { ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
import product from 'vs/platform/product/node/product';
|
||||
@@ -47,7 +46,7 @@ export async function main(argv: string[]): Promise<any> {
|
||||
// Help
|
||||
if (args.help) {
|
||||
const executable = `${product.applicationName}${os.platform() === 'win32' ? '.exe' : ''}`;
|
||||
console.log(buildHelpMessage(product.nameLong, executable, pkg.version));
|
||||
console.log(buildHelpMessage(product.nameLong, executable, pkg.version, OPTIONS));
|
||||
}
|
||||
|
||||
// Version Info
|
||||
@@ -118,10 +117,15 @@ export async function main(argv: string[]): Promise<any> {
|
||||
|
||||
// Just Code
|
||||
else {
|
||||
const env = assign({}, process.env, {
|
||||
const env: NodeJS.ProcessEnv = {
|
||||
...process.env,
|
||||
'VSCODE_CLI': '1', // this will signal Code that it was spawned from this module
|
||||
'ELECTRON_NO_ATTACH_CONSOLE': '1'
|
||||
});
|
||||
};
|
||||
|
||||
if (args['force-user-env']) {
|
||||
env['VSCODE_FORCE_USER_ENV'] = '1';
|
||||
}
|
||||
|
||||
delete env['ELECTRON_RUN_AS_NODE'];
|
||||
|
||||
|
||||
@@ -83,23 +83,14 @@ export class Main {
|
||||
async run(argv: ParsedArgs): Promise<void> {
|
||||
if (argv['install-source']) {
|
||||
await this.setInstallSource(argv['install-source']);
|
||||
|
||||
} else if (argv['list-extensions']) {
|
||||
await this.listExtensions(!!argv['show-versions'], argv['category']);
|
||||
|
||||
} else if (argv['install-extension']) {
|
||||
const arg = argv['install-extension'];
|
||||
const args: string[] = typeof arg === 'string' ? [arg] : arg;
|
||||
await this.installExtensions(args, !!argv['force']);
|
||||
|
||||
await this.installExtensions(argv['install-extension'], !!argv['force']);
|
||||
} else if (argv['uninstall-extension']) {
|
||||
const arg = argv['uninstall-extension'];
|
||||
const ids: string[] = typeof arg === 'string' ? [arg] : arg;
|
||||
await this.uninstallExtension(ids);
|
||||
await this.uninstallExtension(argv['uninstall-extension']);
|
||||
} else if (argv['locate-extension']) {
|
||||
const arg = argv['locate-extension'];
|
||||
const ids: string[] = typeof arg === 'string' ? [arg] : arg;
|
||||
await this.locateExtension(ids);
|
||||
await this.locateExtension(argv['locate-extension']);
|
||||
} else if (argv['telemetry']) {
|
||||
console.log(buildTelemetryMessage(this.environmentService.appRoot, this.environmentService.extensionsPath ? this.environmentService.extensionsPath : undefined));
|
||||
}
|
||||
@@ -359,7 +350,7 @@ export async function main(argv: ParsedArgs): Promise<void> {
|
||||
|
||||
const config: ITelemetryServiceConfig = {
|
||||
appender: combinedAppender(...appenders),
|
||||
commonProperties: resolveCommonProperties(product.commit, pkg.version, stateService.getItem('telemetry.machineId'), installSourcePath),
|
||||
commonProperties: resolveCommonProperties(product.commit, pkg.version, stateService.getItem('telemetry.machineId'), product.msftInternalDomains, installSourcePath),
|
||||
piiPaths: extensionsPath ? [appRoot, extensionsPath] : [appRoot]
|
||||
};
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ export function getShellEnvironment(logService: ILogService, environmentService:
|
||||
} else if (isWindows) {
|
||||
logService.trace('getShellEnvironment: running on Windows, skipping');
|
||||
_shellEnv = Promise.resolve({});
|
||||
} else if (process.env['VSCODE_CLI'] === '1') {
|
||||
} else if (process.env['VSCODE_CLI'] === '1' && process.env['VSCODE_FORCE_USER_ENV'] !== '1') {
|
||||
logService.trace('getShellEnvironment: running on CLI, skipping');
|
||||
_shellEnv = Promise.resolve({});
|
||||
} else {
|
||||
|
||||
@@ -14,7 +14,7 @@ export interface ISimpleWindow {
|
||||
openedWorkspace?: IWorkspaceIdentifier;
|
||||
openedFolderUri?: URI;
|
||||
|
||||
extensionDevelopmentPath?: string | string[];
|
||||
extensionDevelopmentPath?: string[];
|
||||
lastFocusTime: number;
|
||||
}
|
||||
|
||||
@@ -95,30 +95,17 @@ export function findWindowOnWorkspace<W extends ISimpleWindow>(windows: W[], wor
|
||||
return null;
|
||||
}
|
||||
|
||||
export function findWindowOnExtensionDevelopmentPath<W extends ISimpleWindow>(windows: W[], extensionDevelopmentPath: string | string[]): W | null {
|
||||
export function findWindowOnExtensionDevelopmentPath<W extends ISimpleWindow>(windows: W[], extensionDevelopmentPaths: string[]): W | null {
|
||||
|
||||
const matches = (uriString: string): boolean => {
|
||||
if (Array.isArray(extensionDevelopmentPath)) {
|
||||
return extensionDevelopmentPath.some(p => extpath.isEqual(p, uriString, !platform.isLinux /* ignorecase */));
|
||||
} else if (extensionDevelopmentPath) {
|
||||
return extpath.isEqual(extensionDevelopmentPath, uriString, !platform.isLinux /* ignorecase */);
|
||||
}
|
||||
return false;
|
||||
return extensionDevelopmentPaths.some(p => extpath.isEqual(p, uriString, !platform.isLinux /* ignorecase */));
|
||||
};
|
||||
|
||||
for (const window of windows) {
|
||||
// match on extension development path. The path can be one or more paths or uri strings, using paths.isEqual is not 100% correct but good enough
|
||||
|
||||
if (window.extensionDevelopmentPath) {
|
||||
if (Array.isArray(window.extensionDevelopmentPath)) {
|
||||
if (window.extensionDevelopmentPath.some(p => matches(p))) {
|
||||
return window;
|
||||
}
|
||||
} else if (window.extensionDevelopmentPath) {
|
||||
if (matches(window.extensionDevelopmentPath)) {
|
||||
return window;
|
||||
}
|
||||
}
|
||||
const currPaths = window.extensionDevelopmentPath;
|
||||
if (currPaths && currPaths.some(p => matches(p))) {
|
||||
return window;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,29 +4,28 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as assert from 'assert';
|
||||
import { formatOptions, Option, addArg } from 'vs/platform/environment/node/argv';
|
||||
import { ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
|
||||
suite('formatOptions', () => {
|
||||
|
||||
function o(id: keyof ParsedArgs, description: string): Option {
|
||||
function o(description: string): Option<any> {
|
||||
return {
|
||||
id, description, type: 'string'
|
||||
description, type: 'string'
|
||||
};
|
||||
}
|
||||
|
||||
test('Text should display small columns correctly', () => {
|
||||
assert.deepEqual(
|
||||
formatOptions([
|
||||
o('add', 'bar')
|
||||
], 80),
|
||||
formatOptions({
|
||||
'add': o('bar')
|
||||
}, 80),
|
||||
[' --add bar']
|
||||
);
|
||||
assert.deepEqual(
|
||||
formatOptions([
|
||||
o('add', 'bar'),
|
||||
o('wait', 'ba'),
|
||||
o('trace', 'b')
|
||||
], 80),
|
||||
formatOptions({
|
||||
'add': o('bar'),
|
||||
'wait': o('ba'),
|
||||
'trace': o('b')
|
||||
}, 80),
|
||||
[
|
||||
' --add bar',
|
||||
' --wait ba',
|
||||
@@ -36,9 +35,9 @@ suite('formatOptions', () => {
|
||||
|
||||
test('Text should wrap', () => {
|
||||
assert.deepEqual(
|
||||
formatOptions([
|
||||
o('add', (<any>'bar ').repeat(9))
|
||||
], 40),
|
||||
formatOptions({
|
||||
'add': o((<any>'bar ').repeat(9))
|
||||
}, 40),
|
||||
[
|
||||
' --add bar bar bar bar bar bar bar bar',
|
||||
' bar'
|
||||
@@ -47,9 +46,9 @@ suite('formatOptions', () => {
|
||||
|
||||
test('Text should revert to the condensed view when the terminal is too narrow', () => {
|
||||
assert.deepEqual(
|
||||
formatOptions([
|
||||
o('add', (<any>'bar ').repeat(9))
|
||||
], 30),
|
||||
formatOptions({
|
||||
'add': o((<any>'bar ').repeat(9))
|
||||
}, 30),
|
||||
[
|
||||
' --add',
|
||||
' bar bar bar bar bar bar bar bar bar '
|
||||
|
||||
Reference in New Issue
Block a user