diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index 2d6713d409d09..ba8a8e86feefd 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -12,7 +12,7 @@ import { Platform } from '../../../base/common/platform.js'; import { URI } from '../../../base/common/uri.js'; import { localize2 } from '../../../nls.js'; import { ExtensionType, IExtension, IExtensionManifest, TargetPlatform } from '../../extensions/common/extensions.js'; -import { IFileService } from '../../files/common/files.js'; +import { FileOperationError, FileOperationResult, IFileService, IFileStat } from '../../files/common/files.js'; import { createDecorator } from '../../instantiation/common/instantiation.js'; export const EXTENSION_IDENTIFIER_PATTERN = '^([a-z0-9A-Z][a-z0-9-A-Z]*)\\.([a-z0-9A-Z][a-z0-9-A-Z]*)$'; @@ -640,7 +640,15 @@ export interface IAllowedExtensionsService { } export async function computeSize(location: URI, fileService: IFileService): Promise { - const stat = await fileService.resolve(location); + let stat: IFileStat; + try { + stat = await fileService.resolve(location); + } catch (e) { + if ((e).fileOperationResult === FileOperationResult.FILE_NOT_FOUND) { + return 0; + } + throw e; + } if (stat.children) { const sizes = await Promise.all(stat.children.map(c => computeSize(c.resource, fileService))); return sizes.reduce((r, s) => r + s, 0); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index d5d8e0b3cd61c..a47806e80f404 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -1157,12 +1157,14 @@ class AdditionalDetailsWidget extends Disposable { $('div.more-info-entry-name', undefined, localize('id', "Identifier")), $('code', undefined, extension.identifier.id) )); - append(installInfo, - $('.more-info-entry', undefined, - $('div.more-info-entry-name', undefined, localize('Version', "Version")), - $('code', undefined, extension.manifest.version) - ) - ); + if (extension.type !== ExtensionType.System) { + append(installInfo, + $('.more-info-entry', undefined, + $('div.more-info-entry-name', undefined, localize('Version', "Version")), + $('code', undefined, extension.manifest.version) + ) + ); + } if (extension.installedTimestamp) { append(installInfo, $('.more-info-entry', undefined, @@ -1171,7 +1173,7 @@ class AdditionalDetailsWidget extends Disposable { ) ); } - if (extension.source !== 'gallery') { + if (!extension.isBuiltin && extension.source !== 'gallery') { const element = $('div', undefined, extension.source === 'vsix' ? localize('vsix', "VSIX") : localize('other', "Local")); append(installInfo, $('.more-info-entry', undefined, diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts index 12423a7f38fc6..841b309d3648c 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts @@ -454,6 +454,7 @@ export class SearchEditor extends AbstractTextCodeEditor if (!matchRanges) { return; } const matchRange = (reverse ? findPrevRange : findNextRange)(matchRanges, currentPosition); + if (!matchRange) { return; } this.searchResultEditor.setSelection(matchRange); this.searchResultEditor.revealLineInCenterIfOutsideViewport(matchRange.startLineNumber); diff --git a/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts b/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts index ddfd1f0553fde..6a1eb065c6c19 100644 --- a/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts +++ b/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts @@ -6,7 +6,7 @@ import { IUserDataSyncService, IAuthenticationProvider, isAuthenticationProvider, IUserDataAutoSyncService, IUserDataSyncStoreManagementService, SyncStatus, IUserDataSyncEnablementService, IUserDataSyncResource, IResourcePreview, USER_DATA_SYNC_SCHEME, USER_DATA_SYNC_LOG_ID, } from '../../../../platform/userDataSync/common/userDataSync.js'; import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js'; import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js'; -import { IUserDataSyncWorkbenchService, IUserDataSyncAccount, AccountStatus, CONTEXT_SYNC_ENABLEMENT, CONTEXT_SYNC_STATE, CONTEXT_ACCOUNT_STATE, SHOW_SYNC_LOG_COMMAND_ID, CONTEXT_ENABLE_ACTIVITY_VIEWS, SYNC_VIEW_CONTAINER_ID, SYNC_TITLE, SYNC_CONFLICTS_VIEW_ID, CONTEXT_ENABLE_SYNC_CONFLICTS_VIEW, CONTEXT_HAS_CONFLICTS, IUserDataSyncConflictsView } from '../common/userDataSync.js'; +import { IUserDataSyncWorkbenchService, IUserDataSyncAccount, AccountStatus, CONTEXT_SYNC_ENABLEMENT, CONTEXT_SYNC_STATE, CONTEXT_ACCOUNT_STATE, SHOW_SYNC_LOG_COMMAND_ID, CONTEXT_ENABLE_ACTIVITY_VIEWS, SYNC_VIEW_CONTAINER_ID, SYNC_TITLE, SYNC_CONFLICTS_VIEW_ID, CONTEXT_ENABLE_SYNC_CONFLICTS_VIEW, CONTEXT_HAS_CONFLICTS, IUserDataSyncConflictsView, getSyncAreaLabel } from '../common/userDataSync.js'; import { Disposable, DisposableStore } from '../../../../base/common/lifecycle.js'; import { Emitter, Event } from '../../../../base/common/event.js'; import { getCurrentAuthenticationSessionInfo } from '../../authentication/browser/authenticationService.js'; @@ -403,9 +403,21 @@ export class UserDataSyncWorkbenchService extends Disposable implements IUserDat } private async handleConflictsWhileTurningOn(token: CancellationToken): Promise { + const conflicts = this.userDataSyncService.conflicts; + const andSeparator = localize('and', ' and '); + let conflictsText = ''; + for (let i = 0; i < conflicts.length; i++) { + if (i === conflicts.length - 1 && i !== 0) { + conflictsText += andSeparator; + } else if (i !== 0) { + conflictsText += ', '; + } + conflictsText += getSyncAreaLabel(conflicts[i].syncResource); + } + const singleConflictResource = conflicts.length === 1 ? getSyncAreaLabel(conflicts[0].syncResource) : undefined; await this.dialogService.prompt({ type: Severity.Warning, - message: localize('conflicts detected', "Conflicts Detected"), + message: localize('conflicts detected', "Conflicts Detected in {0}", conflictsText), detail: localize('resolve', "Please resolve conflicts to turn on..."), buttons: [ { @@ -417,11 +429,11 @@ export class UserDataSyncWorkbenchService extends Disposable implements IUserDat } }, { - label: localize({ key: 'replace local', comment: ['&& denotes a mnemonic'] }, "Replace &&Local"), + label: singleConflictResource ? localize({ key: 'replace local single', comment: ['&& denotes a mnemonic'] }, "Accept &&Remote {0}", singleConflictResource) : localize({ key: 'replace local', comment: ['&& denotes a mnemonic'] }, "Accept &&Remote"), run: async () => this.replace(true) }, { - label: localize({ key: 'replace remote', comment: ['&& denotes a mnemonic'] }, "Replace &&Remote"), + label: singleConflictResource ? localize({ key: 'replace remote single', comment: ['&& denotes a mnemonic'] }, "Accept &&Local {0}", singleConflictResource) : localize({ key: 'replace remote', comment: ['&& denotes a mnemonic'] }, "Accept &&Local"), run: () => this.replace(false) }, ],