mirror of
https://github.com/Microsoft/vscode
synced 2024-10-02 17:32:41 +00:00
Merge branch 'main' into aamunger/notebookInfoRegistration2
This commit is contained in:
commit
f5f7127f8f
11
.github/commands/codespaces_issue.yml
vendored
Normal file
11
.github/commands/codespaces_issue.yml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Learn more about the syntax here:
|
||||
# https://docs.github.com/en/early-access/github/save-time-with-slash-commands/syntax-for-user-defined-slash-commands
|
||||
---
|
||||
trigger: codespaces_issue
|
||||
title: Codespaces Issue
|
||||
description: Report downstream
|
||||
|
||||
steps:
|
||||
- type: fill
|
||||
template: |-
|
||||
This looks like an issue with the Codespaces service which we don't track in this repository. You can report this to the Codespaces team at https://github.com/orgs/community/discussions/categories/codespaces
|
|
@ -520,9 +520,9 @@ safe-buffer@~5.2.0:
|
|||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
|
||||
semver@^7.3.5:
|
||||
version "7.3.8"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798"
|
||||
integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==
|
||||
version "7.5.3"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e"
|
||||
integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==
|
||||
dependencies:
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
|
|
79
build/win32/Cargo.lock
generated
79
build/win32/Cargo.lock
generated
|
@ -19,12 +19,6 @@ version = "1.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "build_const"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4ae4235e6dac0694637c763029ecea1a2ec9e4e06ec2729bd21ba4d9c863eb7"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
|
@ -39,13 +33,19 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||
|
||||
[[package]]
|
||||
name = "crc"
|
||||
version = "1.8.1"
|
||||
version = "3.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
|
||||
checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe"
|
||||
dependencies = [
|
||||
"build_const",
|
||||
"crc-catalog",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc-catalog"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.5"
|
||||
|
@ -109,14 +109,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "inno_updater"
|
||||
version = "0.9.0"
|
||||
version = "0.10.0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"crc",
|
||||
"slog",
|
||||
"slog-async",
|
||||
"slog-term",
|
||||
"winapi",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -329,3 +329,60 @@ name = "winapi-x86_64-pc-windows-gnu"
|
|||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
||||
|
|
|
@ -1,18 +1,30 @@
|
|||
[package]
|
||||
name = "inno_updater"
|
||||
version = "0.9.0"
|
||||
version = "0.10.0"
|
||||
authors = ["Microsoft <monacotools@microsoft.com>"]
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
byteorder = "1"
|
||||
crc = "^1.0.0"
|
||||
slog = "2.1.1"
|
||||
slog-async = "2.2.0"
|
||||
slog-term = "2.3.0"
|
||||
byteorder = "1.4.3"
|
||||
crc = "3.0.1"
|
||||
slog = "2.7.0"
|
||||
slog-async = "2.7.0"
|
||||
slog-term = "2.9.0"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = { version = "^0.3.9", features = ["winuser", "libloaderapi", "commctrl", "processthreadsapi", "tlhelp32", "handleapi", "psapi", "errhandlingapi", "winbase", "shellapi"] }
|
||||
[target.'cfg(windows)'.dependencies.windows-sys]
|
||||
version = "0.42"
|
||||
features = [
|
||||
"Win32_Foundation",
|
||||
"Win32_System_Shutdown",
|
||||
"Win32_UI_WindowsAndMessaging",
|
||||
"Win32_System_Threading",
|
||||
"Win32_System_LibraryLoader",
|
||||
"Win32_System_Diagnostics_Debug",
|
||||
"Win32_Storage_FileSystem",
|
||||
"Win32_Security",
|
||||
"Win32_System_ProcessStatus",
|
||||
"Win32_System_Diagnostics_ToolHelp"
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
|
Binary file not shown.
|
@ -34,9 +34,9 @@ minimatch@^5.1.0:
|
|||
brace-expansion "^2.0.1"
|
||||
|
||||
semver@^7.3.7:
|
||||
version "7.3.7"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f"
|
||||
integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==
|
||||
version "7.5.3"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e"
|
||||
integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==
|
||||
dependencies:
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ export function activate(context: vscode.ExtensionContext) {
|
|||
const lineResult = parseSearchResults(document, token)[position.line];
|
||||
if (!lineResult) { return []; }
|
||||
if (lineResult.type === 'file') {
|
||||
return lineResult.allLocations;
|
||||
return lineResult.allLocations.map(l => ({ ...l, originSelectionRange: lineResult.location.originSelectionRange }));
|
||||
}
|
||||
|
||||
const location = lineResult.locations.find(l => l.originSelectionRange.contains(position));
|
||||
|
|
|
@ -661,9 +661,9 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
|||
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
||||
|
||||
semver@^7.3.5:
|
||||
version "7.3.5"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
|
||||
integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
|
||||
version "7.5.3"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e"
|
||||
integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==
|
||||
dependencies:
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
|
|
|
@ -4,38 +4,32 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { isStandalone } from 'vs/base/browser/browser';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { parse } from 'vs/base/common/marshalling';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { isEqual } from 'vs/base/common/resources';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { request } from 'vs/base/parts/request/browser/request';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import { isFolderToOpen, isWorkspaceToOpen } from 'vs/platform/window/common/window';
|
||||
import { create } from 'vs/workbench/workbench.web.main';
|
||||
import { posix } from 'vs/base/common/path';
|
||||
import { ltrim } from 'vs/base/common/strings';
|
||||
import type { ICredentialsProvider } from 'vs/platform/credentials/common/credentials';
|
||||
import type { IURLCallbackProvider } from 'vs/workbench/services/url/browser/urlService';
|
||||
import type { IWorkbenchConstructionOptions } from 'vs/workbench/browser/web.api';
|
||||
import type { IWorkspace, IWorkspaceProvider } from 'vs/workbench/services/host/browser/browserHostService';
|
||||
import { ISecretStorageProvider } from 'vs/platform/secrets/common/secrets';
|
||||
import { AuthenticationSessionInfo } from 'vs/workbench/services/authentication/browser/authenticationService';
|
||||
|
||||
interface ICredential {
|
||||
service: string;
|
||||
account: string;
|
||||
password: string;
|
||||
}
|
||||
class LocalStorageSecretStorageProvider implements ISecretStorageProvider {
|
||||
private static readonly STORAGE_KEY = 'secrets.provider';
|
||||
|
||||
class LocalStorageCredentialsProvider implements ICredentialsProvider {
|
||||
private _secrets: Record<string, string> | undefined;
|
||||
|
||||
private static readonly CREDENTIALS_STORAGE_KEY = 'credentials.provider';
|
||||
|
||||
private readonly authService: string | undefined;
|
||||
type: 'in-memory' | 'persisted' | 'unknown' = 'persisted';
|
||||
|
||||
constructor() {
|
||||
let authSessionInfo: { readonly id: string; readonly accessToken: string; readonly providerId: string; readonly canSignOut?: boolean; readonly scopes: string[][] } | undefined;
|
||||
let authSessionInfo: (AuthenticationSessionInfo & { scopes: string[][] }) | undefined;
|
||||
const authSessionElement = document.getElementById('vscode-workbench-auth-session');
|
||||
const authSessionElementAttribute = authSessionElement ? authSessionElement.getAttribute('data-settings') : undefined;
|
||||
if (authSessionElementAttribute) {
|
||||
|
@ -46,11 +40,15 @@ class LocalStorageCredentialsProvider implements ICredentialsProvider {
|
|||
|
||||
if (authSessionInfo) {
|
||||
// Settings Sync Entry
|
||||
this.setPassword(`${product.urlProtocol}.login`, 'account', JSON.stringify(authSessionInfo));
|
||||
this.set(`${product.urlProtocol}.loginAccount`, JSON.stringify(authSessionInfo));
|
||||
|
||||
// Auth extension Entry
|
||||
this.authService = `${product.urlProtocol}-${authSessionInfo.providerId}.login`;
|
||||
this.setPassword(this.authService, 'account', JSON.stringify(authSessionInfo.scopes.map(scopes => ({
|
||||
if (authSessionInfo.providerId !== 'github') {
|
||||
console.error(`Unexpected auth provider: ${authSessionInfo.providerId}. Expected 'github'.`);
|
||||
return;
|
||||
}
|
||||
const authAccount = JSON.stringify({ extensionId: 'vscode.github-authentication', key: 'github.auth' });
|
||||
this.set(authAccount, JSON.stringify(authSessionInfo.scopes.map(scopes => ({
|
||||
id: authSessionInfo!.id,
|
||||
scopes,
|
||||
accessToken: authSessionInfo!.accessToken
|
||||
|
@ -58,121 +56,44 @@ class LocalStorageCredentialsProvider implements ICredentialsProvider {
|
|||
}
|
||||
}
|
||||
|
||||
private _credentials: ICredential[] | undefined;
|
||||
private get credentials(): ICredential[] {
|
||||
if (!this._credentials) {
|
||||
get(key: string): Promise<string | undefined> {
|
||||
return Promise.resolve(this.secrets[key]);
|
||||
}
|
||||
set(key: string, value: string): Promise<void> {
|
||||
this.secrets[key] = value;
|
||||
this.save();
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
async delete(key: string): Promise<void> {
|
||||
delete this.secrets[key];
|
||||
|
||||
this.save();
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
private get secrets(): Record<string, string> {
|
||||
if (!this._secrets) {
|
||||
try {
|
||||
const serializedCredentials = window.localStorage.getItem(LocalStorageCredentialsProvider.CREDENTIALS_STORAGE_KEY);
|
||||
const serializedCredentials = window.localStorage.getItem(LocalStorageSecretStorageProvider.STORAGE_KEY);
|
||||
if (serializedCredentials) {
|
||||
this._credentials = JSON.parse(serializedCredentials);
|
||||
this._secrets = JSON.parse(serializedCredentials);
|
||||
}
|
||||
} catch (error) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (!Array.isArray(this._credentials)) {
|
||||
this._credentials = [];
|
||||
if (!(this._secrets instanceof Object)) {
|
||||
this._secrets = {};
|
||||
}
|
||||
}
|
||||
|
||||
return this._credentials;
|
||||
return this._secrets;
|
||||
}
|
||||
|
||||
private save(): void {
|
||||
window.localStorage.setItem(LocalStorageCredentialsProvider.CREDENTIALS_STORAGE_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.doDeletePassword(service, account);
|
||||
|
||||
this.credentials.push({ service, account, password });
|
||||
|
||||
this.save();
|
||||
|
||||
try {
|
||||
if (password && service === this.authService) {
|
||||
const value = JSON.parse(password);
|
||||
if (Array.isArray(value) && value.length === 0) {
|
||||
await this.logout(service);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
async deletePassword(service: string, account: string): Promise<boolean> {
|
||||
const result = await this.doDeletePassword(service, account);
|
||||
|
||||
if (result && service === this.authService) {
|
||||
try {
|
||||
await this.logout(service);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async doDeletePassword(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 }));
|
||||
}
|
||||
|
||||
private async logout(service: string): Promise<void> {
|
||||
const queryValues: Map<string, string> = new Map();
|
||||
queryValues.set('logout', String(true));
|
||||
queryValues.set('service', service);
|
||||
|
||||
await request({
|
||||
url: doCreateUri('/auth/logout', queryValues).toString(true)
|
||||
}, CancellationToken.None);
|
||||
}
|
||||
|
||||
async clear(): Promise<void> {
|
||||
window.localStorage.removeItem(LocalStorageCredentialsProvider.CREDENTIALS_STORAGE_KEY);
|
||||
window.localStorage.setItem(LocalStorageSecretStorageProvider.STORAGE_KEY, JSON.stringify(this.secrets));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -469,24 +390,6 @@ class WorkspaceProvider implements IWorkspaceProvider {
|
|||
}
|
||||
}
|
||||
|
||||
function 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 });
|
||||
}
|
||||
|
||||
(function () {
|
||||
|
||||
// Find config by checking for DOM
|
||||
|
@ -504,6 +407,6 @@ function doCreateUri(path: string, queryValues: Map<string, string>): URI {
|
|||
settingsSyncOptions: config.settingsSyncOptions ? { enabled: config.settingsSyncOptions.enabled, } : undefined,
|
||||
workspaceProvider: WorkspaceProvider.create(config),
|
||||
urlCallbackProvider: new LocalStorageURLCallbackProvider(config.callbackRoute),
|
||||
credentialsProvider: config.remoteAuthority ? undefined /* with a remote, we don't use a local credentials provider */ : new LocalStorageCredentialsProvider()
|
||||
secretStorageProvider: config.remoteAuthority ? undefined /* with a remote, we don't use a local secret storage provider */ : new LocalStorageSecretStorageProvider()
|
||||
});
|
||||
})();
|
||||
|
|
|
@ -70,6 +70,7 @@ import { ILoggerMainService, LoggerMainService } from 'vs/platform/log/electron-
|
|||
import { LogService } from 'vs/platform/log/common/logService';
|
||||
import { massageMessageBoxOptions } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { SaveStrategy, StateService } from 'vs/platform/state/node/stateService';
|
||||
import { FileUserDataProvider } from 'vs/platform/userData/common/fileUserDataProvider';
|
||||
|
||||
/**
|
||||
* The main VS Code entry point.
|
||||
|
@ -178,6 +179,10 @@ class CodeMain {
|
|||
const diskFileSystemProvider = new DiskFileSystemProvider(logService);
|
||||
fileService.registerProvider(Schemas.file, diskFileSystemProvider);
|
||||
|
||||
// Use FileUserDataProvider for user data to
|
||||
// enable atomic read / write operations.
|
||||
fileService.registerProvider(Schemas.vscodeUserData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.vscodeUserData, logService));
|
||||
|
||||
// URI Identity
|
||||
const uriIdentityService = new UriIdentityService(fileService);
|
||||
services.set(IUriIdentityService, uriIdentityService);
|
||||
|
|
|
@ -26,7 +26,6 @@ import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsServ
|
|||
import { IDownloadService } from 'vs/platform/download/common/download';
|
||||
import { DownloadService } from 'vs/platform/download/common/downloadService';
|
||||
import { INativeEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { SharedProcessEnvironmentService } from 'vs/platform/sharedProcess/node/sharedProcessEnvironmentService';
|
||||
import { GlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService';
|
||||
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService';
|
||||
import { IExtensionGalleryService, IExtensionManagementService, IExtensionTipsService, IGlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
|
@ -112,6 +111,7 @@ import { RemoteStorageService } from 'vs/platform/storage/common/storageService'
|
|||
import { IRemoteSocketFactoryService, RemoteSocketFactoryService } from 'vs/platform/remote/common/remoteSocketFactoryService';
|
||||
import { RemoteConnectionType } from 'vs/platform/remote/common/remoteAuthorityResolver';
|
||||
import { nodeSocketFactory } from 'vs/platform/remote/node/nodeSocketFactory';
|
||||
import { NativeEnvironmentService } from 'vs/platform/environment/node/environmentService';
|
||||
|
||||
class SharedProcessMain extends Disposable {
|
||||
|
||||
|
@ -191,7 +191,7 @@ class SharedProcessMain extends Disposable {
|
|||
services.set(IPolicyService, policyService);
|
||||
|
||||
// Environment
|
||||
const environmentService = new SharedProcessEnvironmentService(this.configuration.args, productService);
|
||||
const environmentService = new NativeEnvironmentService(this.configuration.args, productService);
|
||||
services.set(INativeEnvironmentService, environmentService);
|
||||
|
||||
// Logger
|
||||
|
|
|
@ -16,4 +16,17 @@
|
|||
position: absolute;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/*
|
||||
Ensure spinning icons are pixel-perfectly centered and avoid wobble.
|
||||
This is only applied to icons that spin to avoid unnecessary
|
||||
GPU layers and blurry subpixel AA.
|
||||
*/
|
||||
.monaco-editor .glyph-margin-widgets .cgmr.codicon-modifier-spin::before {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { toLocalISOString } from 'vs/base/common/date';
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
import { FileAccess } from 'vs/base/common/network';
|
||||
import { FileAccess, Schemas } from 'vs/base/common/network';
|
||||
import { dirname, join, normalize, resolve } from 'vs/base/common/path';
|
||||
import { env } from 'vs/base/common/process';
|
||||
import { joinPath } from 'vs/base/common/resources';
|
||||
|
@ -65,10 +65,10 @@ export abstract class AbstractNativeEnvironmentService implements INativeEnviron
|
|||
get stateResource(): URI { return joinPath(this.appSettingsHome, 'globalStorage', 'storage.json'); }
|
||||
|
||||
@memoize
|
||||
get userRoamingDataHome(): URI { return this.appSettingsHome; }
|
||||
get userRoamingDataHome(): URI { return this.appSettingsHome.with({ scheme: Schemas.vscodeUserData }); }
|
||||
|
||||
@memoize
|
||||
get userDataSyncHome(): URI { return joinPath(this.userRoamingDataHome, 'sync'); }
|
||||
get userDataSyncHome(): URI { return joinPath(this.appSettingsHome, 'sync'); }
|
||||
|
||||
get logsHome(): URI {
|
||||
if (!this.args.logsPath) {
|
||||
|
|
|
@ -12,7 +12,7 @@ import { URI, UriComponents } from 'vs/base/common/uri';
|
|||
import { Metadata, isIExtensionIdentifier } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { IExtension, IExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { FileOperationResult, IFileService, toFileOperationResult } from 'vs/platform/files/common/files';
|
||||
import { FileOperationResult, IFileService, hasFileAtomicWriteCapability, toFileOperationResult } from 'vs/platform/files/common/files';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
|
||||
|
@ -290,7 +290,8 @@ export abstract class AbstractExtensionsProfileScannerService extends Disposable
|
|||
relativeLocation: this.toRelativePath(e.location),
|
||||
metadata: e.metadata
|
||||
}));
|
||||
await this.fileService.writeFile(file, VSBuffer.fromString(JSON.stringify(storedProfileExtensions)));
|
||||
const fsp = this.fileService.getProvider(file.scheme);
|
||||
await this.fileService.writeFile(file, VSBuffer.fromString(JSON.stringify(storedProfileExtensions)), fsp && hasFileAtomicWriteCapability(fsp) ? { atomic: { postfix: '.vsctmp' } } : undefined);
|
||||
}
|
||||
|
||||
return extensions;
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { NativeEnvironmentService } from 'vs/platform/environment/node/environmentService';
|
||||
|
||||
export class SharedProcessEnvironmentService extends NativeEnvironmentService {
|
||||
|
||||
@memoize
|
||||
override get userRoamingDataHome(): URI { return this.appSettingsHome.with({ scheme: Schemas.vscodeUserData }); }
|
||||
|
||||
}
|
|
@ -23,8 +23,8 @@ export class ElectronPtyHostStarter extends Disposable implements IPtyHostStarte
|
|||
|
||||
private utilityProcess: UtilityProcess | undefined = undefined;
|
||||
|
||||
private readonly _onBeforeWindowConnection = new Emitter<void>();
|
||||
readonly onBeforeWindowConnection = this._onBeforeWindowConnection.event;
|
||||
private readonly _onRequestConnection = new Emitter<void>();
|
||||
readonly onRequestConnection = this._onRequestConnection.event;
|
||||
private readonly _onWillShutdown = new Emitter<void>();
|
||||
readonly onWillShutdown = this._onWillShutdown.event;
|
||||
|
||||
|
@ -104,7 +104,7 @@ export class ElectronPtyHostStarter extends Disposable implements IPtyHostStarte
|
|||
}
|
||||
|
||||
private _onWindowConnection(e: IpcMainEvent, nonce: string) {
|
||||
this._onBeforeWindowConnection.fire();
|
||||
this._onRequestConnection.fire();
|
||||
|
||||
const port = this.utilityProcess!.connect();
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ export interface IPtyHostConnection {
|
|||
}
|
||||
|
||||
export interface IPtyHostStarter extends IDisposable {
|
||||
onBeforeWindowConnection?: Event<void>;
|
||||
onRequestConnection?: Event<void>;
|
||||
onWillShutdown?: Event<void>;
|
||||
|
||||
/**
|
||||
|
|
|
@ -88,6 +88,7 @@ async function startPtyHost() {
|
|||
|
||||
// Clean up
|
||||
process.once('exit', () => {
|
||||
logService.trace('Pty host exiting');
|
||||
logService.dispose();
|
||||
heartbeatService.dispose();
|
||||
ptyService.dispose();
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IProcessEnvironment, OperatingSystem, isWindows } from 'vs/base/common/platform';
|
||||
import { IProcessEnvironment, OS, OperatingSystem, isWindows } from 'vs/base/common/platform';
|
||||
import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ILogService, ILoggerService } from 'vs/platform/log/common/log';
|
||||
import { ILogService, ILoggerService, LogLevel } from 'vs/platform/log/common/log';
|
||||
import { RemoteLoggerChannelClient } from 'vs/platform/log/common/logIpc';
|
||||
import { getResolvedShellEnv } from 'vs/platform/shell/node/shellEnv';
|
||||
import { IPtyHostProcessReplayEvent } from 'vs/platform/terminal/common/capabilities/capabilities';
|
||||
|
@ -19,6 +19,7 @@ import { IGetTerminalLayoutInfoArgs, IProcessDetails, ISetTerminalLayoutInfoArgs
|
|||
import { IPtyHostConnection, IPtyHostStarter } from 'vs/platform/terminal/node/ptyHost';
|
||||
import { detectAvailableProfiles } from 'vs/platform/terminal/node/terminalProfiles';
|
||||
import * as performance from 'vs/base/common/performance';
|
||||
import { getSystemShell } from 'vs/base/node/shell';
|
||||
|
||||
enum Constants {
|
||||
MaxRestarts = 5
|
||||
|
@ -43,6 +44,13 @@ export class PtyHostService extends Disposable implements IPtyService {
|
|||
this._ensurePtyHost();
|
||||
return this.__proxy!;
|
||||
}
|
||||
/**
|
||||
* Get the proxy if it exists, otherwise undefined. This is used when calls are not needed to be
|
||||
* passed through to the pty host if it has not yet been spawned.
|
||||
*/
|
||||
private get _optionalProxy(): IPtyService | undefined {
|
||||
return this.__proxy;
|
||||
}
|
||||
|
||||
private _ensurePtyHost() {
|
||||
if (!this.__connection) {
|
||||
|
@ -102,12 +110,9 @@ export class PtyHostService extends Disposable implements IPtyService {
|
|||
this._resolveVariablesRequestStore = this._register(new RequestStore(undefined, this._logService));
|
||||
this._resolveVariablesRequestStore.onCreateRequest(this._onPtyHostRequestResolveVariables.fire, this._onPtyHostRequestResolveVariables);
|
||||
|
||||
// Force the pty host to start as the first window is starting if the starter has that
|
||||
// capability
|
||||
if (this._ptyHostStarter.onBeforeWindowConnection) {
|
||||
Event.once(this._ptyHostStarter.onBeforeWindowConnection)(() => this._ensurePtyHost());
|
||||
} else {
|
||||
this._ensurePtyHost();
|
||||
// Start the pty host when a window requests a connection, if the starter has that capability.
|
||||
if (this._ptyHostStarter.onRequestConnection) {
|
||||
Event.once(this._ptyHostStarter.onRequestConnection)(() => this._ensurePtyHost());
|
||||
}
|
||||
|
||||
this._ptyHostStarter.onWillShutdown?.(() => this._wasQuitRequested = true);
|
||||
|
@ -118,7 +123,7 @@ export class PtyHostService extends Disposable implements IPtyService {
|
|||
}
|
||||
|
||||
private async _refreshIgnoreProcessNames(): Promise<void> {
|
||||
return this._proxy.refreshIgnoreProcessNames?.(this._ignoreProcessNames);
|
||||
return this._optionalProxy?.refreshIgnoreProcessNames?.(this._ignoreProcessNames);
|
||||
}
|
||||
|
||||
private async _resolveShellEnv(): Promise<typeof process.env> {
|
||||
|
@ -139,6 +144,11 @@ export class PtyHostService extends Disposable implements IPtyService {
|
|||
const connection = this._ptyHostStarter.start();
|
||||
const client = connection.client;
|
||||
|
||||
// Log a full stack trace which will tell the exact reason the pty host is starting up
|
||||
if (this._logService.getLevel() === LogLevel.Trace) {
|
||||
this._logService.trace('PtyHostService#_startPtyHost', new Error().stack?.replace(/^Error/, ''));
|
||||
}
|
||||
|
||||
// Setup heartbeat service and trigger a heartbeat immediately to reset the timeouts
|
||||
const heartbeatService = ProxyChannel.toService<IHeartbeatService>(client.getChannel(TerminalIpcChannels.Heartbeat));
|
||||
heartbeatService.onBeat(() => this._handleHeartbeat());
|
||||
|
@ -224,13 +234,10 @@ export class PtyHostService extends Disposable implements IPtyService {
|
|||
return this._proxy.listProcesses();
|
||||
}
|
||||
async getPerformanceMarks(): Promise<performance.PerformanceMark[]> {
|
||||
if (!this.__proxy) {
|
||||
return [];
|
||||
}
|
||||
return this._proxy.getPerformanceMarks();
|
||||
return this._optionalProxy?.getPerformanceMarks() ?? [];
|
||||
}
|
||||
reduceConnectionGraceTime(): Promise<void> {
|
||||
return this._proxy.reduceConnectionGraceTime();
|
||||
async reduceConnectionGraceTime(): Promise<void> {
|
||||
return this._optionalProxy?.reduceConnectionGraceTime();
|
||||
}
|
||||
start(id: number): Promise<ITerminalLaunchError | { injectedArgs: string[] } | undefined> {
|
||||
return this._proxy.start(id);
|
||||
|
@ -280,7 +287,7 @@ export class PtyHostService extends Disposable implements IPtyService {
|
|||
}
|
||||
|
||||
getDefaultSystemShell(osOverride?: OperatingSystem): Promise<string> {
|
||||
return this._proxy.getDefaultSystemShell(osOverride);
|
||||
return this._optionalProxy?.getDefaultSystemShell(osOverride) ?? getSystemShell(osOverride ?? OS, process.env);
|
||||
}
|
||||
async getProfiles(workspaceId: string, profiles: unknown, defaultProfile: unknown, includeDetectedProfiles: boolean = false): Promise<ITerminalProfile[]> {
|
||||
const shellEnv = await this._resolveShellEnv();
|
||||
|
|
|
@ -13,7 +13,7 @@ import { IProcessEnvironment, isLinux, isMacintosh, isWindows } from 'vs/base/co
|
|||
import { URI } from 'vs/base/common/uri';
|
||||
import { Promises } from 'vs/base/node/pfs';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { ILogService, LogLevel } from 'vs/platform/log/common/log';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { FlowControlConstants, IShellLaunchConfig, ITerminalChildProcess, ITerminalLaunchError, IProcessProperty, IProcessPropertyMap as IProcessPropertyMap, ProcessPropertyType, TerminalShellType, IProcessReadyEvent, ITerminalProcessOptions, PosixShellType, IProcessReadyWindowsPty } from 'vs/platform/terminal/common/terminal';
|
||||
import { ChildProcessMonitor } from 'vs/platform/terminal/node/childProcessMonitor';
|
||||
|
@ -353,6 +353,9 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
|
|||
// Allow any trailing data events to be sent before the exit event is sent.
|
||||
// See https://github.com/Tyriar/node-pty/issues/72
|
||||
private _queueProcessExit() {
|
||||
if (this._logService.getLevel() === LogLevel.Trace) {
|
||||
this._logService.trace('TerminalProcess#_queueProcessExit', new Error().stack?.replace(/^Error/, ''));
|
||||
}
|
||||
if (this._closeTimeout) {
|
||||
clearTimeout(this._closeTimeout);
|
||||
}
|
||||
|
@ -417,6 +420,9 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
|
|||
}
|
||||
|
||||
shutdown(immediate: boolean): void {
|
||||
if (this._logService.getLevel() === LogLevel.Trace) {
|
||||
this._logService.trace('TerminalProcess#shutdown', new Error().stack?.replace(/^Error/, ''));
|
||||
}
|
||||
// don't force immediate disposal of the terminal processes on Windows as an additional
|
||||
// mitigation for https://github.com/microsoft/vscode/issues/71966 which causes the pty host
|
||||
// to become unresponsive, disconnecting all terminals across all windows.
|
||||
|
|
|
@ -4,13 +4,14 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IFileSystemProviderWithFileReadWriteCapability, IFileChange, IWatchOptions, IStat, IFileOverwriteOptions, FileType, IFileWriteOptions, IFileDeleteOptions, FileSystemProviderCapabilities, IFileSystemProviderWithFileReadStreamCapability, IFileReadStreamOptions, IFileSystemProviderWithFileAtomicReadCapability, IFileSystemProviderWithFileFolderCopyCapability, hasFileFolderCopyCapability } from 'vs/platform/files/common/files';
|
||||
import { IFileSystemProviderWithFileReadWriteCapability, IFileChange, IWatchOptions, IStat, IFileOverwriteOptions, FileType, IFileWriteOptions, IFileDeleteOptions, FileSystemProviderCapabilities, IFileSystemProviderWithFileReadStreamCapability, IFileReadStreamOptions, IFileSystemProviderWithFileAtomicReadCapability, IFileSystemProviderWithFileFolderCopyCapability, hasFileFolderCopyCapability, hasFileAtomicWriteCapability } from 'vs/platform/files/common/files';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { newWriteableStream, ReadableStreamEvents } from 'vs/base/common/stream';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { TernarySearchTree } from 'vs/base/common/ternarySearchTree';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { isObject } from 'vs/base/common/types';
|
||||
|
||||
/**
|
||||
* This is a wrapper on top of the local filesystem provider which will
|
||||
|
@ -85,6 +86,9 @@ export class FileUserDataProvider extends Disposable implements
|
|||
}
|
||||
|
||||
writeFile(resource: URI, content: Uint8Array, opts: IFileWriteOptions): Promise<void> {
|
||||
if (!isObject(opts.atomic) && hasFileAtomicWriteCapability(this.fileSystemProvider)) {
|
||||
opts = { ...opts, atomic: { postfix: '.vsctmp' } };
|
||||
}
|
||||
return this.fileSystemProvider.writeFile(this.toFileSystemResource(resource), content, opts);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ import { NativeEnvironmentService } from 'vs/platform/environment/node/environme
|
|||
import { OPTIONS, OptionDescriptions } from 'vs/platform/environment/node/argv';
|
||||
import { refineServiceDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IEnvironmentService, INativeEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
export const serverOptions: OptionDescriptions<Required<ServerParsedArgs>> = {
|
||||
|
||||
|
@ -211,5 +213,7 @@ export interface IServerEnvironmentService extends INativeEnvironmentService {
|
|||
}
|
||||
|
||||
export class ServerEnvironmentService extends NativeEnvironmentService implements IServerEnvironmentService {
|
||||
@memoize
|
||||
override get userRoamingDataHome(): URI { return this.appSettingsHome; }
|
||||
override get args(): ServerParsedArgs { return super.args as ServerParsedArgs; }
|
||||
}
|
||||
|
|
|
@ -110,6 +110,7 @@ class OldMainThreadSecretState extends Disposable implements MainThreadSecretSta
|
|||
export class MainThreadSecretState extends Disposable implements MainThreadSecretStateShape {
|
||||
private readonly _proxy: ExtHostSecretStateShape;
|
||||
|
||||
// TODO: Remove this when all known embedders implement a secret storage provider
|
||||
private readonly _oldMainThreadSecretState: OldMainThreadSecretState | undefined;
|
||||
|
||||
private readonly _sequencer = new SequencerByKey<string>();
|
||||
|
@ -131,7 +132,11 @@ export class MainThreadSecretState extends Disposable implements MainThreadSecre
|
|||
|
||||
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostSecretState);
|
||||
|
||||
if (environmentService.options?.credentialsProvider) {
|
||||
// If the embedder doesn't implement a secret storage provider, then we need to use the old API
|
||||
// to ensure that secrets are still stored in a secure way. This is only temporary until all
|
||||
// embedders implement a secret storage provider.
|
||||
// TODO: Remove this when all known embedders implement a secret storage provider
|
||||
if (environmentService.options?.credentialsProvider && !environmentService.options?.secretStorageProvider) {
|
||||
this._oldMainThreadSecretState = this._register(new OldMainThreadSecretState(
|
||||
this._proxy,
|
||||
credentialsService,
|
||||
|
@ -158,7 +163,7 @@ export class MainThreadSecretState extends Disposable implements MainThreadSecre
|
|||
}
|
||||
|
||||
private async doGetPassword(extensionId: string, key: string): Promise<string | undefined> {
|
||||
// TODO: Remove this when we remove the old API
|
||||
// TODO: Remove this when all known embedders implement a secret storage provider
|
||||
if (this._oldMainThreadSecretState) {
|
||||
return await this._oldMainThreadSecretState.$getPassword(extensionId, key);
|
||||
}
|
||||
|
@ -184,7 +189,7 @@ export class MainThreadSecretState extends Disposable implements MainThreadSecre
|
|||
}
|
||||
|
||||
private async doSetPassword(extensionId: string, key: string, value: string): Promise<void> {
|
||||
// TODO: Remove this when we remove the old API
|
||||
// TODO: Remove this when all known embedders implement a secret storage provider
|
||||
if (this._oldMainThreadSecretState) {
|
||||
return await this._oldMainThreadSecretState.$setPassword(extensionId, key, value);
|
||||
}
|
||||
|
@ -200,7 +205,7 @@ export class MainThreadSecretState extends Disposable implements MainThreadSecre
|
|||
}
|
||||
|
||||
private async doDeletePassword(extensionId: string, key: string): Promise<void> {
|
||||
// TODO: Remove this when we remove the old API
|
||||
// TODO: Remove this when all known embedders implement a secret storage provider
|
||||
if (this._oldMainThreadSecretState) {
|
||||
return await this._oldMainThreadSecretState.$deletePassword(extensionId, key);
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ import { ICredentialsService } from 'vs/platform/credentials/common/credentials'
|
|||
import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile';
|
||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { ISecretStorageService } from 'vs/platform/secrets/common/secrets';
|
||||
|
||||
export class ViewContainerActivityAction extends ActivityAction {
|
||||
|
||||
|
@ -235,7 +236,7 @@ export class AccountsActivityActionViewItem extends MenuActivityActionViewItem {
|
|||
private readonly problematicProviders: Set<string> = new Set();
|
||||
|
||||
private initialized = false;
|
||||
private sessionFromEmbedder = getCurrentAuthenticationSessionInfo(this.credentialsService, this.productService);
|
||||
private sessionFromEmbedder = getCurrentAuthenticationSessionInfo(this.credentialsService, this.secretStorageService, this.productService);
|
||||
|
||||
constructor(
|
||||
action: ActivityAction,
|
||||
|
@ -253,6 +254,7 @@ export class AccountsActivityActionViewItem extends MenuActivityActionViewItem {
|
|||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@ISecretStorageService private readonly secretStorageService: ISecretStorageService,
|
||||
@ICredentialsService private readonly credentialsService: ICredentialsService,
|
||||
@ILogService private readonly logService: ILogService
|
||||
) {
|
||||
|
|
|
@ -92,6 +92,10 @@ import { BrowserRemoteResourceLoader } from 'vs/workbench/services/remote/browse
|
|||
import { BufferLogger } from 'vs/platform/log/common/bufferLog';
|
||||
import { FileLoggerService } from 'vs/platform/log/common/fileLog';
|
||||
import { IEmbedderTerminalService } from 'vs/workbench/services/terminal/common/embedderTerminalService';
|
||||
import { BrowserSecretStorageService } from 'vs/workbench/services/secrets/browser/secretStorageService';
|
||||
import { EncryptionService } from 'vs/workbench/services/encryption/browser/encryptionService';
|
||||
import { IEncryptionService } from 'vs/platform/encryption/common/encryptionService';
|
||||
import { ISecretStorageService } from 'vs/platform/secrets/common/secrets';
|
||||
|
||||
export class BrowserMain extends Disposable {
|
||||
|
||||
|
@ -384,9 +388,14 @@ export class BrowserMain extends Disposable {
|
|||
const credentialsService = new BrowserCredentialsService(environmentService, remoteAgentService, productService);
|
||||
serviceCollection.set(ICredentialsService, credentialsService);
|
||||
|
||||
const encryptionService = new EncryptionService();
|
||||
serviceCollection.set(IEncryptionService, encryptionService);
|
||||
const secretStorageService = new BrowserSecretStorageService(storageService, encryptionService, environmentService, logService);
|
||||
serviceCollection.set(ISecretStorageService, secretStorageService);
|
||||
|
||||
// Userdata Initialize Service
|
||||
const userDataInitializers: IUserDataInitializer[] = [];
|
||||
userDataInitializers.push(new UserDataSyncInitializer(environmentService, credentialsService, userDataSyncStoreManagementService, fileService, userDataProfilesService, storageService, productService, requestService, logService, uriIdentityService));
|
||||
userDataInitializers.push(new UserDataSyncInitializer(environmentService, secretStorageService, credentialsService, userDataSyncStoreManagementService, fileService, userDataProfilesService, storageService, productService, requestService, logService, uriIdentityService));
|
||||
if (environmentService.options.profile) {
|
||||
userDataInitializers.push(new UserDataProfileInitializer(environmentService, fileService, userDataProfileService, storageService, logService, uriIdentityService, requestService));
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import { IUserDataSyncMachinesService, UserDataSyncMachinesService } from 'vs/pl
|
|||
import { Emitter } from 'vs/base/common/event';
|
||||
import { CancellationError } from 'vs/base/common/errors';
|
||||
import { EditSessionsStoreClient } from 'vs/workbench/contrib/editSessions/common/editSessionsStorageClient';
|
||||
import { ISecretStorageService } from 'vs/platform/secrets/common/secrets';
|
||||
|
||||
type ExistingSession = IQuickPickItem & { session: AuthenticationSession & { providerId: string } };
|
||||
type AuthenticationProviderOption = IQuickPickItem & { provider: IAuthenticationProvider };
|
||||
|
@ -81,6 +82,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes
|
|||
@IProductService private readonly productService: IProductService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IDialogService private readonly dialogService: IDialogService,
|
||||
@ISecretStorageService private readonly secretStorageService: ISecretStorageService,
|
||||
@ICredentialsService private readonly credentialsService: ICredentialsService
|
||||
) {
|
||||
super();
|
||||
|
@ -278,7 +280,7 @@ export class EditSessionsWorkbenchService extends Disposable implements IEditSes
|
|||
// If settings sync is already enabled, avoid asking again to authenticate
|
||||
if (this.shouldAttemptEditSessionInit()) {
|
||||
this.logService.info(`Reusing user data sync enablement`);
|
||||
const authenticationSessionInfo = await getCurrentAuthenticationSessionInfo(this.credentialsService, this.productService);
|
||||
const authenticationSessionInfo = await getCurrentAuthenticationSessionInfo(this.credentialsService, this.secretStorageService, this.productService);
|
||||
if (authenticationSessionInfo !== undefined) {
|
||||
this.logService.info(`Using current authentication session with ID ${authenticationSessionInfo.id}`);
|
||||
this.existingSessionId = authenticationSessionInfo.id;
|
||||
|
|
|
@ -40,6 +40,18 @@
|
|||
height: 22px;
|
||||
}
|
||||
|
||||
.monaco-workbench .notebookOverlay .notebook-toolbar-container .notebook-toolbar-left .monaco-action-bar li a[tabindex="0"]:focus {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.monaco-workbench .notebookOverlay .notebook-toolbar-container .notebook-toolbar-left .monaco-action-bar li:has(a:focus) {
|
||||
outline-width: 1px;
|
||||
outline-style: solid;
|
||||
outline-offset: -1px;
|
||||
outline-color: var(--vscode-focusBorder);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.monaco-workbench .notebookOverlay .notebook-toolbar-container .notebook-toolbar-left .monaco-action-bar .action-item .action-label.separator {
|
||||
margin: 5px 0px !important;
|
||||
padding: 0px !important;
|
||||
|
|
|
@ -18,9 +18,8 @@
|
|||
.settings-editor > .settings-body .settings-tree-container .setting-item.setting-item-list .setting-list-sibling,
|
||||
.settings-editor > .settings-body .settings-tree-container .setting-item.setting-item-list .setting-list-object-widget .setting-list-object-key,
|
||||
.settings-editor > .settings-body .settings-tree-container .setting-item.setting-item-list .setting-list-object-widget .setting-list-object-value {
|
||||
white-space: pre;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: normal;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
|
||||
.settings-editor > .settings-body .settings-tree-container .setting-item-bool .setting-value-checkbox {
|
||||
|
|
|
@ -8,8 +8,8 @@ import { STATUS_BAR_HOST_NAME_BACKGROUND, STATUS_BAR_HOST_NAME_FOREGROUND } from
|
|||
import { themeColorFromId } from 'vs/platform/theme/common/themeService';
|
||||
import { IRemoteAgentService, remoteConnectionLatencyMeasurer } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||
import { RunOnceScheduler, retry } from 'vs/base/common/async';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { Disposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { MenuId, IMenuService, MenuItemAction, MenuRegistry, registerAction2, Action2, SubmenuItemAction } from 'vs/platform/actions/common/actions';
|
||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { StatusbarAlignment, IStatusbarService, IStatusbarEntryAccessor, IStatusbarEntry } from 'vs/workbench/services/statusbar/browser/statusbar';
|
||||
|
@ -47,7 +47,7 @@ import { IProductService } from 'vs/platform/product/common/productService';
|
|||
import { DomEmitter } from 'vs/base/browser/event';
|
||||
import { registerColor } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { ThemeIcon } from 'vs/base/common/themables';
|
||||
import { infoIcon } from 'vs/workbench/contrib/extensions/browser/extensionsIcons';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
|
@ -115,6 +115,9 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr
|
|||
private loggedInvalidGroupNames: { [group: string]: boolean } = Object.create(null);
|
||||
private readonly remoteExtensionMetadata: RemoteExtensionMetadata[];
|
||||
private remoteMetadataInitialized: boolean = false;
|
||||
private readonly _onDidChangeEntries = this._register(new Emitter<void>());
|
||||
private readonly onDidChangeEntries: Event<void> = this._onDidChangeEntries.event;
|
||||
|
||||
constructor(
|
||||
@IStatusbarService private readonly statusbarService: IStatusbarService,
|
||||
@IBrowserWorkbenchEnvironmentService private readonly environmentService: IBrowserWorkbenchEnvironmentService,
|
||||
|
@ -322,25 +325,22 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr
|
|||
for (let i = 0; i < this.remoteExtensionMetadata.length; i++) {
|
||||
const extensionId = this.remoteExtensionMetadata[i].id;
|
||||
const supportedPlatforms = this.remoteExtensionMetadata[i].supportedPlatforms;
|
||||
// Update compatibility
|
||||
const token = new CancellationTokenSource();
|
||||
const galleryExtension = (await this.extensionGalleryService.getExtensions([{ id: extensionId }], token.token))[0];
|
||||
if (!await this.extensionManagementService.canInstall(galleryExtension)) {
|
||||
this.remoteExtensionMetadata[i].isPlatformCompatible = false;
|
||||
const isInstalled = (await this.extensionManagementService.getInstalled()).find(value => ExtensionIdentifier.equals(value.identifier.id, extensionId)) ? true : false;
|
||||
|
||||
this.remoteExtensionMetadata[i].installed = isInstalled;
|
||||
if (isInstalled) {
|
||||
this.remoteExtensionMetadata[i].isPlatformCompatible = true;
|
||||
}
|
||||
else if (supportedPlatforms && !supportedPlatforms.includes(currentPlatform)) {
|
||||
this.remoteExtensionMetadata[i].isPlatformCompatible = false;
|
||||
}
|
||||
else {
|
||||
this.remoteExtensionMetadata[i].isPlatformCompatible = true;
|
||||
this.remoteExtensionMetadata[i].dependencies = galleryExtension.properties.extensionPack ?? [];
|
||||
}
|
||||
|
||||
// Check if installed and enabled
|
||||
this.remoteExtensionMetadata[i].installed = (await this.extensionManagementService.getInstalled()).find(value => ExtensionIdentifier.equals(value.identifier.id, extensionId)) ? true : false;
|
||||
}
|
||||
|
||||
this.remoteMetadataInitialized = true;
|
||||
this._onDidChangeEntries.fire();
|
||||
showRemoteStartEntry.bindTo(this.contextKeyService).set(true);
|
||||
this.updateRemoteStatusIndicator();
|
||||
}
|
||||
|
@ -551,15 +551,8 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr
|
|||
}
|
||||
}
|
||||
|
||||
// Show when there are commands or installable remote extensions.
|
||||
if (this.hasRemoteMenuCommands(true) || this.remoteExtensionMetadata.some(ext => !ext.installed && ext.isPlatformCompatible)) {
|
||||
this.renderRemoteStatusIndicator(`$(remote)`, nls.localize('noHost.tooltip', "Open a Remote Window"));
|
||||
return;
|
||||
}
|
||||
|
||||
// No Remote Extensions: hide status indicator
|
||||
dispose(this.remoteStatusEntry);
|
||||
this.remoteStatusEntry = undefined;
|
||||
this.renderRemoteStatusIndicator(`$(remote)`, nls.localize('noHost.tooltip', "Open a Remote Window"));
|
||||
return;
|
||||
}
|
||||
|
||||
private renderRemoteStatusIndicator(initialText: string, initialTooltip?: string | MarkdownString, command?: string, showProgress?: boolean): void {
|
||||
|
@ -573,7 +566,7 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr
|
|||
text,
|
||||
showProgress,
|
||||
tooltip,
|
||||
command: command ?? (this.hasRemoteMenuCommands(false) || this.remoteExtensionMetadata.some(ext => !ext.installed && ext.isPlatformCompatible)) ? RemoteStatusIndicator.REMOTE_ACTIONS_COMMAND_ID : undefined
|
||||
command: command ?? RemoteStatusIndicator.REMOTE_ACTIONS_COMMAND_ID
|
||||
};
|
||||
|
||||
if (this.remoteStatusEntry) {
|
||||
|
@ -834,17 +827,15 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr
|
|||
const itemUpdater = this.remoteIndicatorMenu.onDidChange(() => quickPick.items = computeItems());
|
||||
quickPick.onDidHide(itemUpdater.dispose);
|
||||
|
||||
if (!this.remoteMetadataInitialized) {
|
||||
quickPick.busy = true;
|
||||
this._register(this.onDidChangeEntries(() => {
|
||||
// If quick pick is open, update the quick pick items after initialization.
|
||||
quickPick.busy = false;
|
||||
quickPick.items = computeItems();
|
||||
}));
|
||||
}
|
||||
|
||||
quickPick.show();
|
||||
}
|
||||
|
||||
private hasRemoteMenuCommands(ignoreInstallAdditional: boolean): boolean {
|
||||
if (this.remoteAuthority !== undefined || this.virtualWorkspaceLocation !== undefined) {
|
||||
if (RemoteStatusIndicator.SHOW_CLOSE_REMOTE_COMMAND_ID) {
|
||||
return true;
|
||||
}
|
||||
} else if (!ignoreInstallAdditional && this.extensionGalleryService.isEnabled()) {
|
||||
return true;
|
||||
}
|
||||
return this.getRemoteMenuActions().length > 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -210,6 +210,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
|
|||
protected _taskSystemInfos: Map<string, ITaskSystemInfo[]>;
|
||||
|
||||
protected _workspaceTasksPromise?: Promise<Map<string, IWorkspaceFolderTaskResult>>;
|
||||
protected readonly _whenTaskSystemReady: Promise<void>;
|
||||
|
||||
protected _taskSystem?: ITaskSystem;
|
||||
protected _taskSystemListeners?: IDisposable[] = [];
|
||||
|
@ -267,7 +268,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
|
|||
@IInstantiationService private readonly _instantiationService: IInstantiationService
|
||||
) {
|
||||
super();
|
||||
|
||||
this._whenTaskSystemReady = Event.toPromise(this.onDidChangeTaskSystemInfo);
|
||||
this._workspaceTasksPromise = undefined;
|
||||
this._taskSystem = undefined;
|
||||
this._taskSystemListeners = undefined;
|
||||
|
@ -373,7 +374,6 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
|
|||
this._tasksReconnected = true;
|
||||
return;
|
||||
}
|
||||
this._getTaskSystem();
|
||||
this.getWorkspaceTasks().then(async () => {
|
||||
this._tasksReconnected = await this._reconnectTasks();
|
||||
});
|
||||
|
@ -2200,9 +2200,8 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
|
|||
return new Map();
|
||||
}
|
||||
await this._waitForSupportedExecutions;
|
||||
// The build task might be run before folder open. On folder open, we need to update the tasks so that
|
||||
// all tasks are parsed. #173384
|
||||
if (runSource !== TaskRunSource.FolderOpen && this._workspaceTasksPromise) {
|
||||
await this._whenTaskSystemReady;
|
||||
if (this._workspaceTasksPromise) {
|
||||
return this._workspaceTasksPromise;
|
||||
}
|
||||
return this._updateWorkspaceTasks(runSource);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import { DeferredPromise } from 'vs/base/common/async';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { revive } from 'vs/base/common/marshalling';
|
||||
import { PerformanceMark } from 'vs/base/common/performance';
|
||||
import { PerformanceMark, mark } from 'vs/base/common/performance';
|
||||
import { IProcessEnvironment, OperatingSystem } from 'vs/base/common/platform';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
|
@ -324,22 +324,28 @@ class RemoteTerminalBackend extends BaseTerminalBackend implements ITerminalBack
|
|||
// Revive processes if needed
|
||||
const serializedState = this._storageService.get(TerminalStorageKeys.TerminalBufferState, StorageScope.WORKSPACE);
|
||||
const parsed = this._deserializeTerminalState(serializedState);
|
||||
if (parsed) {
|
||||
try {
|
||||
// Note that remote terminals do not get their environment re-resolved unlike in local terminals
|
||||
if (!parsed) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
await this._remoteTerminalChannel.reviveTerminalProcesses(parsed, Intl.DateTimeFormat().resolvedOptions().locale);
|
||||
this._storageService.remove(TerminalStorageKeys.TerminalBufferState, StorageScope.WORKSPACE);
|
||||
// If reviving processes, send the terminal layout info back to the pty host as it
|
||||
// will not have been persisted on application exit
|
||||
const layoutInfo = this._storageService.get(TerminalStorageKeys.TerminalLayoutInfo, StorageScope.WORKSPACE);
|
||||
if (layoutInfo) {
|
||||
await this._remoteTerminalChannel.setTerminalLayoutInfo(JSON.parse(layoutInfo));
|
||||
this._storageService.remove(TerminalStorageKeys.TerminalLayoutInfo, StorageScope.WORKSPACE);
|
||||
}
|
||||
} catch {
|
||||
// no-op
|
||||
try {
|
||||
// Note that remote terminals do not get their environment re-resolved unlike in local terminals
|
||||
|
||||
mark('code/terminal/willReviveTerminalProcessesRemote');
|
||||
await this._remoteTerminalChannel.reviveTerminalProcesses(parsed, Intl.DateTimeFormat().resolvedOptions().locale);
|
||||
mark('code/terminal/didReviveTerminalProcessesRemote');
|
||||
this._storageService.remove(TerminalStorageKeys.TerminalBufferState, StorageScope.WORKSPACE);
|
||||
// If reviving processes, send the terminal layout info back to the pty host as it
|
||||
// will not have been persisted on application exit
|
||||
const layoutInfo = this._storageService.get(TerminalStorageKeys.TerminalLayoutInfo, StorageScope.WORKSPACE);
|
||||
if (layoutInfo) {
|
||||
mark('code/terminal/willSetTerminalLayoutInfoRemote');
|
||||
await this._remoteTerminalChannel.setTerminalLayoutInfo(JSON.parse(layoutInfo));
|
||||
mark('code/terminal/didSetTerminalLayoutInfoRemote');
|
||||
this._storageService.remove(TerminalStorageKeys.TerminalLayoutInfo, StorageScope.WORKSPACE);
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
this._logService.warn('RemoteTerminalBackend#getTerminalLayoutInfo Error', e && typeof e === 'object' && 'message' in e ? e.message : e);
|
||||
}
|
||||
|
||||
return this._remoteTerminalChannel.getTerminalLayoutInfo();
|
||||
|
|
|
@ -2080,7 +2080,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
|||
this._refreshEnvironmentVariableInfoWidgetState(info);
|
||||
}
|
||||
|
||||
private _refreshEnvironmentVariableInfoWidgetState(info?: IEnvironmentVariableInfo): void {
|
||||
private async _refreshEnvironmentVariableInfoWidgetState(info?: IEnvironmentVariableInfo): Promise<void> {
|
||||
// Check if the status should exist
|
||||
if (!info) {
|
||||
this.statusList.remove(TerminalStatus.RelaunchNeeded);
|
||||
|
@ -2088,16 +2088,25 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
|||
return;
|
||||
}
|
||||
|
||||
// Recreate the process if the terminal has not yet been interacted with and it's not a
|
||||
// special terminal (eg. extension terminal)
|
||||
// Recreate the process seamlessly without informing the use if the following conditions are
|
||||
// met.
|
||||
if (
|
||||
// The change requires a relaunch
|
||||
info.requiresAction &&
|
||||
// The feature is enabled
|
||||
this._configHelper.config.environmentChangesRelaunch &&
|
||||
// Has not been interacted with
|
||||
!this._processManager.hasWrittenData &&
|
||||
// Not a feature terminal or is a reconnecting task terminal (TODO: Need to explain the latter case)
|
||||
(!this._shellLaunchConfig.isFeatureTerminal || (this.reconnectionProperties && this._configurationService.getValue(TaskSettingId.Reconnection) === true)) &&
|
||||
!this._shellLaunchConfig.customPtyImplementation
|
||||
&& !this._shellLaunchConfig.isExtensionOwnedTerminal &&
|
||||
!this._shellLaunchConfig.attachPersistentProcess
|
||||
// Not a custom pty
|
||||
!this._shellLaunchConfig.customPtyImplementation &&
|
||||
// Not an extension owned terminal
|
||||
!this._shellLaunchConfig.isExtensionOwnedTerminal &&
|
||||
// Not a reconnected or revived terminal
|
||||
!this._shellLaunchConfig.attachPersistentProcess &&
|
||||
// Not a Windows remote using ConPTY (#187084)
|
||||
!(this._processManager.remoteAuthority && this._configHelper.config.windowsEnableConpty && (await this._processManager.getBackendOS()) === OperatingSystem.Windows)
|
||||
) {
|
||||
this.relaunch();
|
||||
return;
|
||||
|
|
|
@ -422,7 +422,7 @@ export class TerminalService implements ITerminalService {
|
|||
private _setConnected() {
|
||||
this._connectionState = TerminalConnectionState.Connected;
|
||||
this._onDidChangeConnectionState.fire();
|
||||
this._logService.trace('Reconnected to terminals');
|
||||
this._logService.trace('Pty host ready');
|
||||
}
|
||||
|
||||
private async _reconnectToRemoteTerminals(): Promise<void> {
|
||||
|
@ -444,6 +444,8 @@ export class TerminalService implements ITerminalService {
|
|||
// now that terminals have been restored,
|
||||
// attach listeners to update remote when terminals are changed
|
||||
this._attachProcessLayoutListeners();
|
||||
|
||||
this._logService.trace('Reconnected to remote terminals');
|
||||
}
|
||||
|
||||
private async _reconnectToLocalTerminals(): Promise<void> {
|
||||
|
@ -462,6 +464,8 @@ export class TerminalService implements ITerminalService {
|
|||
// now that terminals have been restored,
|
||||
// attach listeners to update local state when terminals are changed
|
||||
this._attachProcessLayoutListeners();
|
||||
|
||||
this._logService.trace('Reconnected to local terminals');
|
||||
}
|
||||
|
||||
private _recreateTerminalGroups(layoutInfo?: ITerminalsLayoutInfo): Promise<ITerminalGroup[]> {
|
||||
|
|
|
@ -54,7 +54,7 @@ class TerminalLinkContribution extends DisposableStore implements ITerminalContr
|
|||
this._processManager.onProcessReady(() => {
|
||||
linkManager.setWidgetManager(this._widgetManager);
|
||||
});
|
||||
this._linkManager = linkManager;
|
||||
this._linkManager = this.add(linkManager);
|
||||
|
||||
// Attach the link provider(s) to the instance and listen for changes
|
||||
for (const linkProvider of this._terminalLinkProviderService.linkProviders) {
|
||||
|
|
|
@ -77,7 +77,7 @@ export class TerminalLinkManager extends DisposableStore {
|
|||
this._setupLinkDetector(TerminalMultiLineLinkDetector.id, this._instantiationService.createInstance(TerminalMultiLineLinkDetector, this._xterm, this._processManager, this._linkResolver));
|
||||
this._setupLinkDetector(TerminalLocalLinkDetector.id, this._instantiationService.createInstance(TerminalLocalLinkDetector, this._xterm, capabilities, this._processManager, this._linkResolver));
|
||||
}
|
||||
this._setupLinkDetector(TerminalWordLinkDetector.id, this._instantiationService.createInstance(TerminalWordLinkDetector, this._xterm));
|
||||
this._setupLinkDetector(TerminalWordLinkDetector.id, this.add(this._instantiationService.createInstance(TerminalWordLinkDetector, this._xterm)));
|
||||
|
||||
// Setup link openers
|
||||
const localFileOpener = this._instantiationService.createInstance(TerminalLocalFileLinkOpener);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { escapeRegExpCharacters } from 'vs/base/common/strings';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
|
@ -27,7 +28,7 @@ interface Word {
|
|||
text: string;
|
||||
}
|
||||
|
||||
export class TerminalWordLinkDetector implements ITerminalLinkDetector {
|
||||
export class TerminalWordLinkDetector extends Disposable implements ITerminalLinkDetector {
|
||||
static id = 'word';
|
||||
|
||||
// Word links typically search the workspace so it makes sense that their maximum link length is
|
||||
|
@ -41,12 +42,14 @@ export class TerminalWordLinkDetector implements ITerminalLinkDetector {
|
|||
@IConfigurationService private readonly _configurationService: IConfigurationService,
|
||||
@IProductService private readonly _productService: IProductService,
|
||||
) {
|
||||
super();
|
||||
|
||||
this._refreshSeparatorCodes();
|
||||
this._configurationService.onDidChangeConfiguration(e => {
|
||||
this._register(this._configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration(TerminalSettingId.WordSeparators)) {
|
||||
this._refreshSeparatorCodes();
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
detect(lines: IBufferLine[], startLine: number, endLine: number): ITerminalSimpleLink[] {
|
||||
|
|
|
@ -12,6 +12,7 @@ import { flatTestItemDelimiter } from 'vs/workbench/contrib/testing/browser/expl
|
|||
import { ITestTreeProjection, TestExplorerTreeElement, TestItemTreeElement, TestTreeErrorMessage, getChildrenForParent, testIdentityProvider } from 'vs/workbench/contrib/testing/browser/explorerProjections/index';
|
||||
import { ISerializedTestTreeCollapseState, isCollapsedInSerializedTestTree } from 'vs/workbench/contrib/testing/browser/explorerProjections/testingViewState';
|
||||
import { TestId } from 'vs/workbench/contrib/testing/common/testId';
|
||||
import { TestResultItemChangeReason } from 'vs/workbench/contrib/testing/common/testResult';
|
||||
import { ITestResultService } from 'vs/workbench/contrib/testing/common/testResultService';
|
||||
import { ITestService } from 'vs/workbench/contrib/testing/common/testService';
|
||||
import { ITestItemUpdate, InternalTestItem, TestDiffOpType, TestItemExpandState, TestResultState, TestsDiff, applyTestItemUpdate } from 'vs/workbench/contrib/testing/common/testTypes';
|
||||
|
@ -106,6 +107,10 @@ export class ListProjection extends Disposable implements ITestTreeProjection {
|
|||
|
||||
// when test states change, reflect in the tree
|
||||
this._register(results.onTestChanged(ev => {
|
||||
if (ev.reason === TestResultItemChangeReason.NewMessage) {
|
||||
return; // no effect in the tree
|
||||
}
|
||||
|
||||
let result = ev.item;
|
||||
// if the state is unset, or the latest run is not making the change,
|
||||
// double check that it's valid. Retire calls might cause previous
|
||||
|
|
|
@ -139,6 +139,10 @@ export class TreeProjection extends Disposable implements ITestTreeProjection {
|
|||
|
||||
// when test states change, reflect in the tree
|
||||
this._register(results.onTestChanged(ev => {
|
||||
if (ev.reason === TestResultItemChangeReason.NewMessage) {
|
||||
return; // no effect in the tree
|
||||
}
|
||||
|
||||
let result = ev.item;
|
||||
// if the state is unset, or the latest run is not making the change,
|
||||
// double check that it's valid. Retire calls might cause previous
|
||||
|
|
|
@ -183,6 +183,10 @@
|
|||
border-bottom-width: 2px;
|
||||
}
|
||||
|
||||
.test-output-peek-message-container {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.test-output-peek-message-container,
|
||||
.test-output-peek-tree {
|
||||
height: 100%;
|
||||
|
@ -229,10 +233,6 @@
|
|||
max-width: none;
|
||||
}
|
||||
|
||||
.testing-filter-wrapper {
|
||||
height: 27px;
|
||||
}
|
||||
|
||||
.testing-filter-action-item .testing-filter-wrapper {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
|
|
@ -566,7 +566,8 @@ class TestingExplorerViewModel extends Disposable {
|
|||
keyboardNavigationLabelProvider: instantiationService.createInstance(TreeKeyboardNavigationLabelProvider),
|
||||
accessibilityProvider: instantiationService.createInstance(ListAccessibilityProvider),
|
||||
filter: this.filter,
|
||||
findWidgetEnabled: false
|
||||
findWidgetEnabled: false,
|
||||
openOnSingleClick: false,
|
||||
}) as TestingObjectTree<FuzzyScore>;
|
||||
|
||||
|
||||
|
@ -612,7 +613,7 @@ class TestingExplorerViewModel extends Disposable {
|
|||
testService.excluded.onTestExclusionsChanged,
|
||||
)(this.tree.refilter, this.tree));
|
||||
|
||||
this._register(this.tree.onMouseDblClick(e => {
|
||||
this._register(this.tree.onDidOpen(e => {
|
||||
if (e.element instanceof TestItemTreeElement && !e.element.children.size && e.element.test.item.uri) {
|
||||
commandService.executeCommand('vscode.revealTest', e.element.test.item.extId);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import { ICompressedTreeElement, ICompressedTreeNode } from 'vs/base/browser/ui/
|
|||
import { ICompressibleTreeRenderer } from 'vs/base/browser/ui/tree/objectTree';
|
||||
import { ITreeContextMenuEvent, ITreeNode } from 'vs/base/browser/ui/tree/tree';
|
||||
import { Action, IAction, Separator } from 'vs/base/common/actions';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { Delayer, RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
|
@ -26,7 +26,6 @@ import { Iterable } from 'vs/base/common/iterator';
|
|||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import { Lazy } from 'vs/base/common/lazy';
|
||||
import { Disposable, DisposableStore, IDisposable, IReference, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { clamp } from 'vs/base/common/numbers';
|
||||
import { count } from 'vs/base/common/strings';
|
||||
import { ThemeIcon } from 'vs/base/common/themables';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
@ -520,8 +519,8 @@ export class TestingOutputPeekController extends Disposable implements IEditorCo
|
|||
* Shows a peek for the message in the editor.
|
||||
*/
|
||||
public async show(uri: URI) {
|
||||
const subjecet = this.retrieveTest(uri);
|
||||
if (!subjecet) {
|
||||
const subject = this.retrieveTest(uri);
|
||||
if (!subject) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -537,12 +536,12 @@ export class TestingOutputPeekController extends Disposable implements IEditorCo
|
|||
this.peek.value!.create();
|
||||
}
|
||||
|
||||
if (subjecet instanceof MessageSubject) {
|
||||
const message = subjecet.messages[subjecet.messageIndex];
|
||||
if (subject instanceof MessageSubject) {
|
||||
const message = subject.messages[subject.messageIndex];
|
||||
alert(renderStringAsPlaintext(message.message));
|
||||
}
|
||||
|
||||
this.peek.value.setModel(subjecet);
|
||||
this.peek.value.setModel(subject);
|
||||
this.currentPeekUri = uri;
|
||||
}
|
||||
|
||||
|
@ -711,13 +710,10 @@ class TestResultsViewContent extends Disposable {
|
|||
historyVisible: IObservableValue<boolean>;
|
||||
showRevealLocationOnMessages: boolean;
|
||||
},
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@ITextModelService protected readonly modelService: ITextModelService,
|
||||
) {
|
||||
super();
|
||||
|
||||
TestingContextKeys.isInPeek.bindTo(contextKeyService);
|
||||
}
|
||||
|
||||
public fillBody(containerElement: HTMLElement): void {
|
||||
|
@ -806,6 +802,7 @@ class TestResultsPeek extends PeekViewWidget {
|
|||
|
||||
private readonly visibilityChange = this._disposables.add(new Emitter<boolean>());
|
||||
private readonly content: TestResultsViewContent;
|
||||
private scopedContextKeyService?: IContextKeyService;
|
||||
private dimension?: dom.Dimension;
|
||||
public current?: InspectSubject;
|
||||
|
||||
|
@ -821,7 +818,6 @@ class TestResultsPeek extends PeekViewWidget {
|
|||
) {
|
||||
super(editor, { showFrame: true, frameWidth: 1, showArrow: true, isResizeable: true, isAccessible: true, className: 'test-output-peek' }, instantiationService);
|
||||
|
||||
TestingContextKeys.isInPeek.bindTo(contextKeyService);
|
||||
this._disposables.add(themeService.onDidColorThemeChange(this.applyTheme, this));
|
||||
this._disposables.add(this.onDidClose(() => this.visibilityChange.fire(false)));
|
||||
this.content = this._disposables.add(instantiationService.createInstance(TestResultsViewContent, editor, { historyVisible: testingPeek.historyVisible, showRevealLocationOnMessages: false }));
|
||||
|
@ -841,6 +837,15 @@ class TestResultsPeek extends PeekViewWidget {
|
|||
});
|
||||
}
|
||||
|
||||
protected override _fillContainer(container: HTMLElement): void {
|
||||
if (!this.scopedContextKeyService) {
|
||||
this.scopedContextKeyService = this._disposables.add(this.contextKeyService.createScoped(container));
|
||||
TestingContextKeys.isInPeek.bindTo(this.scopedContextKeyService).set(true);
|
||||
}
|
||||
|
||||
super._fillContainer(container);
|
||||
}
|
||||
|
||||
protected override _fillHead(container: HTMLElement): void {
|
||||
super._fillHead(container);
|
||||
|
||||
|
@ -1016,7 +1021,7 @@ const diffEditorOptions: IDiffEditorConstructionOptions = {
|
|||
diffAlgorithm: 'advanced',
|
||||
};
|
||||
|
||||
const isDiffable = (message: ITestMessage): message is ITestErrorMessage & { actualOutput: string; expectedOutput: string } =>
|
||||
const isDiffable = (message: ITestMessage): message is ITestErrorMessage & { actual: string; expected: string } =>
|
||||
message.type === TestMessageType.Error && message.actual !== undefined && message.expected !== undefined;
|
||||
|
||||
class DiffContentProvider extends Disposable implements IPeekOutputRenderer {
|
||||
|
@ -1222,6 +1227,7 @@ class PlainTextMessagePeek extends Disposable implements IPeekOutputRenderer {
|
|||
class TerminalMessagePeek extends Disposable implements IPeekOutputRenderer {
|
||||
private dimensions?: dom.IDimension;
|
||||
private readonly terminalCwd = this._register(new MutableObservableValue<string>(''));
|
||||
private readonly xtermLayoutDelayer = this._register(new Delayer(50));
|
||||
|
||||
/** Active terminal instance. */
|
||||
private readonly terminal = this._register(new MutableDisposable<IDetachedXtermTerminal>());
|
||||
|
@ -1337,6 +1343,7 @@ class TerminalMessagePeek extends Disposable implements IPeekOutputRenderer {
|
|||
|
||||
private clear() {
|
||||
this.outputDataListener.clear();
|
||||
this.xtermLayoutDelayer.cancel();
|
||||
this.terminal.clear();
|
||||
}
|
||||
|
||||
|
@ -1353,10 +1360,12 @@ class TerminalMessagePeek extends Disposable implements IPeekOutputRenderer {
|
|||
height = this.dimensions?.height ?? this.container.clientHeight
|
||||
) {
|
||||
width -= 10 + 20; // scrollbar width + margin
|
||||
const scaled = getXtermScaledDimensions(xterm.getFont(), width, height);
|
||||
if (scaled) {
|
||||
xterm.resize(scaled.cols, scaled.rows);
|
||||
}
|
||||
this.xtermLayoutDelayer.trigger(() => {
|
||||
const scaled = getXtermScaledDimensions(xterm.getFont(), width, height);
|
||||
if (scaled) {
|
||||
xterm.resize(scaled.cols, scaled.rows);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1371,8 +1380,9 @@ const firstLine = (str: string) => {
|
|||
};
|
||||
|
||||
const isMultiline = (str: string | undefined) => !!str && str.includes('\n');
|
||||
const hintPeekStrHeight = (str: string | undefined) =>
|
||||
clamp(str ? Math.max(count(str, '\n'), Math.ceil(str.length / 80)) + 3 : 0, 14, 24);
|
||||
|
||||
// add 5ish lines for the size of the title and decorations in the peek.
|
||||
const hintPeekStrHeight = (str: string) => Math.min(count(str, '\n') + 5, 24);
|
||||
|
||||
class SimpleDiffEditorModel extends EditorModel {
|
||||
public readonly original = this._original.object.textEditorModel;
|
||||
|
@ -1696,7 +1706,9 @@ class OutputPeekTree extends Disposable {
|
|||
|
||||
const itemNode = taskNode.itemsCache.get(e.item);
|
||||
if (itemNode && this.tree.hasElement(itemNode)) {
|
||||
this.tree.setChildren(itemNode, getTestChildren(result, e.item, index), { diffIdentityProvider });
|
||||
if (e.reason === TestResultItemChangeReason.NewMessage) {
|
||||
this.tree.setChildren(itemNode, getTestChildren(result, e.item, index), { diffIdentityProvider });
|
||||
}
|
||||
itemNode.changeEmitter.fire();
|
||||
return;
|
||||
}
|
||||
|
@ -1990,7 +2002,7 @@ class TreeActionsProvider {
|
|||
const extId = element.test.item.extId;
|
||||
primary.push(new Action(
|
||||
'testing.outputPeek.goToFile',
|
||||
localize('testing.goToFile', "Go to File"),
|
||||
localize('testing.goToFile', "Go to Source"),
|
||||
ThemeIcon.asClassName(Codicon.goToFile),
|
||||
undefined,
|
||||
() => this.commandService.executeCommand('vscode.revealTest', extId),
|
||||
|
|
|
@ -82,7 +82,7 @@ export class TestingProgressTrigger extends Disposable {
|
|||
}
|
||||
|
||||
private openTestView() {
|
||||
this.viewsService.openView(Testing.ExplorerViewId, false);
|
||||
this.viewsService.openView(Testing.ResultsViewId, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -215,11 +215,13 @@ const itemToNode = (controllerId: string, item: ITestItem, parent: string | null
|
|||
export const enum TestResultItemChangeReason {
|
||||
ComputedStateChange,
|
||||
OwnStateChange,
|
||||
NewMessage,
|
||||
}
|
||||
|
||||
export type TestResultItemChange = { item: TestResultItem; result: ITestResult } & (
|
||||
| { reason: TestResultItemChangeReason.ComputedStateChange }
|
||||
| { reason: TestResultItemChangeReason.OwnStateChange; previousState: TestResultState; previousOwnDuration: number | undefined }
|
||||
| { reason: TestResultItemChangeReason.NewMessage }
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -319,8 +321,10 @@ export class LiveTestResult implements ITestResult {
|
|||
type: TestMessageType.Output,
|
||||
};
|
||||
|
||||
if (testId) {
|
||||
this.testById.get(testId)?.tasks[index].messages.push(message);
|
||||
const test = testId && this.testById.get(testId);
|
||||
if (test) {
|
||||
test.tasks[index].messages.push(message);
|
||||
this.changeEmitter.fire({ item: test, result: this, reason: TestResultItemChangeReason.NewMessage });
|
||||
} else {
|
||||
task.otherMessages.push(message);
|
||||
}
|
||||
|
@ -390,13 +394,7 @@ export class LiveTestResult implements ITestResult {
|
|||
}
|
||||
|
||||
entry.tasks[this.mustGetTaskIndex(taskId)].messages.push(message);
|
||||
this.changeEmitter.fire({
|
||||
item: entry,
|
||||
result: this,
|
||||
reason: TestResultItemChangeReason.OwnStateChange,
|
||||
previousState: entry.ownComputedState,
|
||||
previousOwnDuration: entry.ownDuration,
|
||||
});
|
||||
this.changeEmitter.fire({ item: entry, result: this, reason: TestResultItemChangeReason.NewMessage });
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,7 +35,7 @@ export namespace TestingContextKeys {
|
|||
export const viewMode = new RawContextKey<TestExplorerViewMode>('testing.explorerViewMode', TestExplorerViewMode.List);
|
||||
export const viewSorting = new RawContextKey<TestExplorerViewSorting>('testing.explorerViewSorting', TestExplorerViewSorting.ByLocation);
|
||||
export const isRunning = new RawContextKey<boolean>('testing.isRunning', false);
|
||||
export const isInPeek = new RawContextKey<boolean>('testing.isInPeek', true);
|
||||
export const isInPeek = new RawContextKey<boolean>('testing.isInPeek', false);
|
||||
export const isPeekVisible = new RawContextKey<boolean>('testing.isPeekVisible', false);
|
||||
|
||||
export const peekItemType = new RawContextKey<string | undefined>('peekItemType', undefined, {
|
||||
|
|
|
@ -224,7 +224,8 @@ export class DesktopMain extends Disposable {
|
|||
const diskFileSystemProvider = this._register(new DiskFileSystemProvider(mainProcessService, utilityProcessWorkerWorkbenchService, logService));
|
||||
fileService.registerProvider(Schemas.file, diskFileSystemProvider);
|
||||
|
||||
// User Data Provider
|
||||
// Use FileUserDataProvider for user data to
|
||||
// enable atomic read / write operations.
|
||||
fileService.registerProvider(Schemas.vscodeUserData, this._register(new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.vscodeUserData, logService)));
|
||||
|
||||
// URI Identity
|
||||
|
|
|
@ -19,6 +19,7 @@ import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/
|
|||
import { Severity } from 'vs/platform/notification/common/notification';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { ISecretStorageService } from 'vs/platform/secrets/common/secrets';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity';
|
||||
import { IAuthenticationCreateSessionOptions, AuthenticationProviderInformation, AuthenticationSession, AuthenticationSessionsChangeEvent, IAuthenticationProvider, IAuthenticationService } from 'vs/workbench/services/authentication/common/authentication';
|
||||
|
@ -76,9 +77,17 @@ export function addAccountUsage(storageService: IStorageService, providerId: str
|
|||
storageService.store(accountKey, JSON.stringify(usages), StorageScope.APPLICATION, StorageTarget.MACHINE);
|
||||
}
|
||||
|
||||
// TODO: pull this out into its own service
|
||||
export type AuthenticationSessionInfo = { readonly id: string; readonly accessToken: string; readonly providerId: string; readonly canSignOut?: boolean };
|
||||
export async function getCurrentAuthenticationSessionInfo(credentialsService: ICredentialsService, productService: IProductService): Promise<AuthenticationSessionInfo | undefined> {
|
||||
const authenticationSessionValue = await credentialsService.getPassword(`${productService.urlProtocol}.login`, 'account');
|
||||
export async function getCurrentAuthenticationSessionInfo(
|
||||
// TODO: Remove when all known embedders implement SecretStorageProviders instead of CredentialsProviders
|
||||
credentialsService: ICredentialsService,
|
||||
secretStorageService: ISecretStorageService,
|
||||
productService: IProductService
|
||||
): Promise<AuthenticationSessionInfo | undefined> {
|
||||
const authenticationSessionValue =
|
||||
await secretStorageService.get(`${productService.urlProtocol}.loginAccount`)
|
||||
?? await credentialsService.getPassword(`${productService.urlProtocol}.login`, 'account');
|
||||
if (authenticationSessionValue) {
|
||||
try {
|
||||
const authenticationSessionInfo: AuthenticationSessionInfo = JSON.parse(authenticationSessionValue);
|
||||
|
@ -90,7 +99,8 @@ export async function getCurrentAuthenticationSessionInfo(credentialsService: IC
|
|||
return authenticationSessionInfo;
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore as this is a best effort operation.
|
||||
// This is a best effort operation.
|
||||
console.error(`Failed parsing current auth session value: ${e}`);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
|
|
|
@ -84,9 +84,6 @@ export class NativeWorkbenchEnvironmentService extends AbstractNativeEnvironment
|
|||
};
|
||||
}
|
||||
|
||||
@memoize
|
||||
override get userRoamingDataHome(): URI { return this.appSettingsHome.with({ scheme: Schemas.vscodeUserData }); }
|
||||
|
||||
@memoize
|
||||
get windowLogsPath(): URI { return joinPath(this.logsHome, `window${this.configuration.windowId}`); }
|
||||
|
||||
|
|
|
@ -5,9 +5,7 @@
|
|||
|
||||
import { IEncryptionService } from 'vs/platform/encryption/common/encryptionService';
|
||||
import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { ISecretStorageProvider, ISecretStorageService, BaseSecretStorageService } from 'vs/platform/secrets/common/secrets';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
|
||||
|
@ -20,8 +18,6 @@ export class BrowserSecretStorageService extends BaseSecretStorageService {
|
|||
@IStorageService storageService: IStorageService,
|
||||
@IEncryptionService encryptionService: IEncryptionService,
|
||||
@IBrowserWorkbenchEnvironmentService environmentService: IBrowserWorkbenchEnvironmentService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@INotificationService notificationService: INotificationService,
|
||||
@ILogService logService: ILogService
|
||||
) {
|
||||
super(storageService, encryptionService, logService);
|
||||
|
|
|
@ -35,6 +35,7 @@ import { TasksInitializer } from 'vs/platform/userDataSync/common/tasksSync';
|
|||
import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
|
||||
import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
|
||||
import { IUserDataInitializer } from 'vs/workbench/services/userData/browser/userDataInit';
|
||||
import { ISecretStorageService } from 'vs/platform/secrets/common/secrets';
|
||||
|
||||
export class UserDataSyncInitializer implements IUserDataInitializer {
|
||||
|
||||
|
@ -46,6 +47,7 @@ export class UserDataSyncInitializer implements IUserDataInitializer {
|
|||
|
||||
constructor(
|
||||
@IBrowserWorkbenchEnvironmentService private readonly environmentService: IBrowserWorkbenchEnvironmentService,
|
||||
@ISecretStorageService private readonly secretStorageService: ISecretStorageService,
|
||||
@ICredentialsService private readonly credentialsService: ICredentialsService,
|
||||
@IUserDataSyncStoreManagementService private readonly userDataSyncStoreManagementService: IUserDataSyncStoreManagementService,
|
||||
@IFileService private readonly fileService: IFileService,
|
||||
|
@ -90,7 +92,7 @@ export class UserDataSyncInitializer implements IUserDataInitializer {
|
|||
|
||||
let authenticationSession;
|
||||
try {
|
||||
authenticationSession = await getCurrentAuthenticationSessionInfo(this.credentialsService, this.productService);
|
||||
authenticationSession = await getCurrentAuthenticationSessionInfo(this.credentialsService, this.secretStorageService, this.productService);
|
||||
} catch (error) {
|
||||
this.logService.error(error);
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'
|
|||
import { isDiffEditorInput } from 'vs/workbench/common/editor';
|
||||
import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
|
||||
import { IUserDataInitializationService } from 'vs/workbench/services/userData/browser/userDataInit';
|
||||
import { ISecretStorageService } from 'vs/platform/secrets/common/secrets';
|
||||
|
||||
type AccountQuickPickItem = { label: string; authenticationProvider: IAuthenticationProvider; account?: UserDataSyncAccount; description?: string };
|
||||
|
||||
|
@ -105,6 +106,7 @@ export class UserDataSyncWorkbenchService extends Disposable implements IUserDat
|
|||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IBrowserWorkbenchEnvironmentService private readonly environmentService: IBrowserWorkbenchEnvironmentService,
|
||||
@ICredentialsService private readonly credentialsService: ICredentialsService,
|
||||
@ISecretStorageService private readonly secretStorageService: ISecretStorageService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IProgressService private readonly progressService: IProgressService,
|
||||
@IDialogService private readonly dialogService: IDialogService,
|
||||
|
@ -169,7 +171,7 @@ export class UserDataSyncWorkbenchService extends Disposable implements IUserDat
|
|||
}
|
||||
|
||||
private async initialize(): Promise<void> {
|
||||
const authenticationSession = await getCurrentAuthenticationSessionInfo(this.credentialsService, this.productService);
|
||||
const authenticationSession = await getCurrentAuthenticationSessionInfo(this.credentialsService, this.secretStorageService, this.productService);
|
||||
if (this.currentSessionId === undefined && authenticationSession?.id) {
|
||||
if (this.environmentService.options?.settingsSyncOptions?.authenticationProvider && this.environmentService.options.settingsSyncOptions.enabled) {
|
||||
this.currentSessionId = authenticationSession.id;
|
||||
|
|
Loading…
Reference in a new issue