|
|
|
|
@@ -1,3 +1,25 @@
|
|
|
|
|
diff --git a/.eslintrc.json b/.eslintrc.json
|
|
|
|
|
index 055bc22f8e48e7dee559b83ac56c12a54c6ad544..14c026c04a7df5ac94bea2856e3a7a513c213775 100644
|
|
|
|
|
--- a/.eslintrc.json
|
|
|
|
|
+++ b/.eslintrc.json
|
|
|
|
|
@@ -64,7 +64,7 @@
|
|
|
|
|
"code-no-standalone-editor": "warn",
|
|
|
|
|
"code-no-unexternalized-strings": "warn",
|
|
|
|
|
"code-layering": [
|
|
|
|
|
- "warn",
|
|
|
|
|
+ "off",
|
|
|
|
|
{
|
|
|
|
|
"common": [],
|
|
|
|
|
"node": [
|
|
|
|
|
@@ -90,7 +90,7 @@
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
"code-import-patterns": [
|
|
|
|
|
- "warn",
|
|
|
|
|
+ "off",
|
|
|
|
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
|
// !!! Do not relax these rules !!!
|
|
|
|
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
|
diff --git a/.gitignore b/.gitignore
|
|
|
|
|
index b7f5b58c8ede171be547c56b61ce76f79a3accc3..856fbd8c67460fe099d7fbee1475e906b500f053 100644
|
|
|
|
|
--- a/.gitignore
|
|
|
|
|
@@ -264,9 +286,18 @@ index 28f8a69a2a91f9cb9f4dbd73ed3e689b2b3afe84..b5f5b10004d3e36092a30f685938a606
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
diff --git a/product.json b/product.json
|
|
|
|
|
index 7cab6d1b9f3b84bfc703856e93773a293fd198cf..31d3d5a943192eee791e1121415b436dc1ed3822 100644
|
|
|
|
|
index 7cab6d1b9f3b84bfc703856e93773a293fd198cf..6924d94f65b390f52885b1036f7e96bce0e34680 100644
|
|
|
|
|
--- a/product.json
|
|
|
|
|
+++ b/product.json
|
|
|
|
|
@@ -1,6 +1,6 @@
|
|
|
|
|
{
|
|
|
|
|
- "nameShort": "Code - OSS",
|
|
|
|
|
- "nameLong": "Code - OSS",
|
|
|
|
|
+ "nameShort": "code-server",
|
|
|
|
|
+ "nameLong": "code-server",
|
|
|
|
|
"applicationName": "code-oss",
|
|
|
|
|
"dataFolderName": ".vscode-oss",
|
|
|
|
|
"win32MutexName": "vscodeoss",
|
|
|
|
|
@@ -20,7 +20,7 @@
|
|
|
|
|
"darwinBundleIdentifier": "com.visualstudio.code.oss",
|
|
|
|
|
"linuxIconName": "com.visualstudio.code.oss",
|
|
|
|
|
@@ -276,6 +307,22 @@ index 7cab6d1b9f3b84bfc703856e93773a293fd198cf..31d3d5a943192eee791e1121415b436d
|
|
|
|
|
"urlProtocol": "code-oss",
|
|
|
|
|
"extensionAllowedProposedApi": [
|
|
|
|
|
"ms-vscode.vscode-js-profile-flame",
|
|
|
|
|
@@ -136,5 +136,14 @@
|
|
|
|
|
"publisherDisplayName": "Microsoft"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
- ]
|
|
|
|
|
+ ],
|
|
|
|
|
+
|
|
|
|
|
+ "//": "https://github.com/VSCodium/vscodium/pull/155/files",
|
|
|
|
|
+ "documentationUrl": "https://go.microsoft.com/fwlink/?LinkID=533484#vscode",
|
|
|
|
|
+ "keyboardShortcutsUrlMac": "https://go.microsoft.com/fwlink/?linkid=832143",
|
|
|
|
|
+ "keyboardShortcutsUrlLinux": "https://go.microsoft.com/fwlink/?linkid=832144",
|
|
|
|
|
+ "keyboardShortcutsUrlWin": "https://go.microsoft.com/fwlink/?linkid=832145",
|
|
|
|
|
+ "introductoryVideosUrl": "https://go.microsoft.com/fwlink/?linkid=832146",
|
|
|
|
|
+ "tipsAndTricksUrl": "https://go.microsoft.com/fwlink/?linkid=852118",
|
|
|
|
|
+ "newsletterSignupUrl": "https://www.research.net/r/vsc-newsletter"
|
|
|
|
|
}
|
|
|
|
|
diff --git a/remote/.yarnrc b/remote/.yarnrc
|
|
|
|
|
deleted file mode 100644
|
|
|
|
|
index c1a32ce532afa501fb19bdbcf6bcb0ec151ecd99..0000000000000000000000000000000000000000
|
|
|
|
|
@@ -412,7 +459,7 @@ index ef2291d49b13c9c995afc90eab9c92afabc2b3b4..29b2f9dfc2b7fa998ac1188db06dee95
|
|
|
|
|
\ No newline at end of file
|
|
|
|
|
+}
|
|
|
|
|
diff --git a/src/vs/base/node/languagePacks.js b/src/vs/base/node/languagePacks.js
|
|
|
|
|
index 2c64061da7b01aef0bfe3cec851da232ca9461c8..c0ef8faedd406c38bf9c55bbbdbbb060046492d9 100644
|
|
|
|
|
index 2c64061da7b01aef0bfe3cec851da232ca9461c8..db47fe2eb1cded1e9c33b42fe700421c36a1d481 100644
|
|
|
|
|
--- a/src/vs/base/node/languagePacks.js
|
|
|
|
|
+++ b/src/vs/base/node/languagePacks.js
|
|
|
|
|
@@ -128,7 +128,10 @@ function factory(nodeRequire, path, fs, perf) {
|
|
|
|
|
@@ -423,12 +470,12 @@ index 2c64061da7b01aef0bfe3cec851da232ca9461c8..c0ef8faedd406c38bf9c55bbbdbbb060
|
|
|
|
|
+ // NOTE@coder: Swapped require with readFile since require is cached and
|
|
|
|
|
+ // we don't restart the server-side portion of code-server when the
|
|
|
|
|
+ // language changes.
|
|
|
|
|
+ return JSON.parse(fs.readFileSync(configFile, "utf8"));
|
|
|
|
|
+ return JSON.parse(fs.readFileSync(configFile, 'utf8'));
|
|
|
|
|
} catch (err) {
|
|
|
|
|
// Do nothing. If we can't read the file we have no
|
|
|
|
|
// language pack config.
|
|
|
|
|
diff --git a/src/vs/code/browser/workbench/workbench.ts b/src/vs/code/browser/workbench/workbench.ts
|
|
|
|
|
index 0ef8b9dc81419b53b27cf111fb206d72ba56bada..62a79602a831bca0dc62ad57dc10a9375f8b9cdb 100644
|
|
|
|
|
index 0ef8b9dc81419b53b27cf111fb206d72ba56bada..e490cf7449623f96c780a65d538fad72cf9306e4 100644
|
|
|
|
|
--- a/src/vs/code/browser/workbench/workbench.ts
|
|
|
|
|
+++ b/src/vs/code/browser/workbench/workbench.ts
|
|
|
|
|
@@ -17,6 +17,7 @@ import { isStandalone } from 'vs/base/browser/browser';
|
|
|
|
|
@@ -471,7 +518,7 @@ index 0ef8b9dc81419b53b27cf111fb206d72ba56bada..62a79602a831bca0dc62ad57dc10a937
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // Strip the protocol from the authority if it exists.
|
|
|
|
|
+ const normalizeAuthority = (authority: string): string => authority.replace(/^https?:\/\//, "");
|
|
|
|
|
+ const normalizeAuthority = (authority: string): string => authority.replace(/^https?:\/\//, '');
|
|
|
|
|
+ if (config.remoteAuthority) {
|
|
|
|
|
+ (config as any).remoteAuthority = normalizeAuthority(config.remoteAuthority);
|
|
|
|
|
+ }
|
|
|
|
|
@@ -687,7 +734,7 @@ index 3715cbb8e6ee41c3d9b5090918d243b723ae2d00..c65de8ad37e727d66da97a8f8b170cbc
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
diff --git a/src/vs/platform/remote/common/remoteAgentConnection.ts b/src/vs/platform/remote/common/remoteAgentConnection.ts
|
|
|
|
|
index fdd5890c69f72025b94913380f0d226226e8c8fb..e084236526b38c1144d47b8b3000b367c3207fe8 100644
|
|
|
|
|
index fdd5890c69f72025b94913380f0d226226e8c8fb..957b4812783f6b1d97d1003c63725f541042059f 100644
|
|
|
|
|
--- a/src/vs/platform/remote/common/remoteAgentConnection.ts
|
|
|
|
|
+++ b/src/vs/platform/remote/common/remoteAgentConnection.ts
|
|
|
|
|
@@ -93,7 +93,7 @@ async function connectToRemoteExtensionHostAgent(options: ISimpleConnectionOptio
|
|
|
|
|
@@ -699,6 +746,25 @@ index fdd5890c69f72025b94913380f0d226226e8c8fb..e084236526b38c1144d47b8b3000b367
|
|
|
|
|
(err: any, socket: ISocket | undefined) => {
|
|
|
|
|
if (err || !socket) {
|
|
|
|
|
options.logService.error(`${logPrefix} socketFactory.connect() failed. Error:`);
|
|
|
|
|
@@ -338,7 +338,8 @@ export class ReconnectionWaitEvent {
|
|
|
|
|
public readonly type = PersistentConnectionEventType.ReconnectionWait;
|
|
|
|
|
constructor(
|
|
|
|
|
public readonly durationSeconds: number,
|
|
|
|
|
- private readonly cancellableTimer: CancelablePromise<void>
|
|
|
|
|
+ private readonly cancellableTimer: CancelablePromise<void>,
|
|
|
|
|
+ public readonly connectionAttempt: number
|
|
|
|
|
) { }
|
|
|
|
|
|
|
|
|
|
public skipWait(): void {
|
|
|
|
|
@@ -422,7 +423,7 @@ abstract class PersistentConnection extends Disposable {
|
|
|
|
|
const waitTime = (attempt < TIMES.length ? TIMES[attempt] : TIMES[TIMES.length - 1]);
|
|
|
|
|
try {
|
|
|
|
|
const sleepPromise = sleep(waitTime);
|
|
|
|
|
- this._onDidStateChange.fire(new ReconnectionWaitEvent(waitTime, sleepPromise));
|
|
|
|
|
+ this._onDidStateChange.fire(new ReconnectionWaitEvent(waitTime, sleepPromise, attempt+1));
|
|
|
|
|
|
|
|
|
|
this._options.logService.info(`${logPrefix} waiting for ${waitTime} seconds before reconnecting...`);
|
|
|
|
|
try {
|
|
|
|
|
diff --git a/src/vs/platform/storage/browser/storageService.ts b/src/vs/platform/storage/browser/storageService.ts
|
|
|
|
|
index ab3fd347b69f8a3d9b96e706cd87c911b8ffed6b..9d351037b577f9f1edfd18ae9b3c48a211f4467f 100644
|
|
|
|
|
--- a/src/vs/platform/storage/browser/storageService.ts
|
|
|
|
|
@@ -744,10 +810,10 @@ index 096b9e23493539c9937940a56e555d95bbae38d9..ef37e614004f550f7b64eacd362f6894
|
|
|
|
|
remove(key: string, scope: StorageScope): void {
|
|
|
|
|
diff --git a/src/vs/server/browser/client.ts b/src/vs/server/browser/client.ts
|
|
|
|
|
new file mode 100644
|
|
|
|
|
index 0000000000000000000000000000000000000000..3c0703b7174ad792a4b42841e96ee93765d71601
|
|
|
|
|
index 0000000000000000000000000000000000000000..8a92b722b38f8743403892ea97cfb2a2a8726e3b
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/src/vs/server/browser/client.ts
|
|
|
|
|
@@ -0,0 +1,189 @@
|
|
|
|
|
@@ -0,0 +1,241 @@
|
|
|
|
|
+import { Emitter } from 'vs/base/common/event';
|
|
|
|
|
+import { URI } from 'vs/base/common/uri';
|
|
|
|
|
+import { localize } from 'vs/nls';
|
|
|
|
|
@@ -766,6 +832,8 @@ index 0000000000000000000000000000000000000000..3c0703b7174ad792a4b42841e96ee937
|
|
|
|
|
+import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
|
|
|
|
+import { Options } from 'vs/server/ipc.d';
|
|
|
|
|
+import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
|
|
|
|
+import { ILogService } from 'vs/platform/log/common/log';
|
|
|
|
|
+import * as path from 'vs/base/common/path';
|
|
|
|
|
+
|
|
|
|
|
+class TelemetryService extends TelemetryChannelClient {
|
|
|
|
|
+ public constructor(
|
|
|
|
|
@@ -779,7 +847,7 @@ index 0000000000000000000000000000000000000000..3c0703b7174ad792a4b42841e96ee937
|
|
|
|
|
+ * Remove extra slashes in a URL.
|
|
|
|
|
+ */
|
|
|
|
|
+export const normalize = (url: string, keepTrailing = false): string => {
|
|
|
|
|
+ return url.replace(/\/\/+/g, "/").replace(/\/+$/, keepTrailing ? "/" : "");
|
|
|
|
|
+ return url.replace(/\/\/+/g, '/').replace(/\/+$/, keepTrailing ? '/' : '');
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
@@ -787,7 +855,7 @@ index 0000000000000000000000000000000000000000..3c0703b7174ad792a4b42841e96ee937
|
|
|
|
|
+ */
|
|
|
|
|
+export const getOptions = <T extends Options>(): T => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ return JSON.parse(document.getElementById("coder-options")!.getAttribute("data-settings")!);
|
|
|
|
|
+ return JSON.parse(document.getElementById('coder-options')!.getAttribute('data-settings')!);
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ return {} as T;
|
|
|
|
|
+ }
|
|
|
|
|
@@ -897,10 +965,60 @@ index 0000000000000000000000000000000000000000..3c0703b7174ad792a4b42841e96ee937
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const logService = (services.get(ILogService) as ILogService);
|
|
|
|
|
+ const storageService = (services.get(IStorageService) as IStorageService);
|
|
|
|
|
+ const updateCheckEndpoint = path.join(options.base, '/update/check');
|
|
|
|
|
+ const getUpdate = async (): Promise<void> => {
|
|
|
|
|
+ logService.debug('Checking for update...');
|
|
|
|
|
+
|
|
|
|
|
+ const response = await fetch(updateCheckEndpoint, {
|
|
|
|
|
+ headers: { 'Accept': 'application/json' },
|
|
|
|
|
+ });
|
|
|
|
|
+ if (!response.ok) {
|
|
|
|
|
+ throw new Error(response.statusText);
|
|
|
|
|
+ }
|
|
|
|
|
+ const json = await response.json();
|
|
|
|
|
+ if (json.error) {
|
|
|
|
|
+ throw new Error(json.error);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (json.isLatest) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const lastNoti = storageService.getNumber('csLastUpdateNotification', StorageScope.GLOBAL);
|
|
|
|
|
+ if (lastNoti) {
|
|
|
|
|
+ // Only remind them again after 1 week.
|
|
|
|
|
+ const timeout = 1000*60*60*24*7;
|
|
|
|
|
+ const threshold = lastNoti + timeout;
|
|
|
|
|
+ if (Date.now() < threshold) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ storageService.store('csLastUpdateNotification', Date.now(), StorageScope.GLOBAL);
|
|
|
|
|
+ (services.get(INotificationService) as INotificationService).notify({
|
|
|
|
|
+ severity: Severity.Info,
|
|
|
|
|
+ message: `[code-server v${json.latest}](https://github.com/cdr/code-server/releases/tag/v${json.latest}) has been released!`,
|
|
|
|
|
+ });
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const updateLoop = (): void => {
|
|
|
|
|
+ getUpdate().catch((error) => {
|
|
|
|
|
+ logService.debug(`failed to check for update: ${error}`);
|
|
|
|
|
+ }).finally(() => {
|
|
|
|
|
+ // Check again every 6 hours.
|
|
|
|
|
+ setTimeout(updateLoop, 1000*60*60*6);
|
|
|
|
|
+ });
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ if (!options.disableUpdateCheck) {
|
|
|
|
|
+ updateLoop();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // This will be used to set the background color while VS Code loads.
|
|
|
|
|
+ const theme = (services.get(IStorageService) as IStorageService).get("colorThemeData", StorageScope.GLOBAL);
|
|
|
|
|
+ const theme = storageService.get('colorThemeData', StorageScope.GLOBAL);
|
|
|
|
|
+ if (theme) {
|
|
|
|
|
+ localStorage.setItem("colorThemeData", theme);
|
|
|
|
|
+ localStorage.setItem('colorThemeData', theme);
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
@@ -996,7 +1114,7 @@ index 0000000000000000000000000000000000000000..5dd5406befcb593ad6366d9e98f46485
|
|
|
|
|
+export const IExtHostNodeProxy = createDecorator<IExtHostNodeProxy>('IExtHostNodeProxy');
|
|
|
|
|
diff --git a/src/vs/server/browser/mainThreadNodeProxy.ts b/src/vs/server/browser/mainThreadNodeProxy.ts
|
|
|
|
|
new file mode 100644
|
|
|
|
|
index 0000000000000000000000000000000000000000..21a139288e5b8f56016491879d69d01da929decb
|
|
|
|
|
index 0000000000000000000000000000000000000000..acabf8c167cabc954b8611a77f57641f3ca0b444
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/src/vs/server/browser/mainThreadNodeProxy.ts
|
|
|
|
|
@@ -0,0 +1,55 @@
|
|
|
|
|
@@ -1039,7 +1157,7 @@ index 0000000000000000000000000000000000000000..21a139288e5b8f56016491879d69d01d
|
|
|
|
|
+ scheme: window.location.protocol.replace(':', ''),
|
|
|
|
|
+ authority: window.location.host,
|
|
|
|
|
+ // Use FileAccess to get the static base path.
|
|
|
|
|
+ path: FileAccess.asBrowserUri("", require).path,
|
|
|
|
|
+ path: FileAccess.asBrowserUri('', require).path,
|
|
|
|
|
+ query: `tar=${encodeURIComponent(extensionUri.path)}`,
|
|
|
|
|
+ });
|
|
|
|
|
+ const response = await fetch(fetchUri.toString(true));
|
|
|
|
|
@@ -1329,16 +1447,18 @@ index 0000000000000000000000000000000000000000..56331ff1fc32bbd82e769aaecb551e42
|
|
|
|
|
+require('../../bootstrap-amd').load('vs/server/entry');
|
|
|
|
|
diff --git a/src/vs/server/ipc.d.ts b/src/vs/server/ipc.d.ts
|
|
|
|
|
new file mode 100644
|
|
|
|
|
index 0000000000000000000000000000000000000000..6ce56bec114a6d8daf5dd3ded945ea78fc72a5c6
|
|
|
|
|
index 0000000000000000000000000000000000000000..c8a613ac2db1ff154a49aa7b6da5f7d2af902ec7
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/src/vs/server/ipc.d.ts
|
|
|
|
|
@@ -0,0 +1,131 @@
|
|
|
|
|
@@ -0,0 +1,133 @@
|
|
|
|
|
+/**
|
|
|
|
|
+ * External interfaces for integration into code-server over IPC. No vs imports
|
|
|
|
|
+ * should be made in this file.
|
|
|
|
|
+ */
|
|
|
|
|
+export interface Options {
|
|
|
|
|
+ base: string
|
|
|
|
|
+ disableTelemetry: boolean
|
|
|
|
|
+ disableUpdateCheck: boolean
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export interface InitMessage {
|
|
|
|
|
@@ -1442,8 +1562,8 @@ index 0000000000000000000000000000000000000000..6ce56bec114a6d8daf5dd3ded945ea78
|
|
|
|
|
+ readonly logLevel?: number;
|
|
|
|
|
+ readonly workspaceProvider?: {
|
|
|
|
|
+ payload: [
|
|
|
|
|
+ ["userDataPath", string],
|
|
|
|
|
+ ["enableProposedApi", string],
|
|
|
|
|
+ ['userDataPath', string],
|
|
|
|
|
+ ['enableProposedApi', string],
|
|
|
|
|
+ ];
|
|
|
|
|
+ };
|
|
|
|
|
+ };
|
|
|
|
|
@@ -1466,10 +1586,10 @@ index 0000000000000000000000000000000000000000..6ce56bec114a6d8daf5dd3ded945ea78
|
|
|
|
|
+}
|
|
|
|
|
diff --git a/src/vs/server/node/channel.ts b/src/vs/server/node/channel.ts
|
|
|
|
|
new file mode 100644
|
|
|
|
|
index 0000000000000000000000000000000000000000..693174ee0d21353c3a08a42fd30eaad1e95c3b9d
|
|
|
|
|
index 0000000000000000000000000000000000000000..a6c1f9f848f441b761397ba78e2fef60329b56fa
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/src/vs/server/node/channel.ts
|
|
|
|
|
@@ -0,0 +1,897 @@
|
|
|
|
|
@@ -0,0 +1,906 @@
|
|
|
|
|
+import { field, logger } from '@coder/logger';
|
|
|
|
|
+import { Server } from '@coder/node-browser';
|
|
|
|
|
+import * as os from 'os';
|
|
|
|
|
@@ -1900,7 +2020,7 @@ index 0000000000000000000000000000000000000000..693174ee0d21353c3a08a42fd30eaad1
|
|
|
|
|
+class Terminal {
|
|
|
|
|
+ private readonly process: TerminalProcess;
|
|
|
|
|
+ private _pid: number = -1;
|
|
|
|
|
+ private _title: string = "";
|
|
|
|
|
+ private _title: string = '';
|
|
|
|
|
+ public readonly workspaceId: string;
|
|
|
|
|
+ public readonly workspaceName: string;
|
|
|
|
|
+ private readonly persist: boolean;
|
|
|
|
|
@@ -1908,6 +2028,9 @@ index 0000000000000000000000000000000000000000..693174ee0d21353c3a08a42fd30eaad1
|
|
|
|
|
+ private readonly _onDispose = new Emitter<void>();
|
|
|
|
|
+ public get onDispose(): Event<void> { return this._onDispose.event; }
|
|
|
|
|
+
|
|
|
|
|
+ private _isOrphan = true;
|
|
|
|
|
+ public get isOrphan(): boolean { return this._isOrphan; }
|
|
|
|
|
+
|
|
|
|
|
+ // These are replayed when a client reconnects.
|
|
|
|
|
+ private cols: number;
|
|
|
|
|
+ private rows: number;
|
|
|
|
|
@@ -1927,6 +2050,7 @@ index 0000000000000000000000000000000000000000..693174ee0d21353c3a08a42fd30eaad1
|
|
|
|
|
+ // Don't bind to data until something is listening.
|
|
|
|
|
+ onFirstListenerAdd: () => {
|
|
|
|
|
+ logger.debug('Terminal bound', field('id', this.id));
|
|
|
|
|
+ this._isOrphan = false;
|
|
|
|
|
+ if (!this.buffering) {
|
|
|
|
|
+ this.buffering = true;
|
|
|
|
|
+ this.bufferer.startBuffering(this.id, this.process.onProcessData);
|
|
|
|
|
@@ -1937,7 +2061,7 @@ index 0000000000000000000000000000000000000000..693174ee0d21353c3a08a42fd30eaad1
|
|
|
|
|
+ onFirstListenerDidAdd: () => {
|
|
|
|
|
+ // We only need to replay if the terminal is being reconnected which is
|
|
|
|
|
+ // true if there is a dispose timeout.
|
|
|
|
|
+ if (typeof this.disposeTimeout !== "undefined") {
|
|
|
|
|
+ if (typeof this.disposeTimeout !== 'undefined') {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
@@ -1950,13 +2074,14 @@ index 0000000000000000000000000000000000000000..693174ee0d21353c3a08a42fd30eaad1
|
|
|
|
|
+ events: [{
|
|
|
|
|
+ cols: this.cols,
|
|
|
|
|
+ rows: this.rows,
|
|
|
|
|
+ data: this.replayData.join(""),
|
|
|
|
|
+ data: this.replayData.join(''),
|
|
|
|
|
+ }]
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ onLastListenerRemove: () => {
|
|
|
|
|
+ logger.debug('Terminal unbound', field('id', this.id));
|
|
|
|
|
+ this._isOrphan = true;
|
|
|
|
|
+ if (!this.persist) { // Used by debug consoles.
|
|
|
|
|
+ this.dispose();
|
|
|
|
|
+ } else {
|
|
|
|
|
@@ -2169,7 +2294,7 @@ index 0000000000000000000000000000000000000000..693174ee0d21353c3a08a42fd30eaad1
|
|
|
|
|
+
|
|
|
|
|
+ private async createTerminalProcess(remoteAuthority: string, args: terminal.ICreateTerminalProcessArguments): Promise<terminal.ICreateTerminalProcessResult> {
|
|
|
|
|
+ const terminalId = this.id++;
|
|
|
|
|
+ logger.debug('Creating terminal', field('id', terminalId), field("terminals", this.terminals.size));
|
|
|
|
|
+ logger.debug('Creating terminal', field('id', terminalId), field('terminals', this.terminals.size));
|
|
|
|
|
+
|
|
|
|
|
+ const shellLaunchConfig: IShellLaunchConfig = {
|
|
|
|
|
+ name: args.shellLaunchConfig.name,
|
|
|
|
|
@@ -2177,7 +2302,7 @@ index 0000000000000000000000000000000000000000..693174ee0d21353c3a08a42fd30eaad1
|
|
|
|
|
+ args: args.shellLaunchConfig.args,
|
|
|
|
|
+ // TODO: Should we transform if it's a string as well? The incoming
|
|
|
|
|
+ // transform only takes `UriComponents` so I suspect it's not necessary.
|
|
|
|
|
+ cwd: typeof args.shellLaunchConfig.cwd !== "string"
|
|
|
|
|
+ cwd: typeof args.shellLaunchConfig.cwd !== 'string'
|
|
|
|
|
+ ? transformIncoming(remoteAuthority, args.shellLaunchConfig.cwd)
|
|
|
|
|
+ : args.shellLaunchConfig.cwd,
|
|
|
|
|
+ env: args.shellLaunchConfig.env,
|
|
|
|
|
@@ -2349,7 +2474,7 @@ index 0000000000000000000000000000000000000000..693174ee0d21353c3a08a42fd30eaad1
|
|
|
|
|
+ // behavior when first listing terminals but I don't know what you'd want to
|
|
|
|
|
+ // do differently. Maybe it's to reset the terminal dispose timeouts or
|
|
|
|
|
+ // something like that, but why not do it each time you list?
|
|
|
|
|
+ return Promise.all(Array.from(this.terminals).map(async ([id, terminal]) => {
|
|
|
|
|
+ const terminals = await Promise.all(Array.from(this.terminals).map(async ([id, terminal]) => {
|
|
|
|
|
+ const cwd = await terminal.getCwd();
|
|
|
|
|
+ return {
|
|
|
|
|
+ id,
|
|
|
|
|
@@ -2358,8 +2483,12 @@ index 0000000000000000000000000000000000000000..693174ee0d21353c3a08a42fd30eaad1
|
|
|
|
|
+ cwd,
|
|
|
|
|
+ workspaceId: terminal.workspaceId,
|
|
|
|
|
+ workspaceName: terminal.workspaceName,
|
|
|
|
|
+ isOrphan: terminal.isOrphan,
|
|
|
|
|
+ };
|
|
|
|
|
+ }));
|
|
|
|
|
+ // Only returned orphaned terminals so we don't end up attaching to
|
|
|
|
|
+ // terminals already attached elsewhere.
|
|
|
|
|
+ return terminals.filter((t) => t.isOrphan);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
@@ -2369,10 +2498,10 @@ index 0000000000000000000000000000000000000000..693174ee0d21353c3a08a42fd30eaad1
|
|
|
|
|
+}
|
|
|
|
|
diff --git a/src/vs/server/node/connection.ts b/src/vs/server/node/connection.ts
|
|
|
|
|
new file mode 100644
|
|
|
|
|
index 0000000000000000000000000000000000000000..93062cadc627c61e0829c27a72894b81e6a0e039
|
|
|
|
|
index 0000000000000000000000000000000000000000..fb7999ee343ddfd5f225a5ef727c9e559059fb58
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/src/vs/server/node/connection.ts
|
|
|
|
|
@@ -0,0 +1,171 @@
|
|
|
|
|
@@ -0,0 +1,189 @@
|
|
|
|
|
+import { field, Logger, logger } from '@coder/logger';
|
|
|
|
|
+import * as cp from 'child_process';
|
|
|
|
|
+import { VSBuffer } from 'vs/base/common/buffer';
|
|
|
|
|
@@ -2383,6 +2512,7 @@ index 0000000000000000000000000000000000000000..93062cadc627c61e0829c27a72894b81
|
|
|
|
|
+import { INativeEnvironmentService } from 'vs/platform/environment/common/environment';
|
|
|
|
|
+import { getNlsConfiguration } from 'vs/server/node/nls';
|
|
|
|
|
+import { Protocol } from 'vs/server/node/protocol';
|
|
|
|
|
+import { IExtHostReadyMessage } from 'vs/workbench/services/extensions/common/extensionHostProtocol';
|
|
|
|
|
+
|
|
|
|
|
+export abstract class Connection {
|
|
|
|
|
+ private readonly _onClose = new Emitter<void>();
|
|
|
|
|
@@ -2444,6 +2574,19 @@ index 0000000000000000000000000000000000000000..93062cadc627c61e0829c27a72894b81
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+interface DisconnectedMessage {
|
|
|
|
|
+ type: 'VSCODE_EXTHOST_DISCONNECTED';
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+interface ConsoleMessage {
|
|
|
|
|
+ type: '__$console';
|
|
|
|
|
+ // See bootstrap-fork.js#L135.
|
|
|
|
|
+ severity: 'log' | 'warn' | 'error';
|
|
|
|
|
+ arguments: any[];
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+type ExtHostMessage = DisconnectedMessage | ConsoleMessage | IExtHostReadyMessage;
|
|
|
|
|
+
|
|
|
|
|
+export class ExtensionHostConnection extends Connection {
|
|
|
|
|
+ private process?: cp.ChildProcess;
|
|
|
|
|
+ private readonly logger: Logger;
|
|
|
|
|
@@ -2453,7 +2596,7 @@ index 0000000000000000000000000000000000000000..93062cadc627c61e0829c27a72894b81
|
|
|
|
|
+ private readonly environment: INativeEnvironmentService,
|
|
|
|
|
+ ) {
|
|
|
|
|
+ super(protocol, token);
|
|
|
|
|
+ this.logger = logger.named("exthost", field("token", token));
|
|
|
|
|
+ this.logger = logger.named('exthost', field('token', token));
|
|
|
|
|
+ this.protocol.dispose();
|
|
|
|
|
+ this.spawn(locale, buffer).then((p) => this.process = p);
|
|
|
|
|
+ this.protocol.getUnderlyingSocket().pause();
|
|
|
|
|
@@ -2520,11 +2663,15 @@ index 0000000000000000000000000000000000000000..93062cadc627c61e0829c27a72894b81
|
|
|
|
|
+ proc.stderr.setEncoding('utf8').on('data', (d) => this.logger.error(d));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ proc.on('message', (event) => {
|
|
|
|
|
+ switch (event && event.type) {
|
|
|
|
|
+ proc.on('message', (event: ExtHostMessage) => {
|
|
|
|
|
+ switch (event.type) {
|
|
|
|
|
+ case '__$console':
|
|
|
|
|
+ const severity = (<any>this.logger)[event.severity] || 'info';
|
|
|
|
|
+ (<any>this.logger)[severity]('console', field('arguments', event.arguments));
|
|
|
|
|
+ const fn = this.logger[event.severity === 'log' ? 'info' : event.severity];
|
|
|
|
|
+ if (fn) {
|
|
|
|
|
+ fn('console', field('arguments', event.arguments));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.logger.error('Unexpected severity', field('event', event));
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case 'VSCODE_EXTHOST_DISCONNECTED':
|
|
|
|
|
+ this.logger.trace('Going offline');
|
|
|
|
|
@@ -2535,7 +2682,7 @@ index 0000000000000000000000000000000000000000..93062cadc627c61e0829c27a72894b81
|
|
|
|
|
+ this.sendInitMessage(buffer);
|
|
|
|
|
+ break;
|
|
|
|
|
+ default:
|
|
|
|
|
+ this.logger.error('Unexpected message', field("event", event));
|
|
|
|
|
+ this.logger.error('Unexpected message', field('event', event));
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
@@ -3025,7 +3172,7 @@ index 0000000000000000000000000000000000000000..3d428a57d31f29c40f9c3ce45f715b44
|
|
|
|
|
+};
|
|
|
|
|
diff --git a/src/vs/server/node/protocol.ts b/src/vs/server/node/protocol.ts
|
|
|
|
|
new file mode 100644
|
|
|
|
|
index 0000000000000000000000000000000000000000..0d9310038c0ca378579652d89bc8ac84924213db
|
|
|
|
|
index 0000000000000000000000000000000000000000..57213f92828fafefcab0e3c401a1e8ede472c9cc
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/src/vs/server/node/protocol.ts
|
|
|
|
|
@@ -0,0 +1,91 @@
|
|
|
|
|
@@ -3067,7 +3214,7 @@ index 0000000000000000000000000000000000000000..0d9310038c0ca378579652d89bc8ac84
|
|
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
|
|
+ const timeout = setTimeout(() => {
|
|
|
|
|
+ logger.error('Handshake timed out', field('token', this.options.reconnectionToken));
|
|
|
|
|
+ reject(new Error("timed out"));
|
|
|
|
|
+ reject(new Error('timed out'));
|
|
|
|
|
+ }, 10000); // Matches the client timeout.
|
|
|
|
|
+
|
|
|
|
|
+ const handler = this.onControlMessage((rawMessage) => {
|
|
|
|
|
@@ -3122,7 +3269,7 @@ index 0000000000000000000000000000000000000000..0d9310038c0ca378579652d89bc8ac84
|
|
|
|
|
+}
|
|
|
|
|
diff --git a/src/vs/server/node/server.ts b/src/vs/server/node/server.ts
|
|
|
|
|
new file mode 100644
|
|
|
|
|
index 0000000000000000000000000000000000000000..c10a5a3a6771a94b2cbcb699bb1261051c71e08b
|
|
|
|
|
index 0000000000000000000000000000000000000000..5521d51a92d1b1e3469e890bae41277b560d08a2
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/src/vs/server/node/server.ts
|
|
|
|
|
@@ -0,0 +1,302 @@
|
|
|
|
|
@@ -3136,7 +3283,7 @@ index 0000000000000000000000000000000000000000..c10a5a3a6771a94b2cbcb699bb126105
|
|
|
|
|
+import { getMachineId } from 'vs/base/node/id';
|
|
|
|
|
+import { ClientConnectionEvent, createChannelReceiver, IPCServer, IServerChannel } from 'vs/base/parts/ipc/common/ipc';
|
|
|
|
|
+import { LogsDataCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/logsDataCleaner';
|
|
|
|
|
+import { main } from "vs/code/node/cliProcessMain";
|
|
|
|
|
+import { main } from 'vs/code/node/cliProcessMain';
|
|
|
|
|
+import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
|
|
|
|
+import { ConfigurationService } from 'vs/platform/configuration/common/configurationService';
|
|
|
|
|
+import { ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc';
|
|
|
|
|
@@ -3184,7 +3331,7 @@ index 0000000000000000000000000000000000000000..c10a5a3a6771a94b2cbcb699bb126105
|
|
|
|
|
+import { Protocol } from 'vs/server/node/protocol';
|
|
|
|
|
+import { getUriTransformer } from 'vs/server/node/util';
|
|
|
|
|
+import { REMOTE_TERMINAL_CHANNEL_NAME } from 'vs/workbench/contrib/terminal/common/remoteTerminalChannel';
|
|
|
|
|
+import { REMOTE_FILE_SYSTEM_CHANNEL_NAME } from "vs/workbench/services/remote/common/remoteAgentFileSystemChannel";
|
|
|
|
|
+import { REMOTE_FILE_SYSTEM_CHANNEL_NAME } from 'vs/workbench/services/remote/common/remoteAgentFileSystemChannel';
|
|
|
|
|
+import { RemoteExtensionLogFileName } from 'vs/workbench/services/remote/common/remoteAgentService';
|
|
|
|
|
+
|
|
|
|
|
+export class Vscode {
|
|
|
|
|
@@ -3230,8 +3377,8 @@ index 0000000000000000000000000000000000000000..c10a5a3a6771a94b2cbcb699bb126105
|
|
|
|
|
+ logLevel: getLogLevel(environment),
|
|
|
|
|
+ workspaceProvider: {
|
|
|
|
|
+ payload: [
|
|
|
|
|
+ ["userDataPath", environment.userDataPath],
|
|
|
|
|
+ ["enableProposedApi", JSON.stringify(options.args["enable-proposed-api"] || [])]
|
|
|
|
|
+ ['userDataPath', environment.userDataPath],
|
|
|
|
|
+ ['enableProposedApi', JSON.stringify(options.args['enable-proposed-api'] || [])]
|
|
|
|
|
+ ],
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
@@ -3331,7 +3478,7 @@ index 0000000000000000000000000000000000000000..c10a5a3a6771a94b2cbcb699bb126105
|
|
|
|
|
+ const offline = Array.from(connections.values())
|
|
|
|
|
+ .filter((connection) => typeof connection.offline !== 'undefined');
|
|
|
|
|
+ for (let i = 0, max = offline.length - this.maxExtraOfflineConnections; i < max; ++i) {
|
|
|
|
|
+ logger.debug('Disposing offline connection', field("token", offline[i].token));
|
|
|
|
|
+ logger.debug('Disposing offline connection', field('token', offline[i].token));
|
|
|
|
|
+ offline[i].dispose();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
@@ -3430,7 +3577,7 @@ index 0000000000000000000000000000000000000000..c10a5a3a6771a94b2cbcb699bb126105
|
|
|
|
|
+}
|
|
|
|
|
diff --git a/src/vs/server/node/util.ts b/src/vs/server/node/util.ts
|
|
|
|
|
new file mode 100644
|
|
|
|
|
index 0000000000000000000000000000000000000000..fa47e993b46802f1a26457649e9e8bc467a73bf2
|
|
|
|
|
index 0000000000000000000000000000000000000000..d76f655e36647b1c9d38d2f7986f2b78a4bcfb50
|
|
|
|
|
--- /dev/null
|
|
|
|
|
+++ b/src/vs/server/node/util.ts
|
|
|
|
|
@@ -0,0 +1,13 @@
|
|
|
|
|
@@ -3445,7 +3592,7 @@ index 0000000000000000000000000000000000000000..fa47e993b46802f1a26457649e9e8bc4
|
|
|
|
|
+ * preserves slashes so it can be edited by hand more easily.
|
|
|
|
|
+ */
|
|
|
|
|
+export const encodePath = (path: string): string => {
|
|
|
|
|
+ return path.split("/").map((p) => encodeURIComponent(p)).join("/");
|
|
|
|
|
+ return path.split('/').map((p) => encodeURIComponent(p)).join('/');
|
|
|
|
|
+};
|
|
|
|
|
diff --git a/src/vs/workbench/api/browser/extensionHost.contribution.ts b/src/vs/workbench/api/browser/extensionHost.contribution.ts
|
|
|
|
|
index a4df8523631563a498c9ab6e51105074616a481a..f03da094e9080544102bbd3f037a71b348e5bd83 100644
|
|
|
|
|
@@ -3616,7 +3763,7 @@ index b3c89e51cfc25a53293a352a2a8ad50d5f26d595..e21abe4e13bc25a5b72f556bbfb61085
|
|
|
|
|
registerSingleton(IExtHostTunnelService, ExtHostTunnelService);
|
|
|
|
|
+registerSingleton(IExtHostNodeProxy, class extends NotImplementedProxy<IExtHostNodeProxy>(String(IExtHostNodeProxy)) { whenReady = Promise.resolve(); });
|
|
|
|
|
diff --git a/src/vs/workbench/api/node/extHostCLIServer.ts b/src/vs/workbench/api/node/extHostCLIServer.ts
|
|
|
|
|
index b3857616f7006127c423dcef7020ae4653da5ff6..1c1b80a2767bf77f30ca5bfee715c337120d3625 100644
|
|
|
|
|
index b3857616f7006127c423dcef7020ae4653da5ff6..594cd75b546a4b845e56122c846f63e29dc5f948 100644
|
|
|
|
|
--- a/src/vs/workbench/api/node/extHostCLIServer.ts
|
|
|
|
|
+++ b/src/vs/workbench/api/node/extHostCLIServer.ts
|
|
|
|
|
@@ -11,6 +11,8 @@ import { IWindowOpenable, IOpenWindowOptions } from 'vs/platform/windows/common/
|
|
|
|
|
@@ -3633,7 +3780,7 @@ index b3857616f7006127c423dcef7020ae4653da5ff6..1c1b80a2767bf77f30ca5bfee715c337
|
|
|
|
|
|
|
|
|
|
private async setup(): Promise<string> {
|
|
|
|
|
+ // NOTE@coder: Write this out so we can get the most recent path.
|
|
|
|
|
+ fs.promises.writeFile(join(tmpdir(), "vscode-ipc"), this._ipcHandlePath).catch((error) => {
|
|
|
|
|
+ fs.promises.writeFile(join(tmpdir(), 'vscode-ipc'), this._ipcHandlePath).catch((error) => {
|
|
|
|
|
+ this.logService.error(error);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
@@ -3658,7 +3805,7 @@ index 3843fdec386edc09a1d361b63de892a04e0070ed..8aac4df527857e964798362a69f5591b
|
|
|
|
|
registerSingleton(ILogService, ExtHostLogService);
|
|
|
|
|
+registerSingleton(IExtHostNodeProxy, ExtHostNodeProxy);
|
|
|
|
|
diff --git a/src/vs/workbench/api/worker/extHostExtensionService.ts b/src/vs/workbench/api/worker/extHostExtensionService.ts
|
|
|
|
|
index 021af6e0f8983c492f9cdd048ba2dcae7640bc1d..814dd0ff2fa7737e07833d8092c8f48953c73c47 100644
|
|
|
|
|
index 021af6e0f8983c492f9cdd048ba2dcae7640bc1d..4474a93beba03365709c3cda98b682131ad4745f 100644
|
|
|
|
|
--- a/src/vs/workbench/api/worker/extHostExtensionService.ts
|
|
|
|
|
+++ b/src/vs/workbench/api/worker/extHostExtensionService.ts
|
|
|
|
|
@@ -11,6 +11,7 @@ import { RequireInterceptor } from 'vs/workbench/api/common/extHostRequireInterc
|
|
|
|
|
@@ -3676,7 +3823,7 @@ index 021af6e0f8983c492f9cdd048ba2dcae7640bc1d..814dd0ff2fa7737e07833d8092c8f489
|
|
|
|
|
- return extensionDescription.browser;
|
|
|
|
|
+ // NOTE@coder: We can support regular Node modules as well. These will just
|
|
|
|
|
+ // require the root of the extension.
|
|
|
|
|
+ return extensionDescription.browser || ".";
|
|
|
|
|
+ return extensionDescription.browser || '.';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- protected async _loadCommonJSModule<T>(module: URI, activationTimesBuilder: ExtensionActivationTimesBuilder): Promise<T> {
|
|
|
|
|
@@ -3687,6 +3834,20 @@ index 021af6e0f8983c492f9cdd048ba2dcae7640bc1d..814dd0ff2fa7737e07833d8092c8f489
|
|
|
|
|
|
|
|
|
|
module = module.with({ path: ensureSuffix(module.path, '.js') });
|
|
|
|
|
const response = await fetch(module.toString(true));
|
|
|
|
|
diff --git a/src/vs/workbench/browser/actions/navigationActions.ts b/src/vs/workbench/browser/actions/navigationActions.ts
|
|
|
|
|
index 7344a3a29b32f7b370b99bf0cfdc79a322195ff8..dc21396e83e2f53914447d3460c2ee1103ecb28e 100644
|
|
|
|
|
--- a/src/vs/workbench/browser/actions/navigationActions.ts
|
|
|
|
|
+++ b/src/vs/workbench/browser/actions/navigationActions.ts
|
|
|
|
|
@@ -310,4 +310,8 @@ actionsRegistry.registerWorkbenchAction(SyncActionDescriptor.from(FocusNextPart,
|
|
|
|
|
actionsRegistry.registerWorkbenchAction(SyncActionDescriptor.from(FocusPreviousPart, { primary: KeyMod.Shift | KeyCode.F6 }), 'View: Focus Previous Part', CATEGORIES.View.value);
|
|
|
|
|
|
|
|
|
|
const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
|
|
|
|
|
-workbenchRegistry.registerWorkbenchContribution(GoHomeContributor, LifecyclePhase.Ready);
|
|
|
|
|
+// See https://github.com/cdr/code-server/issues/2328
|
|
|
|
|
+// workbenchRegistry.registerWorkbenchContribution(GoHomeContributor, LifecyclePhase.Ready);
|
|
|
|
|
+export const _1 = workbenchRegistry;
|
|
|
|
|
+export const _2 = GoHomeContributor;
|
|
|
|
|
+export const _3 = LifecyclePhase.Ready;
|
|
|
|
|
diff --git a/src/vs/workbench/browser/parts/activitybar/media/activitybarpart.css b/src/vs/workbench/browser/parts/activitybar/media/activitybarpart.css
|
|
|
|
|
index ced2d815834e40a1543e80516472799075980733..dfcae73e8a042307600c67f163aa00ba9e0762f4 100644
|
|
|
|
|
--- a/src/vs/workbench/browser/parts/activitybar/media/activitybarpart.css
|
|
|
|
|
@@ -3745,6 +3906,43 @@ index 94e7e7a4bac154c45078a1b5034e50634a7a43af..8164200dcef1efbc65b50eef9c270af3
|
|
|
|
|
this._filenameKey.set(value ? basename(value) : null);
|
|
|
|
|
this._dirnameKey.set(value ? dirname(value).fsPath : null);
|
|
|
|
|
this._pathKey.set(value ? value.fsPath : null);
|
|
|
|
|
diff --git a/src/vs/workbench/contrib/remote/browser/remote.ts b/src/vs/workbench/contrib/remote/browser/remote.ts
|
|
|
|
|
index c6d98b601a3b6966e8a99d2c05b3b7f02b08e6ca..c2a76fbd75d24d509f312cb8bf094eb297374f04 100644
|
|
|
|
|
--- a/src/vs/workbench/contrib/remote/browser/remote.ts
|
|
|
|
|
+++ b/src/vs/workbench/contrib/remote/browser/remote.ts
|
|
|
|
|
@@ -778,17 +778,30 @@ class RemoteAgentConnectionStatusListener implements IWorkbenchContribution {
|
|
|
|
|
}
|
|
|
|
|
switch (e.type) {
|
|
|
|
|
case PersistentConnectionEventType.ConnectionLost:
|
|
|
|
|
+ break;
|
|
|
|
|
+ case PersistentConnectionEventType.ReconnectionWait:
|
|
|
|
|
+ const BACKGROUND_RECONNECT_THRESHOLD = 2;
|
|
|
|
|
+ // If the first reconnect fails, we show the popup.
|
|
|
|
|
+ // This corresponds to about 5s wait.
|
|
|
|
|
+ if (e.connectionAttempt < BACKGROUND_RECONNECT_THRESHOLD) {
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
if (!visibleProgress) {
|
|
|
|
|
visibleProgress = showProgress(ProgressLocation.Dialog, [reconnectButton, reloadButton]);
|
|
|
|
|
}
|
|
|
|
|
visibleProgress.report(nls.localize('connectionLost', "Connection Lost"));
|
|
|
|
|
- break;
|
|
|
|
|
- case PersistentConnectionEventType.ReconnectionWait:
|
|
|
|
|
+
|
|
|
|
|
reconnectWaitEvent = e;
|
|
|
|
|
visibleProgress = showProgress(lastLocation || ProgressLocation.Notification, [reconnectButton, reloadButton]);
|
|
|
|
|
visibleProgress.startTimer(Date.now() + 1000 * e.durationSeconds);
|
|
|
|
|
break;
|
|
|
|
|
case PersistentConnectionEventType.ReconnectionRunning:
|
|
|
|
|
+ if (!visibleProgress) {
|
|
|
|
|
+ // Our background reconnection threshold hasn't been hit yet.
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
visibleProgress = showProgress(lastLocation || ProgressLocation.Notification, [reloadButton]);
|
|
|
|
|
visibleProgress.report(nls.localize('reconnectionRunning', "Attempting to reconnect..."));
|
|
|
|
|
|
|
|
|
|
diff --git a/src/vs/workbench/contrib/scm/browser/media/scm.css b/src/vs/workbench/contrib/scm/browser/media/scm.css
|
|
|
|
|
index 74f6922e98b4bb6a7fb100f5aac015afe9fc171b..3243a97c2d378013d96ffbe87e9df6dd4a66776d 100644
|
|
|
|
|
--- a/src/vs/workbench/contrib/scm/browser/media/scm.css
|
|
|
|
|
@@ -3764,6 +3962,73 @@ index 74f6922e98b4bb6a7fb100f5aac015afe9fc171b..3243a97c2d378013d96ffbe87e9df6dd
|
|
|
|
|
|
|
|
|
|
.scm-view .monaco-list .monaco-list-row .resource-group > .actions,
|
|
|
|
|
.scm-view .monaco-list .monaco-list-row .resource > .name > .monaco-icon-label > .actions {
|
|
|
|
|
diff --git a/src/vs/workbench/contrib/welcome/page/browser/vs_code_welcome_page.ts b/src/vs/workbench/contrib/welcome/page/browser/vs_code_welcome_page.ts
|
|
|
|
|
index 6af6a4b7f42654ec6cc60e0ba5efd376919f3e04..3a8176951628e0b2528aae8796ba684c3ab53d9a 100644
|
|
|
|
|
--- a/src/vs/workbench/contrib/welcome/page/browser/vs_code_welcome_page.ts
|
|
|
|
|
+++ b/src/vs/workbench/contrib/welcome/page/browser/vs_code_welcome_page.ts
|
|
|
|
|
@@ -4,6 +4,7 @@
|
|
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
import { escape } from 'vs/base/common/strings';
|
|
|
|
|
+import product from 'vs/platform/product/common/product';
|
|
|
|
|
import { localize } from 'vs/nls';
|
|
|
|
|
|
|
|
|
|
export default () => `
|
|
|
|
|
@@ -11,7 +12,7 @@ export default () => `
|
|
|
|
|
<div class="welcomePage" role="document">
|
|
|
|
|
<div class="title">
|
|
|
|
|
<h1 class="caption">${escape(localize('welcomePage.vscode', "Visual Studio Code"))}</h1>
|
|
|
|
|
- <p class="subtitle detail">${escape(localize({ key: 'welcomePage.editingEvolved', comment: ['Shown as subtitle on the Welcome page.'] }, "Editing evolved"))}</p>
|
|
|
|
|
+ <p class="subtitle detail">VS Code v${product.version}</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="row">
|
|
|
|
|
<div class="splash">
|
|
|
|
|
@@ -32,6 +33,19 @@ export default () => `
|
|
|
|
|
</ul>
|
|
|
|
|
<p class="none detail">${escape(localize('welcomePage.noRecentFolders', "No recent folders"))}</p>
|
|
|
|
|
</div>
|
|
|
|
|
+ <div class="section help">
|
|
|
|
|
+ <h2 class="caption">code-server ${escape(localize('welcomePage.help', "Help"))}</h2>
|
|
|
|
|
+ <ul>
|
|
|
|
|
+ <li><a href="https://github.com/cdr/code-server">GitHub Repository</a></li>
|
|
|
|
|
+ <li><a href="https://github.com/cdr/code-server/releases/tag/v${product.codeServerVersion}">Release Notes</a></li>
|
|
|
|
|
+ <li><a href="https://github.com/cdr/code-server/issues">Issue Tracker</a></li>
|
|
|
|
|
+ <li><a href="https://github.com/cdr/code-server/blob/master/doc/FAQ.md">FAQ</a></li>
|
|
|
|
|
+ <li><a href="https://github.com/cdr/code-server/blob/master/doc/guide.md">Setup Guide</a></li>
|
|
|
|
|
+ <li><a href="https://github.com/cdr/code-server/tree/master/doc">Docs</a></li>
|
|
|
|
|
+ <li><a href="https://github.com/cdr/code-server/discussions">Discussions</a></li>
|
|
|
|
|
+ <li><a href="https://cdr.co/join-community">Slack</a></li>
|
|
|
|
|
+ </ul>
|
|
|
|
|
+ </div>
|
|
|
|
|
<div class="section help">
|
|
|
|
|
<h2 class="caption">${escape(localize('welcomePage.help', "Help"))}</h2>
|
|
|
|
|
<ul>
|
|
|
|
|
diff --git a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.css b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.css
|
|
|
|
|
index 738ce140c1af76ee0017c59cc883578e966f5348..80833b7023ed5795bb3de303b54ec08d9dab9b94 100644
|
|
|
|
|
--- a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.css
|
|
|
|
|
+++ b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.css
|
|
|
|
|
@@ -94,7 +94,7 @@
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.monaco-workbench .part.editor > .content .welcomePage .splash .section {
|
|
|
|
|
- margin-bottom: 5em;
|
|
|
|
|
+ margin-bottom: 3em;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.monaco-workbench .part.editor > .content .welcomePage .splash ul {
|
|
|
|
|
diff --git a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts
|
|
|
|
|
index 4a61a79fe447e2aa238af568791bff1e0cec4d29..69cc2e4331a3b04d05d79632920f5c5bbfa924e8 100644
|
|
|
|
|
--- a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts
|
|
|
|
|
+++ b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts
|
|
|
|
|
@@ -328,7 +328,7 @@ class WelcomePage extends Disposable {
|
|
|
|
|
|
|
|
|
|
const prodName = container.querySelector('.welcomePage .title .caption') as HTMLElement;
|
|
|
|
|
if (prodName) {
|
|
|
|
|
- prodName.textContent = this.productService.nameLong;
|
|
|
|
|
+ prodName.textContent = `code-server v${this.productService.codeServerVersion}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
recentlyOpened.then(({ workspaces }) => {
|
|
|
|
|
diff --git a/src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts b/src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts
|
|
|
|
|
index ed4f26407391bd62219a9f8245a5cd63a7cb7488..92f26d1b082f80475cf76409a4569e948e9e0bd9 100644
|
|
|
|
|
--- a/src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts
|
|
|
|
|
@@ -3797,30 +4062,37 @@ index 85d83f37da179a1e39266cf72a02e971f590308e..0659738b36df1747c9afcabf8d9abf26
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts
|
|
|
|
|
index a8d43045ecc8cbe04b3f8440cff16d42aadbcad0..cd589c6f75eccbeefbf364d426ac882396b26fb4 100644
|
|
|
|
|
index a8d43045ecc8cbe04b3f8440cff16d42aadbcad0..d051473515e35b331672b780109bd40229153c8c 100644
|
|
|
|
|
--- a/src/vs/workbench/services/environment/browser/environmentService.ts
|
|
|
|
|
+++ b/src/vs/workbench/services/environment/browser/environmentService.ts
|
|
|
|
|
@@ -119,8 +119,18 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment
|
|
|
|
|
@@ -119,8 +119,25 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment
|
|
|
|
|
@memoize
|
|
|
|
|
get logFile(): URI { return joinPath(this.options.logsPath, 'window.log'); }
|
|
|
|
|
|
|
|
|
|
+ // NOTE@coder: Use the regular path for extensions that write directly to disk
|
|
|
|
|
+ // instead of using the VS Code API.
|
|
|
|
|
+ // NOTE@coder: Use the same path in // ../../../../platform/environment/node/environmentService.ts
|
|
|
|
|
+ // and don't use the user data scheme. This solves two problems:
|
|
|
|
|
+ // 1. Extensions running in the browser (like Vim) might use these paths
|
|
|
|
|
+ // directly instead of using the file service and most likely can't write
|
|
|
|
|
+ // to `/User` on disk.
|
|
|
|
|
+ // 2. Settings will be stored in the file system instead of in browser
|
|
|
|
|
+ // storage. Using browser storage makes sharing or seeding settings
|
|
|
|
|
+ // between browsers difficult. We may want to revisit this once/if we get
|
|
|
|
|
+ // settings sync.
|
|
|
|
|
@memoize
|
|
|
|
|
- get userRoamingDataHome(): URI { return URI.file('/User').with({ scheme: Schemas.userData }); }
|
|
|
|
|
+ get userRoamingDataHome(): URI { return URI.file(this.userDataPath).with({ scheme: Schemas.userData }); }
|
|
|
|
|
+ get userRoamingDataHome(): URI { return joinPath(URI.file(this.userDataPath).with({ scheme: Schemas.vscodeRemote }), 'User'); }
|
|
|
|
|
+ @memoize
|
|
|
|
|
+ get userDataPath(): string {
|
|
|
|
|
+ const dataPath = this.payload?.get("userDataPath");
|
|
|
|
|
+ const dataPath = this.payload?.get('userDataPath');
|
|
|
|
|
+ if (!dataPath) {
|
|
|
|
|
+ throw new Error("userDataPath was not provided to environment service");
|
|
|
|
|
+ throw new Error('userDataPath was not provided to environment service');
|
|
|
|
|
+ }
|
|
|
|
|
+ return dataPath;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
@memoize
|
|
|
|
|
get settingsResource(): URI { return joinPath(this.userRoamingDataHome, 'settings.json'); }
|
|
|
|
|
@@ -301,7 +311,12 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment
|
|
|
|
|
@@ -301,7 +318,12 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment
|
|
|
|
|
extensionHostDebugEnvironment.params.port = parseInt(value);
|
|
|
|
|
break;
|
|
|
|
|
case 'enableProposedApi':
|
|
|
|
|
@@ -3875,9 +4147,18 @@ index de7e301d3f0c67ce662827f61427a5a7b3616b9f..877ea8e11e6e6d34b9a8fe16287af309
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
diff --git a/src/vs/workbench/services/extensions/browser/extensionService.ts b/src/vs/workbench/services/extensions/browser/extensionService.ts
|
|
|
|
|
index 1dff19bf177eff24f722b748b79835a653241c4d..0f59ad290c82cc4c9d09c565c1018cc275ca0249 100644
|
|
|
|
|
index 1dff19bf177eff24f722b748b79835a653241c4d..01ce9bc00cc39c27e75db006425c359f813a4719 100644
|
|
|
|
|
--- a/src/vs/workbench/services/extensions/browser/extensionService.ts
|
|
|
|
|
+++ b/src/vs/workbench/services/extensions/browser/extensionService.ts
|
|
|
|
|
@@ -87,7 +87,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
|
|
|
|
if (code === ExtensionHostExitCode.StartTimeout10s) {
|
|
|
|
|
this._notificationService.prompt(
|
|
|
|
|
Severity.Error,
|
|
|
|
|
- nls.localize('extensionService.startTimeout', "The Web Worker Extension Host did not start in 10s."),
|
|
|
|
|
+ nls.localize('extensionService.startTimeout', 'The Web Worker Extension Host did not start in 10s.'),
|
|
|
|
|
[]
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
@@ -177,8 +177,10 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
|
|
|
|
this._remoteAgentService.getEnvironment(),
|
|
|
|
|
this._remoteAgentService.scanExtensions()
|
|
|
|
|
@@ -3886,10 +4167,19 @@ index 1dff19bf177eff24f722b748b79835a653241c4d..0f59ad290c82cc4c9d09c565c1018cc2
|
|
|
|
|
remoteExtensions = this._checkEnabledAndProposedAPI(remoteExtensions);
|
|
|
|
|
+ // NOTE@coder: Include remotely hosted extensions that should run locally.
|
|
|
|
|
+ localExtensions = this._checkEnabledAndProposedAPI(localExtensions)
|
|
|
|
|
+ .concat(remoteExtensions.filter(ext => !ext.browser && ext.extensionKind && (ext.extensionKind === "web" || ext.extensionKind.includes("web"))));
|
|
|
|
|
+ .concat(remoteExtensions.filter(ext => !ext.browser && ext.extensionKind && (ext.extensionKind === 'web' || ext.extensionKind.includes('web'))));
|
|
|
|
|
|
|
|
|
|
const remoteAgentConnection = this._remoteAgentService.getConnection();
|
|
|
|
|
this._runningLocation = this._runningLocationClassifier.determineRunningLocation(localExtensions, remoteExtensions);
|
|
|
|
|
@@ -188,7 +190,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
|
|
|
|
|
|
|
|
|
const result = this._registry.deltaExtensions(remoteExtensions.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._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(', ')));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (remoteEnv && remoteAgentConnection) {
|
|
|
|
|
diff --git a/src/vs/workbench/services/extensions/common/extensionsUtil.ts b/src/vs/workbench/services/extensions/common/extensionsUtil.ts
|
|
|
|
|
index 65e532ee58dfc06ed944846d01b885cb8f260ebc..0b6282fde7ad03c7ea9872a777cbf487253abed1 100644
|
|
|
|
|
--- a/src/vs/workbench/services/extensions/common/extensionsUtil.ts
|
|
|
|
|
|